FpDebug: DW_AT_const_value for basic constants. / Fix for SLEB128

git-svn-id: trunk@59730 -
This commit is contained in:
martin 2018-12-05 19:43:30 +00:00
parent f09614b9a8
commit d69ccc1655
2 changed files with 88 additions and 12 deletions

View File

@ -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 }

View File

@ -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;