FpDebug: Re-structured the reading of debug-information from multiple files.

git-svn-id: trunk@48638 -
This commit is contained in:
joost 2015-04-05 20:08:17 +00:00
parent aa026d9f75
commit 8f9d2106db
9 changed files with 194 additions and 148 deletions

View File

@ -190,13 +190,13 @@ type
FName: String;
FProcess: TDbgProcess;
FSymbolTableInfo: TFpSymbolInfo;
FLoader: TDbgImageLoader;
FLoaderList: TDbgImageLoaderList;
protected
FDbgInfo: TDbgInfo;
function InitializeLoader: TDbgImageLoader; virtual;
procedure InitializeLoaders; virtual;
procedure SetName(const AValue: String);
property Loader: TDbgImageLoader read FLoader write FLoader;
property LoaderList: TDbgImageLoaderList read FLoaderList write FLoaderList;
public
constructor Create(const AProcess: TDbgProcess); virtual;
destructor Destroy; override;
@ -577,12 +577,13 @@ end;
function TDbgInstance.AddrOffset: Int64;
begin
Result := FLoader.ImageBase;
Result := FLoaderList.ImageBase;
end;
constructor TDbgInstance.Create(const AProcess: TDbgProcess);
begin
FProcess := AProcess;
FLoaderList := TDbgImageLoaderList.Create(True);
inherited Create;
end;
@ -591,7 +592,7 @@ destructor TDbgInstance.Destroy;
begin
FreeAndNil(FDbgInfo);
FreeAndNil(FSymbolTableInfo);
FreeAndNil(FLoader);
FreeAndNil(FLoaderList);
inherited;
end;
@ -604,14 +605,14 @@ end;
procedure TDbgInstance.LoadInfo;
begin
FLoader := InitializeLoader;
if FLoader.Image64Bit then
InitializeLoaders;
if FLoaderList.Image64Bit then
FMode:=dm64
else
FMode:=dm32;
FDbgInfo := TFpDwarfInfo.Create(FLoader);
FDbgInfo := TFpDwarfInfo.Create(FLoaderList);
TFpDwarfInfo(FDbgInfo).LoadCompilationUnits;
FSymbolTableInfo := TFpSymbolInfo.Create(FLoader);
FSymbolTableInfo := TFpSymbolInfo.Create(FLoaderList);
end;
function TDbgInstance.RemoveBreak(const AFileName: String; ALine: Cardinal): Boolean;
@ -630,9 +631,9 @@ begin
FName := AValue;
end;
function TDbgInstance.InitializeLoader: TDbgImageLoader;
procedure TDbgInstance.InitializeLoaders;
begin
result := nil;
// Do nothing;
end;
{ TDbgLibrary }

View File

