+ added line decoder

* splitup verbose/nonverbose classes

git-svn-id: trunk@10026 -
This commit is contained in:
marc 2006-10-03 19:28:25 +00:00
parent 73cc06aa51
commit f2088e4dab
5 changed files with 1142 additions and 234 deletions

View File

@ -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.

View File

@ -1,5 +1,6 @@
unit AsmTestUnit;
{$mode objfpc}{$H+}
interface

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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