FpDebug: Move reading dwarf-2 length of dyn-array to fpc specific unit (fpdbgdwarffreepascal)

git-svn-id: trunk@61415 -
This commit is contained in:
martin 2019-06-18 18:39:15 +00:00
parent 5effef2a57
commit 5d6b05e0c0
2 changed files with 76 additions and 60 deletions

View File

@ -189,6 +189,7 @@ type
property TypeCastTargetType: TFpDwarfSymbolType read FTypeCastTargetType;
property TypeCastSourceValue: TFpDbgValue read FTypeCastSourceValue;
property Owner: TFpDwarfSymbolType read FOwner;
public
constructor Create(AOwner: TFpDwarfSymbolType);
destructor Destroy; override;
@ -656,7 +657,7 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
end;
{ TFpDwarfSymbolTypeSubRange }
TFpDwarfSubRangeBoundReadState = (rfNotRead, rfNotFound, rfConst, rfValue);
TFpDwarfSubRangeBoundReadState = (rfNotRead, rfNotFound, rfError, rfConst, rfValue);
TFpDwarfSymbolTypeSubRange = class(TFpDwarfSymbolTypeModifier)
// TODO not a modifier, maybe have a forwarder base class
@ -691,6 +692,11 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
function GetValueBounds(AValueObj: TFpDwarfValue; out ALowBound,
AHighBound: Int64): Boolean; override;
procedure ResetValueBounds; override;
property LowBoundState: TFpDwarfSubRangeBoundReadState read FLowBoundState;
property HighBoundState: TFpDwarfSubRangeBoundReadState read FHighBoundState;
property CountState: TFpDwarfSubRangeBoundReadState read FCountState;
end;
{ TFpDwarfSymbolTypePointer }
@ -2698,26 +2704,7 @@ begin
if t.MemberCount < 1 then // IndexTypeCount;
exit;
t2 := t.Member[0]; // IndexType[0];
if not ((t2 is TFpDwarfSymbolType) and (TFpDwarfSymbolType(t2).GetValueBounds(self, LowBound, HighBound))) and
not t2.HasBounds then begin
if (sfDynArray in t.Flags) and (AsCardinal <> 0) and
GetDwarfDataAddress(Addr, TFpDwarfSymbolType(FOwner))
then begin
if not (IsReadableMem(Addr) and (LocToAddr(Addr) > AddressSize)) then
exit;
Addr.Address := Addr.Address - AddressSize;
if MemManager.ReadSignedInt(Addr, AddressSize, i) then begin
Result := Integer(i)+1;
exit;
end
else
FLastError := MemManager.LastError;
end;
exit;
end;
if t2.HasBounds then begin
LowBound := t2.OrdLowBound;
HighBound := t2.OrdHighBound;
if TFpDwarfSymbolType(t2).GetValueBounds(self, LowBound, HighBound) then begin
if HighBound < LowBound then
exit(0); // empty array // TODO: error
// TODO: XXXXX Dynamic max limit
@ -3613,7 +3600,9 @@ begin
FLowBoundValue := TFpDwarfSymbolValue.CreateValueSubClass('', NewInfo);
NewInfo.ReleaseReference;
if FLowBoundValue = nil then begin
FLowBoundState := rfNotFound; // not implemented => so for all purpose tread it as if there is no dwarf description of the low bound
// Not implemented in DwarfSymbolClassMap.GetDwarfSymbolClass
// or not a value type (bound can not be a type)
FLowBoundState := rfError;
exit;
end
else
@ -3627,7 +3616,7 @@ begin
begin
//FLowBoundConst := 0; // the default
//FLowBoundState := rfConst;
FLowBoundState := rfNotFound;
FLowBoundState := rfError;
exit; // incomplete type
end;
end
@ -3641,7 +3630,7 @@ begin
FHighBoundValue := TFpDwarfSymbolValue.CreateValueSubClass('', NewInfo);
NewInfo.ReleaseReference;
if FHighBoundValue = nil then begin
FHighBoundState := rfNotFound; // not implemented => so for all purpose tread it as if there is no dwarf description of the low bound
FHighBoundState := rfError;
exit;
end
else
@ -3661,7 +3650,7 @@ begin
FHighBoundConst := Int64(AnAddress.Address);
end
else
FHighBoundState := rfNotFound;
FHighBoundState := rfError;
end;
end
else
@ -3675,7 +3664,7 @@ begin
FCountValue := TFpDwarfSymbolValue.CreateValueSubClass('', NewInfo);
NewInfo.ReleaseReference;
if FCountValue = nil then begin
FCountState := rfNotFound;
FCountState := rfError;
exit;
end
else
@ -3686,7 +3675,7 @@ begin
FCountState := rfConst;
end
else
FCountState := rfNotFound;
FCountState := rfError;
end
else
FCountState := rfNotFound;

