home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
vp21beta.zip
/
LRTLSRC.RAR
/
PE2ELF
/
ELFLIST.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
2000-08-15
|
17KB
|
450 lines
//
(*$D+,L+,Locinfo+*)
//programmheader und sektionenheader auswerten (doppelte anzeige)
//oder /P | /S | /A | /E | /? | /H
//!!!.got auflisten
// note sektion (S.42)
{█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█}
{█ █}
{█ Virtual Pascal for Linux █}
{█ ELF dump utility █}
{█ ─────────────────────────────────────────────────█}
{█ Copyright (C) 1999 Veit Kannegieser █}
{█ █}
{▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀}
(*$I+,Delphi+,X+*)
program elflist;
uses
strings,
elfdef;
type
fa=array[0..1000000] of char;
var
elf_kopf:Elf32_Ehdr_type;
programm_kopf:program_header_type;
sektionen_kopf:section_header_type;
d:file;
z,z2:longint;
sh_namen_feld,symbol_namen_feld:^fa;
Elf32_Rela:Elf32_Rela_type;
Elf32_Rel :Elf32_Rel_type;
b:array[0..500] of char;
Elf32_Sym:Elf32_Sym_type;
Elf32_Dyn:Elf32_Dyn_type;
spaltenbreite:longint;
nbucket,nchain,ll:longint;
{ Return hexadecimal equivalent of parameter Number as a string }
Function Int2Hex( Number : Longint; N : Byte ) : String;
Const
HexDigit : Array[0..$f] of char = '0123456789ABCDEF';
Var
s : String;
i : Integer;
begin
SetLength(s, N);
For i := N downto 1 do
begin
s[i] := HexDigit[Number and $F];
Number := Number shr 4;
end;
Int2Hex := s;
end;
{ Return hexadecimal equivalent of Pointer }
Function Ptr2Hex( p : Pointer ) : String;
begin
Ptr2Hex := Int2Hex( Word(p), 8 );
end;
function sh_name_(o:longint):string;
begin
sh_name_:=StrPas(@sh_namen_feld^[o]);
end;
function sh_name_1(o:longint):string;
var
sektionen_kopf:section_header_type;
begin
case o of
SHN_UNDEF :sh_name_1:='SHN_UNDEF';
SHN_ABS :sh_name_1:='SHN_ABS';
SHN_COMMON:sh_name_1:='SHN_Common';
else
Seek(d,elf_kopf.e_shoff+o*elf_kopf.e_shentsize);
BlockRead(d,sektionen_kopf,SizeOf(sektionen_kopf));
sh_name_1:='"'+sh_name_(sektionen_kopf.sh_name)+'"';
end;
end;
function symbol_name_(const o:longint;var l0:longint):string;
begin
symbol_name_:=StrPas(@symbol_namen_feld^[o]);
if l0<>0 then
symbol_name_:='"'+Result+'"';
if Length(Result)<l0 then
while Length(Result)<l0 do
symbol_name_:=Result+' '
else
l0:=Length(Result);
end;
procedure lade_string_tabelle(o:longint);
var
sektionen_kopf:section_header_type;
begin
if symbol_namen_feld<>nil then
FreeMem(symbol_namen_feld);
Seek(d,elf_kopf.e_shoff+o*elf_kopf.e_shentsize);
BlockRead(d,sektionen_kopf,SizeOf(sektionen_kopf));
GetMem(symbol_namen_feld,sektionen_kopf.sh_size);
Seek(d,sektionen_kopf.sh_offset);
BlockRead(d,symbol_namen_feld^,sektionen_kopf.sh_size);
end;
function ermittle_symbol_tabellen_name(link,index_:longint;var breite:longint):string;
var
sektionen_kopf:section_header_type;
Elf32_Sym:Elf32_Sym_type;
begin
Seek(d,elf_kopf.e_shoff+link*elf_kopf.e_shentsize);
BlockRead(d,sektionen_kopf,SizeOf(sektionen_kopf));
Seek(d,sektionen_kopf.sh_offset+index_*SizeOf(Elf32_Sym_type));
BlockRead(d,Elf32_Sym,SizeOf(Elf32_Sym_type));
lade_string_tabelle(sektionen_kopf.sh_link);
ermittle_symbol_tabellen_name:=symbol_name_(Elf32_Sym.st_name,breite);
end;
function rel_typ(t:byte):string;
begin
case t of
0:rel_typ:='Rel_386_None ';
1:rel_typ:='Rel_386_32 ';
2:rel_typ:='Rel_386_PC32 ';
3:rel_typ:='R_386_GOT32 ';
4:rel_typ:='R_386_PLT32 ';
5:rel_typ:='R_386_COPY ';
6:rel_typ:='R_386_GLOB_DAT ';
7:rel_typ:='R_386_JMP_SLOT ';
8:rel_typ:='R_386_RELATIVE ';
9:rel_typ:='R_386_GOTOFF ';
10:rel_typ:='R_386_GOTPC ';
else
rel_typ:='Rel ?? ('+Int2Hex(t,2)+')';
end;
end;
begin
if ParamCount=0 then
begin
WriteLn('ELFLIST Copyright (C) 1999 Veit Kannegieser');
WriteLn;
WriteLn('Usage: ELFLIST <infile>');
Halt(1);
end;
Assign(d,ParamStr({1}ParamCount));
FileMode:=$40;
Reset(d,1);
BlockRead(d,elf_kopf,SizeOf(elf_kopf));
with elf_kopf do
begin
WriteLn('magic0123 = ',Copy(magic0123,1,4));
WriteLn('file_class = ',file_class );
WriteLn('data_encoding = ',data_encoding );
WriteLn('file_version = ',file_version );
// WriteLn('padding = ',padding );
WriteLn('e_type = ',e_type );
WriteLn('e_machine = ',e_machine );
WriteLn('e_version = ',e_version );
WriteLn('e_entry = $',Int2Hex(e_entry,8));
WriteLn('e_phoff = $',Int2Hex(e_phoff,8));
WriteLn('e_shoff = $',Int2Hex(e_shoff,8));
WriteLn('e_flags = ',e_flags );
WriteLn('e_ehsize = $',Int2Hex(e_ehsize,8));
WriteLn('e_phentsize = $',Int2Hex(e_phentsize,8));
WriteLn('e_phnum = ',e_phnum );
WriteLn('e_shentsize = $',Int2Hex(e_shentsize,8));
WriteLn('e_shnum = ',e_shnum );
WriteLn('e_shstrndx = ',e_shstrndx );
end;
Seek(d,elf_kopf.e_shoff+elf_kopf.e_shstrndx*elf_kopf.e_shentsize);
BlockRead(d,sektionen_kopf,SizeOf(sektionen_kopf));
Seek(d,sektionen_kopf.sh_offset);
getmem(sh_namen_feld,sektionen_kopf.sh_size);
BlockRead(d,sh_namen_feld^,sektionen_kopf.sh_size);
symbol_namen_feld:=nil;
for z:=0 to elf_kopf.e_phnum-1 do
begin
WriteLn;
WriteLn('program header ',z,' ...');
Seek(d,elf_kopf.e_phoff+z*elf_kopf.e_phentsize);
BlockRead(d,programm_kopf,SizeOf(programm_kopf));
with programm_kopf do
begin
Write (' p_type = ');
case p_type of
PT_NULL :WriteLn('PT_NULL');
PT_LOAD :WriteLn('PT_LOAD');
PT_DYNAMIC :WriteLn('PT_DYNAMIC');
PT_INTERP :WriteLn('PT_INTERP');
PT_NOTE :WriteLn('PT_NOTE');
PT_SHLIB :WriteLn('PT_SHLIB');
PT_PHDR :WriteLn('PT_PHDR');
else
WriteLn(Int2Hex(p_type,8));
end;
WriteLn(' p_offset = $',Int2Hex(p_offset,8));
WriteLn(' p_vaddr = $',Int2Hex(p_vaddr,8));
WriteLn(' p_paddr = $',Int2Hex(p_paddr,8));
WriteLn(' p_filesz = $',Int2Hex(p_filesz,8));
WriteLn(' p_memsz = $',Int2Hex(p_memsz,8));
Write (' p_flags = ');
if (p_flags and PF_X)>0 then Write('PF_X ');
if (p_flags and PF_W)>0 then Write('PF_W ');
if (p_flags and PF_R)>0 then Write('PF_R ');
WriteLn;
WriteLn(' p_align = ',p_align );
if p_type=PT_INTERP then
begin
Seek(d,p_offset);
BlockRead(d,b,p_filesz);
WriteLn('"',b,'"');
end;
WriteLn;
end;
end;
for z:=0 to elf_kopf.e_shnum-1 do
begin
WriteLn;
WriteLn('section header ',z,' ...');
Seek(d,elf_kopf.e_shoff+z*elf_kopf.e_shentsize);
BlockRead(d,sektionen_kopf,SizeOf(sektionen_kopf));
with sektionen_kopf do
begin
//WriteLn(' sh_name = ',sh_name );
WriteLn(' sh_name = "',sh_name_(sh_name),'"');
Write (' sh_type = ');
case sh_type of
SHT_NULL :WriteLn('SHT_NULL (unbenutzt)');
SHT_PROGBITS :WriteLn('SHT_PROGBITS (wird geladen)');
SHT_SYMTAB :WriteLn('SHT_SYMTAB (importierte? Objekte, aufgebäht)');
SHT_STRTAB :WriteLn('SHT_STRTAB (Stringtabelle)');
SHT_RELA :WriteLn('SHT_RELA (Relokationen)');
SHT_HASH :WriteLn('SHT_HASH (Hash-Tabelle)');
SHT_DYNAMIC :WriteLn('SHT_DYNAMIC (Informationen für den Dynamischen Lader)');
SHT_NOTE :WriteLn('SHT_NOTE (Schrott)');
SHT_NOBITS :WriteLn('SHT_NOBITS (wird nicht aus der Datei geladen)');
SHT_REL :WriteLn('SHT_REL (Relokationen)');
SHT_SHLIB :WriteLn('SHT_SHLIB (undefiniert)');
SHT_DYNSYM :WriteLn('SHT_DYNSYM (importierte Objekte)');
else
WriteLn(sh_type);
end;
Write (' sh_flags = ');
if (sh_flags and SHF_WRITE )>0 then Write('SHF_WRITE ');
if (sh_flags and SHF_ALLOC )>0 then Write('SHF_ALLOC ');
if (sh_flags and SHF_EXECINSTR)>0 then Write('SHF_EXECINSTR ');
WriteLn;
WriteLn(' sh_addr = $',Int2Hex(sh_addr,8));
WriteLn(' sh_offset = $',Int2Hex(sh_offset,8));
WriteLn(' sh_size = $',Int2Hex(sh_size,8));
WriteLn(' sh_link = ',sh_link:3,' (',sh_name_1(sh_link),')');
WriteLn(' sh_info = ',sh_info:3,' (',sh_name_1(sh_info),')');
WriteLn(' sh_addralign = ',sh_addralign );
WriteLn(' sh_entsize = ',sh_entsize );
if sh_type=SHT_RELA then
begin
WriteLn(' r_offset r_info(sym) t_info(rel_typ) Addendum');
spaltenbreite:=15;
for z2:=1 to (sh_size div SizeOf(Elf32_Rela)) do
begin
Seek(d,sh_offset+(z2-1)*SizeOf(Elf32_Rela));
BlockRead(d,Elf32_Rela,SizeOf(Elf32_Rela));
Write(' * $',Int2Hex(Elf32_Rela.r_offset,8),' ');
{if (Elf32_Rela.r_info and 255) in [0..2] then
Write(sh_name_(Elf32_Rela.r_info shr 8))//Int2Hex(Elf32_Rela.r_info shr 8,8)
else}
Write(ermittle_symbol_tabellen_name(sh_link,Elf32_Rela.r_info shr 8,spaltenbreite));
WriteLn(' ',rel_typ(Elf32_Rela.r_info and 255),' ',
Int2Hex(Elf32_Rela.r_addend,8));
end;
end;
if sh_type=SHT_REL then
begin
WriteLn(' r_offset r_info(sym) t_info(rel_typ)');
spaltenbreite:=15;
for z2:=1 to (sh_size div SizeOf(Elf32_Rel)) do
begin
Seek(d,sh_offset+(z2-1)*SizeOf(Elf32_Rel));
BlockRead(d,Elf32_Rel,SizeOf(Elf32_Rel));
WriteLn(' * $',Int2Hex(Elf32_Rel.r_offset,8),' ',
ermittle_symbol_tabellen_name(sh_link,Elf32_Rel.r_info shr 8,spaltenbreite),' ',
rel_typ(Elf32_Rel.r_info and 255));
end;
end;
if sh_name_(sh_name)='.interp' then
begin
Seek(d,sh_offset);
BlockRead(d,b,sh_size);
WriteLn('"',b,'"');
end;
if sh_type=sht_hash then
begin
Seek(d,sh_offset);
BlockRead(d,nbucket,SizeOf(nbucket));
BlockRead(d,nchain,SizeOf(nchain));
WriteLn(nbucket,' Eimer');
for z2:=0 to nbucket-1 do
begin
BlockRead(d,ll,SizeOf(ll));
WriteLn(' ',z2:4,' : ',ll:4{,' -> ',});
end;
Writeln(nchain,' Verkettungen');
for z2:=0 to nchain-1 do
begin
BlockRead(d,ll,SizeOf(ll));
Write(' ',z2:4,' : ');
if ll=0 then
WriteLn('-')
else
WriteLn(ll:4);
end;
end;
if sh_type in [SHT_SYMTAB,SHT_DYNSYM] then
begin
lade_string_tabelle(sh_link);
WriteLn('= st_name.................. st_value. st_size Bind.. Type.... Index');
spaltenbreite:=length('"_GLOBAL_OFFSET_TABLE_" ');
for z2:=1 to sh_size div SizeOf(Elf32_Sym_type) do
begin
Seek(d,sh_offset+(z2-1)*SizeOf(Elf32_Sym_type));
BlockRead(d,Elf32_Sym,SizeOf(Elf32_Sym_type));
with Elf32_Sym do
begin
Write (' * ',symbol_name_(st_name,spaltenbreite),
' $',Int2Hex(st_value,8),
' ',st_size:7,' ');
// st_info.Bind
case st_info shr 4 of
0:Write('Local ');
1:Write('Global ');
2:Write('Weak ');
else
Write(st_info shr 4:7);
end;
// st_info.Type
case st_info and $f of
0:Write('NoType ');
1:Write('Object ');
2:Write('Func ');
3:Write('Section ');
4:Write('File ');
else
Write(st_info shr 4:8);
end;
(* st_other =0 *)
//Write(' $',Int2Hex(st_shndx,4));
Write(' ',sh_name_1(st_shndx));
WriteLn;
end;
end;
end;
if sh_type=SHT_DYNAMIC then
begin
lade_string_tabelle(sh_link);
WriteLn(' d_tag d_val/d_ptr');
for z2:=1 to sh_size div SizeOf(Elf32_Dyn_type) do
begin
Seek(d,sh_offset+(z2-1)*SizeOf(Elf32_Dyn_type));
BlockRead(d,Elf32_Dyn,SizeOf(Elf32_Dyn));
Write(' * ');
with Elf32_Dyn do
begin
case d_tag of
DT_NULL :Write('DT_NULL ');
DT_NEEDED :Write('DT_NEEDED ');
DT_PLTRELSZ :Write('DT_PLTRELSZ');
DT_PLTGOT :Write('DT_PLTGOT ');
DT_HASH :Write('DT_HASH ');
DT_STRTAB :Write('DT_STRTAB ');
DT_SYMTAB :Write('DT_SYMTAB ');
DT_RELA :Write('DT_RELA ');
DT_RELASZ :Write('DT_RELASZ ');
DT_RELAENT :Write('DT_RELAENT ');
DT_STRSZ :Write('DT_STRSZ ');
DT_SYMENT :Write('DT_SYMENT ');
DT_INIT :Write('DT_INIT ');
DT_FINI :Write('DT_FINI ');
DT_SONAME :Write('DT_SONAME ');
DT_RPATH :Write('DT_RPATH ');
DT_SYMBOLIC :Write('DT_SYMBOLIC');
DT_REL :Write('DT_REL ');
DT_RELSZ :Write('DT_RELSZ ');
DT_RELENT :Write('DT_RELENT ');
DT_PLTREL :Write('DT_PLTREL ');
DT_DEBUG :Write('DT_DEBUG ');
DT_TEXTREL :Write('DT_TEXTREL ');
DT_JMPREL :Write('DT_JMPREL ');
DT_BIND_NOW :Write('DT_BIND_NOW');
else
Write('$',Int2Hex(d_tag,8),' ');
end;
if not (d_tag in [DT_NULL,DT_SYMBOLIC,DT_TEXTREL,DT_BIND_NOW]) then
Write(' $',Int2Hex(d_val,8));
if d_tag in [DT_NEEDED,DT_SONAME,DT_RPATH] then
begin
spaltenbreite:=0;
Write(' ',symbol_name_(d_val,spaltenbreite));
end;
WriteLn;
end;
end;
end;
WriteLn;
end;
end;
end.