FpDebug: Improve using linker symbols (.symtab) on Linux. (Store SectionEnd Addr as upper bound for search)

git-svn-id: trunk@63501 -
This commit is contained in:
martin 2020-07-03 13:35:35 +00:00
parent 582cb02032
commit 9d8b224756
3 changed files with 76 additions and 10 deletions

View File

@ -10,27 +10,69 @@ uses
type
TfpLinkerSymbol = record
Addr: TDBGPtr;
SectionEnd: TDBGPtr; // Max upper Addr bound
end;
PfpLinkerSymbol = ^TfpLinkerSymbol;
{ TfpSymbolList }
TfpSymbolList= class(specialize TFPGMap<String, TDBGPtr>)
// TODO: TFPGMapObject, if we store more data
TfpSymbolList= class(specialize TFPGMap<String, TfpLinkerSymbol>)
private
FHighAddr: TDBGPtr;
FLowAddr: TDBGPtr;
function GetDataPtr(const AIndex: Integer): PfpLinkerSymbol;
function GetKeyDataPtr(const AKey: string): PfpLinkerSymbol;
public
procedure SetAddressBounds(ALowAddr, AHighAddr: TDBGPtr);
property LowAddr: TDBGPtr read FLowAddr;
property HighAddr: TDBGPtr read FHighAddr;
function Add(const AKey: String; const AData: TDBGPtr): Integer; inline; overload;
function Add(const AKey: String; const AData, ASectionEnd: TDBGPtr): Integer; inline; overload;
property KeyDataPtr[const AKey: string]: PfpLinkerSymbol read GetKeyDataPtr;
property DataPtr[const AIndex: Integer]: PfpLinkerSymbol read GetDataPtr;
end;
implementation
{ TfpSymbolList }
function TfpSymbolList.GetDataPtr(const AIndex: Integer): PfpLinkerSymbol;
begin
Result := PfpLinkerSymbol(TFPSMap(Self).Data[AIndex]);
end;
function TfpSymbolList.GetKeyDataPtr(const AKey: string): PfpLinkerSymbol;
begin
Result := PfpLinkerSymbol(TFPSMap(Self).KeyData[@AKey]);
end;
procedure TfpSymbolList.SetAddressBounds(ALowAddr, AHighAddr: TDBGPtr);
begin
FLowAddr := ALowAddr;
FHighAddr := AHighAddr;
end;
function TfpSymbolList.Add(const AKey: String; const AData: TDBGPtr): Integer;
var
d: TfpLinkerSymbol;
begin
d.Addr := AData;
d.SectionEnd := 0;
Result := Add(AKey, d);
end;
function TfpSymbolList.Add(const AKey: String; const AData, ASectionEnd: TDBGPtr
): Integer;
var
d: TfpLinkerSymbol;
begin
d.Addr := AData;
d.SectionEnd := ASectionEnd;
Result := Add(AKey, d);
end;
end.

View File

@ -111,7 +111,7 @@ begin
if i > -1 then
begin
val := Default(TFpDbgMemLocation);
val.Address:=FFpSymbolInfo.FSymbolList.Data[i];
val.Address:=FFpSymbolInfo.FSymbolList.DataPtr[i]^.Addr;
val.MType:=mlfTargetMem;
result := TFpValueConstAddress.Create(val);
end
@ -165,7 +165,7 @@ var
begin
i := FSymbolList.IndexOf(AName);
if i >= 0 then
Result := TFpSymbolTableProc.Create(AName, FSymbolList.Data[i])
Result := TFpSymbolTableProc.Create(AName, FSymbolList.DataPtr[i]^.Addr)
else
result := nil;
end;
@ -176,6 +176,7 @@ var
i, NearestIdx: integer;
a, NearestAddr: TDBGPtr;
NPreFix: String;
d: PfpLinkerSymbol;
begin
NPreFix := '';
if FLibName <> '' then
@ -190,19 +191,22 @@ begin
Result := nil;
i := FSymbolList.Count - 1;
while i >= 0 do begin
a := FSymbolList.Data[i];
if a = AnAdress then begin
Result := TFpSymbolTableProc.Create(NPreFix + FSymbolList.Keys[i], FSymbolList.Data[i]);
d := FSymbolList.DataPtr[i];
a := d^.Addr;
if (a = AnAdress) then begin
Result := TFpSymbolTableProc.Create(NPreFix + FSymbolList.Keys[i], a);
exit;
end;
if CheckRange and (a <= AnAdress) and (a > NearestAddr) then begin
if CheckRange and (a <= AnAdress) and (a > NearestAddr) and
( (d^.SectionEnd = 0) or (AnAdress <= d^.SectionEnd) )
then begin
NearestIdx := i;
NearestAddr := a;
end;
dec(i);
end;
if NearestIdx >= 0 then begin
Result := TFpSymbolTableProc.Create(NPreFix + FSymbolList.Keys[NearestIdx], FSymbolList.Data[NearestIdx]);
Result := TFpSymbolTableProc.Create(NPreFix + FSymbolList.Keys[NearestIdx], FSymbolList.DataPtr[NearestIdx]^.Addr);
end;
end;

View File

@ -44,6 +44,7 @@ type
Address : QWord;
Size : QWord;
end;
PElfSection = ^TElfSection;
{ TElfFile }
@ -393,7 +394,10 @@ var
i: integer;
SymbolCount: integer;
SymbolName: AnsiString;
SectIdx: Word;
Sect: PElfSection;
begin
AfpSymbolInfo.SetAddressBounds(1, High(AFpSymbolInfo.HighAddr)); // always search / TODO: iterate all sections for bounds
p := Section[_symbol];
ps := Section[_symbolstrings];
if assigned(p) and assigned(ps) then
@ -410,8 +414,16 @@ begin
{$R-}
if SymbolArr64^[i].st_name<>0 then
begin
SectIdx := SymbolArr64^[i].st_shndx;
if (SectIdx < 0) or (SectIdx >= fElfFile.seccount) then
continue;
Sect := @fElfFile.sections[SectIdx];
if Sect^.Address = 0 then
continue; // not loaded, symbol not in memory
SymbolName:=pchar(SymbolStr+SymbolArr64^[i].st_name);
AfpSymbolInfo.Add(SymbolName, TDbgPtr(SymbolArr64^[i].st_value+ImageBase));
AfpSymbolInfo.Add(SymbolName, TDbgPtr(SymbolArr64^[i].st_value+ImageBase),
Sect^.Address + Sect^.Size);
end;
{$pop}
end
@ -426,8 +438,16 @@ begin
begin
if SymbolArr32^[i].st_name<>0 then
begin
SectIdx := SymbolArr64^[i].st_shndx;
if (SectIdx < 0) or (SectIdx >= fElfFile.seccount) then
continue;
Sect := @fElfFile.sections[SectIdx];
if Sect^.Address = 0 then
continue; // not loaded, symbol not in memory
SymbolName:=pchar(SymbolStr+SymbolArr32^[i].st_name);
AfpSymbolInfo.Add(SymbolName, TDBGPtr(SymbolArr32^[i].st_value+ImageBase));
AfpSymbolInfo.Add(SymbolName, TDBGPtr(SymbolArr32^[i].st_value+ImageBase),
Sect^.Address + Sect^.Size);
end;
end
end;