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 >
Pascal/Delphi Source File  |  2000-08-15  |  17KB  |  450 lines

  1. //
  2. (*$D+,L+,Locinfo+*)
  3.  
  4.  
  5. //programmheader und sektionenheader auswerten (doppelte anzeige)
  6. //oder /P | /S | /A | /E | /? | /H
  7. //!!!.got auflisten
  8. // note sektion (S.42)
  9. {█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█}
  10. {█                                                       █}
  11. {█      Virtual Pascal for Linux                         █}
  12. {█      ELF dump utility                                 █}
  13. {█      ─────────────────────────────────────────────────█}
  14. {█      Copyright (C) 1999 Veit Kannegieser              █}
  15. {█                                                       █}
  16. {▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀}
  17.  
  18. (*$I+,Delphi+,X+*)
  19.  
  20. program elflist;
  21.  
  22. uses
  23.   strings,
  24.   elfdef;
  25.  
  26. type
  27.   fa=array[0..1000000] of char;
  28.  
  29. var
  30.   elf_kopf:Elf32_Ehdr_type;
  31.  
  32.   programm_kopf:program_header_type;
  33.   sektionen_kopf:section_header_type;
  34.   d:file;
  35.  
  36.   z,z2:longint;
  37.   sh_namen_feld,symbol_namen_feld:^fa;
  38.  
  39.   Elf32_Rela:Elf32_Rela_type;
  40.   Elf32_Rel :Elf32_Rel_type;
  41.  
  42.   b:array[0..500] of char;
  43.  
  44.   Elf32_Sym:Elf32_Sym_type;
  45.  
  46.   Elf32_Dyn:Elf32_Dyn_type;
  47.  
  48.   spaltenbreite:longint;
  49.  
  50.   nbucket,nchain,ll:longint;
  51.  
  52. { Return hexadecimal equivalent of parameter Number as a string }
  53. Function Int2Hex( Number : Longint; N : Byte ) : String;
  54. Const
  55.   HexDigit : Array[0..$f] of char = '0123456789ABCDEF';
  56. Var
  57.   s : String;
  58.   i : Integer;
  59.  
  60. begin
  61.   SetLength(s, N);
  62.   For i := N downto 1 do
  63.     begin
  64.       s[i] := HexDigit[Number and $F];
  65.       Number := Number shr 4;
  66.     end;
  67.   Int2Hex := s;
  68. end;
  69.  
  70. { Return hexadecimal equivalent of Pointer }
  71. Function Ptr2Hex( p : Pointer ) : String;
  72. begin
  73.   Ptr2Hex := Int2Hex( Word(p), 8 );
  74. end;
  75.  
  76. function sh_name_(o:longint):string;
  77.   begin
  78.     sh_name_:=StrPas(@sh_namen_feld^[o]);
  79.   end;
  80.  
  81. function sh_name_1(o:longint):string;
  82.   var
  83.     sektionen_kopf:section_header_type;
  84.   begin
  85.     case o of
  86.       SHN_UNDEF :sh_name_1:='SHN_UNDEF';
  87.       SHN_ABS   :sh_name_1:='SHN_ABS';
  88.       SHN_COMMON:sh_name_1:='SHN_Common';
  89.     else
  90.       Seek(d,elf_kopf.e_shoff+o*elf_kopf.e_shentsize);
  91.       BlockRead(d,sektionen_kopf,SizeOf(sektionen_kopf));
  92.       sh_name_1:='"'+sh_name_(sektionen_kopf.sh_name)+'"';
  93.     end;
  94.   end;
  95.  
  96. function symbol_name_(const o:longint;var l0:longint):string;
  97.   begin
  98.     symbol_name_:=StrPas(@symbol_namen_feld^[o]);
  99.     if l0<>0 then
  100.       symbol_name_:='"'+Result+'"';
  101.     if Length(Result)<l0 then
  102.       while Length(Result)<l0 do
  103.         symbol_name_:=Result+' '
  104.     else
  105.       l0:=Length(Result);
  106.   end;
  107.  
  108. procedure lade_string_tabelle(o:longint);
  109.   var
  110.     sektionen_kopf:section_header_type;
  111.   begin
  112.     if symbol_namen_feld<>nil then
  113.       FreeMem(symbol_namen_feld);
  114.  
  115.     Seek(d,elf_kopf.e_shoff+o*elf_kopf.e_shentsize);
  116.     BlockRead(d,sektionen_kopf,SizeOf(sektionen_kopf));
  117.     GetMem(symbol_namen_feld,sektionen_kopf.sh_size);
  118.     Seek(d,sektionen_kopf.sh_offset);
  119.     BlockRead(d,symbol_namen_feld^,sektionen_kopf.sh_size);
  120.   end;
  121.  
  122. function ermittle_symbol_tabellen_name(link,index_:longint;var breite:longint):string;
  123.   var
  124.     sektionen_kopf:section_header_type;
  125.     Elf32_Sym:Elf32_Sym_type;
  126.   begin
  127.     Seek(d,elf_kopf.e_shoff+link*elf_kopf.e_shentsize);
  128.     BlockRead(d,sektionen_kopf,SizeOf(sektionen_kopf));
  129.     Seek(d,sektionen_kopf.sh_offset+index_*SizeOf(Elf32_Sym_type));
  130.     BlockRead(d,Elf32_Sym,SizeOf(Elf32_Sym_type));
  131.     lade_string_tabelle(sektionen_kopf.sh_link);
  132.     ermittle_symbol_tabellen_name:=symbol_name_(Elf32_Sym.st_name,breite);
  133.   end;
  134.  
  135. function rel_typ(t:byte):string;
  136.   begin
  137.     case t of
  138.       0:rel_typ:='Rel_386_None     ';
  139.       1:rel_typ:='Rel_386_32       ';
  140.       2:rel_typ:='Rel_386_PC32     ';
  141.       3:rel_typ:='R_386_GOT32      ';
  142.       4:rel_typ:='R_386_PLT32      ';
  143.       5:rel_typ:='R_386_COPY       ';
  144.       6:rel_typ:='R_386_GLOB_DAT   ';
  145.       7:rel_typ:='R_386_JMP_SLOT   ';
  146.       8:rel_typ:='R_386_RELATIVE   ';
  147.       9:rel_typ:='R_386_GOTOFF     ';
  148.      10:rel_typ:='R_386_GOTPC      ';
  149.     else
  150.         rel_typ:='Rel ?? ('+Int2Hex(t,2)+')';
  151.     end;
  152.  
  153.   end;
  154.  
  155. begin
  156.   if ParamCount=0 then
  157.     begin
  158.        WriteLn('ELFLIST Copyright (C) 1999 Veit Kannegieser');
  159.        WriteLn;
  160.        WriteLn('Usage: ELFLIST <infile>');
  161.        Halt(1);
  162.     end;
  163.  
  164.   Assign(d,ParamStr({1}ParamCount));
  165.   FileMode:=$40;
  166.   Reset(d,1);
  167.   BlockRead(d,elf_kopf,SizeOf(elf_kopf));
  168.  
  169.   with elf_kopf do
  170.     begin
  171.       WriteLn('magic0123     = ',Copy(magic0123,1,4));
  172.       WriteLn('file_class    = ',file_class    );
  173.       WriteLn('data_encoding = ',data_encoding );
  174.       WriteLn('file_version  = ',file_version  );
  175.    // WriteLn('padding       = ',padding       );
  176.       WriteLn('e_type        = ',e_type        );
  177.       WriteLn('e_machine     = ',e_machine     );
  178.       WriteLn('e_version     = ',e_version     );
  179.       WriteLn('e_entry       = $',Int2Hex(e_entry,8));
  180.       WriteLn('e_phoff       = $',Int2Hex(e_phoff,8));
  181.       WriteLn('e_shoff       = $',Int2Hex(e_shoff,8));
  182.       WriteLn('e_flags       = ',e_flags       );
  183.       WriteLn('e_ehsize      = $',Int2Hex(e_ehsize,8));
  184.       WriteLn('e_phentsize   = $',Int2Hex(e_phentsize,8));
  185.       WriteLn('e_phnum       = ',e_phnum       );
  186.       WriteLn('e_shentsize   = $',Int2Hex(e_shentsize,8));
  187.       WriteLn('e_shnum       = ',e_shnum       );
  188.       WriteLn('e_shstrndx    = ',e_shstrndx    );
  189.     end;
  190.  
  191.   Seek(d,elf_kopf.e_shoff+elf_kopf.e_shstrndx*elf_kopf.e_shentsize);
  192.   BlockRead(d,sektionen_kopf,SizeOf(sektionen_kopf));
  193.   Seek(d,sektionen_kopf.sh_offset);
  194.   getmem(sh_namen_feld,sektionen_kopf.sh_size);
  195.   BlockRead(d,sh_namen_feld^,sektionen_kopf.sh_size);
  196.   symbol_namen_feld:=nil;
  197.  
  198.   for z:=0 to elf_kopf.e_phnum-1 do
  199.     begin
  200.       WriteLn;
  201.       WriteLn('program header ',z,' ...');
  202.       Seek(d,elf_kopf.e_phoff+z*elf_kopf.e_phentsize);
  203.       BlockRead(d,programm_kopf,SizeOf(programm_kopf));
  204.       with programm_kopf do
  205.         begin
  206.            Write  ('  p_type     = ');
  207.            case p_type of
  208.              PT_NULL     :WriteLn('PT_NULL');
  209.              PT_LOAD     :WriteLn('PT_LOAD');
  210.              PT_DYNAMIC  :WriteLn('PT_DYNAMIC');
  211.              PT_INTERP   :WriteLn('PT_INTERP');
  212.              PT_NOTE     :WriteLn('PT_NOTE');
  213.              PT_SHLIB    :WriteLn('PT_SHLIB');
  214.              PT_PHDR     :WriteLn('PT_PHDR');
  215.            else
  216.                           WriteLn(Int2Hex(p_type,8));
  217.            end;
  218.            WriteLn('  p_offset   = $',Int2Hex(p_offset,8));
  219.            WriteLn('  p_vaddr    = $',Int2Hex(p_vaddr,8));
  220.            WriteLn('  p_paddr    = $',Int2Hex(p_paddr,8));
  221.            WriteLn('  p_filesz   = $',Int2Hex(p_filesz,8));
  222.            WriteLn('  p_memsz    = $',Int2Hex(p_memsz,8));
  223.            Write  ('  p_flags    = ');
  224.            if (p_flags and PF_X)>0 then Write('PF_X ');
  225.            if (p_flags and PF_W)>0 then Write('PF_W ');
  226.            if (p_flags and PF_R)>0 then Write('PF_R ');
  227.            WriteLn;
  228.            WriteLn('  p_align    = ',p_align   );
  229.  
  230.           if p_type=PT_INTERP then
  231.             begin
  232.               Seek(d,p_offset);
  233.               BlockRead(d,b,p_filesz);
  234.               WriteLn('"',b,'"');
  235.             end;
  236.  
  237.           WriteLn;
  238.         end;
  239.     end;
  240.  
  241.   for z:=0 to elf_kopf.e_shnum-1 do
  242.     begin
  243.       WriteLn;
  244.       WriteLn('section header ',z,' ...');
  245.       Seek(d,elf_kopf.e_shoff+z*elf_kopf.e_shentsize);
  246.       BlockRead(d,sektionen_kopf,SizeOf(sektionen_kopf));
  247.       with sektionen_kopf do
  248.         begin
  249.            //WriteLn('  sh_name      = ',sh_name       );
  250.            WriteLn('  sh_name      = "',sh_name_(sh_name),'"');
  251.            Write  ('  sh_type      = ');
  252.            case sh_type of
  253.              SHT_NULL        :WriteLn('SHT_NULL     (unbenutzt)');
  254.              SHT_PROGBITS    :WriteLn('SHT_PROGBITS (wird geladen)');
  255.              SHT_SYMTAB      :WriteLn('SHT_SYMTAB   (importierte? Objekte, aufgebäht)');
  256.              SHT_STRTAB      :WriteLn('SHT_STRTAB   (Stringtabelle)');
  257.              SHT_RELA        :WriteLn('SHT_RELA     (Relokationen)');
  258.              SHT_HASH        :WriteLn('SHT_HASH     (Hash-Tabelle)');
  259.              SHT_DYNAMIC     :WriteLn('SHT_DYNAMIC  (Informationen für den Dynamischen Lader)');
  260.              SHT_NOTE        :WriteLn('SHT_NOTE     (Schrott)');
  261.              SHT_NOBITS      :WriteLn('SHT_NOBITS   (wird nicht aus der Datei geladen)');
  262.              SHT_REL         :WriteLn('SHT_REL      (Relokationen)');
  263.              SHT_SHLIB       :WriteLn('SHT_SHLIB    (undefiniert)');
  264.              SHT_DYNSYM      :WriteLn('SHT_DYNSYM   (importierte Objekte)');
  265.            else
  266.                               WriteLn(sh_type);
  267.            end;
  268.            Write  ('  sh_flags     = ');
  269.            if (sh_flags and SHF_WRITE    )>0 then Write('SHF_WRITE ');
  270.            if (sh_flags and SHF_ALLOC    )>0 then Write('SHF_ALLOC ');
  271.            if (sh_flags and SHF_EXECINSTR)>0 then Write('SHF_EXECINSTR ');
  272.            WriteLn;
  273.            WriteLn('  sh_addr      = $',Int2Hex(sh_addr,8));
  274.            WriteLn('  sh_offset    = $',Int2Hex(sh_offset,8));
  275.            WriteLn('  sh_size      = $',Int2Hex(sh_size,8));
  276.            WriteLn('  sh_link      = ',sh_link:3,' (',sh_name_1(sh_link),')');
  277.            WriteLn('  sh_info      = ',sh_info:3,' (',sh_name_1(sh_info),')');
  278.            WriteLn('  sh_addralign = ',sh_addralign  );
  279.            WriteLn('  sh_entsize   = ',sh_entsize    );
  280.  
  281.            if sh_type=SHT_RELA then
  282.              begin
  283.                WriteLn('     r_offset  r_info(sym)     t_info(rel_typ)   Addendum');
  284.                spaltenbreite:=15;
  285.                for z2:=1 to (sh_size div SizeOf(Elf32_Rela)) do
  286.                  begin
  287.                    Seek(d,sh_offset+(z2-1)*SizeOf(Elf32_Rela));
  288.                    BlockRead(d,Elf32_Rela,SizeOf(Elf32_Rela));
  289.                    Write('   * $',Int2Hex(Elf32_Rela.r_offset,8),' ');
  290.                    {if (Elf32_Rela.r_info and 255) in [0..2] then
  291.                      Write(sh_name_(Elf32_Rela.r_info shr 8))//Int2Hex(Elf32_Rela.r_info shr 8,8)
  292.                    else}
  293.                      Write(ermittle_symbol_tabellen_name(sh_link,Elf32_Rela.r_info shr 8,spaltenbreite));
  294.                    WriteLn(' ',rel_typ(Elf32_Rela.r_info and 255),' ',
  295.                                Int2Hex(Elf32_Rela.r_addend,8));
  296.  
  297.                  end;
  298.                end;
  299.  
  300.            if sh_type=SHT_REL then
  301.              begin
  302.                WriteLn('     r_offset  r_info(sym)     t_info(rel_typ)');
  303.                spaltenbreite:=15;
  304.                for z2:=1 to (sh_size div SizeOf(Elf32_Rel)) do
  305.                  begin
  306.                    Seek(d,sh_offset+(z2-1)*SizeOf(Elf32_Rel));
  307.                    BlockRead(d,Elf32_Rel,SizeOf(Elf32_Rel));
  308.                    WriteLn('   * $',Int2Hex(Elf32_Rel.r_offset,8),' ',
  309.                                  ermittle_symbol_tabellen_name(sh_link,Elf32_Rel.r_info shr 8,spaltenbreite),' ',
  310.                                  rel_typ(Elf32_Rel.r_info and 255));
  311.  
  312.                  end;
  313.              end;
  314.  
  315.            if sh_name_(sh_name)='.interp' then
  316.              begin
  317.                Seek(d,sh_offset);
  318.                BlockRead(d,b,sh_size);
  319.                WriteLn('"',b,'"');
  320.              end;
  321.  
  322.            if sh_type=sht_hash then
  323.              begin
  324.                Seek(d,sh_offset);
  325.                BlockRead(d,nbucket,SizeOf(nbucket));
  326.                BlockRead(d,nchain,SizeOf(nchain));
  327.                WriteLn(nbucket,' Eimer');
  328.                for z2:=0 to nbucket-1 do
  329.                  begin
  330.                    BlockRead(d,ll,SizeOf(ll));
  331.                    WriteLn('  ',z2:4,' : ',ll:4{,' -> ',});
  332.                  end;
  333.                Writeln(nchain,' Verkettungen');
  334.                for z2:=0 to nchain-1 do
  335.                  begin
  336.                    BlockRead(d,ll,SizeOf(ll));
  337.                    Write('  ',z2:4,' : ');
  338.                    if ll=0 then
  339.                      WriteLn('-')
  340.                    else
  341.                      WriteLn(ll:4);
  342.                  end;
  343.              end;
  344.  
  345.            if sh_type in [SHT_SYMTAB,SHT_DYNSYM] then
  346.              begin
  347.                lade_string_tabelle(sh_link);
  348.                WriteLn('= st_name.................. st_value. st_size Bind.. Type.... Index');
  349.                spaltenbreite:=length('"_GLOBAL_OFFSET_TABLE_" ');
  350.                for z2:=1 to sh_size div SizeOf(Elf32_Sym_type) do
  351.                  begin
  352.                    Seek(d,sh_offset+(z2-1)*SizeOf(Elf32_Sym_type));
  353.                    BlockRead(d,Elf32_Sym,SizeOf(Elf32_Sym_type));
  354.                    with Elf32_Sym do
  355.                      begin
  356.                        Write  (' * ',symbol_name_(st_name,spaltenbreite),
  357.                                ' $',Int2Hex(st_value,8),
  358.                                ' ',st_size:7,' ');
  359.  
  360.                        // st_info.Bind
  361.                        case st_info shr 4 of
  362.                          0:Write('Local  ');
  363.                          1:Write('Global ');
  364.                          2:Write('Weak   ');
  365.                        else
  366.                            Write(st_info shr 4:7);
  367.                        end;
  368.  
  369.                        // st_info.Type
  370.                        case st_info and $f of
  371.                          0:Write('NoType  ');
  372.                          1:Write('Object  ');
  373.                          2:Write('Func    ');
  374.                          3:Write('Section ');
  375.                          4:Write('File    ');
  376.                        else
  377.                            Write(st_info shr 4:8);
  378.                        end;
  379.  
  380.                        (* st_other =0 *)
  381.  
  382.                        //Write(' $',Int2Hex(st_shndx,4));
  383.                        Write(' ',sh_name_1(st_shndx));
  384.                        WriteLn;
  385.                      end;
  386.                  end;
  387.              end;
  388.  
  389.            if sh_type=SHT_DYNAMIC then
  390.              begin
  391.                lade_string_tabelle(sh_link);
  392.                WriteLn('     d_tag       d_val/d_ptr');
  393.                for z2:=1 to sh_size div SizeOf(Elf32_Dyn_type) do
  394.                  begin
  395.                    Seek(d,sh_offset+(z2-1)*SizeOf(Elf32_Dyn_type));
  396.                    BlockRead(d,Elf32_Dyn,SizeOf(Elf32_Dyn));
  397.                    Write('   * ');
  398.                    with Elf32_Dyn do
  399.                      begin
  400.                        case d_tag of
  401.                          DT_NULL     :Write('DT_NULL    ');
  402.                          DT_NEEDED   :Write('DT_NEEDED  ');
  403.                          DT_PLTRELSZ :Write('DT_PLTRELSZ');
  404.                          DT_PLTGOT   :Write('DT_PLTGOT  ');
  405.                          DT_HASH     :Write('DT_HASH    ');
  406.                          DT_STRTAB   :Write('DT_STRTAB  ');
  407.                          DT_SYMTAB   :Write('DT_SYMTAB  ');
  408.                          DT_RELA     :Write('DT_RELA    ');
  409.                          DT_RELASZ   :Write('DT_RELASZ  ');
  410.                          DT_RELAENT  :Write('DT_RELAENT ');
  411.                          DT_STRSZ    :Write('DT_STRSZ   ');
  412.                          DT_SYMENT   :Write('DT_SYMENT  ');
  413.                          DT_INIT     :Write('DT_INIT    ');
  414.                          DT_FINI     :Write('DT_FINI    ');
  415.                          DT_SONAME   :Write('DT_SONAME  ');
  416.                          DT_RPATH    :Write('DT_RPATH   ');
  417.                          DT_SYMBOLIC :Write('DT_SYMBOLIC');
  418.                          DT_REL      :Write('DT_REL     ');
  419.                          DT_RELSZ    :Write('DT_RELSZ   ');
  420.                          DT_RELENT   :Write('DT_RELENT  ');
  421.                          DT_PLTREL   :Write('DT_PLTREL  ');
  422.                          DT_DEBUG    :Write('DT_DEBUG   ');
  423.                          DT_TEXTREL  :Write('DT_TEXTREL ');
  424.                          DT_JMPREL   :Write('DT_JMPREL  ');
  425.                          DT_BIND_NOW :Write('DT_BIND_NOW');
  426.                        else
  427.                                       Write('$',Int2Hex(d_tag,8),'  ');
  428.                        end;
  429.  
  430.                        if not (d_tag in [DT_NULL,DT_SYMBOLIC,DT_TEXTREL,DT_BIND_NOW]) then
  431.                          Write(' $',Int2Hex(d_val,8));
  432.  
  433.                        if d_tag in [DT_NEEDED,DT_SONAME,DT_RPATH] then
  434.                          begin
  435.                            spaltenbreite:=0;
  436.                            Write(' ',symbol_name_(d_val,spaltenbreite));
  437.                          end;
  438.  
  439.                        WriteLn;
  440.                      end;
  441.                  end;
  442.              end;
  443.  
  444.           WriteLn;
  445.         end;
  446.     end;
  447.  
  448. end.
  449.  
  450.