FpDebug: Differentiate between the BaseAddr and the RelocationOffset

This commit is contained in:
Joost van der Sluis 2021-12-13 22:45:48 +01:00
parent d116a8f5cc
commit 70d007f0de
8 changed files with 62 additions and 45 deletions

View File

@ -466,7 +466,7 @@ type
procedure SetFileName(const AValue: String);
procedure SetMode(AMode: TFPDMode); experimental; // for testcase
public
constructor Create(const AProcess: TDbgProcess); virtual;
constructor Create(const AProcess: TDbgProcess; ARelocationOffset: TDBGPtr = 0); virtual;
destructor Destroy; override;
// Returns the addresses at the given source-filename and line-number.
@ -498,12 +498,15 @@ type
TDbgLibrary = class(TDbgInstance)
private
FModuleHandle: THandle;
FBaseAddr: TDBGPtr;
FRelocationOffset: TDBGPtr;
public
constructor Create(const AProcess: TDbgProcess; const ADefaultName: String; const AModuleHandle: THandle; const ABaseAddr: TDbgPtr);
constructor Create(const AProcess: TDbgProcess; const ADefaultName: String; const AModuleHandle: THandle; const ARelocationAddress: TDbgPtr);
property Name: String read FFileName;
property ModuleHandle: THandle read FModuleHandle;
property BaseAddr: TDBGPtr read FBaseAddr;
// The relocationoffset is the offset at which the binary (most likely
// library) is loaded into memory. It is not part of the binary itself, unlike
// the BaseAddr.
property RelocationOffset: TDBGPtr read FRelocationOffset;
end;
TStartInstanceFlag = (siRediretOutput, siForceNewConsole);
@ -1634,11 +1637,11 @@ begin
Result := SymbolTableInfo.FindProcSymbol(AName);
end;
constructor TDbgInstance.Create(const AProcess: TDbgProcess);
constructor TDbgInstance.Create(const AProcess: TDbgProcess; ARelocationOffset: TDBGPtr);
begin
FProcess := AProcess;
FMemManager := AProcess.MemManager;
FLoaderList := TDbgImageLoaderList.Create(True);
FLoaderList := TDbgImageLoaderList.Create(True, ARelocationOffset);
inherited Create;
end;
@ -1722,12 +1725,12 @@ end;
{ TDbgLibrary }
constructor TDbgLibrary.Create(const AProcess: TDbgProcess; const ADefaultName: String; const AModuleHandle: THandle; const ABaseAddr: TDbgPtr);
constructor TDbgLibrary.Create(const AProcess: TDbgProcess; const ADefaultName: String; const AModuleHandle: THandle; const ARelocationAddress: TDbgPtr);
begin
inherited Create(AProcess);
inherited Create(AProcess, ARelocationAddress);
FModuleHandle:=AModuleHandle;
FBaseAddr:=ABaseAddr;
FRelocationOffset:=ARelocationAddress;
end;
{ TDbgProcess }

View File

