mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-30 20:30:41 +02:00
FpDebug: Move reading dwarf-2 length of dyn-array to fpc specific unit (fpdbgdwarffreepascal)
git-svn-id: trunk@61415 -
This commit is contained in:
parent
5effef2a57
commit
5d6b05e0c0
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user