@ -134,7 +134,7 @@ type
procedure OnForkEvent(Sender : TObject);
{$endif}
protected
function InitializeLoader: TDbgImageLoader; override;
procedure InitializeLoaders; override;
function CreateThread(AthreadIdentifier: THandle; out IsMainThread: boolean): TDbgThread; override;
function AnalyseDebugEvent(AThread: TDbgThread): TFPDEvent; override;
public
@ -637,9 +637,34 @@ begin
result := true;
end;
function TDbgDarwinProcess.InitializeLoader: TDbgImageLoader;
procedure TDbgDarwinProcess.InitializeLoaders;
var
dSYMFilename: string;
ALoader: TDbgImageLoader;
begin
result := TDbgImageLoader.Create(FExecutableFilename);
LoaderList.Add(TDbgImageLoader.Create(FExecutableFilename));
// JvdS: Mach-O binaries do not contain DWARF-debug info. Instead this info
// is stored inside the .o files, and the executable contains a map (in stabs-
// format) of all these .o files. An alternative to parsing this map and reading
// those .o files a dSYM-bundle could be used, which could be generated
// with dsymutil.
dSYMFilename:=ChangeFileExt(FExecutableFilename, '.dSYM');
dSYMFilename:=dSYMFilename+'/Contents/Resources/DWARF/'+ExtractFileName(Name);
if ExtractFileExt(dSYMFilename)='.app' then
dSYMFilename := ChangeFileExt(dSYMFilename,'');
if FileExists(dSYMFilename) then
begin
ALoader := TDbgImageLoader.Create(dSYMFilename);
if GUIDToString(ALoader.UUID)<>GUIDToString(LoaderList[0].UUID) then
log('The unique UUID''s of the executable and the dSYM bundle with debug-info ('+dSYMFilename+') do not match. This can lead to problems during debugging.', dllInfo);
LoaderList.Add(ALoader);
end
else
log('No dSYM bundle ('+dSYMFilename+') found.', dllInfo);
end;
function TDbgDarwinProcess.CreateThread(AthreadIdentifier: THandle; out IsMainThread: boolean): TDbgThread;
@ -670,42 +695,9 @@ begin
end;
procedure TDbgDarwinProcess.LoadInfo;
var
dSYMFilename: string;
ALoader: TDbgImageLoader;
begin
inherited LoadInfo;
// JvdS: Mach-O binaries do not contain DWARF-debug info. Instead this info
// is stored inside the .o files, and the executable contains a map (in stabs-
// format) of all these .o files. An alternative to parsing this map and reading
// those .o files a dSYM-bundle could be used, which could be generated
// with dsymutil.
dSYMFilename:=ChangeFileExt(Name, '.dSYM');
dSYMFilename:=dSYMFilename+'/Contents/Resources/DWARF/'+ExtractFileName(Name);
if ExtractFileExt(dSYMFilename)='.app' then
dSYMFilename := ChangeFileExt(dSYMFilename,'');
if FileExists(dSYMFilename) then
begin
ALoader := TDbgImageLoader.Create(dSYMFilename);
if GUIDToString(ALoader.UUID)<>GUIDToString(Loader.UUID) then
log('The unique UUID''s of the executable and the dSYM bundle with debug-info ('+dSYMFilename+') do not match. This can lead to problems during debugging.', dllInfo);
FDbgInfo.Free;
Loader.Free;
Loader := ALoader;
FDbgInfo := TFpDwarfInfo.Create(Loader);
TFpDwarfInfo(FDbgInfo).LoadCompilationUnits;
if FDbgInfo.HasInfo then
begin
if FSymInstances.IndexOf(Self)=-1 then
FSymInstances.Add(Self);
end;
end
else
log('No dSYM bundle ('+dSYMFilename+') found.', dllInfo);
end;
class function TDbgDarwinProcess.StartInstance(AFileName: string; AParams, AnEnvironment: TStrings; AWorkingDirectory, AConsoleTty: string; AOnLog: TOnLog; ReDirectOutput: boolean): TDbgProcess;

View File