@ -757,6 +757,7 @@ type
FFiles: array of TDwarfDebugFile;
private
FImageBase: QWord;
FRelocationOffset: TDBGPtr;
function GetCompilationUnit(AIndex: Integer): TDwarfCompilationUnit; inline;
protected
function GetCompilationUnitClass: TDwarfCompilationUnitClass; virtual;
@ -779,6 +780,7 @@ type
property CompilationUnits[AIndex: Integer]: TDwarfCompilationUnit read GetCompilationUnit;
property ImageBase: QWord read FImageBase;
property RelocationOffset: TDBGPtr read FRelocationOffset;
property WorkQueue: TFpGlobalThreadWorkerQueue read FWorkQueue;
end;
@ -3615,6 +3617,7 @@ begin
FTargetInfo := ALoaderList.TargetInfo;
FCompilationUnits := TList.Create;
FImageBase := ALoaderList.ImageBase;
FRelocationOffset := ALoaderList.RelocationOffset;
SetLength(FFiles, ALoaderList.Count);
for i := 0 to ALoaderList.Count-1 do
@ -4947,7 +4950,7 @@ end;
function TDwarfCompilationUnit.CalculateRelocatedAddress(AValue: QWord): QWord;
begin
Result := AValue + FOwner.ImageBase;
Result := AValue + FOwner.RelocationOffset;
end;
function TDwarfCompilationUnit.GetProcStartEnd(const AAddress: TDBGPtr; out

View File

@ -374,7 +374,7 @@ type
protected
procedure InitializeLoaders; override;
public
constructor Create(const AProcess: TDbgProcess; const AFileName: string; const AModuleHandle: THandle; const ABaseAddr: TDbgPtr);
constructor Create(const AProcess: TDbgProcess; const AFileName: string; const AModuleHandle: THandle; const ARelocationAddress: TDbgPtr);
end;
@ -396,20 +396,20 @@ procedure tDbgLinuxLibrary.InitializeLoaders;
var
Loader: TDbgImageLoader;
begin
Loader := TDbgImageLoader.Create(Name, nil, BaseAddr);
Loader := TDbgImageLoader.Create(Name, nil, LoaderList.RelocationOffset);
// The dynamic-loader (dl) on Linux also loads other stuff then ELF-
// formatted libraries.
// So it is reasonable likely that the loaded 'library' can not be handled
// by the detault readers from the loader.
// by the default readers from the loader.
if Loader.IsValid then
Loader.AddToLoaderList(LoaderList)
else
Loader.Free;
end;
constructor tDbgLinuxLibrary.Create(const AProcess: TDbgProcess; const AFileName: string; const AModuleHandle: THandle; const ABaseAddr: TDbgPtr);
constructor tDbgLinuxLibrary.Create(const AProcess: TDbgProcess; const AFileName: string; const AModuleHandle: THandle; const ARelocationAddress: TDbgPtr);
begin
Inherited Create(AProcess, AFileName, AModuleHandle, ABaseAddr);
Inherited Create(AProcess, AFileName, AModuleHandle, ARelocationAddress);
SetFileName(AFileName);
LoadInfo;
@ -1075,7 +1075,7 @@ procedure TDbgLinuxProcess.AddLib(const ALibrary: TDbgLibrary);
var
ID: TDbgPtr;
begin
ID := ALibrary.BaseAddr;
ID := ALibrary.RelocationOffset;
FLibMap.Add(ID, ALibrary);
if (ALibrary.DbgInfo.HasInfo) or (ALibrary.SymbolTableInfo.HasInfo) then
FSymInstances.Add(ALibrary);

View File

@ -73,10 +73,10 @@ type
public
constructor Create; virtual;
constructor Create(AFileName: String; ADebugMap: TObject = nil;
ALoadedTargetImageAddr: TDBGPtr = 0);
ARelocationOffset: TDBGPtr = 0);
{$ifdef USE_WIN_FILE_MAPPING}
constructor Create(AFileHandle: THandle; ADebugMap: TObject = nil;
ALoadedTargetImageAddr: TDBGPtr = 0);
ARelocationOffset: TDBGPtr = 0);
{$endif}
destructor Destroy; override;
procedure ParseSymbolTable(AFpSymbolInfo: TfpSymbolList); virtual;
@ -110,13 +110,16 @@ type
TDbgImageLoaderList = class(TFPObjectList)
private
FRelocationOffset: TDBGPtr;
function GetImageBase: QWord;
function GetTargetInfo: TTargetDescriptor;
function GetItem(Index: Integer): TDbgImageLoader;
procedure SetItem(Index: Integer; AValue: TDbgImageLoader);
public
constructor Create(FreeObjects : Boolean; ARelocationOffset: TDbgPtr);
property Items[Index: Integer]: TDbgImageLoader read GetItem write SetItem; default;
property ImageBase: QWord read GetImageBase;
property RelocationOffset: QWord read FRelocationOffset;
property TargetInfo: TTargetDescriptor read GetTargetInfo;
end;
@ -150,6 +153,12 @@ begin
inherited SetItem(Index, AValue);
end;
constructor TDbgImageLoaderList.Create(FreeObjects: Boolean; ARelocationOffset: TDbgPtr);
begin
inherited Create(FreeObjects);
FRelocationOffset := ARelocationOffset;
end;
{ TDbgImageLoaderLibrary }
procedure TDbgImageLoaderLibrary.ParseSymbolTable(AFpSymbolInfo: TfpSymbolList);
@ -229,21 +238,21 @@ begin
end;
constructor TDbgImageLoader.Create(AFileName: String; ADebugMap: TObject;
ALoadedTargetImageAddr: TDBGPtr);
ARelocationOffset: TDBGPtr);
begin
FFileName := AFileName;
FFileLoader := TDbgFileLoader.Create(AFileName);
FImgReader := GetImageReader(FFileLoader, ADebugMap, ALoadedTargetImageAddr, False);
FImgReader := GetImageReader(FFileLoader, ADebugMap, ARelocationOffset, False);
if not Assigned(FImgReader) then
FreeAndNil(FFileLoader);
end;
{$ifdef USE_WIN_FILE_MAPPING}
constructor TDbgImageLoader.Create(AFileHandle: THandle; ADebugMap: TObject;
ALoadedTargetImageAddr: TDBGPtr);
ARelocationOffset: TDBGPtr);
begin
FFileLoader := TDbgFileLoader.Create(AFileHandle);
FImgReader := GetImageReader(FFileLoader, ADebugMap, ALoadedTargetImageAddr, False);
FImgReader := GetImageReader(FFileLoader, ADebugMap, ARelocationOffset, False);
if not Assigned(FImgReader) then
FreeAndNil(FFileLoader);
end;

