FpDebug: Refactor passing upper+lowercase name for search

git-svn-id: trunk@63807 -
This commit is contained in:
martin 2020-08-22 20:27:08 +00:00
parent 13e47b6cbd
commit 24a3af8855
3 changed files with 104 additions and 53 deletions

View File

@ -99,12 +99,12 @@ type
function SymbolToValue(ASym: TFpSymbolDwarf): TFpValue; inline;
function GetSelfParameter: TFpValueDwarf;
function FindExportedSymbolInUnits(const AName: String; PNameUpper, PNameLower: PChar;
function FindExportedSymbolInUnits(const AName: String; const ANameInfo: TNameSearchInfo;
SkipCompUnit: TDwarfCompilationUnit; out ADbgValue: TFpValue): Boolean; inline;
function FindSymbolInStructure(const AName: String; PNameUpper, PNameLower: PChar;
function FindSymbolInStructure(const AName: String; const ANameInfo: TNameSearchInfo;
InfoEntry: TDwarfInformationEntry; out ADbgValue: TFpValue): Boolean; inline;
// FindLocalSymbol: for the subroutine itself
function FindLocalSymbol(const AName: String; PNameUpper, PNameLower: PChar;
function FindLocalSymbol(const AName: String; const ANameInfo: TNameSearchInfo;
InfoEntry: TDwarfInformationEntry; out ADbgValue: TFpValue): Boolean; virtual;
public
constructor Create(ALocationContext: TFpDbgLocationContext; ASymbol: TFpSymbol; ADwarf: TFpDwarfInfo);
@ -1238,8 +1238,9 @@ begin
FSelfParameter := Result;
end;
function TFpDwarfInfoSymbolScope.FindExportedSymbolInUnits(const AName: String; PNameUpper,
PNameLower: PChar; SkipCompUnit: TDwarfCompilationUnit; out ADbgValue: TFpValue): Boolean;
function TFpDwarfInfoSymbolScope.FindExportedSymbolInUnits(const AName: String;
const ANameInfo: TNameSearchInfo; SkipCompUnit: TDwarfCompilationUnit; out
ADbgValue: TFpValue): Boolean;
var
i, ExtVal: Integer;
CU: TDwarfCompilationUnit;
@ -1247,6 +1248,7 @@ var
s: String;
begin
Result := False;
ADbgValue := nil;
InfoEntry := nil;
FoundInfoEntry := nil;
@ -1267,14 +1269,14 @@ begin
// compile_unit can not have startscope
s := CU.UnitName;
if (s <> '') and (CompareUtf8BothCase(PNameUpper, PNameLower, @s[1])) then begin
if (s <> '') and (CompareUtf8BothCase(PChar(ANameInfo.NameUpper), PChar(ANameInfo.NameLower), @s[1])) then begin
ReleaseRefAndNil(FoundInfoEntry);
ADbgValue := SymbolToValue(TFpSymbolDwarf.CreateSubClass(AName, InfoEntry));
break;
end;
CU.ScanAllEntries;
if InfoEntry.GoNamedChildEx(PNameUpper, PNameLower) then begin
if InfoEntry.GoNamedChildEx(ANameInfo) then begin
if InfoEntry.IsAddressInStartScope(FAddress) then begin
// only variables are marked "external", but types not / so we may need all top level
FoundInfoEntry.ReleaseReference;
@ -1299,8 +1301,9 @@ begin
Result := ADbgValue <> nil;
end;
function TFpDwarfInfoSymbolScope.FindSymbolInStructure(const AName: String; PNameUpper,
PNameLower: PChar; InfoEntry: TDwarfInformationEntry; out ADbgValue: TFpValue): Boolean;
function TFpDwarfInfoSymbolScope.FindSymbolInStructure(const AName: String;
const ANameInfo: TNameSearchInfo; InfoEntry: TDwarfInformationEntry; out
ADbgValue: TFpValue): Boolean;
var
InfoEntryInheritance: TDwarfInformationEntry;
FwdInfoPtr: Pointer;
@ -1317,7 +1320,7 @@ begin
InfoEntryInheritance := InfoEntry.FindChildByTag(DW_TAG_inheritance);
if InfoEntry.GoNamedChildEx(PNameUpper, PNameLower) then begin
if InfoEntry.GoNamedChildEx(ANameInfo) then begin
if InfoEntry.IsAddressInStartScope(FAddress) then begin
SelfParam := GetSelfParameter;
if (SelfParam <> nil) then begin
@ -1350,14 +1353,15 @@ begin
Result := ADbgValue <> nil;
end;
function TFpDwarfInfoSymbolScope.FindLocalSymbol(const AName: String; PNameUpper,
PNameLower: PChar; InfoEntry: TDwarfInformationEntry; out ADbgValue: TFpValue): Boolean;
function TFpDwarfInfoSymbolScope.FindLocalSymbol(const AName: String;
const ANameInfo: TNameSearchInfo; InfoEntry: TDwarfInformationEntry; out
ADbgValue: TFpValue): Boolean;
begin
Result := False;
ADbgValue := nil;
if not(Symbol is TFpSymbolDwarfDataProc) then
exit;
if not InfoEntry.GoNamedChildEx(PNameUpper, PNameLower) then
if not InfoEntry.GoNamedChildEx(ANameInfo) then
exit;
if InfoEntry.IsAddressInStartScope(FAddress) and not InfoEntry.IsArtificial then begin
ADbgValue := SymbolToValue(TFpSymbolDwarf.CreateSubClass(AName, InfoEntry));
@ -1394,10 +1398,9 @@ var
//Scope,
StartScopeIdx: Integer;
InfoEntry: TDwarfInformationEntry;
NameUpper, NameLower: String;
NameInfo: TNameSearchInfo;
InfoName: PChar;
tg: Cardinal;
PNameUpper, PNameLower: PChar;
begin
Result := nil;
//if (FSymbol = nil) or not(FSymbol is TFpSymbolDwarfDataProc) or (AName = '') then
@ -1408,13 +1411,10 @@ begin
SubRoutine := TFpSymbolDwarfDataProc(FSymbol)
else
SubRoutine := nil;
NameUpper := UTF8UpperCase(AName);
NameLower := UTF8LowerCase(AName);
PNameUpper := @NameUpper[1];
PNameLower := @NameLower[1];
NameInfo := NameInfoForSearch(AName);
if Symbol = nil then begin
FindExportedSymbolInUnits(AName, PNameUpper, PNameLower, nil, Result);
FindExportedSymbolInUnits(AName, NameInfo, nil, Result);
ApplyContext(Result);
if Result = nil then
Result := inherited FindSymbol(AName);
@ -1442,12 +1442,12 @@ begin
if InfoEntry.ReadName(InfoName) and not InfoEntry.IsArtificial
then begin
if (CompareUtf8BothCase(PNameUpper, PNameLower, InfoName)) then begin
if (CompareUtf8BothCase(PChar(NameInfo.NameUpper), PChar(NameInfo.NameLower), InfoName)) then begin
// TODO: this is a pascal specific search order? Or not?
// If this is a type with a pointer or ref, need to find the pointer or ref.
InfoEntry.GoParent;
if InfoEntry.HasValidScope and
InfoEntry.GoNamedChildEx(PNameUpper, PNameLower)
InfoEntry.GoNamedChildEx(NameInfo)
then begin
if InfoEntry.IsAddressInStartScope(FAddress) and not InfoEntry.IsArtificial then begin
Result := SymbolToValue(TFpSymbolDwarf.CreateSubClass(AName, InfoEntry));
@ -1464,7 +1464,7 @@ begin
tg := InfoEntry.AbbrevTag;
if (tg = DW_TAG_class_type) or (tg = DW_TAG_structure_type) then begin
if FindSymbolInStructure(AName,PNameUpper, PNameLower, InfoEntry, Result) then begin
if FindSymbolInStructure(AName,NameInfo, InfoEntry, Result) then begin
exit; // TODO: check error
end;
//InfoEntry.ScopeIndex := StartScopeIdx;
@ -1472,7 +1472,7 @@ begin
else
if (SubRoutine <> nil) and (StartScopeIdx = SubRoutine.InformationEntry.ScopeIndex) then begin // searching in subroutine
if FindLocalSymbol(AName,PNameUpper, PNameLower, InfoEntry, Result) then begin
if FindLocalSymbol(AName,NameInfo, InfoEntry, Result) then begin
exit; // TODO: check error
end;
//InfoEntry.ScopeIndex := StartScopeIdx;
@ -1480,7 +1480,7 @@ begin
// TODO: nested subroutine
else
if InfoEntry.GoNamedChildEx(PNameUpper, PNameLower) then begin
if InfoEntry.GoNamedChildEx(NameInfo) then begin
if InfoEntry.IsAddressInStartScope(FAddress) and not InfoEntry.IsArtificial then begin
Result := SymbolToValue(TFpSymbolDwarf.CreateSubClass(AName, InfoEntry));
exit;
@ -1492,7 +1492,7 @@ begin
InfoEntry.GoParent;
end;
FindExportedSymbolInUnits(AName, PNameUpper, PNameLower, CU, Result);
FindExportedSymbolInUnits(AName, NameInfo, CU, Result);
finally
if (Result = nil) or (InfoEntry = nil)
@ -5468,12 +5468,9 @@ begin
t.ReleaseReference;
end;
var
ThisNameInfo, SelfNameInfo: TNameSearchInfo;
function TFpSymbolDwarfDataProc.GetSelfParameter(AnAddress: TDbgPtr): TFpValueDwarf;
const
this1: string = 'THIS';
this2: string = 'this';
self1: string = '$SELF';
self2: string = '$self';
var
InfoEntry: TDwarfInformationEntry;
tg: Cardinal;
@ -5488,10 +5485,10 @@ begin
tg := InfoEntry.AbbrevTag;
if (tg = DW_TAG_class_type) or (tg = DW_TAG_structure_type) then begin
InfoEntry.ScopeIndex := InformationEntry.ScopeIndex;
found := InfoEntry.GoNamedChildEx(@this1[1], @this2[1]);
found := InfoEntry.GoNamedChildEx(ThisNameInfo);
if not found then begin
InfoEntry.ScopeIndex := InformationEntry.ScopeIndex;
found := InfoEntry.GoNamedChildEx(@self1[1], @self2[1]);
found := InfoEntry.GoNamedChildEx(SelfNameInfo);
end;
if found then begin
if ((AnAddress = 0) or InfoEntry.IsAddressInStartScope(AnAddress)) and
@ -5704,5 +5701,8 @@ initialization
FPDBG_DWARF_SEARCH := DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_SEARCH' {$IFDEF FPDBG_DWARF_SEARCH} , True {$ENDIF} );
FPDBG_DWARF_DATA_WARNINGS := DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_DATA_WARNINGS' {$IFDEF FPDBG_DWARF_DATA_WARNINGS} , True {$ENDIF} );
ThisNameInfo := NameInfoForSearch('THIS');
SelfNameInfo := NameInfoForSearch('$SELF');
end.

View File

@ -198,6 +198,10 @@ type
end;
{%endregion Abbreviation Data / Section "debug_abbrev"}
TNameSearchInfo = record
NameUpper, NameLower: String;
end;
{%region Information Entry / Section "debug_info"}
(* Link, can either be
- "Next Sibling" (for the parent): Link will be greater than current index
@ -315,7 +319,12 @@ type
function GoNamedChild(AName: String): Boolean;
// find in enum too // TODO: control search with a flags param, if needed
function GoNamedChildEx(ANameUpper, AnameLower: PChar): Boolean;
function GoNamedChildEx(const ANameInfo: TNameSearchInfo): Boolean;
// GoNamedChildMatchCaseEx will use
// - UpperName for Hash
// - LowerName for compare
// GoNamedChildMatchCaseEx does not search in enums
function GoNamedChildMatchCaseEx(const ANameInfo: TNameSearchInfo): Boolean;
function GoNamedChildEx(AName: String): Boolean; inline;
function FindNamedChild(AName: String): TDwarfInformationEntry;
@ -737,6 +746,7 @@ function Dbgs(AInfoEntry: TDwarfInformationEntry; ACompUnit: TDwarfCompilationUn
function DbgsDump(AScope: TDwarfScopeInfo; ACompUnit: TDwarfCompilationUnit): String; overload;
function GetDwarfSymbolClassMapList: TFpSymbolDwarfClassMapList; inline;
function NameInfoForSearch(const AName: String): TNameSearchInfo;
property DwarfSymbolClassMapList: TFpSymbolDwarfClassMapList read GetDwarfSymbolClassMapList;
@ -758,6 +768,12 @@ begin
Result := TheDwarfSymbolClassMapList;
end;
function NameInfoForSearch(const AName: String): TNameSearchInfo;
begin
Result.NameLower := UTF8LowerCase(AName);
Result.NameUpper := UTF8UpperCase(AName);
end;
function Dbgs(AInfoData: Pointer; ACompUnit: TDwarfCompilationUnit): String;
var
Attrib: Pointer;
@ -2552,7 +2568,7 @@ begin
end;
end;
function TDwarfInformationEntry.GoNamedChildEx(ANameUpper, AnameLower: PChar): Boolean;
function TDwarfInformationEntry.GoNamedChildEx(const ANameInfo: TNameSearchInfo): Boolean;
var
EntryName: PChar;
InEnum: Boolean;
@ -2560,7 +2576,7 @@ var
begin
Result := False;
InEnum := False;
if ANameUpper = nil then
if ANameInfo.NameUpper = '' then
exit;
GoChild;
if not HasValidScope then
@ -2572,14 +2588,15 @@ begin
GoNext;
Continue;
end;
if not ReadValue(DW_AT_name, EntryName) then begin
GoNext;
Continue;
end;
if CompareUtf8BothCase(ANameUpper, AnameLower, EntryName) then begin
if CompareUtf8BothCase(PChar(ANameInfo.NameUpper), PChar(ANameInfo.nameLower), EntryName) then begin
// TODO: check DW_AT_start_scope;
DebugLn(FPDBG_DWARF_SEARCH, ['GoNamedChildEX found ', dbgs(FScope, FCompUnit), ' Result=', DbgSName(Self), ' FOR ', AnameLower]);
DebugLn(FPDBG_DWARF_SEARCH, ['GoNamedChildEX found ', dbgs(FScope, FCompUnit), ' Result=', DbgSName(Self), ' FOR ', ANameInfo.nameLower]);
Result := True;
exit;
end;
@ -2605,16 +2622,47 @@ begin
end;
end;
function TDwarfInformationEntry.GoNamedChildEx(AName: String): Boolean;
function TDwarfInformationEntry.GoNamedChildMatchCaseEx(
const ANameInfo: TNameSearchInfo): Boolean;
var
s1, s2: String;
EntryName: PChar;
begin
Result := False;
if ANameInfo.NameUpper = '' then
exit;
GoChild;
if not HasValidScope then
exit;
while HasValidScope do begin
PrepareAbbrev;
if not (dafHasName in FAbbrev^.flags) then begin
GoNext;
Continue;
end;
if not ReadValue(DW_AT_name, EntryName) then begin
GoNext;
Continue;
end;
if CompareMem(PChar(ANameInfo.nameLower), @EntryName, Length(EntryName)) then begin
// TODO: check DW_AT_start_scope;
DebugLn(FPDBG_DWARF_SEARCH, ['GoNamedChildEX found ', dbgs(FScope, FCompUnit), ' Result=', DbgSName(Self), ' FOR ', ANameInfo.nameLower]);
Result := True;
exit;
end;
GoNext;
end;
end;
function TDwarfInformationEntry.GoNamedChildEx(AName: String): Boolean;
begin
Result := False;
if AName = '' then
exit;
s1 := UTF8UpperCase(AName);
s2 := UTF8LowerCase(AName);
Result := GoNamedChildEx(@s1[1], @s2[1]);
Result := GoNamedChildEx(NameInfoForSearch(AName));
end;
constructor TDwarfInformationEntry.Create(ACompUnit: TDwarfCompilationUnit;

View File

@ -87,7 +87,7 @@ type
FOuterNestContext: TFpDbgSymbolScope;
FOuterNotFound: Boolean;
protected
function FindLocalSymbol(const AName: String; PNameUpper, PNameLower: PChar;
function FindLocalSymbol(const AName: String; const ANameInfo: TNameSearchInfo;
InfoEntry: TDwarfInformationEntry; out ADbgValue: TFpValue): Boolean; override;
public
destructor Destroy; override;
@ -478,12 +478,13 @@ end;
{ TFpDwarfFreePascalSymbolScope }
function TFpDwarfFreePascalSymbolScope.FindLocalSymbol(const AName: String; PNameUpper,
PNameLower: PChar; InfoEntry: TDwarfInformationEntry; out ADbgValue: TFpValue): Boolean;
var
ParentFpLowerNameInfo, ParentFp2LowerNameInfo, SelfLowerNameInfo: TNameSearchInfo; // case sensitive
function TFpDwarfFreePascalSymbolScope.FindLocalSymbol(const AName: String;
const ANameInfo: TNameSearchInfo; InfoEntry: TDwarfInformationEntry; out
ADbgValue: TFpValue): Boolean;
const
parentfp: string = 'parentfp';
parentfp2: string = '$parentfp';
selfname: string = 'self';
selfname = 'self';
// TODO: get reg num via memreader name-to-num
RegFp64 = 6;
RegPc64 = 16;
@ -510,7 +511,7 @@ begin
RegFP := RegFp32;
RegPc := RegPc32;
end;
if (Length(AName) = length(selfname)) and (CompareUtf8BothCase(PNameUpper, PNameLower, @selfname[1])) then begin
if (Length(AName) = length(selfname)) and (CompareUtf8BothCase(PChar(ANameInfo.NameUpper), PChar(ANameInfo.NameLower), @selfname[1])) then begin
ADbgValue := GetSelfParameter;
if ADbgValue <> nil then begin
ADbgValue.AddReference;
@ -520,7 +521,7 @@ begin
end;
StartScopeIdx := InfoEntry.ScopeIndex;
Result := inherited FindLocalSymbol(AName, PNameUpper, PNameLower, InfoEntry, ADbgValue);
Result := inherited FindLocalSymbol(AName, ANameInfo, InfoEntry, ADbgValue);
if Result then
exit;
@ -535,9 +536,9 @@ begin
InfoEntry.ScopeIndex := StartScopeIdx;
if not InfoEntry.GoNamedChildEx(@parentfp[1], @parentfp[1]) then begin
if not InfoEntry.GoNamedChildEx(ParentFpLowerNameInfo) then begin
InfoEntry.ScopeIndex := StartScopeIdx;
if not InfoEntry.GoNamedChildEx(@parentfp2[1], @parentfp2[1]) then begin
if not InfoEntry.GoNamedChildEx(ParentFp2LowerNameInfo) then begin
FOuterNotFound := True;
exit;
end;
@ -1403,5 +1404,7 @@ initialization
FPDBG_DWARF_VERBOSE := DebugLogger.FindOrRegisterLogGroup('FPDBG_DWARF_VERBOSE' {$IFDEF FPDBG_DWARF_VERBOSE} , True {$ENDIF} );
ParentFpLowerNameInfo := NameInfoForSearch('parentfp');
ParentFp2LowerNameInfo := NameInfoForSearch('$parentfp');
end.