mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-02 14:00:18 +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
|
uses
|
||||||
Classes, Windows, SysUtils, WinDDwarf, WinDPETypes, WinDDwarfConst,
|
Classes, Windows, SysUtils, WinDDwarf, WinDPETypes, WinDDwarfConst,
|
||||||
WinDSymbols, WinDLoader;
|
WinDSymbols, WinDLoader, maps;
|
||||||
|
|
||||||
var
|
var
|
||||||
ModulePtr: Pointer;
|
|
||||||
Is64: Boolean;
|
|
||||||
Sections: TStringList;
|
|
||||||
hMap, hFile: THandle;
|
|
||||||
DosHeader: PImageDosHeader;
|
|
||||||
NtHeaders: PImageNtHeaders;
|
|
||||||
SectionHeader, InfoSH, AbbrevSH: PImageSectionHeader;
|
|
||||||
n, idx: Integer;
|
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;
|
Dwarf: TDbgDwarf;
|
||||||
AbbrevDecoder: TDwarfAbbrevDecoder;
|
AbbrevDecoder: TDwarfAbbrevDecoder;
|
||||||
|
StatementDecoder: TDwarfStatementDecoder;
|
||||||
|
|
||||||
Loader: TDbgImageLoader;
|
Loader: TDbgImageLoader;
|
||||||
|
|
||||||
@ -70,150 +56,20 @@ begin
|
|||||||
|
|
||||||
Loader := TDbgWinPEImageLoader.Create(ParamStr(1));
|
Loader := TDbgWinPEImageLoader.Create(ParamStr(1));
|
||||||
|
|
||||||
(*
|
Dwarf := TDbgVerboseDwarf.Create(Loader);
|
||||||
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;
|
|
||||||
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;
|
n := Dwarf.LoadCompilationUnits;
|
||||||
for idx := 0 to n - 1 do
|
for idx := 0 to n - 1 do
|
||||||
begin
|
begin
|
||||||
Dwarf.CompilationUnits[idx].LoadAbbrevs;
|
|
||||||
AbbrevDecoder := TDwarfAbbrevDecoder.Create(Dwarf.CompilationUnits[idx]);
|
AbbrevDecoder := TDwarfAbbrevDecoder.Create(Dwarf.CompilationUnits[idx]);
|
||||||
AbbrevDecoder.Decode;
|
AbbrevDecoder.Decode;
|
||||||
|
AbbrevDecoder.Free;
|
||||||
|
StatementDecoder := TDwarfStatementDecoder.Create(Dwarf.CompilationUnits[idx]);
|
||||||
|
StatementDecoder.Decode;
|
||||||
|
StatementDecoder.Free;
|
||||||
|
WriteLN;
|
||||||
end;
|
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;
|
Dwarf.Free;
|
||||||
Loader.Free;
|
Loader.Free;
|
||||||
(*
|
|
||||||
finally
|
|
||||||
UnmapViewOfFile(ModulePtr);
|
|
||||||
CloseHandle(hMap);
|
|
||||||
Sections.Free;
|
|
||||||
end;
|
|
||||||
finally
|
|
||||||
CloseHandle(hFile);
|
|
||||||
end;
|
|
||||||
*)
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
unit AsmTestUnit;
|
unit AsmTestUnit;
|
||||||
|
|
||||||
|
|
||||||
{$mode objfpc}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -57,16 +57,22 @@ type
|
|||||||
TDbgImageLoader = class(TObject)
|
TDbgImageLoader = class(TObject)
|
||||||
private
|
private
|
||||||
FFileName: String;
|
FFileName: String;
|
||||||
|
FImage64Bit: Boolean;
|
||||||
|
FImageBase: QWord;
|
||||||
FSections: TStringList;
|
FSections: TStringList;
|
||||||
function GetSection(const AName: String): PDbgImageSection;
|
function GetSection(const AName: String): PDbgImageSection;
|
||||||
protected
|
protected
|
||||||
procedure Add(const AName: String; ARawData: Pointer; ASize: QWord; AVirtualAdress: QWord);
|
procedure Add(const AName: String; ARawData: Pointer; ASize: QWord; AVirtualAdress: QWord);
|
||||||
|
procedure SetImageBase(ABase: QWord);
|
||||||
|
procedure SetImage64Bit(AValue: Boolean);
|
||||||
procedure LoadSections; virtual; abstract;
|
procedure LoadSections; virtual; abstract;
|
||||||
procedure UnloadSections; virtual; abstract;
|
procedure UnloadSections; virtual; abstract;
|
||||||
public
|
public
|
||||||
constructor Create(const AFileName: String); virtual;
|
constructor Create(const AFileName: String); virtual;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
property FileName: String read FFileName;
|
property FileName: String read FFileName;
|
||||||
|
property ImageBase: QWord read FImageBase;
|
||||||
|
Property Image64Bit: Boolean read FImage64Bit;
|
||||||
property Section[const AName: String]: PDbgImageSection read GetSection;
|
property Section[const AName: String]: PDbgImageSection read GetSection;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -147,13 +153,24 @@ begin
|
|||||||
else Result := PDbgImageSection(FSections.Objects[idx]);
|
else Result := PDbgImageSection(FSections.Objects[idx]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TDbgImageLoader.SetImage64Bit(AValue: Boolean);
|
||||||
|
begin
|
||||||
|
FImage64Bit := AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDbgImageLoader.SetImageBase(ABase: QWord);
|
||||||
|
begin
|
||||||
|
FImageBase := ABase;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TDbgPEImageLoader }
|
{ TDbgPEImageLoader }
|
||||||
|
|
||||||
procedure TDbgPEImageLoader.LoadSections;
|
procedure TDbgPEImageLoader.LoadSections;
|
||||||
var
|
var
|
||||||
ModulePtr: Pointer;
|
ModulePtr: Pointer;
|
||||||
Is64: Boolean;
|
|
||||||
NtHeaders: PImageNtHeaders;
|
NtHeaders: PImageNtHeaders;
|
||||||
|
NtHeaders32: PImageNtHeaders32 absolute NtHeaders;
|
||||||
|
NtHeaders64: PImageNtHeaders64 absolute NtHeaders;
|
||||||
SectionHeader: PImageSectionHeader;
|
SectionHeader: PImageSectionHeader;
|
||||||
n, idx: Integer;
|
n, idx: Integer;
|
||||||
p: Pointer;
|
p: Pointer;
|
||||||
@ -167,7 +184,11 @@ begin
|
|||||||
Exit;
|
Exit;
|
||||||
end;
|
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
|
for n := 0 to NtHeaders^.FileHeader.NumberOfSections - 1 do
|
||||||
begin
|
begin
|
||||||
|
@ -56,7 +56,7 @@ const
|
|||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
{$packrecords 2}
|
{$packrecords 2}
|
||||||
|
{$IFNDEF windows}
|
||||||
type
|
type
|
||||||
_IMAGE_DOS_HEADER = record // DOS .EXE header
|
_IMAGE_DOS_HEADER = record // DOS .EXE header
|
||||||
e_magic: WORD; // Magic number
|
e_magic: WORD; // Magic number
|
||||||
@ -82,6 +82,7 @@ type
|
|||||||
IMAGE_DOS_HEADER = _IMAGE_DOS_HEADER;
|
IMAGE_DOS_HEADER = _IMAGE_DOS_HEADER;
|
||||||
TImageDosHeader = _IMAGE_DOS_HEADER;
|
TImageDosHeader = _IMAGE_DOS_HEADER;
|
||||||
PImageDosHeader = ^TImageDosHeader;
|
PImageDosHeader = ^TImageDosHeader;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
type
|
type
|
||||||
_IMAGE_OS2_HEADER = record // OS/2 .EXE header
|
_IMAGE_OS2_HEADER = record // OS/2 .EXE header
|
||||||
|
Loading…
Reference in New Issue
Block a user