@ -455,12 +455,26 @@ type
end;
{%endregion Base classes for handling Symbols in unit FPDbgDwarf}
TDwarfSectionInfo = record
Section: TDwarfSection;
VirtualAddress: QWord;
Size: QWord; // the virtual size
RawData: Pointer;
end;
PDwarfSectionInfo = ^TDwarfSectionInfo;
TDwarfDebugFile = record
Sections: array[TDwarfSection] of TDwarfSectionInfo;
end;
PDwarfDebugFile = ^TDwarfDebugFile;
{ TDwarfCompilationUnit }
TDwarfCompilationUnitClass = class of TDwarfCompilationUnit;
TDwarfCompilationUnit = class
private
FOwner: TFpDwarfInfo;
FDebugFile: PDwarfDebugFile;
FDwarfSymbolClassMap: TFpDwarfSymbolClassMapClass;
FValid: Boolean; // set if the compilationunit has compile unit tag.
@ -532,7 +546,7 @@ type
function ReadValue(AAttribute: Pointer; AForm: Cardinal; out AValue: TByteDynArray): Boolean;
public
constructor Create(AOwner: TFpDwarfInfo; ADataOffset: QWord; ALength: QWord; AVersion: Word; AAbbrevOffset: QWord; AAddressSize: Byte; AIsDwarf64: Boolean); virtual;
constructor Create(AOwner: TFpDwarfInfo; ADebugFile: PDwarfDebugFile; ADataOffset: QWord; ALength: QWord; AVersion: Word; AAbbrevOffset: QWord; AAddressSize: Byte; AIsDwarf64: Boolean); virtual;
destructor Destroy; override;
procedure ScanAllEntries; inline;
function GetDefinition(AAbbrevPtr: Pointer; out ADefinition: TDwarfAbbrev): Boolean; inline;
@ -552,6 +566,7 @@ type
property AddressSize: Byte read FAddressSize; // the address size of the target in bytes
property IsDwarf64: Boolean read FIsDwarf64; // Set if the dwarf info in this unit is 64bit
property Owner: TFpDwarfInfo read FOwner;
property DebugFile: PDwarfDebugFile read FDebugFile;
property DwarfSymbolClassMap: TFpDwarfSymbolClassMapClass read FDwarfSymbolClassMap;
property FirstScope: TDwarfScopeInfo read FScope;
@ -566,28 +581,19 @@ type
{ TFpDwarfInfo }
TDwarfSectionInfo = record
Section: TDwarfSection;
VirtualAddress: QWord;
Size: QWord; // the virtual size
RawData: Pointer;
end;
PDwarfSectionInfo = ^TDwarfSectionInfo;
TFpDwarfInfo = class(TDbgInfo)
private
FCompilationUnits: TList;
FImageBase: QWord;
FMemManager: TFpDbgMemManager;
FSections: array[TDwarfSection] of TDwarfSectionInfo;
FFiles: array of TDwarfDebugFile;
function GetCompilationUnit(AIndex: Integer): TDwarfCompilationUnit;
function GetSections(AIndex: TDwarfSection): TDwarfSectionInfo;
protected
function GetCompilationUnitClass: TDwarfCompilationUnitClass; virtual;
function FindCompilationUnitByOffs(AOffs: QWord): TDwarfCompilationUnit;
function FindProcSymbol(AAddress: TDbgPtr): TDbgDwarfSymbolBase;
public
constructor Create(ALoader: TDbgImageLoader); override;
constructor Create(ALoaderList: TDbgImageLoaderList); override;
destructor Destroy; override;
function FindContext(AThreadId, AStackFrame: Integer; AAddress: TDbgPtr = 0): TFpDbgInfoContext; override;
function FindContext(AAddress: TDbgPtr): TFpDbgInfoContext; override;
@ -597,12 +603,10 @@ type
function GetLineAddressMap(const AFileName: String): PDWarfLineMap;
function LoadCompilationUnits: Integer;
function PointerFromRVA(ARVA: QWord): Pointer;
function PointerFromVA(ASection: TDwarfSection; AVA: QWord): Pointer;
function CompilationUnitsCount: Integer;
property CompilationUnits[AIndex: Integer]: TDwarfCompilationUnit read GetCompilationUnit;
property MemManager: TFpDbgMemManager read FMemManager write FMemManager;
property Sections [AIndex: TDwarfSection]: TDwarfSectionInfo read GetSections;
property ImageBase: QWord read FImageBase;
end;
@ -1406,7 +1410,6 @@ begin
SetCapacity(AInfoLen div 16 + 1);
{$Endif}
SetLength(FDefinitions, 256);
//LoadAbbrevs(FOwner.PointerFromVA(dsAbbrev, FAbbrevOffset));
LoadAbbrevs(AnAbbrData + AnAbbrevOffset);
{$IFnDEF USE_ABBREV_TMAP}
Finish;
@ -2677,7 +2680,7 @@ begin
Result := FCompUnit.ReadValue(InfoData, Form, Offs);
if not Result then
exit;
AValue := FCompUnit.FOwner.FSections[dsInfo].RawData + Offs;
AValue := FCompUnit.DebugFile^.Sections[dsInfo].RawData + Offs;
if (AValue >= FCompUnit.FInfoData) and (AValue < FCompUnit.FInfoData + FCompUnit.FLength) then
ACompUnit := FCompUnit
else
@ -2803,22 +2806,28 @@ end;
{ TFpDwarfInfo }
constructor TFpDwarfInfo.Create(ALoader: TDbgImageLoader);
constructor TFpDwarfInfo.Create(ALoaderList: TDbgImageLoaderList);
var
Section: TDwarfSection;
p: PDbgImageSection;
i: Integer;
begin
inherited Create(ALoader);
inherited Create(ALoaderList);
FCompilationUnits := TList.Create;
FImageBase := ALoader.ImageBase;
for Section := Low(Section) to High(Section) do
FImageBase := ALoaderList.ImageBase;
SetLength(FFiles, ALoaderList.Count);
for i := 0 to ALoaderList.Count-1 do
begin
p := ALoader.Section[DWARF_SECTION_NAME[Section]];
if p = nil then Continue;
FSections[Section].Section := Section;
FSections[Section].RawData := p^.RawData;
FSections[Section].Size := p^.Size;
FSections[Section].VirtualAddress := p^.VirtualAddress;
for Section := Low(Section) to High(Section) do
begin
p := ALoaderList[i].Section[DWARF_SECTION_NAME[Section]];
if p = nil then Continue;
FFiles[i].Sections[Section].Section := Section;
FFiles[i].Sections[Section].RawData := p^.RawData;
FFiles[i].Sections[Section].Size := p^.Size;
FFiles[i].Sections[Section].VirtualAddress := p^.VirtualAddress;
end;
end;
end;
@ -2862,11 +2871,6 @@ begin
Result := TDwarfCompilationUnit(FCompilationUnits[Aindex]);
end;
function TFpDwarfInfo.GetSections(AIndex: TDwarfSection): TDwarfSectionInfo;
begin
Result := FSections[AIndex];
end;
function TFpDwarfInfo.GetCompilationUnitClass: TDwarfCompilationUnitClass;
begin
Result := TDwarfCompilationUnit;
@ -2878,10 +2882,10 @@ var
p: Pointer;
begin
Result := nil;
p := FSections[dsInfo].RawData + AOffs;
l := 0;
h := FCompilationUnits.Count - 1;
while h > l do begin
p := TDwarfCompilationUnit(FCompilationUnits[m]).DebugFile^.Sections[dsInfo].RawData + AOffs;
m := (h + l + 1) div 2;
if TDwarfCompilationUnit(FCompilationUnits[m]).FInfoData <= p
then l := m
@ -2988,41 +2992,47 @@ var
CU: TDwarfCompilationUnit;
CUClass: TDwarfCompilationUnitClass;
inf: TDwarfSectionInfo;
i: integer;
begin
CUClass := GetCompilationUnitClass;
inf := FSections[dsInfo];
p := FSections[dsInfo].RawData;
pe := inf.RawData + inf.Size;
while (p <> nil) and (p < pe) do
for i := 0 to high(FFiles) do
begin
if CU64^.Signature = DWARF_HEADER64_SIGNATURE
then begin
if CU64^.Version < 3 then
DebugLn(FPDBG_DWARF_WARNINGS, ['Unexpected 64 bit signature found for DWARF version 2']); // or version 1...
CU := CUClass.Create(
Self,
PtrUInt(CU64 + 1) - PtrUInt(FSections[dsInfo].RawData),
CU64^.Length - SizeOf(CU64^) + SizeOf(CU64^.Signature) + SizeOf(CU64^.Length),
CU64^.Version,
CU64^.AbbrevOffset,
CU64^.AddressSize,
True);
p := Pointer(@CU64^.Version) + CU64^.Length;
end
else begin
if CU32^.Length = 0 then Break;
CU := CUClass.Create(
Self,
PtrUInt(CU32 + 1) - PtrUInt(FSections[dsInfo].RawData),
CU32^.Length - SizeOf(CU32^) + SizeOf(CU32^.Length),
CU32^.Version,
CU32^.AbbrevOffset,
CU32^.AddressSize,
False);
p := Pointer(@CU32^.Version) + CU32^.Length;
inf := FFiles[i].Sections[dsInfo];
p := inf.RawData;
pe := inf.RawData + inf.Size;
while (p <> nil) and (p < pe) do
begin
if CU64^.Signature = DWARF_HEADER64_SIGNATURE
then begin
if CU64^.Version < 3 then
DebugLn(FPDBG_DWARF_WARNINGS, ['Unexpected 64 bit signature found for DWARF version 2']); // or version 1...
CU := CUClass.Create(
Self,
@FFiles[i],
PtrUInt(CU64 + 1) - PtrUInt(inf.RawData),
CU64^.Length - SizeOf(CU64^) + SizeOf(CU64^.Signature) + SizeOf(CU64^.Length),
CU64^.Version,
CU64^.AbbrevOffset,
CU64^.AddressSize,
True);
p := Pointer(@CU64^.Version) + CU64^.Length;
end
else begin
if CU32^.Length = 0 then Break;
CU := CUClass.Create(
Self,
@FFiles[i],
PtrUInt(CU32 + 1) - PtrUInt(inf.RawData),
CU32^.Length - SizeOf(CU32^) + SizeOf(CU32^.Length),
CU32^.Version,
CU32^.AbbrevOffset,
CU32^.AddressSize,
False);
p := Pointer(@CU32^.Version) + CU32^.Length;
end;
FCompilationUnits.Add(CU);
if CU.Valid then SetHasInfo;
end;
FCompilationUnits.Add(CU);
if CU.Valid then SetHasInfo;
end;
Result := FCompilationUnits.Count;
end;
@ -3032,11 +3042,6 @@ begin
Result := Pointer(PtrUInt(FImageBase + ARVA));
end;
function TFpDwarfInfo.PointerFromVA(ASection: TDwarfSection; AVA: QWord): Pointer;
begin
Result := FSections[ASection].RawData + AVA - FImageBase - FSections[ASection].VirtualAddress;
end;
function TFpDwarfInfo.CompilationUnitsCount: Integer;
begin
Result := FCompilationUnits.Count;
@ -3462,7 +3467,7 @@ begin
FAddressMapBuild := True;
end;
constructor TDwarfCompilationUnit.Create(AOwner: TFpDwarfInfo; ADataOffset: QWord; ALength: QWord; AVersion: Word; AAbbrevOffset: QWord; AAddressSize: Byte; AIsDwarf64: Boolean);
constructor TDwarfCompilationUnit.Create(AOwner: TFpDwarfInfo; ADebugFile: PDwarfDebugFile; ADataOffset: QWord; ALength: QWord; AVersion: Word; AAbbrevOffset: QWord; AAddressSize: Byte; AIsDwarf64: Boolean);
procedure FillLineInfo(AData: Pointer);
var
LNP32: PDwarfLNPHeader32 absolute AData;
@ -3567,15 +3572,16 @@ begin
//DebugLn(FPDBG_DWARF_VERBOSE, ['----------------------']);
inherited Create;
FOwner := AOwner;
FInfoData := FOwner.FSections[dsInfo].RawData + ADataOffset;
FDebugFile := ADebugFile;
FInfoData := ADebugFile^.Sections[dsInfo].RawData + ADataOffset;
FLength := ALength;
FVersion := AVersion;
FAbbrevOffset := AAbbrevOffset;
// check for address as offset
if FAbbrevOffset > FOwner.FSections[dsAbbrev].Size
if FAbbrevOffset > ADebugFile^.Sections[dsAbbrev].Size
then begin
Offs := FAbbrevOffset - FOwner.FImageBase - FOwner.FSections[dsAbbrev].VirtualAddress;
if (Offs >= 0) and (Offs < FOwner.FSections[dsAbbrev].Size)
Offs := FAbbrevOffset - FOwner.FImageBase - ADebugFile^.Sections[dsAbbrev].VirtualAddress;
if (Offs >= 0) and (Offs < ADebugFile^.Sections[dsAbbrev].Size)
then begin
DebugLn(FPDBG_DWARF_WARNINGS, ['WARNING: Got Abbrev offset as address, adjusting..']);
FAbbrevOffset := Offs;
@ -3585,8 +3591,8 @@ begin
FAddressSize := AAddressSize;
FIsDwarf64 := AIsDwarf64;
FAbbrevList := TDwarfAbbrevList.Create(FOwner.FSections[dsAbbrev].RawData,
FOwner.FSections[dsAbbrev].RawData + FOwner.FSections[dsAbbrev].Size,
FAbbrevList := TDwarfAbbrevList.Create(ADebugFile^.Sections[dsAbbrev].RawData,
ADebugFile^.Sections[dsAbbrev].RawData + ADebugFile^.Sections[dsAbbrev].Size,
FAbbrevOffset, FLength);
// use internally 64 bit target pointer
@ -3631,16 +3637,16 @@ begin
and ReadValue(Attrib, Form, StatementListOffs)
then begin
// check for address as offset
if StatementListOffs < FOwner.FSections[dsLine].Size
if StatementListOffs < ADebugFile^.Sections[dsLine].Size
then begin
FillLineInfo(FOwner.FSections[dsLine].RawData + StatementListOffs);
FillLineInfo(ADebugFile^.Sections[dsLine].RawData + StatementListOffs);
end
else begin
Offs := StatementListOffs - FOwner.FImageBase - FOwner.FSections[dsLine].VirtualAddress;
if (Offs >= 0) and (Offs < FOwner.FSections[dsLine].Size)
Offs := StatementListOffs - FOwner.FImageBase - ADebugFile^.Sections[dsLine].VirtualAddress;
if (Offs >= 0) and (Offs < ADebugFile^.Sections[dsLine].Size)
then begin
DebugLn(FPDBG_DWARF_WARNINGS, ['WARNING: Got Lineinfo offset as address, adjusting..']);
FillLineInfo(FOwner.FSections[dsLine].RawData + Offs);
FillLineInfo(ADebugFile^.Sections[dsLine].RawData + Offs);
end;
end;
end;
@ -4097,7 +4103,7 @@ begin
AValue := PChar(AAttribute);
end;
DW_FORM_strp: begin
AValue := pchar(PtrUInt(FOwner.Sections[dsStr].RawData)+PDWord(AAttribute)^);
AValue := pchar(PtrUInt(FDebugFile^.Sections[dsStr].RawData)+PDWord(AAttribute)^);
end;
else
Result := False;
@ -4149,7 +4155,7 @@ begin
AValue := PChar(AAttribute);
end;
DW_FORM_strp: begin
AValue := PChar(PtrUInt(FOwner.Sections[dsStr].RawData)+PDWord(AAttribute)^);
AValue := PChar(PtrUInt(FDebugFile^.Sections[dsStr].RawData)+PDWord(AAttribute)^);
end;
else
Result := False;

View File

@ -600,7 +600,7 @@ p := AData;
DW_AT_type: begin
DebugLn(FPDBG_DWARF_VERBOSE, ['-->']);
try
p := FCU.Owner.Sections[dsInfo].RawData + Value - FCU.Owner.ImageBase - FCU.Owner.Sections[dsInfo].VirtualAddress;
p := FCU.DebugFile^.Sections[dsInfo].RawData + Value - FCU.Owner.ImageBase - FCU.DebugFile^.Sections[dsInfo].VirtualAddress;
InternalDecode(p, p, Indent + ' ');
except
on E: Exception do DebugLn(FPDBG_DWARF_WARNINGS, [AIndent, ' ', E.Message]);
@ -642,7 +642,7 @@ begin
DebugLn(FPDBG_DWARF_WARNINGS, ['No lineinfo']);
Exit;
end;
InternalDecode(AData, FCU.Owner.Sections[dsInfo].RawData + FCU.Owner.Sections[dsInfo].Size);
InternalDecode(AData, FCU.DebugFile^.Sections[dsInfo].RawData + FCU.DebugFile^.Sections[dsInfo].Size);
end;
procedure TDwarfStatementDecoder.InternalDecode(AData: Pointer; AMaxData: Pointer; const AIndent: String);

View File

@ -474,7 +474,7 @@ type
protected
procedure SetHasInfo;
public
constructor Create({%H-}ALoader: TDbgImageLoader); virtual;
constructor Create({%H-}ALoaderList: TDbgImageLoaderList); virtual;
(* Context should be searched by Thread, and StackFrame. The Address can be
derived from this.
However a different Address may be froced.
@ -1352,7 +1352,7 @@ end;
{ TDbgInfo }
constructor TDbgInfo.Create(ALoader: TDbgImageLoader);
constructor TDbgInfo.Create(ALoaderList: TDbgImageLoaderList);
begin
inherited Create;
end;

View File

@ -253,7 +253,7 @@ type
procedure OnForkEvent(Sender : TObject);
{$endif}
protected
function InitializeLoader: TDbgImageLoader; override;
procedure InitializeLoaders; override;
function CreateThread(AthreadIdentifier: THandle; out IsMainThread: boolean): TDbgThread; override;
function AnalyseDebugEvent(AThread: TDbgThread): TFPDEvent; override;
public
@ -555,9 +555,9 @@ end;
{ TDbgLinuxProcess }
function TDbgLinuxProcess.InitializeLoader: TDbgImageLoader;
procedure TDbgLinuxProcess.InitializeLoaders;
begin
result := TDbgImageLoader.Create(Name);
LoaderList.Add(TDbgImageLoader.Create(Name));
end;
function TDbgLinuxProcess.CreateThread(AthreadIdentifier: THandle; out IsMainThread: boolean): TDbgThread;

View File

@ -43,7 +43,7 @@ uses
LCLType,
FpImgReaderBase, FpImgReaderWinPE, FpImgReaderElf, FpImgReaderMacho,
fpDbgSymTable,
Classes, SysUtils;
Classes, SysUtils, contnrs;
type
@ -78,10 +78,54 @@ type
property Section[const AName: String]: PDbgImageSection read GetSection;
end;
{ TDbgImageLoaderList }
TDbgImageLoaderList = class(TFPObjectList)
private
function GetImage64Bit: Boolean;
function GetImageBase: QWord;
function GetItem(Index: Integer): TDbgImageLoader;
procedure SetItem(Index: Integer; AValue: TDbgImageLoader);
public
property Items[Index: Integer]: TDbgImageLoader read GetItem write SetItem; default;
property ImageBase: QWord read GetImageBase;
Property Image64Bit: Boolean read GetImage64Bit;
end;
implementation
{ TDbgImageLoaderList }
function TDbgImageLoaderList.GetImage64Bit: Boolean;
begin
if Count<0 then
result := Items[0].Image64Bit
else
{$ifdef CPU64}
result := true
{$else}
result := false;
{$endif}
end;
function TDbgImageLoaderList.GetImageBase: QWord;
begin
if Count<0 then
result := Items[0].ImageBase
else
result := 0;
end;
function TDbgImageLoaderList.GetItem(Index: Integer): TDbgImageLoader;
begin
result := TDbgImageLoader(inherited GetItem(Index));
end;
procedure TDbgImageLoaderList.SetItem(Index: Integer; AValue: TDbgImageLoader);
begin
inherited SetItem(Index, AValue);
end;
{ TDbgImageLoader }
function TDbgImageLoader.GetImage64Bit: Boolean;

View File

@ -42,7 +42,7 @@ type
FContext: TFpSymbolContext;
FImage64Bit: boolean;
public
constructor Create(ALoader: TDbgImageLoader); override;
constructor Create(ALoaderList: TDbgImageLoaderList); override;
destructor Destroy; override;
function FindContext(AThreadId, AStackFrame: Integer; AAddress: TDbgPtr = 0): TFpDbgInfoContext; override;
function FindContext(AAddress: TDbgPtr): TFpDbgInfoContext; override;
@ -104,15 +104,18 @@ end;
{ TFpSymbolInfo }
constructor TFpSymbolInfo.Create(ALoader: TDbgImageLoader);
constructor TFpSymbolInfo.Create(ALoaderList: TDbgImageLoaderList);
var
i: Integer;
begin
inherited Create(ALoader);
inherited Create(ALoaderList);
FContext := TFpSymbolContext.Create(self);
FSymbolList := TfpSymbolList.Create;
ALoader.ParseSymbolTable(FSymbolList);
FImage64Bit := ALoader.Image64Bit;
for i := 0 to ALoaderList.Count-1 do
ALoaderList[i].ParseSymbolTable(FSymbolList);
FImage64Bit := ALoaderList.Image64Bit;
end;
destructor TFpSymbolInfo.Destroy;

View File

@ -93,7 +93,7 @@ type
protected
function GetHandle: THandle; override;
function GetLastEventProcessIdentifier: THandle; override;
function InitializeLoader: TDbgImageLoader; override;
procedure InitializeLoaders; override;
public
destructor Destroy; override;
@ -131,7 +131,7 @@ type
private
FInfo: TLoadDLLDebugInfo;
protected
function InitializeLoader: TDbgImageLoader; override;
procedure InitializeLoaders; override;
public
constructor Create(const AProcess: TDbgProcess; const ADefaultName: String;
const AModuleHandle: THandle; const ABaseAddr: TDbgPtr; AInfo: TLoadDLLDebugInfo);
@ -245,9 +245,9 @@ end;
{ tDbgWinLibrary }
function tDbgWinLibrary.InitializeLoader: TDbgImageLoader;
procedure tDbgWinLibrary.InitializeLoaders;
begin
result := TDbgImageLoader.Create(FInfo.hFile);
LoaderList.Add(TDbgImageLoader.Create(FInfo.hFile));
end;
constructor tDbgWinLibrary.Create(const AProcess: TDbgProcess;
@ -278,9 +278,9 @@ begin
Result:= MDebugEvent.LoadDll.hFile;
end;
function TDbgWinProcess.InitializeLoader: TDbgImageLoader;
procedure TDbgWinProcess.InitializeLoaders;
begin
result := TDbgImageLoader.Create(FInfo.hFile);
LoaderList.Add(TDbgImageLoader.Create(FInfo.hFile));
end;
destructor TDbgWinProcess.Destroy;