mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-19 10:49:44 +02:00
FpDebug: DW_AT_const_value for basic constants. / Fix for SLEB128
git-svn-id: trunk@59730 -
This commit is contained in:
parent
f09614b9a8
commit
d69ccc1655
@ -469,6 +469,11 @@ type
|
||||
AnInformationEntry: TDwarfInformationEntry = nil;
|
||||
ASucessOnMissingTag: Boolean = False
|
||||
): Boolean;
|
||||
function ConstantFromTag(ATag: Cardinal; out AConstData: TByteDynArray;
|
||||
var AnAddress: TFpDbgMemLocation; // kept, if tag does not exist
|
||||
AnInformationEntry: TDwarfInformationEntry = nil;
|
||||
ASucessOnMissingTag: Boolean = False
|
||||
): Boolean;
|
||||
// GetDataAddress: data of a class, or string
|
||||
function GetDataAddress(AValueObj: TFpDwarfValue; var AnAddress: TFpDbgMemLocation;
|
||||
ATargetType: TFpDwarfSymbolType; ATargetCacheIndex: Integer): Boolean;
|
||||
@ -857,6 +862,8 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
|
||||
{ TFpDwarfSymbolValueVariable }
|
||||
|
||||
TFpDwarfSymbolValueVariable = class(TFpDwarfSymbolValueWithLocation)
|
||||
private
|
||||
FConstData: TByteDynArray;
|
||||
protected
|
||||
function GetValueAddress(AValueObj: TFpDwarfValue; out AnAddress: TFpDbgMemLocation): Boolean; override;
|
||||
function HasAddress: Boolean; override;
|
||||
@ -2333,7 +2340,8 @@ begin
|
||||
FValueSymbol.GetValueAddress(Self, t);
|
||||
assert(SizeOf(FDataAddress) >= AddressSize, 'TDbgDwarfStructSymbolValue.GetDataAddress');
|
||||
if (MemManager <> nil) then begin
|
||||
FDataAddress := MemManager.ReadAddress(t, AddressSize);
|
||||
// TODO: wrong for records (const / DW_AT_FORM) // use GetDwarfDataAddress??
|
||||
FDataAddress := MemManager.ReadAddress(t, AddressSize);
|
||||
if not IsValidLoc(FDataAddress) then
|
||||
FLastError := MemManager.LastError;
|
||||
end;
|
||||
@ -2885,7 +2893,7 @@ begin
|
||||
if not Result then
|
||||
AnAddress := InvalidLoc;
|
||||
if not Result then
|
||||
DebugLn(['LocationFromTag: failed to read DW_AT_location / ASucessOnMissingTag=', dbgs(ASucessOnMissingTag)]);
|
||||
DebugLn(['LocationFromTag: failed to read DW_AT_location / ASucessOnMissingTag=', dbgs(ASucessOnMissingTag)]);
|
||||
exit;
|
||||
end;
|
||||
|
||||
@ -2904,7 +2912,7 @@ begin
|
||||
SetLastError(LocationParser.LastError);
|
||||
|
||||
if LocationParser.ResultKind in [lseValue] then begin
|
||||
AnAddress := TargetLoc(LocationParser.ResultData);
|
||||
AnAddress := TargetLoc(LocationParser.ResultData);// TODO: wrong, if origin was selfmem
|
||||
if ATag=DW_AT_location then
|
||||
AnAddress.Address :=CompilationUnit.MapAddressToNewValue(AnAddress.Address);
|
||||
Result := True;
|
||||
@ -2920,6 +2928,41 @@ begin
|
||||
LocationParser.Free;
|
||||
end;
|
||||
|
||||
function TFpDwarfSymbol.ConstantFromTag(ATag: Cardinal; out
|
||||
AConstData: TByteDynArray; var AnAddress: TFpDbgMemLocation;
|
||||
AnInformationEntry: TDwarfInformationEntry; ASucessOnMissingTag: Boolean
|
||||
): Boolean;
|
||||
var
|
||||
i: Integer;
|
||||
v: QWord;
|
||||
s: string;
|
||||
dummy: pointer;
|
||||
begin
|
||||
AConstData := nil;
|
||||
i := InformationEntry.AttribIdx(DW_AT_const_value, dummy);
|
||||
if i >= 0 then
|
||||
case InformationEntry.AttribForm[i] of
|
||||
DW_FORM_string, DW_FORM_strp,
|
||||
DW_FORM_block, DW_FORM_block1, DW_FORM_block2, DW_FORM_block4: begin
|
||||
Result := InformationEntry.ReadValue(DW_AT_const_value, AConstData, True);
|
||||
if Result then
|
||||
if Length(AConstData) > 0 then
|
||||
AnAddress := SelfLoc(@AConstData[0])
|
||||
else
|
||||
AnAddress := InvalidLoc; // TODO: ???
|
||||
end;
|
||||
DW_FORM_data1, DW_FORM_data2, DW_FORM_data4, DW_FORM_data8, DW_FORM_sdata, DW_FORM_udata: begin
|
||||
Result := InformationEntry.ReadValue(DW_AT_const_value, v);
|
||||
if Result then
|
||||
AnAddress := ConstLoc(v);
|
||||
end;
|
||||
else
|
||||
Result := False; // ASucessOnMissingTag ?
|
||||
end
|
||||
else
|
||||
Result := ASucessOnMissingTag;
|
||||
end;
|
||||
|
||||
function TFpDwarfSymbol.GetDataAddress(AValueObj: TFpDwarfValue;
|
||||
var AnAddress: TFpDbgMemLocation; ATargetType: TFpDwarfSymbolType;
|
||||
ATargetCacheIndex: Integer): Boolean;
|
||||
@ -4699,13 +4742,17 @@ begin
|
||||
Result := IsValidLoc(AnAddress);
|
||||
if IsInitializedLoc(AnAddress) then
|
||||
exit;
|
||||
Result := LocationFromTag(DW_AT_location, AValueObj, AnAddress);
|
||||
if InformationEntry.HasAttrib(DW_AT_location) then
|
||||
Result := LocationFromTag(DW_AT_location, AValueObj, AnAddress)
|
||||
else
|
||||
Result := ConstantFromTag(DW_AT_const_value, FConstData, AnAddress);
|
||||
AValueObj.DataAddressCache[0] := AnAddress;
|
||||
end;
|
||||
|
||||
function TFpDwarfSymbolValueVariable.HasAddress: Boolean;
|
||||
begin
|
||||
Result := InformationEntry.HasAttrib(DW_AT_location);
|
||||
Result := InformationEntry.HasAttrib(DW_AT_location) or
|
||||
InformationEntry.HasAttrib(DW_AT_const_value);
|
||||
end;
|
||||
|
||||
{ TFpDwarfSymbolValueParameter }
|
||||
|
@ -280,6 +280,7 @@ type
|
||||
FAbstractOrigin: TDwarfInformationEntry;
|
||||
FFlags: set of (dieAbbrevValid, dieAbbrevDataValid, dieAbstractOriginValid);
|
||||
|
||||
function GetAttribForm(AnIdx: Integer): Cardinal;
|
||||
procedure PrepareAbbrev; inline;
|
||||
function PrepareAbbrevData: Boolean; inline;
|
||||
function PrepareAbstractOrigin: Boolean; inline; // Onli call, if abbrev is valid AND dafHasAbstractOrigin set
|
||||
@ -299,6 +300,7 @@ type
|
||||
|
||||
function AttribIdx(AnAttrib: Cardinal; out AInfoPointer: pointer): Integer; inline;
|
||||
function HasAttrib(AnAttrib: Cardinal): Boolean; inline;
|
||||
property AttribForm[AnIdx: Integer]: Cardinal read GetAttribForm;
|
||||
|
||||
function GoNamedChild(AName: String): Boolean;
|
||||
// find in enum too // TODO: control search with a flags param, if needed
|
||||
@ -318,7 +320,7 @@ type
|
||||
function ReadValue(AnAttrib: Cardinal; out AValue: QWord): Boolean;
|
||||
function ReadValue(AnAttrib: Cardinal; out AValue: PChar): Boolean;
|
||||
function ReadValue(AnAttrib: Cardinal; out AValue: String): Boolean;
|
||||
function ReadValue(AnAttrib: Cardinal; out AValue: TByteDynArray): Boolean;
|
||||
function ReadValue(AnAttrib: Cardinal; out AValue: TByteDynArray; AnFormString: Boolean = False): Boolean;
|
||||
function ReadReference(AnAttrib: Cardinal; out AValue: Pointer; out ACompUnit: TDwarfCompilationUnit): Boolean;
|
||||
|
||||
function ReadName(out AName: String): Boolean; inline;
|
||||
@ -550,7 +552,7 @@ type
|
||||
function ReadValue(AAttribute: Pointer; AForm: Cardinal; out AValue: QWord): Boolean;
|
||||
function ReadValue(AAttribute: Pointer; AForm: Cardinal; out AValue: String): Boolean;
|
||||
function ReadValue(AAttribute: Pointer; AForm: Cardinal; out AValue: PChar): Boolean;
|
||||
function ReadValue(AAttribute: Pointer; AForm: Cardinal; out AValue: TByteDynArray): Boolean;
|
||||
function ReadValue(AAttribute: Pointer; AForm: Cardinal; out AValue: TByteDynArray; AnFormString: Boolean = False): Boolean;
|
||||
// Read a value that contains an address. The address is evaluated using MapAddressToNewValue
|
||||
function ReadAddressValue(AAttribute: Pointer; AForm: Cardinal; out AValue: QWord): Boolean;
|
||||
|
||||
@ -802,7 +804,7 @@ begin
|
||||
until Stop or (n > 128);
|
||||
|
||||
// sign extend when msbit = 1
|
||||
if (p[-1] and $40) <> 0
|
||||
if ((p[-1] and $40) <> 0) and (n < 64) // only supports 64 bit
|
||||
then Result := Result or (Int64(-1) shl n);
|
||||
end;
|
||||
|
||||
@ -2211,6 +2213,11 @@ begin
|
||||
Include(FFlags, dieAbbrevValid);
|
||||
end;
|
||||
|
||||
function TDwarfInformationEntry.GetAttribForm(AnIdx: Integer): Cardinal;
|
||||
begin
|
||||
Result := FAbbrevData[AnIdx].Form;
|
||||
end;
|
||||
|
||||
function TDwarfInformationEntry.PrepareAbbrevData: Boolean;
|
||||
var
|
||||
AbbrList: TDwarfAbbrevList;
|
||||
@ -2641,7 +2648,7 @@ begin
|
||||
end;
|
||||
|
||||
function TDwarfInformationEntry.ReadValue(AnAttrib: Cardinal; out
|
||||
AValue: TByteDynArray): Boolean;
|
||||
AValue: TByteDynArray; AnFormString: Boolean): Boolean;
|
||||
var
|
||||
AData: pointer;
|
||||
i: Integer;
|
||||
@ -2649,11 +2656,11 @@ begin
|
||||
i := AttribIdx(AnAttrib, AData);
|
||||
if i < 0 then begin
|
||||
if (dafHasAbstractOrigin in FAbbrev^.flags) and PrepareAbstractOrigin
|
||||
then Result := FAbstractOrigin.ReadValue(AnAttrib, AValue)
|
||||
then Result := FAbstractOrigin.ReadValue(AnAttrib, AValue, AnFormString)
|
||||
else Result := False;
|
||||
end
|
||||
else
|
||||
Result := FCompUnit.ReadValue(AData, FAbbrevData[i].Form, AValue);
|
||||
Result := FCompUnit.ReadValue(AData, FAbbrevData[i].Form, AValue, AnFormString);
|
||||
end;
|
||||
|
||||
function TDwarfInformationEntry.ReadReference(AnAttrib: Cardinal; out AValue: Pointer; out
|
||||
@ -4315,9 +4322,11 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDwarfCompilationUnit.ReadValue(AAttribute: Pointer; AForm: Cardinal; out AValue: TByteDynArray): Boolean;
|
||||
function TDwarfCompilationUnit.ReadValue(AAttribute: Pointer; AForm: Cardinal;
|
||||
out AValue: TByteDynArray; AnFormString: Boolean): Boolean;
|
||||
var
|
||||
Size: Cardinal;
|
||||
mx, i: Pointer;
|
||||
begin
|
||||
Result := True;
|
||||
case AForm of
|
||||
@ -4336,6 +4345,26 @@ begin
|
||||
Size := PLongWord(AAttribute)^;
|
||||
Inc(AAttribute, 4);
|
||||
end;
|
||||
DW_FORM_strp, DW_FORM_string: begin
|
||||
Result := AnFormString;
|
||||
Size := 0;
|
||||
if Result then begin
|
||||
mx := FDebugFile^.Sections[dsInfo].RawData +FDebugFile^.Sections[dsInfo].Size;
|
||||
if AForm = DW_FORM_strp then begin
|
||||
AAttribute := FDebugFile^.Sections[dsStr].RawData+PDWord(AAttribute)^;
|
||||
mx := FDebugFile^.Sections[dsStr].RawData +FDebugFile^.Sections[dsStr].Size;
|
||||
end;
|
||||
i := AAttribute;
|
||||
while (PByte(i)^ <> 0) and (i < mx) do Inc(i);
|
||||
if i = mx then begin
|
||||
DebugLn(FPDBG_DWARF_ERRORS, 'String exceeds section');
|
||||
Result := False;
|
||||
end
|
||||
else begin
|
||||
Size := i + 1 - AAttribute; // include #0
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
else
|
||||
Result := False;
|
||||
Size := 0;
|
||||
|
Loading…
Reference in New Issue
Block a user