View File

@ -527,58 +527,85 @@ end;
function TFpDwarfValueFreePascalArray.GetMemberCount: Integer;
var
t, t2: TFpDbgSymbol;
Info, Info2: TDwarfInformationEntry;
Info: TDwarfInformationEntry;
n: AnsiString;
UpperBoundSym: TFpDwarfSymbol;
val: TFpDbgValue;
l, h: Int64;
Addr: TFpDbgMemLocation;
begin
Result := 0;
t := TypeInfo;
if t.MemberCount < 1 then // IndexTypeCount;
if (t.Kind <> skArray) or (t.MemberCount < 1) then // IndexTypeCount;
exit(inherited GetMemberCount);
t2 := t.Member[0]; // IndexType[0];
if not (t2 is TFpDwarfSymbolTypeSubRange) then
exit(inherited GetMemberCount);
TFpDwarfSymbolTypeSubRange(t2).GetValueBounds(Self, l, h);
if (l <> 0) or
(TFpDwarfSymbolTypeSubRange(t2).LowBoundState <> rfConst) or
(TFpDwarfSymbolTypeSubRange(t2).HighBoundState <> rfNotFound) or
(TFpDwarfSymbolTypeSubRange(t2).CountState <> rfNotFound)
then
exit(inherited GetMemberCount);
// Check for open array param
if (t is TFpDwarfSymbolTypeArray) and
(t2 is TFpDwarfSymbolTypeSubRange) and
(DbgSymbol is TFpDwarfSymbolValueParameter) // open array exists only as param
then begin
Info := TFpDwarfSymbolTypeSubRange(t2).InformationEntry;
if Info.HasAttrib(DW_AT_lower_bound) and
not Info.HasAttrib(DW_AT_upper_bound)
Info := TFpDwarfSymbolValueParameter(DbgSymbol).InformationEntry.Clone;
Info.GoNext;
if Info.HasValidScope and
Info.HasAttrib(DW_AT_location) and // the high param must have a location / cannot be a constant
Info.ReadName(n)
then begin
Info2 := TFpDwarfSymbolValueParameter(DbgSymbol).InformationEntry.Clone;
Info2.GoNext;
if Info2.HasValidScope and
Info2.HasAttrib(DW_AT_location) and // the high param must have a location / cannot be a constant
Info2.ReadName(n)
then begin
if (n <> '') and (n[1] = '$') then // dwarf3 // TODO: make required in dwarf3
delete(n, 1, 1);
if (copy(n,1,4) = 'high') and (UpperCase(copy(n, 5, length(n))) = UpperCase(DbgSymbol.Name)) then begin
UpperBoundSym := TFpDwarfSymbol.CreateSubClass('', Info2);
if UpperBoundSym <> nil then begin
val := UpperBoundSym.Value;
TFpDwarfValue(val).Context := Context;
l := t2.OrdLowBound;
h := Val.AsInteger;
if h > l then begin
if h - l > 5000 then
h := l + 5000;
Result := h - l + 1;
end
else
Result := 0;
Info2.ReleaseReference;
UpperBoundSym.ReleaseReference;
exit;
end;
if (n <> '') and (n[1] = '$') then // dwarf3 // TODO: make required in dwarf3
delete(n, 1, 1);
if (copy(n,1,4) = 'high') and (UpperCase(copy(n, 5, length(n))) = UpperCase(DbgSymbol.Name)) then begin
UpperBoundSym := TFpDwarfSymbol.CreateSubClass('', Info);
if UpperBoundSym <> nil then begin
val := UpperBoundSym.Value;
TFpDwarfValue(val).Context := Context;
//l := t2.OrdLowBound;
h := Val.AsInteger;
if h > l then begin
if h - l > 5000 then
h := l + 5000;
Result := h - l + 1;
end
else
Result := 0;
Info.ReleaseReference;
UpperBoundSym.ReleaseReference;
exit;
end;
end;
Info2.ReleaseReference;
end;
Info.ReleaseReference;
end;
// dynamic array
if (sfDynArray in t.Flags) and (AsCardinal <> 0) and
GetDwarfDataAddress(Addr, TFpDwarfSymbolType(Owner))
then begin
if not (IsReadableMem(Addr) and (LocToAddr(Addr) > 4)) then
exit(0); // dyn array, but bad data
Addr.Address := Addr.Address - AddressSize;
//debugln(['TFpDwarfValueArray.GetMemberCount XXXXXXXXXXXXXXX dwarf 2 read len']);
if MemManager.ReadSignedInt(Addr, AddressSize, h) then begin
Result := Integer(h)+1;
exit;
end
else
FLastError := MemManager.LastError;
Result := 0;
exit;
end;
// Should not be here. There is no knowledeg how many members there are
Result := inherited GetMemberCount;
end;