View File

@ -97,7 +97,7 @@ type
private
FImageBase: QWord;
FImageSize: QWord;
FLoadedTargetImageAddr: TDBGPtr;
FRelocationOffset: TDBGPtr;
FReaderErrors: String;
FUUID: TGuid;
protected
@ -117,9 +117,12 @@ type
class function UserName: AnsiString; virtual; abstract;
procedure ParseSymbolTable(AFpSymbolInfo: TfpSymbolList); virtual;
procedure ParseLibrarySymbolTable(AFpSymbolInfo: TfpSymbolList); virtual;
constructor Create({%H-}ASource: TDbgFileLoader; {%H-}ADebugMap: TObject; ALoadedTargetImageAddr: TDbgPtr; OwnSource: Boolean); virtual;
constructor Create({%H-}ASource: TDbgFileLoader; {%H-}ADebugMap: TObject; ARelocationOffset: TDbgPtr; OwnSource: Boolean); virtual;
procedure AddSubFilesToLoaderList(ALoaderList: TObject; PrimaryLoader: TObject); virtual;
// The ImageBase is the address at which the linker assumed the binary will be
// loaded. So it is stored inside the binary itself, in contrast to the
// RelocationOffset, which contains an offset once the binary has really
// been loaded into another position.
property ImageBase: QWord read FImageBase;
property ImageSize: QWord read FImageSize;
@ -132,13 +135,14 @@ type
property AddressMapList: TDbgAddressMapList read GetAddressMapList;
property ReaderErrors: String read FReaderErrors;
// The target (library/process) is loaded/mapped into memory at the
// LoadedTargetImageAddr address.
property LoadedTargetImageAddr: TDBGPtr read FLoadedTargetImageAddr;
// The relocationoffset is the offset at which the binary (most likely
// library) is loaded into memory. It is not part of the binary itself, unlike
// the BaseAddr.
property RelocationOffset: TDBGPtr read FRelocationOffset;
end;
TDbgImageReaderClass = class of TDbgImageReader;
function GetImageReader(ASource: TDbgFileLoader; ADebugMap: TObject; ALoadedTargetImageAddr: TDbgPtr; OwnSource: Boolean): TDbgImageReader; overload;
function GetImageReader(ASource: TDbgFileLoader; ADebugMap: TObject; ARelocationOffset: TDbgPtr; OwnSource: Boolean): TDbgImageReader; overload;
procedure RegisterImageReaderClass(DataSource: TDbgImageReaderClass);
implementation
@ -180,7 +184,7 @@ end;
result := (r1.OrgAddr=r2.OrgAddr) and (r1.Length=r2.Length) and (r1.NewAddr=r2.NewAddr);
end;
function GetImageReader(ASource: TDbgFileLoader; ADebugMap: TObject; ALoadedTargetImageAddr: TDbgPtr; OwnSource: Boolean): TDbgImageReader;
function GetImageReader(ASource: TDbgFileLoader; ADebugMap: TObject; ARelocationOffset: TDbgPtr; OwnSource: Boolean): TDbgImageReader;
var
i : Integer;
cls : TDbgImageReaderClass;
@ -192,7 +196,7 @@ begin
cls := TDbgImageReaderClass(RegisteredImageReaderClasses[i]);
try
if cls.isValid(ASource) then begin
Result := cls.Create(ASource, ADebugMap, ALoadedTargetImageAddr, OwnSource);
Result := cls.Create(ASource, ADebugMap, ARelocationOffset, OwnSource);
ASource.Close;
Exit;
end
@ -499,10 +503,10 @@ begin
//
end;
constructor TDbgImageReader.Create(ASource: TDbgFileLoader; ADebugMap: TObject; ALoadedTargetImageAddr: TDbgPtr; OwnSource: Boolean);
constructor TDbgImageReader.Create(ASource: TDbgFileLoader; ADebugMap: TObject; ARelocationOffset: TDbgPtr; OwnSource: Boolean);
begin
inherited Create;
FLoadedTargetImageAddr := ALoadedTargetImageAddr;
FRelocationOffset := ARelocationOffset;
end;
procedure TDbgImageReader.AddSubFilesToLoaderList(ALoaderList: TObject;

View File

@ -416,8 +416,6 @@ begin
fElfFile := TElfFile.Create;
fElfFile.LoadFromFile(FFileLoader);
SetImageBase(LoadedTargetImageAddr);
LoadSections;
// check external debug file
if ReadGnuDebugLinkSection(DbgFileName, crc) then
@ -492,8 +490,8 @@ begin
continue; // not loaded, symbol not in memory
SymbolName:=pchar(SymbolStr+SymbolArr64^[i].st_name);
AfpSymbolInfo.Add(SymbolName, TDbgPtr(SymbolArr64^[i].st_value+ImageBase),
Sect^.Address + Sect^.Size + ImageBase);
AfpSymbolInfo.Add(SymbolName, TDbgPtr(SymbolArr64^[i].st_value+RelocationOffset),
Sect^.Address + Sect^.Size + RelocationOffset);
end;
{$pop}
end
@ -516,8 +514,8 @@ begin
continue; // not loaded, symbol not in memory
SymbolName:=pchar(SymbolStr+SymbolArr32^[i].st_name);
AfpSymbolInfo.Add(SymbolName, TDBGPtr(SymbolArr32^[i].st_value+ImageBase),
Sect^.Address + Sect^.Size+ImageBase);
AfpSymbolInfo.Add(SymbolName, TDBGPtr(SymbolArr32^[i].st_value+RelocationOffset),
Sect^.Address + Sect^.Size+RelocationOffset);
end;
end
end;

View File

@ -46,7 +46,7 @@ type
procedure AddSubFilesToLoaderList(ALoaderList: TObject; PrimaryLoader: TObject); override;
procedure ParseSymbolTable(AfpSymbolInfo: TfpSymbolList); override;
public
constructor Create(ASource: TDbgFileLoader; ADebugMap: TObject; ALoadedTargetImageAddr: TDbgPtr; OwnSource: Boolean); override;
constructor Create(ASource: TDbgFileLoader; ADebugMap: TObject; ARelocationOffset: TDbgPtr; OwnSource: Boolean); override;
destructor Destroy; override;
end;
@ -411,7 +411,7 @@ begin
end;
end;
constructor TDbgMachoDataSource.Create(ASource: TDbgFileLoader; ADebugMap: TObject; ALoadedTargetImageAddr: TDbgPtr; OwnSource: Boolean);
constructor TDbgMachoDataSource.Create(ASource: TDbgFileLoader; ADebugMap: TObject; ARelocationOffset: TDbgPtr; OwnSource: Boolean);
const
SymbolsSectionName : array [Boolean] of AnsiString = (_symbol, _symbolstrings);
var
@ -422,7 +422,7 @@ var
soffset: int64;
ssize: int64;
begin
inherited Create(ASource, ADebugMap, ALoadedTargetImageAddr, OwnSource);
inherited Create(ASource, ADebugMap, ARelocationOffset, OwnSource);
fSource := ASource;
fOwnSource := OwnSource;

View File

@ -66,7 +66,7 @@ type
class function isValid(ASource: TDbgFileLoader): Boolean; override;
class function UserName: AnsiString; override;
public
constructor Create(ASource: TDbgFileLoader; ADebugMap: TObject; ALoadedTargetImageAddr: TDbgPtr; OwnSource: Boolean); override;
constructor Create(ASource: TDbgFileLoader; ADebugMap: TObject; ARelocationOffset: TDbgPtr; OwnSource: Boolean); override;
destructor Destroy; override;
procedure ParseSymbolTable(AfpSymbolInfo: TfpSymbolList); override;
procedure ParseLibrarySymbolTable(AFpSymbolInfo: TfpSymbolList); override;
@ -105,13 +105,13 @@ begin
end;
end;
constructor TPEFileSource.Create(ASource: TDbgFileLoader; ADebugMap: TObject; ALoadedTargetImageAddr: TDbgPtr; OwnSource: Boolean);
constructor TPEFileSource.Create(ASource: TDbgFileLoader; ADebugMap: TObject; ARelocationOffset: TDbgPtr; OwnSource: Boolean);
var
crc: cardinal;
DbgFileName, SourceFileName: String;
NewFileLoader: TDbgFileLoader;
begin
inherited Create(ASource, ADebugMap, ALoadedTargetImageAddr, OwnSource);
inherited Create(ASource, ADebugMap, ARelocationOffset, OwnSource);
FSections := TStringListUTF8Fast.Create;
FSections.Sorted := False; // need sections in original order / Symbols use "SectionNumber"
//FSections.Duplicates := dupError;