FPDebug: handle start scope / fix searching class parents

git-svn-id: trunk@43444 -
This commit is contained in:
martin 2013-11-14 14:05:49 +00:00
parent a54cbc502f
commit f3f65fc02b

View File

@ -560,6 +560,7 @@ type
constructor Create(AName: String; AnInformationEntry: TDwarfInformationEntry; constructor Create(AName: String; AnInformationEntry: TDwarfInformationEntry;
AKind: TDbgSymbolKind; AAddress: TDbgPtr); AKind: TDbgSymbolKind; AAddress: TDbgPtr);
destructor Destroy; override; destructor Destroy; override;
function StartScope: TDbgPtr; // return 0, if none. 0 includes all anyway
end; end;
{ TDbgDwarfValueIdentifier } { TDbgDwarfValueIdentifier }
@ -3541,6 +3542,19 @@ begin
ReleaseRefAndNil(FNestedTypeInfo); ReleaseRefAndNil(FNestedTypeInfo);
end; end;
function TDbgDwarfIdentifier.StartScope: TDbgPtr;
var
a: PDwarfAbbrev;
begin
a := FInformationEntry.Abbrev;
if (a <> nil) and (dafHasStartScope in a^.flags) then begin
if not FInformationEntry.ReadValue(DW_AT_start_scope, Result) then
Result := 0;
end
else
Result := 0;
end;
{ TDWarfLineMap } { TDWarfLineMap }
procedure TDWarfLineMap.Init; procedure TDWarfLineMap.Init;
@ -5069,6 +5083,8 @@ var
FwdInfoPtr: Pointer; FwdInfoPtr: Pointer;
tg: Cardinal; tg: Cardinal;
p1, p2: PChar; p1, p2: PChar;
StartScope: TDbgPtr;
abbr: PDwarfAbbrev;
begin begin
Result := nil; Result := nil;
if (FSymbol = nil) or not(FSymbol is TDbgDwarfProcSymbol) or (AName = '') then if (FSymbol = nil) or not(FSymbol is TDbgDwarfProcSymbol) or (AName = '') then
@ -5090,8 +5106,24 @@ begin
debugln(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier Searching ', dbgs(InfoEntry.FScope, CU)]); debugln(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier Searching ', dbgs(InfoEntry.FScope, CU)]);
StartScopeIdx := InfoEntry.ScopeIndex; StartScopeIdx := InfoEntry.ScopeIndex;
// Todo (dafHasName in InfoEntry.Abbrev.flags) and abbr := InfoEntry.Abbrev;
if InfoEntry.ReadValue(DW_AT_name, InfoName) then begin if abbr = nil then
exit;
if (dafHasStartScope in abbr^.flags) and
InfoEntry.ReadValue(DW_AT_start_scope, StartScope)
then begin
if StartScope > FAddress then begin
// CONTINUE: Search parent(s)
InfoEntry.ScopeIndex := StartScopeIdx;
InfoEntry.GoParent;
Continue;
end;
end;
if (dafHasName in abbr^.flags) and
InfoEntry.ReadValue(DW_AT_name, InfoName)
then begin
if (CompareUtf8BothCase(p1, p2, InfoName)) then begin if (CompareUtf8BothCase(p1, p2, InfoName)) then begin
Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntry); Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntry);
DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier found ', dbgs(InfoEntry.FScope, CU), DbgSName(Result)]); DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier found ', dbgs(InfoEntry.FScope, CU), DbgSName(Result)]);
@ -5099,14 +5131,20 @@ begin
end; end;
end; end;
tg := InfoEntry.AbbrevTag;
if InfoEntry.GoNamedChildEx(p1, p2) then begin if InfoEntry.GoNamedChildEx(p1, p2) then begin
if not( (dafHasStartScope in InfoEntry.Abbrev^.flags) and
InfoEntry.ReadValue(DW_AT_start_scope, StartScope) )
then
StartScope := 0;
if StartScope <= FAddress then begin
Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntry); Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntry);
DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier found ', dbgs(InfoEntry.FScope, CU), DbgSName(Result)]); DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier found ', dbgs(InfoEntry.FScope, CU), DbgSName(Result)]);
exit; exit;
end; end;
end;
tg := abbr^.tag;
if (tg = DW_TAG_class_type) or (tg = DW_TAG_structure_type) then begin if (tg = DW_TAG_class_type) or (tg = DW_TAG_structure_type) then begin
// search parent class // search parent class
InfoEntry.ScopeIndex := StartScopeIdx; InfoEntry.ScopeIndex := StartScopeIdx;
@ -5115,13 +5153,27 @@ begin
InfoEntryParent.ReleaseReference; InfoEntryParent.ReleaseReference;
InfoEntryParent := TDwarfInformationEntry.Create(FwdCompUint, FwdInfoPtr); InfoEntryParent := TDwarfInformationEntry.Create(FwdCompUint, FwdInfoPtr);
DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier PARENT ', dbgs(InfoEntryParent, FwdCompUint) ]); DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier PARENT ', dbgs(InfoEntryParent, FwdCompUint) ]);
if (dafHasStartScope in InfoEntryParent.Abbrev^.flags) and
InfoEntryParent.ReadValue(DW_AT_start_scope, StartScope)
then
if StartScope > FAddress then
break;
InfoEntryTmp := InfoEntryParent.FindChildByTag(DW_TAG_inheritance);
if InfoEntryParent.GoNamedChildEx(p1, p2) then begin if InfoEntryParent.GoNamedChildEx(p1, p2) then begin
if not( (dafHasStartScope in InfoEntryParent.Abbrev^.flags) and
InfoEntryParent.ReadValue(DW_AT_start_scope, StartScope) )
then
StartScope := 0;
if StartScope <= FAddress then begin
Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntryParent); Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntryParent);
InfoEntryParent.ReleaseReference; InfoEntryParent.ReleaseReference;
InfoEntryTmp.ReleaseReference;
DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier found ', dbgs(InfoEntryParent.FScope, CU), DbgSName(Result)]); DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier found ', dbgs(InfoEntryParent.FScope, CU), DbgSName(Result)]);
exit; exit;
end; end;
InfoEntryTmp := InfoEntryParent.FindChildByTag(DW_TAG_inheritance); end;
InfoEntryParent.ReleaseReference; InfoEntryParent.ReleaseReference;
InfoEntryParent := InfoEntryTmp; InfoEntryParent := InfoEntryTmp;
end; end;
@ -5147,6 +5199,7 @@ begin
if not InfoEntry.AbbrevTag = DW_TAG_compile_unit then if not InfoEntry.AbbrevTag = DW_TAG_compile_unit then
continue; continue;
// compile_unit can not have startscope
s := CU2.UnitName; s := CU2.UnitName;
if (s <> '') and (CompareUtf8BothCase(p1, p2, @s[1])) then begin if (s <> '') and (CompareUtf8BothCase(p1, p2, @s[1])) then begin
@ -5157,7 +5210,12 @@ begin
CU2.ScanAllEntries; CU2.ScanAllEntries;
if InfoEntry.GoNamedChildEx(p1, p2) then begin if InfoEntry.GoNamedChildEx(p1, p2) then begin
// only variables are marked, but types not / so we may need all top level if not( (dafHasStartScope in InfoEntryParent.Abbrev^.flags) and
InfoEntryParent.ReadValue(DW_AT_start_scope, StartScope) )
then
StartScope := 0;
if StartScope <= FAddress then begin
// only variables are marked "external", but types not / so we may need all top level
Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntry); Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntry);
DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier found (other unit) ', dbgs(InfoEntry.FScope, CU2), DbgSName(Result)]); DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier found (other unit) ', dbgs(InfoEntry.FScope, CU2), DbgSName(Result)]);
// DW_AT_visibility ? // DW_AT_visibility ?
@ -5166,6 +5224,7 @@ begin
break; break;
// Search for better result // Search for better result
end; end;
end;
end; end;