mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-29 10:52:22 +02:00
FpDebug: Re-structured the reading of debug-information from multiple files.
git-svn-id: trunk@48638 -
This commit is contained in:
parent
aa026d9f75
commit
8f9d2106db
@ -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 }
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user