mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 01:59:08 +02:00
+ added line decoder
* splitup verbose/nonverbose classes git-svn-id: trunk@10026 -
This commit is contained in:
parent
73cc06aa51
commit
f2088e4dab
@ -37,27 +37,13 @@ program FPDumpDwarf;
|
||||
|
||||
uses
|
||||
Classes, Windows, SysUtils, WinDDwarf, WinDPETypes, WinDDwarfConst,
|
||||
WinDSymbols, WinDLoader;
|
||||
WinDSymbols, WinDLoader, maps;
|
||||
|
||||
var
|
||||
ModulePtr: Pointer;
|
||||
Is64: Boolean;
|
||||
Sections: TStringList;
|
||||
hMap, hFile: THandle;
|
||||
DosHeader: PImageDosHeader;
|
||||
NtHeaders: PImageNtHeaders;
|
||||
SectionHeader, InfoSH, AbbrevSH: PImageSectionHeader;
|
||||
n, idx: Integer;
|
||||
SectionName: array[0..IMAGE_SIZEOF_SHORT_NAME] of Char;
|
||||
AbbrevPtr, AbbrevPtrMax, AbbrevBase: Pointer;
|
||||
InfoPtr, InfoPtrMax: Pointer;
|
||||
InfoOffset: Int64;
|
||||
Abb: Cardinal;
|
||||
CUHeader, NextCUHeader: PDwarfCUHeader32;
|
||||
p: Pointer;
|
||||
|
||||
Dwarf: TDbgDwarf;
|
||||
AbbrevDecoder: TDwarfAbbrevDecoder;
|
||||
StatementDecoder: TDwarfStatementDecoder;
|
||||
|
||||
Loader: TDbgImageLoader;
|
||||
|
||||
@ -69,151 +55,21 @@ begin
|
||||
end;
|
||||
|
||||
Loader := TDbgWinPEImageLoader.Create(ParamStr(1));
|
||||
|
||||
(*
|
||||
hFile := CreateFile(PChar(ParamStr(1)), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if hFile = INVALID_HANDLE_VALUE
|
||||
then begin
|
||||
WriteLN('Cannot open file: ', ParamStr(1));
|
||||
Exit;
|
||||
|
||||
Dwarf := TDbgVerboseDwarf.Create(Loader);
|
||||
n := Dwarf.LoadCompilationUnits;
|
||||
for idx := 0 to n - 1 do
|
||||
begin
|
||||
AbbrevDecoder := TDwarfAbbrevDecoder.Create(Dwarf.CompilationUnits[idx]);
|
||||
AbbrevDecoder.Decode;
|
||||
AbbrevDecoder.Free;
|
||||
StatementDecoder := TDwarfStatementDecoder.Create(Dwarf.CompilationUnits[idx]);
|
||||
StatementDecoder.Decode;
|
||||
StatementDecoder.Free;
|
||||
WriteLN;
|
||||
end;
|
||||
|
||||
try
|
||||
hMap := 0;
|
||||
ModulePtr := nil;
|
||||
Sections := nil;
|
||||
try
|
||||
hMap := CreateFileMapping(hFile, nil, PAGE_READONLY{ or SEC_IMAGE}, 0, 0, nil);
|
||||
if hMap = 0
|
||||
then begin
|
||||
WriteLn('Could not create module mapping');
|
||||
Exit;
|
||||
end;
|
||||
|
||||
ModulePtr := MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
|
||||
if ModulePtr = nil
|
||||
then begin
|
||||
WriteLn('Could not map view');
|
||||
Exit;
|
||||
end;
|
||||
|
||||
DosHeader := ModulePtr;
|
||||
if (DosHeader^.e_magic <> IMAGE_DOS_SIGNATURE)
|
||||
or (DosHeader^.e_lfanew = 0)
|
||||
then begin
|
||||
WriteLn('Invalid DOS header');
|
||||
Exit;
|
||||
end;
|
||||
|
||||
NTHeaders := ModulePtr + DosHeader^.e_lfanew;
|
||||
|
||||
if NTHeaders^.Signature <> IMAGE_NT_SIGNATURE
|
||||
then begin
|
||||
WriteLn('Invalid NT header: ', IntToHex(NTHeaders^.Signature, 8));
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Is64 := NTHeaders^.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
|
||||
|
||||
Sections := TStringList.Create;
|
||||
Sections.CaseSensitive := False;
|
||||
Sections.Duplicates := dupIgnore;
|
||||
Sections.Sorted := True;
|
||||
for n := 0 to NtHeaders^.FileHeader.NumberOfSections - 1 do
|
||||
begin
|
||||
SectionHeader := @NTHeaders^.OptionalHeader + NTHeaders^.FileHeader.SizeOfOptionalHeader + SizeOf(SectionHeader^) * n;
|
||||
// make a null terminated name
|
||||
Move(SectionHeader^.Name, SectionName, IMAGE_SIZEOF_SHORT_NAME);
|
||||
SectionName[IMAGE_SIZEOF_SHORT_NAME] := #0;
|
||||
if (SectionName[0] = '/') and (SectionName[1] in ['0'..'9'])
|
||||
then begin
|
||||
// long name
|
||||
p := ModulePtr + NTHeaders^.FileHeader.PointerToSymbolTable + NTHeaders^.FileHeader.NumberOfSymbols * IMAGE_SIZEOF_SYMBOL + StrToIntDef(PChar(@SectionName[1]), 0);
|
||||
Sections.AddObject(PChar(p), TObject(SectionHeader));
|
||||
end
|
||||
else begin
|
||||
// short name
|
||||
Sections.AddObject(SectionName, TObject(SectionHeader));
|
||||
end
|
||||
end;
|
||||
|
||||
WriteLN('Sections:');
|
||||
for n := 0 to Sections.Count - 1 do
|
||||
WriteLn(' ', Sections[n], #9'@$', Format('%p', [Pointer(Sections.Objects[n])]));
|
||||
|
||||
idx := Sections.IndexOf('.debug_info');
|
||||
if idx = -1
|
||||
then begin
|
||||
WriteLn('.debug_info section not found. Nothing to do.');
|
||||
Exit;
|
||||
end;
|
||||
|
||||
InfoSH := Pointer(Sections.Objects[idx]);
|
||||
InfoPtr := ModulePtr + InfoSH^.PointerToRawData;
|
||||
InfoPtrMax := InfoPtr + InfoSH^.Misc.VirtualSize - 1;
|
||||
InfoOffset := PtrUInt(InfoPtr) - NTHeaders^.OptionalHeader.ImageBase - InfoSH^.VirtualAddress;
|
||||
|
||||
idx := Sections.IndexOf('.debug_abbrev');
|
||||
if idx = -1
|
||||
then begin
|
||||
WriteLn('.debug_abbrev section not found. Nothing to do.');
|
||||
Exit;
|
||||
end;
|
||||
AbbrevSH := Pointer(Sections.Objects[idx]);
|
||||
AbbrevPtr := ModulePtr + AbbrevSH^.PointerToRawData;
|
||||
AbbrevPtrMax := AbbrevPtr + AbbrevSH^.Misc.VirtualSize - 1;
|
||||
AbbrevBase := AbbrevPtr - NTHeaders^.OptionalHeader.ImageBase - AbbrevSH^.VirtualAddress;
|
||||
*)
|
||||
Dwarf := TDbgDwarf.Create(Loader);
|
||||
n := Dwarf.LoadCompilationUnits;
|
||||
for idx := 0 to n - 1 do
|
||||
begin
|
||||
Dwarf.CompilationUnits[idx].LoadAbbrevs;
|
||||
AbbrevDecoder := TDwarfAbbrevDecoder.Create(Dwarf.CompilationUnits[idx]);
|
||||
AbbrevDecoder.Decode;
|
||||
end;
|
||||
|
||||
(*
|
||||
CUHeader := InfoPtr;
|
||||
while (CUHeader <> nil) and (CUHeader^.Length > 0) and (CUHeader <= InfoPtrMax) do
|
||||
begin
|
||||
WriteLN('Compilation unit:');
|
||||
WriteLn(' length: ', CUHeader^.Length);
|
||||
WriteLn(' version: ', CUHeader^.Version);
|
||||
WriteLn(' abbrev offset: ', IntToHex(CUHeader^.AbbrevOffset, 8));
|
||||
WriteLn(' address size: ', CUHeader^.AddressSize);
|
||||
|
||||
NextCUHeader := @CUHeader^.Version + CUHeader^.Length;
|
||||
|
||||
p := AbbrevBase + CUHeader^.AbbrevOffset;
|
||||
if (p < AbbrevPtr) or (p > AbbrevPtrMax)
|
||||
then begin
|
||||
WriteLN('Warning: Abbrev offset not in .debug_abbrev section');
|
||||
end;
|
||||
|
||||
if NextCUHeader < InfoPtrMax
|
||||
then Abbrev := TDbgDwarf.Create(InfoOffset, p, AbbrevBase + NextCUHeader^.AbbrevOffset)
|
||||
else Abbrev := TDbgDwarf.Create(InfoOffset, p, AbbrevPtrMax);
|
||||
|
||||
p := CUHeader + 1;
|
||||
Abbrev.Decode(p, Pointer(NextCUHeader) - 1);
|
||||
|
||||
FreeAndNil(Abbrev);
|
||||
|
||||
CUHeader := NextCUHeader;
|
||||
end;
|
||||
*)
|
||||
Dwarf.Free;
|
||||
Loader.Free;
|
||||
(*
|
||||
finally
|
||||
UnmapViewOfFile(ModulePtr);
|
||||
CloseHandle(hMap);
|
||||
Sections.Free;
|
||||
end;
|
||||
finally
|
||||
CloseHandle(hFile);
|
||||
end;
|
||||
*)
|
||||
Dwarf.Free;
|
||||
Loader.Free;
|
||||
end.
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
unit AsmTestUnit;
|
||||
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -57,16 +57,22 @@ type
|
||||
TDbgImageLoader = class(TObject)
|
||||
private
|
||||
FFileName: String;
|
||||
FImage64Bit: Boolean;
|
||||
FImageBase: QWord;
|
||||
FSections: TStringList;
|
||||
function GetSection(const AName: String): PDbgImageSection;
|
||||
protected
|
||||
procedure Add(const AName: String; ARawData: Pointer; ASize: QWord; AVirtualAdress: QWord);
|
||||
procedure SetImageBase(ABase: QWord);
|
||||
procedure SetImage64Bit(AValue: Boolean);
|
||||
procedure LoadSections; virtual; abstract;
|
||||
procedure UnloadSections; virtual; abstract;
|
||||
public
|
||||
constructor Create(const AFileName: String); virtual;
|
||||
destructor Destroy; override;
|
||||
property FileName: String read FFileName;
|
||||
property ImageBase: QWord read FImageBase;
|
||||
Property Image64Bit: Boolean read FImage64Bit;
|
||||
property Section[const AName: String]: PDbgImageSection read GetSection;
|
||||
end;
|
||||
|
||||
@ -147,13 +153,24 @@ begin
|
||||
else Result := PDbgImageSection(FSections.Objects[idx]);
|
||||
end;
|
||||
|
||||
procedure TDbgImageLoader.SetImage64Bit(AValue: Boolean);
|
||||
begin
|
||||
FImage64Bit := AValue;
|
||||
end;
|
||||
|
||||
procedure TDbgImageLoader.SetImageBase(ABase: QWord);
|
||||
begin
|
||||
FImageBase := ABase;
|
||||
end;
|
||||
|
||||
{ TDbgPEImageLoader }
|
||||
|
||||
procedure TDbgPEImageLoader.LoadSections;
|
||||
var
|
||||
ModulePtr: Pointer;
|
||||
Is64: Boolean;
|
||||
NtHeaders: PImageNtHeaders;
|
||||
NtHeaders32: PImageNtHeaders32 absolute NtHeaders;
|
||||
NtHeaders64: PImageNtHeaders64 absolute NtHeaders;
|
||||
SectionHeader: PImageSectionHeader;
|
||||
n, idx: Integer;
|
||||
p: Pointer;
|
||||
@ -167,7 +184,11 @@ begin
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Is64 := NtHeaders^.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
|
||||
SetImage64Bit(NtHeaders^.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC);
|
||||
|
||||
if Image64Bit
|
||||
then SetImageBase(NtHeaders64^.OptionalHeader.ImageBase)
|
||||
else SetImageBase(NtHeaders32^.OptionalHeader.ImageBase);
|
||||
|
||||
for n := 0 to NtHeaders^.FileHeader.NumberOfSections - 1 do
|
||||
begin
|
||||
|
@ -56,7 +56,7 @@ const
|
||||
{$endif}
|
||||
|
||||
{$packrecords 2}
|
||||
|
||||
{$IFNDEF windows}
|
||||
type
|
||||
_IMAGE_DOS_HEADER = record // DOS .EXE header
|
||||
e_magic: WORD; // Magic number
|
||||
@ -82,6 +82,7 @@ type
|
||||
IMAGE_DOS_HEADER = _IMAGE_DOS_HEADER;
|
||||
TImageDosHeader = _IMAGE_DOS_HEADER;
|
||||
PImageDosHeader = ^TImageDosHeader;
|
||||
{$ENDIF}
|
||||
|
||||
type
|
||||
_IMAGE_OS2_HEADER = record // OS/2 .EXE header
|
||||
|
Loading…
Reference in New Issue
Block a user