home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / vp21beta.zip / LRTLSRC.RAR / PE2ELF / PE2ELF.PAS < prev    next >
Pascal/Delphi Source File  |  2000-08-15  |  41KB  |  1,167 lines

  1. {█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█}
  2. {█                                                       █}
  3. {█      Virtual Pascal for Linux                         █}
  4. {█      PE to ELF conversion utility                     █}
  5. {█      ─────────────────────────────────────────────────█}
  6. {█      Copyright (C) 1999 Veit Kannegieser              █}
  7. {█                                                       █}
  8. {▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀}
  9.  
  10. (*$Use32+,I+,Delphi+,X+*)
  11. (*  $D+,L+,Locinfo+*)
  12. (*$M 1000000*)
  13.  
  14. program pe2elf;
  15.  
  16. // 1999.07.28 Veit Kannegieser
  17. // ... VK/JP
  18. // 1999.10.22 Version mit funkionierendem .so-Import an J.P. verschickt
  19. // 2000.05.10 -v für Sektionenliste und word->smallword für PE2LETY.PAS
  20.  
  21. uses
  22.   pe2lety,
  23.   reskonv,
  24.   ELFDef,
  25.   dbwrite,
  26.   Strings;
  27.  
  28. type
  29.   PCharArray                    = ^TCharArray;
  30.   TCharArray                    = array[0..512*1024*1024      ] of Char;
  31.   PByteArray                    = ^TByteArray;
  32.   TByteArray                    = array[0..512*1024*1024      ] of Byte;
  33.   PLongArray                    = ^TLongArray;
  34.   TLongArray                    = array[0..512*1024*1024 div 4] of Longint;
  35.  
  36.   dynamic_tabelle_typ           =array[0..20000] of Elf32_Dyn_type;
  37.   dynamic_tabelle_z_typ         =^dynamic_tabelle_typ;
  38.  
  39.   symboltabelle_typ             =array[0..200000] of Elf32_Sym_type;
  40.  
  41.   rel_plt_typ                   =array[0..200000] of Elf32_Rel_type;
  42.   rel_plt_z_typ                 =^rel_plt_typ;
  43.  
  44. var
  45.   d1,d2                         :file;
  46.   pe_kopf                       :pe_kopf_typ;
  47.   pe_obj_tab                    :array[pe_obj_typen] of pe_obj_typ;
  48.  
  49.   code_puffer,
  50.   bss_puffer,
  51.   data_puffer,
  52.   import_puffer,
  53.   relo_puffer,
  54.   reso_temp_puffer,
  55.   reso_puffer                   :speicherfeld_z_typ;
  56.  
  57.   plt_speicher                  :PByteArray;
  58.   got_speicher                  :PLongArray;
  59.   hash_tabelle                  :PLongArray;
  60.  
  61.   symboltabelle                 :^symboltabelle_typ;
  62.  
  63.   symbolstringtabelle           :PCharArray;
  64.  
  65.   rel_plt_speicher              :rel_plt_z_typ;
  66.  
  67.   importe_vorhanden,
  68.   resourcen_vorhanden,
  69.   bss_vorhanden                 :boolean;
  70.  
  71.   programm_kopf                 :array[0..40] of program_header_type;
  72.   sektionen_kopf                :array[0..40] of section_header_type;
  73.   speicher_tabelle              :array[0..40] of pointer;
  74.   pk2                           :array[0..40] of program_header_type;
  75.  
  76.   string_puffer                 :speicherfeld_z_typ;
  77.   string_puffer_laenge          :longint;
  78.   reso_temp_laenge              :longint;
  79.   resource_anker_gefunden       :boolean;
  80.   anzahl_importe                :longint;
  81.  
  82.   InFile, OutFile               : string;
  83.  
  84.  
  85.  
  86. type
  87.   sektionen=(sekt_null,         // reserviert
  88.              sekt_interpreter,  // Programmlader
  89.              sekt_text,         // Code
  90.              sekt_bss,          // wenn vorhanden
  91.              sekt_data_a,       // \ Konstanten, / alle initialisierten Seiten
  92.              sekt_data_b,       // / Variablen   \ alle Nullseiten
  93.              sekt_dynamic,      // Informationen/Zeiger für den Programmlader
  94.              sekt_got,          // Adressen importierter Funktionen
  95.              sekt_dynsym,       // Tabelle importierte Symbole
  96.              sekt_dynsymstr,    // Namen für sekt_dynsym
  97.              sekt_dynsymstrhash,// Hash-Tabelle für sekt_dynsymstr
  98.              sekt_rel_plt,      // Verbindung von plt zu dynsym
  99.              sekt_resource,     // Resourcen
  100.              sekt_plt,          // Aufrufe von importierten Funktionen
  101.              sekt_strings);     // Namen von Sektionen
  102.  
  103.  
  104. var
  105.   sektionen_uebersicht:
  106.     array[low(sektionen)..high(sektionen)] of
  107.       record
  108.         vorhanden               :boolean;
  109.         index_                  :longint;
  110.       end;
  111.  
  112.   anzahl_dynamic_eintraege      :longint;
  113.   dynamic_speicher              :dynamic_tabelle_z_typ;
  114.  
  115.  
  116. const
  117.   sektionen_namen:array[low(sektionen)..high(sektionen)] {of array[1..2]} of string[25]=
  118.     (('null,reserved'           ),
  119.      ('interpreter'             ),
  120.      ('.text (program code)'    ),
  121.      ('"_bss"'                  ),
  122.      ('data_a (.data)'          ),
  123.      ('data_b (.bss)'           ),
  124.      ('.dynamic'                ),
  125.      ('.got'                    ),
  126.      ('.dynsym'                 ),
  127.      ('.dynsymstr'              ),
  128.      ('.dynsymstrhash'          ),
  129.      ('.rel.plt'                ),
  130.      ('resource'                ),
  131.      ('.plt'                    ),
  132.      ('sektion header strings'  ));
  133.  
  134.  
  135.  
  136.  
  137.   elf_kopf:Elf32_Ehdr_type=
  138.    (magic0123                   :magic0123_elf;
  139.     file_class                  :file_class__32bit;
  140.     data_encoding               :ELFDATA2LSB;
  141.     file_version                :e_version__current;
  142.     padding                     :(0,0,0,0,0,0,0,0,0);
  143.     e_type                      :e_type__exec;
  144.     e_machine                   :e_machine__intel386;
  145.     e_version                   :e_version__current;
  146.     e_entry                     :0;                     // entrypoint
  147.     e_phoff                     :0;                     // program header offset
  148.     e_shoff                     :0;                     // sections header offset
  149.     e_flags                     :0;                     // keine
  150.     e_ehsize                    :SizeOf(Elf32_Ehdr_type);
  151.     e_phentsize                 :SizeOf(program_header_type);
  152.     e_phnum                     :0;                     // 0..e_phnum-1 of entrys
  153.     e_shentsize                 :SizeOf(section_header_type);
  154.     e_shnum                     :0;                     // 0..e_shnum-1 of entrys
  155.     e_shstrndx                  :0);
  156.  
  157.   delta=0;
  158.   alignment=4;//1024; //{4096}1024;
  159.  
  160.   // die Doku sagt '/usr/lib/libc.so.1'#0
  161.   programmlader0                ='/lib/ld-linux.so.1'#0;
  162.   programmlader                 :array[0..Length(programmlader0)-1] of char=programmlader0;
  163.  
  164.  
  165. type // Kopie aus resource.pas
  166.   linux_resource_anker_typ=
  167.     packed record
  168.       zeiger                    :pointer;
  169.       laenge                    :longint;
  170.       signatur                  :array[0..3] of char;
  171.     end;
  172.  
  173. { Return hexadecimal equivalent of parameter Number as a string }
  174. Function Int2Hex( Number : Longint; N : Byte ) : String;
  175. Const
  176.   HexDigit : Array[0..$f] of char = '0123456789ABCDEF';
  177. Var
  178.   s : String;
  179.   i : Integer;
  180.  
  181. begin
  182.   SetLength(s, N);
  183.   For i := N downto 1 do
  184.     begin
  185.       s[i] := HexDigit[Number and $F];
  186.       Number := Number shr 4;
  187.     end;
  188.   Int2Hex := s;
  189. end;
  190.  
  191. { Return hexadecimal equivalent of Pointer }
  192. Function Ptr2Hex( p : Pointer ) : String;
  193. begin
  194.   Ptr2Hex := Int2Hex( Word(p), 8 );
  195. end;
  196.  
  197. { Return string representation of Number }
  198. Function Int2Str( Number : Longint ) : String;
  199. Var
  200.   s : String;
  201. begin
  202.   Str( Number, s );
  203.   Int2Str := s;
  204. end;
  205.  
  206.  
  207. procedure Abbruch(const zk:string);
  208.   begin
  209.     WriteLn(zk);
  210.     Halt(255);
  211.   end;
  212.  
  213. procedure Aufrunden(var a:longint;const m:longint);
  214.   var
  215.     rest:longint;
  216.   begin
  217.     rest:=a mod m;
  218.     if rest<>0 then
  219.       a:=a+m-rest;
  220.   end;
  221.  
  222.  
  223. //███████████████████████████████████████████████████████████████████████
  224.  
  225. procedure lade_pe;
  226.  
  227.   var
  228.     pe_start            :longint;
  229.     puffer              :array[0..$3f] of char;
  230.  
  231.   procedure lies(var p:speicherfeld_z_typ;var obj:pe_obj_typ);
  232.     begin
  233.       GetMem(p,obj.physical_size);
  234.       Seek(d1,obj.physical_offset);
  235.       BlockRead(d1,p^,obj.physical_size);
  236.     end;
  237.  
  238.   procedure lies_obj_hdr(var h:pe_obj_typ);
  239.     begin
  240.       blockread(d1,h,SizeOf(h));
  241.  
  242.       (* kann nicht mehr aus Datei laden als SPeicher reserviert ist *)
  243.       if h.physical_size>h.virtual_size then
  244.         h.physical_size:=h.virtual_size;
  245.     end;
  246.  
  247.   begin
  248.     Assign(d1,InFile);
  249.     Reset(d1,1);
  250.  
  251.     pe_start:=0;
  252.     repeat
  253.       BlockRead(d1,puffer,SizeOf(puffer));
  254.  
  255.       if  (puffer[0]='P')
  256.       and (puffer[1]='E')
  257.       and (puffer[2]=#0 )
  258.       and (puffer[3]=#0 )
  259.        then
  260.         break;
  261.  
  262.       if ((puffer[0]='M') and (puffer[1]='Z'))
  263.       or ((puffer[0]='Z') and (puffer[1]='M'))
  264.        then
  265.         begin
  266.           pe_start:=longint_z(@puffer[$3c])^;
  267.           Seek(d1,pe_start);
  268.           Continue;
  269.         end;
  270.  
  271.  
  272.       if  (puffer[0]='L')
  273.       and (puffer[1]='X')
  274.       and (puffer[2]=#0 )
  275.       and (puffer[3]=#0 )
  276.        then
  277.         abbruch('Error: source is LX');
  278.  
  279.       if  (puffer[0]='L')
  280.       and (puffer[1]='E')
  281.       and (puffer[2]=#0 )
  282.       and (puffer[3]=#0 )
  283.        then
  284.         abbruch('Error: source is LE');
  285.  
  286.       if  (puffer[0]=#$7f)
  287.       and (puffer[1]='E' )
  288.       and (puffer[2]='L' )
  289.       and (puffer[3]='F' )
  290.        then
  291.         abbruch('Error: source is ELF');
  292.  
  293.       abbruch('Error: unknown invalid source executable format.');
  294.  
  295.     until false;
  296.  
  297.     Seek(d1,pe_start);
  298.     BlockRead(d1,pe_kopf,sizeof(pe_kopf));
  299.  
  300.     (* obj-Tabelle laden
  301.  
  302.        expected object names:
  303.  
  304.        CODE32
  305.        _BSS     (optional)
  306.        CONST32
  307.        .idata
  308.        .edata   (optional)
  309.        .reloc
  310.        .rsrc    (optional)              *)
  311.  
  312.     if not (pe_kopf.num_obj in [4,5,6,7]) then
  313.       abbruch('Error: not created with VP 2.0');
  314.  
  315.     seek(d1,pe_start+pe_kopf.nthdrsize+$18);
  316.  
  317.     lies_obj_hdr(pe_obj_tab[code32 ]);
  318.     lies_obj_hdr(pe_obj_tab[_bss   ]);
  319.     bss_vorhanden:=(pe_obj_tab[_bss].name='_BSS'#0#0#0#0) or (pe_obj_tab[_bss].name='DATA32'#0#0);
  320.     if not bss_vorhanden then
  321.       begin
  322.         pe_obj_tab[const32]:=pe_obj_tab[_bss];
  323.         fillchar(pe_obj_tab[_bss],SizeOf(pe_obj_tab[_bss]),0);
  324.       end
  325.     else
  326.       lies_obj_hdr(pe_obj_tab[const32]);
  327.     lies_obj_hdr(pe_obj_tab[idata  ]);
  328.     lies_obj_hdr(pe_obj_tab[reloc  ]);
  329.     if pe_obj_tab[reloc  ].name<>'.reloc'#0#0 then (* .edata ? *)
  330.       lies_obj_hdr(pe_obj_tab[reloc  ]);
  331.     lies_obj_hdr(pe_obj_tab[res  ]);
  332.  
  333.     resourcen_vorhanden:=(pe_obj_tab[res    ].name='.rsrc'#0#0#0);
  334.     if not resourcen_vorhanden then
  335.       fillchar(pe_obj_tab[res  ],sizeof(pe_obj_typ),0);
  336.  
  337.     if  (pe_obj_tab[code32 ].name<>'CODE32'#0#0  )
  338.     or ((pe_obj_tab[_bss   ].name<>'_BSS'#0#0#0#0) and (pe_obj_tab[_bss   ].name<>'DATA32'#0#0) and bss_vorhanden)
  339.     or  (pe_obj_tab[const32].name<>'CONST32'#0   )
  340.     or  (pe_obj_tab[idata  ].name<>'.idata'#0#0  )
  341.     or  (pe_obj_tab[reloc  ].name<>'.reloc'#0#0  )
  342.     or ((pe_obj_tab[res    ].name<>'.rsrc'#0#0#0 ) and resourcen_vorhanden)
  343.      then
  344.       abbruch('Error: not created with VP 2.0');
  345.  
  346.     importe_vorhanden:={(pe_obj_tab[idata  ].physical_size>$14)}true;
  347.  
  348.     lies(code_puffer,pe_obj_tab[code32 ]);
  349.     if bss_vorhanden then
  350.       lies(bss_puffer,pe_obj_tab[_bss]);
  351.     lies(data_puffer,pe_obj_tab[const32]);
  352.     lies(import_puffer,pe_obj_tab[idata]);
  353.     lies(relo_puffer,pe_obj_tab[reloc]);
  354.     if resourcen_vorhanden then
  355.       lies(reso_puffer,pe_obj_tab[res]);
  356.  
  357.     Close(d1);
  358.   end;
  359.  
  360. //███████████████████████████████████████████████████████████████████████
  361.  
  362.  
  363. procedure rechne;
  364.   var
  365.     dateiposition,adressposition:longint;
  366.     sekt_z:sektionen;
  367.     index_:longint;
  368.     z1:longint;
  369.  
  370.   function name_speichern(const zk:string):longint;
  371.     begin
  372.       Result:=string_puffer_laenge;
  373.       ReallocMem(string_puffer,string_puffer_laenge+Length(zk)+1);
  374.       Move(zk[1],string_puffer^[string_puffer_laenge],Length(zk));
  375.       Inc(string_puffer_laenge,Length(zk));
  376.       string_puffer^[string_puffer_laenge]:=0; // #0
  377.       Inc(string_puffer_laenge);
  378.     end;
  379.  
  380.   procedure suche_naechste_passende_dateipostion;
  381.     begin
  382.       // mod 4096 = and $fff
  383.       if (dateiposition and $fff)<>(adressposition and $fff) then
  384.         begin
  385.           dateiposition:=(dateiposition and $fffff000)+$1000+(adressposition and $fff);
  386.         end;
  387.     end;
  388.  
  389.   procedure suche_naechste_passende_adressposition;
  390.     begin
  391.       // mod 4096 = and $fff
  392.       if (dateiposition and $fff)<>(adressposition and $fff) then
  393.         begin
  394.           adressposition:=(adressposition and $fffff000)+$1000+(dateiposition and $fff);
  395.         end;
  396.     end;
  397.  
  398.   (*$I impconve.pas*)
  399.   (*$I proghead.pas*)
  400.  
  401.   begin
  402.     string_puffer_laenge:=0;
  403.     string_puffer:=nil;
  404.     name_speichern('');
  405.  
  406.     anzahl_dynamic_eintraege:=0;
  407.     dynamic_speicher:=nil;
  408.  
  409.     // Länge eines Symboltabelleneintrages
  410.     Speichere_in_der_DYNAMIC_Tabelle(DT_SYMENT,SizeOf(Elf32_Sym_type));
  411.  
  412.     // das von VP im Datenbereich angelegte Stacksegment kann gelöscht werden
  413.     z1:=Meml[Ofs(code_puffer^[pe_kopf.entrypoint-pe_obj_tab[code32].rva])+5+1];
  414.     Dec(pe_obj_tab[const32].virtual_size,z1);
  415.  
  416.     // Nullen am Ende des Datenbereiches kommen in den virtuellen Teil
  417.     z1:=pe_obj_tab[const32].physical_size;
  418.     while data_puffer^[z1-1-1]=0 do
  419.       dec(z1);
  420.     // auf 32-Bit-Länge bringen
  421.     Aufrunden(z1,4);
  422.     pe_obj_tab[const32].physical_size:=z1;
  423.  
  424.  
  425.  
  426.     // welche Sektionen werden benötigt ?
  427.     FillChar(sektionen_uebersicht,SizeOf(sektionen_uebersicht),0); // 0,false,..
  428.     sektionen_uebersicht[sekt_null].vorhanden:=true;
  429.     sektionen_uebersicht[sekt_text].vorhanden:=true;
  430.     // >>>>!!!sekt_bss
  431.     sektionen_uebersicht[sekt_data_a].vorhanden:=true;
  432.     if pe_obj_tab[const32].virtual_size>pe_obj_tab[const32].physical_size then
  433.       sektionen_uebersicht[sekt_data_b].vorhanden:=true;
  434.  
  435.     if importe_vorhanden then
  436.       begin
  437.         sektionen_uebersicht[sekt_interpreter   ].vorhanden:=true;
  438.         sektionen_uebersicht[sekt_plt           ].vorhanden:=true;
  439.         sektionen_uebersicht[sekt_rel_plt       ].vorhanden:=true;
  440.         sektionen_uebersicht[sekt_got           ].vorhanden:=true;
  441.         sektionen_uebersicht[sekt_dynamic       ].vorhanden:=true;
  442.         sektionen_uebersicht[sekt_dynsym        ].vorhanden:=true;
  443.         sektionen_uebersicht[sekt_dynsymstr     ].vorhanden:=true;
  444.         sektionen_uebersicht[sekt_dynsymstrhash ].vorhanden:=true;
  445.       end;
  446.  
  447.     // Resourceumwandlung
  448.     if resourcen_vorhanden then
  449.       begin
  450.         // sekt_resource
  451.         sektionen_uebersicht[sekt_resource].vorhanden:=true;
  452.         (* Annahme: viel weniger Platz wird benötigt *)
  453.         getmem(reso_temp_puffer,(pe_obj_tab[res].physical_size*3) div 2);
  454.         reso_temp_laenge:=0;
  455.  
  456.         konvertiere_resourcen(reso_puffer,pe_obj_tab[res].physical_size,pe_obj_tab[res].rva,
  457.                               reso_temp_puffer,reso_temp_laenge);
  458.  
  459.         //!!wirr
  460.         (* neu in richtiger Größe anfordern *)
  461.         ReAllocMem(reso_puffer,reso_temp_laenge);
  462.         (* Daten Kopieren *)
  463.         Move(reso_temp_puffer^,reso_puffer^,reso_temp_laenge);
  464.         (* temporären Speicher freigeben *)
  465.         Dispose(reso_temp_puffer);
  466.         (* neue Länge merken *)
  467.  
  468.         pe_obj_tab[res].virtual_size :=reso_temp_laenge;
  469.         pe_obj_tab[res].physical_size:=reso_temp_laenge;
  470.       end;
  471.  
  472.     sektionen_uebersicht[sekt_strings].vorhanden:=true;
  473.  
  474.     // Nummern verteilen und zählen
  475.     for sekt_z:=low(sektionen) to high(sektionen) do
  476.       if sektionen_uebersicht[sekt_z].vorhanden then
  477.         begin
  478.           sektionen_uebersicht[sekt_z].index_:=elf_kopf.e_shnum;
  479.           Inc(elf_kopf.e_shnum);
  480.         end
  481.       else
  482.         sektionen_uebersicht[sekt_z].index_:=-1;
  483.  
  484.     elf_kopf.e_phnum:=elf_kopf.e_shnum;
  485.  
  486.  
  487.     //*********************************************************************
  488.  
  489.     // Sektionen füllen und Dateipostionen vergeben
  490.     dateiposition:=SizeOf(elf_kopf);
  491.     elf_kopf.e_shoff:=dateiposition;
  492.     Inc(dateiposition,elf_kopf.e_shentsize*elf_kopf.e_shnum);
  493.  
  494.     FillChar(sektionen_kopf[0],SizeOf(sektionen_kopf),0); // SHT_NULL
  495.     FillChar(programm_kopf [0],SizeOf(programm_kopf ),0); // PT_NULL
  496.  
  497.     adressposition:=$00401000-$1000+dateiposition;
  498.     //***********************************************************************
  499.     // Programmlader
  500.     if sektionen_uebersicht[sekt_interpreter].vorhanden then
  501.       begin
  502.         index_:=sektionen_uebersicht[sekt_interpreter].index_;
  503.         with sektionen_kopf[index_] do
  504.           begin
  505.             sh_name         :=name_speichern('.interp');
  506.             sh_type         :=SHT_PROGBITS;
  507.             sh_flags        :=SHF_ALLOC;
  508.             sh_addr         :=adressposition;
  509.             sh_offset       :=dateiposition;
  510.             sh_size         :=Length(programmlader);
  511.             sh_link         :=0;
  512.             sh_info         :=0;
  513.             sh_addralign    :=1;
  514.             sh_entsize      :=0;
  515.           end;
  516.         with programm_kopf [index_] do
  517.           begin
  518.             p_type          :=PT_INTERP;
  519.             p_offset        :=sektionen_kopf[index_].sh_offset;
  520.             p_vaddr         :=sektionen_kopf[index_].sh_addr;
  521.             p_paddr         :=0;
  522.             p_filesz        :=sektionen_kopf[index_].sh_size;
  523.             p_memsz         :=sektionen_kopf[index_].sh_size;
  524.             p_flags         :=PF_R;
  525.             p_align         :=sektionen_kopf[index_].sh_addralign;
  526.           end;
  527.  
  528.         Inc(adressposition,sektionen_kopf[index_].sh_size);
  529.         Inc(dateiposition ,sektionen_kopf[index_].sh_size);
  530.  
  531.         Aufrunden(adressposition,4);
  532.         Aufrunden(dateiposition ,4);
  533.       end;
  534.  
  535.     //***********************************************************************
  536.     // CODE bearbeiten
  537.     // $00401000 damit der VP-debugger funktioniert
  538.     adressposition:=pe_obj_tab[code32].rva+pe_kopf.image_base+delta;
  539.     suche_naechste_passende_dateipostion;
  540.  
  541.     index_:=sektionen_uebersicht[sekt_text].index_;
  542.     with sektionen_kopf[index_] do
  543.       begin
  544.         sh_name         :=name_speichern('.text');
  545.         sh_type         :=SHT_PROGBITS;
  546.         sh_flags        :=SHF_ALLOC+SHF_EXECINSTR;
  547.         sh_addr         :=adressposition;
  548.         sh_offset       :=dateiposition;
  549.         sh_size         :=pe_obj_tab[code32].physical_size;
  550.         sh_link         :=0;
  551.         sh_info         :=0;
  552.         sh_addralign    :=4;
  553.         sh_entsize      :=0;
  554.       end;
  555.     with programm_kopf [index_] do
  556.       begin
  557.         p_type          :=PT_LOAD;
  558.         p_offset        :=sektionen_kopf[index_].sh_offset;
  559.         p_vaddr         :=sektionen_kopf[index_].sh_addr;
  560.         p_paddr         :=0;
  561.         p_filesz        :=sektionen_kopf[index_].sh_size;
  562.         p_memsz         :=sektionen_kopf[index_].sh_size;
  563.         p_flags         :=PF_X+PF_R;
  564.         p_align         :=sektionen_kopf[index_].sh_addralign;
  565.       end;
  566.  
  567.     // Eintrittspunkt
  568.     elf_kopf.e_entry:=pe_kopf.entrypoint+pe_kopf.image_base+delta;
  569.  
  570.     Inc(adressposition,sektionen_kopf[index_].sh_size);
  571.     Inc(dateiposition ,sektionen_kopf[index_].sh_size);
  572.  
  573.     Aufrunden(adressposition,4);
  574.     Aufrunden(dateiposition ,4);
  575.  
  576.     //***********************************************************************
  577.     // BSS
  578.     if sektionen_uebersicht[sekt_bss].vorhanden then
  579.       begin
  580.         adressposition:=pe_obj_tab[_bss].rva+pe_kopf.image_base+delta;
  581.  
  582.         index_:=sektionen_uebersicht[sekt_bss].index_;
  583.         with sektionen_kopf[index_] do
  584.           begin
  585.             sh_name         :=name_speichern('.bss');
  586.             sh_type         :=SHT_NOBITS;
  587.             sh_flags        :=SHF_ALLOC+SHF_WRITE;
  588.             sh_addr         :=adressposition;
  589.             sh_offset       :=0;
  590.             sh_size         :=pe_obj_tab[_bss].virtual_size;
  591.             sh_link         :=0;
  592.             sh_info         :=0;
  593.             sh_addralign    :=4;
  594.             sh_entsize      :=0;
  595.           end;
  596.         with programm_kopf [index_] do
  597.           begin
  598.             p_type          :=PT_LOAD;
  599.             p_offset        :=sektionen_kopf[index_].sh_offset;
  600.             p_vaddr         :=sektionen_kopf[index_].sh_addr;
  601.             p_paddr         :=0;
  602.             p_filesz        :=0;
  603.             p_memsz         :=sektionen_kopf[index_].sh_size;
  604.             p_flags         :=PF_R+PF_W;
  605.             p_align         :=sektionen_kopf[index_].sh_addralign;
  606.           end;
  607.  
  608.         Inc(adressposition,sektionen_kopf[index_].sh_size);
  609.         Aufrunden(adressposition,4);
  610.       end;
  611.  
  612.     //***********************************************************************
  613.     // Konstanten und Daten - Teil 1
  614.     adressposition:=pe_obj_tab[const32].rva+pe_kopf.image_base+delta;
  615.     suche_naechste_passende_dateipostion;
  616.  
  617.     index_:=sektionen_uebersicht[sekt_data_a].index_;
  618.     with sektionen_kopf[index_] do
  619.       begin
  620.         sh_name         :=name_speichern('.data');
  621.         sh_type         :=SHT_PROGBITS;
  622.         sh_flags        :=SHF_ALLOC+SHF_WRITE;
  623.         sh_addr         :=adressposition;
  624.         sh_offset       :=dateiposition;
  625.         sh_size         :=pe_obj_tab[const32].physical_size;
  626.         sh_link         :=0;
  627.         sh_info         :=0;
  628.         sh_addralign    :=4;
  629.         sh_entsize      :=0;
  630.       end;
  631.     with programm_kopf [index_] do
  632.       begin
  633.         p_type          :=PT_LOAD;
  634.         p_offset        :=sektionen_kopf[index_].sh_offset;
  635.         p_vaddr         :=sektionen_kopf[index_].sh_addr;
  636.         p_paddr         :=0;
  637.         p_filesz        :=sektionen_kopf[index_].sh_size;
  638.         p_memsz         :=sektionen_kopf[index_].sh_size;
  639.         p_flags         :=PF_R+PF_W;
  640.         p_align         :=sektionen_kopf[index_].sh_addralign;
  641.       end;
  642.  
  643.     Inc(adressposition,sektionen_kopf[index_].sh_size);
  644.     Inc(dateiposition ,sektionen_kopf[index_].sh_size);
  645.  
  646.     //***********************************************************************
  647.     // Konstanten und Daten - Teil 2
  648.     if sektionen_uebersicht[sekt_data_b].vorhanden then
  649.       begin
  650.         index_:=sektionen_uebersicht[sekt_data_b].index_;
  651.         with sektionen_kopf[index_] do
  652.           begin
  653.             sh_name         :=name_speichern('.bss');
  654.             sh_type         :=SHT_NOBITS;
  655.             sh_flags        :=SHF_ALLOC+SHF_WRITE;
  656.             sh_addr         :=adressposition;
  657.             sh_offset       :=dateiposition;
  658.             sh_size         :=pe_obj_tab[const32].virtual_size-pe_obj_tab[const32].physical_size;
  659.             sh_link         :=0;
  660.             sh_info         :=0;
  661.             sh_addralign    :=4;
  662.             sh_entsize      :=0;
  663.           end;
  664.         with programm_kopf [index_] do
  665.           begin
  666.             p_type          :=PT_LOAD;
  667.             p_offset        :=sektionen_kopf[index_].sh_offset;
  668.             p_vaddr         :=sektionen_kopf[index_].sh_addr;
  669.             p_paddr         :=0;
  670.             p_filesz        :=0;
  671.             p_memsz         :=sektionen_kopf[index_].sh_size;
  672.             p_flags         :=PF_R+PF_W;
  673.             p_align         :=sektionen_kopf[index_].sh_addralign;
  674.           end;
  675.         Inc(adressposition,sektionen_kopf[index_].sh_size);
  676.         Aufrunden(adressposition,4);
  677.         suche_naechste_passende_adressposition;
  678.       end;
  679.  
  680.     resource_adressposition:=0;
  681.     if importe_vorhanden then
  682.       import_umrechnung;
  683.  
  684.  
  685.     //***********************************************************************
  686.     // ".dynamic"
  687.     if sektionen_uebersicht[sekt_dynamic].vorhanden then
  688.       begin
  689.         index_:=sektionen_uebersicht[sekt_dynamic].index_;
  690.         with sektionen_kopf[index_] do
  691.           begin
  692.             sh_name         :=name_speichern('.dynamic');
  693.             sh_type         :=SHT_DYNAMIC;
  694.             sh_flags        :=SHF_WRITE+SHF_ALLOC;
  695.             sh_addr         :=_dynamic_adressposition;
  696.             sh_offset       :=_dynamic_dateiposition ;
  697.             sh_size         :=_dynamic_laenge;
  698.             sh_link         :=sektionen_uebersicht[sekt_dynsymstr].index_;
  699.             sh_info         :=0;
  700.             sh_addralign    :=4;
  701.             sh_entsize      :=SizeOf(Elf32_Dyn_type);
  702.           end;
  703.         with programm_kopf [index_] do
  704.           begin
  705.             p_type          :=PT_DYNAMIC;
  706.             p_offset        :=sektionen_kopf[index_].sh_offset;
  707.             p_vaddr         :=sektionen_kopf[index_].sh_addr;
  708.             p_paddr         :=0;
  709.             p_filesz        :=sektionen_kopf[index_].sh_size;
  710.             p_memsz         :=sektionen_kopf[index_].sh_size;
  711.             p_flags         :=PF_R+PF_W;
  712.             p_align         :=sektionen_kopf[index_].sh_addralign;
  713.           end;
  714.       end;
  715.  
  716.     //***********************************************************************
  717.     // ".got"
  718.     if sektionen_uebersicht[sekt_got].vorhanden then
  719.       begin
  720.         index_:=sektionen_uebersicht[sekt_got].index_;
  721.         with sektionen_kopf[index_] do
  722.           begin
  723.             sh_name         :=name_speichern('.got');
  724.             sh_type         :=SHT_PROGBITS;
  725.             sh_flags        :=SHF_WRITE+SHF_ALLOC;
  726.             sh_addr         :=_got_adressposition;
  727.             sh_offset       :=_got_dateiposition ;
  728.             sh_size         :=_got_laenge;
  729.             sh_link         :=0;
  730.             sh_info         :=0;
  731.             sh_addralign    :=4;
  732.             sh_entsize      :=4;
  733.           end;
  734.         with programm_kopf [index_] do
  735.           begin
  736.             p_type          :=PT_LOAD;
  737.             p_offset        :=sektionen_kopf[index_].sh_offset;
  738.             p_vaddr         :=sektionen_kopf[index_].sh_addr;
  739.             p_paddr         :=0;
  740.             p_filesz        :=sektionen_kopf[index_].sh_size;
  741.             p_memsz         :=sektionen_kopf[index_].sh_size;
  742.             p_flags         :=PF_R+PF_W;
  743.             p_align         :=sektionen_kopf[index_].sh_addralign;
  744.           end;
  745.       end;
  746.  
  747.  
  748.     //***********************************************************************
  749.     // ".dynsym"
  750.     if sektionen_uebersicht[sekt_dynsym].vorhanden then
  751.       begin
  752.         index_:=sektionen_uebersicht[sekt_dynsym].index_;
  753.         with sektionen_kopf[index_] do
  754.           begin
  755.             sh_name         :=name_speichern('.dynsym');
  756.             sh_type         :=SHT_DYNSYM;
  757.             sh_flags        :=SHF_ALLOC;
  758.             sh_addr         :=_dynsym_adressposition;
  759.             sh_offset       :=_dynsym_dateiposition ;
  760.             sh_size         :=_dynsym_laenge;
  761.             sh_link         :=sektionen_uebersicht[sekt_dynsymstr].index_;
  762.             sh_info         :=sektionen_uebersicht[sekt_interpreter].index_;
  763.             sh_addralign    :=4;
  764.             sh_entsize      :=SizeOf(Elf32_Sym_type);
  765.           end;
  766.         with programm_kopf [index_] do
  767.           begin
  768.             p_type          :=PT_LOAD;
  769.             p_offset        :=sektionen_kopf[index_].sh_offset;
  770.             p_vaddr         :=sektionen_kopf[index_].sh_addr;
  771.             p_paddr         :=0;
  772.             p_filesz        :=sektionen_kopf[index_].sh_size;
  773.             p_memsz         :=sektionen_kopf[index_].sh_size;
  774.             p_flags         :=PF_R;
  775.             p_align         :=sektionen_kopf[index_].sh_addralign;
  776.           end;
  777.       end;
  778.  
  779.     //***********************************************************************
  780.     // ".dynstr"
  781.     if sektionen_uebersicht[sekt_dynsymstr].vorhanden then
  782.       begin
  783.         index_:=sektionen_uebersicht[sekt_dynsymstr].index_;
  784.         with sektionen_kopf[index_] do
  785.           begin
  786.             sh_name         :=name_speichern('.dynstr');
  787.             sh_type         :=SHT_STRTAB;
  788.             sh_flags        :=SHF_ALLOC;
  789.             sh_addr         :=_dynsymstr_adressposition;
  790.             sh_offset       :=_dynsymstr_dateiposition;
  791.             sh_size         :=symbolstringtabelle_laenge;
  792.             sh_link         :=0;
  793.             sh_info         :=0;
  794.             sh_addralign    :=4;
  795.             sh_entsize      :=0;
  796.           end;
  797.         with programm_kopf [index_] do
  798.           begin
  799.             p_type          :=PT_LOAD;
  800.             p_offset        :=sektionen_kopf[index_].sh_offset;
  801.             p_vaddr         :=sektionen_kopf[index_].sh_addr;
  802.             p_paddr         :=0;
  803.             p_filesz        :=sektionen_kopf[index_].sh_size;
  804.             p_memsz         :=sektionen_kopf[index_].sh_size;
  805.             p_flags         :=PF_R;
  806.             p_align         :=sektionen_kopf[index_].sh_addralign;
  807.           end;
  808.       end;
  809.  
  810.     //***********************************************************************
  811.     // ".hash"
  812.     if sektionen_uebersicht[sekt_dynsymstrhash].vorhanden then
  813.       begin
  814.         index_:=sektionen_uebersicht[sekt_dynsymstrhash].index_;
  815.         with sektionen_kopf[index_] do
  816.           begin
  817.             sh_name         :=name_speichern('.hash');
  818.             sh_type         :=SHT_HASH;
  819.             sh_flags        :=SHF_ALLOC;
  820.             sh_addr         :=_dynsymstrhash_adressposition;
  821.             sh_offset       :=_dynsymstrhash_dateiposition;
  822.             sh_size         :=hash_tabelle_laenge;
  823.             sh_link         :=sektionen_uebersicht[sekt_dynsym].index_;
  824.             sh_info         :=0;
  825.             sh_addralign    :=4;
  826.             sh_entsize      :=4;
  827.           end;
  828.         with programm_kopf [index_] do
  829.           begin
  830.             p_type          :=PT_LOAD;
  831.             p_offset        :=sektionen_kopf[index_].sh_offset;
  832.             p_vaddr         :=sektionen_kopf[index_].sh_addr;
  833.             p_paddr         :=0;
  834.             p_filesz        :=sektionen_kopf[index_].sh_size;
  835.             p_memsz         :=sektionen_kopf[index_].sh_size;
  836.             p_flags         :=PF_R;
  837.             p_align         :=sektionen_kopf[index_].sh_addralign;
  838.           end;
  839.       end;
  840.  
  841.     //***********************************************************************
  842.     // Resourcen
  843.     if sektionen_uebersicht[sekt_resource].vorhanden then
  844.       begin
  845.         if resource_adressposition=0 then
  846.           begin
  847.             // Adresse und Dateipostion kongruent modulo Seitengröße
  848.             // wenn die Resourcen auf einer beschreibbaren Seite
  849.             // anfangen wuerden, muß eine neue Seite gewählt werden
  850.             if (adressposition mod 4096)>0 then
  851.               Inc(adressposition,4096);
  852.  
  853.             runerror(99); // prüfen,dateiposition...!!!!!!!!!!!!
  854.  
  855.             resource_laenge:=pe_obj_tab[res].physical_size;
  856.             Inc(adressposition,sektionen_kopf[index_].sh_size);
  857.             Inc(dateiposition ,sektionen_kopf[index_].sh_size);
  858.  
  859.             Aufrunden(adressposition,4);
  860.             Aufrunden(dateiposition ,4);
  861.  
  862.  
  863.           end;
  864.  
  865.         index_:=sektionen_uebersicht[sekt_resource].index_;
  866.         with sektionen_kopf[index_] do
  867.           begin
  868.             sh_name         :=name_speichern('resource');
  869.             sh_type         :=SHT_PROGBITS;
  870.             sh_flags        :=SHF_ALLOC;
  871.             sh_addr         :=resource_adressposition;
  872.             sh_offset       :=resource_dateiposition;
  873.             sh_size         :=resource_laenge;
  874.             sh_link         :=0;
  875.             sh_info         :=0;
  876.             sh_addralign    :=4;
  877.             sh_entsize      :=0;
  878.           end;
  879.         with programm_kopf [index_] do
  880.           begin
  881.             p_type          :=PT_LOAD;
  882.             p_offset        :=sektionen_kopf[index_].sh_offset;
  883.             p_vaddr         :=sektionen_kopf[index_].sh_addr;
  884.             p_paddr         :=0;
  885.             p_filesz        :=sektionen_kopf[index_].sh_size;
  886.             p_memsz         :=sektionen_kopf[index_].sh_size;
  887.             p_flags         :=PF_R;
  888.             p_align         :=4;
  889.           end;
  890.       end;
  891.     //***********************************************************************
  892.     // ".rel.plt"
  893.     if sektionen_uebersicht[sekt_rel_plt].vorhanden then
  894.       begin
  895.         index_:=sektionen_uebersicht[sekt_rel_plt].index_;
  896.         with sektionen_kopf[index_] do
  897.           begin
  898.             sh_name         :=name_speichern('.rel.plt');
  899.             sh_type         :=SHT_REL;
  900.             sh_flags        :=SHF_ALLOC;
  901.             sh_addr         :=_rel_plt_adressposition;
  902.             sh_offset       :=_rel_plt_dateiposition;
  903.             sh_size         :=_rel_plt_laenge;
  904.             sh_link         :=sektionen_uebersicht[sekt_dynsym].index_;
  905.             sh_info         :=sektionen_uebersicht[sekt_plt   ].index_;
  906.             sh_addralign    :=4;
  907.             sh_entsize      :=SizeOf(Elf32_Rel_type);
  908.           end;
  909.         with programm_kopf [index_] do
  910.           begin
  911.             p_type          :=PT_LOAD;
  912.             p_offset        :=sektionen_kopf[index_].sh_offset;
  913.             p_vaddr         :=sektionen_kopf[index_].sh_addr;
  914.             p_paddr         :=0;
  915.             p_filesz        :=sektionen_kopf[index_].sh_size;
  916.             p_memsz         :=sektionen_kopf[index_].sh_size;
  917.             p_flags         :=PF_R;
  918.             p_align         :=sektionen_kopf[index_].sh_addralign;
  919.           end;
  920.       end;
  921.  
  922.  
  923.     //***********************************************************************
  924.     // ".plt"
  925.     if sektionen_uebersicht[sekt_plt].vorhanden then
  926.       begin
  927.         index_:=sektionen_uebersicht[sekt_plt].index_;
  928.         with sektionen_kopf[index_] do
  929.           begin
  930.             sh_name         :=name_speichern('.plt');
  931.             sh_type         :=SHT_PROGBITS;
  932.             sh_flags        :=SHF_ALLOC+SHF_EXECINSTR;
  933.             sh_addr         :=_plt_adressposition;
  934.             sh_offset       :=_plt_dateiposition;
  935.             sh_size         :=_plt_laenge;
  936.             sh_link         :=0;
  937.             sh_info         :=0;
  938.             sh_addralign    :=4;
  939.             sh_entsize      :=0;
  940.           end;
  941.         with programm_kopf [index_] do
  942.           begin
  943.             p_type          :=PT_LOAD;
  944.             p_offset        :=sektionen_kopf[index_].sh_offset;
  945.             p_vaddr         :=sektionen_kopf[index_].sh_addr;
  946.             p_paddr         :=0;
  947.             p_filesz        :=sektionen_kopf[index_].sh_size;
  948.             p_memsz         :=sektionen_kopf[index_].sh_size;
  949.             p_flags         :=PF_R+PF_X;
  950.             p_align         :=sektionen_kopf[index_].sh_addralign;
  951.           end;
  952.       end;
  953.  
  954.  
  955.     //***********************************************************************
  956.     // Sektionsnamensektion
  957.     index_:=sektionen_uebersicht[sekt_strings].index_;
  958.     with sektionen_kopf[index_] do
  959.       begin
  960.         sh_name         :=name_speichern('.shstrtab');
  961.         sh_type         :=SHT_STRTAB;
  962.         sh_flags        :=0;
  963.         sh_addr         :=0;
  964.         sh_offset       :=dateiposition;
  965.         sh_size         :=string_puffer_laenge;
  966.         sh_link         :=0;
  967.         sh_info         :=0;
  968.         sh_addralign    :=4;
  969.         sh_entsize      :=0;
  970.       end;
  971.     with programm_kopf [index_] do
  972.       begin
  973.         p_type          :=PT_NULL;
  974.         p_offset        :=sektionen_kopf[index_].sh_offset;
  975.         p_vaddr         :=sektionen_kopf[index_].sh_addr;
  976.         p_paddr         :=0;
  977.         p_filesz        :=string_puffer_laenge;
  978.         p_memsz         :=string_puffer_laenge;
  979.         p_flags         :=0;
  980.         p_align         :=sektionen_kopf[index_].sh_addralign;
  981.       end;
  982.     Inc(dateiposition ,string_puffer_laenge);
  983.     Inc(adressposition,string_puffer_laenge);
  984.     elf_kopf.e_shstrndx:=sektionen_uebersicht[sekt_strings].index_;
  985.  
  986.  
  987.  
  988.     //**********************************************************************
  989.     // wenn Resourcen vorhanden sind, muß der Anker in Resource.pas
  990.     // gefunden und angepaßt werden
  991.     if sektionen_uebersicht[sekt_resource].vorhanden then
  992.       begin
  993.         resource_anker_gefunden:=false;
  994.  
  995.         for z1:=0 to programm_kopf[sektionen_uebersicht[sekt_data_a].index_].
  996.                         p_filesz-Sizeof(linux_resource_anker_typ) do
  997.           // vielleicht zu langsam ..
  998.           with linux_resource_anker_typ(data_puffer^[z1]) do
  999.             if  (zeiger  =Ptr($b582cc18))
  1000.             and (laenge  =    $467a1d0e )
  1001.             and (signatur=    'RES?'    ) then
  1002.               begin
  1003.                 zeiger  :=pointer(sektionen_kopf[sektionen_uebersicht[sekt_resource].index_].sh_addr);
  1004.                 laenge  :=sektionen_kopf[sektionen_uebersicht[sekt_resource].index_].sh_size;
  1005.                 signatur:='RESO';
  1006.                 resource_anker_gefunden:=true;
  1007.                 break;
  1008.               end;
  1009.  
  1010.         if not resource_anker_gefunden then
  1011.           WriteLn('Warning: resource anchor not found !');
  1012.       end;
  1013.  
  1014.     bearbeite_programmheader;
  1015.  
  1016.   end;
  1017.  
  1018. //███████████████████████████████████████████████████████████████████████
  1019.  
  1020. procedure schreibe_elf;
  1021.  
  1022.   procedure Fuellen(const anzahl:longint);
  1023.     var
  1024.       null_feld:array[0..4096-1] of byte;
  1025.     begin
  1026.       if anzahl<=0 then exit;
  1027.       DWriteLn('***'+'  '+
  1028.                Int2Hex(FilePos(d2),8)+'  '+
  1029.                Int2Hex(anzahl,8)
  1030.                {'********'+'  ',});
  1031.  
  1032.       FillChar(null_feld,anzahl,0);
  1033.       BlockWrite(d2,null_feld,anzahl);
  1034.     end;
  1035.  
  1036.   var
  1037.     sekt_z:sektionen;
  1038.     laenge:longint;
  1039.  
  1040.   begin
  1041.     Assign(d2,OutFile);
  1042.     FileMode:=$41;
  1043.     Rewrite(d2,1);
  1044.  
  1045.     BlockWrite(d2,elf_kopf,SizeOf(elf_kopf));
  1046.  
  1047.     BlockWrite(d2,sektionen_kopf,elf_kopf.e_shentsize*elf_kopf.e_shnum);
  1048.  
  1049.     DWriteLn('sec'+'  '+
  1050.              'filepos '+'  '+
  1051.              'len     '+'  '+
  1052.              'addr    '+'  '+
  1053.              'len     '+'  '+
  1054.              'attr  '+
  1055.             {'Name der Sektion'}'name of section');
  1056.  
  1057.     for sekt_z:=sekt_interpreter to high(sektionen) do
  1058.       if sektionen_uebersicht[sekt_z].vorhanden then
  1059.         begin
  1060.           laenge:=programm_kopf[sektionen_uebersicht[sekt_z].index_].p_filesz;
  1061.  
  1062.           Seek(d2,FileSize(d2));
  1063.  
  1064.           if (laenge>0) and (sektionen_kopf[sektionen_uebersicht[sekt_z].index_].sh_offset>0) then
  1065.             Fuellen(sektionen_kopf[sektionen_uebersicht[sekt_z].index_].sh_offset-FilePos(d2));
  1066.  
  1067.           DWrite  (Int2Hex(Ord(sektionen_uebersicht[sekt_z].index_),3)+'  '+
  1068.                    {Int2Hex(FilePos(d2),8),'  ',}
  1069.                    Int2Hex(sektionen_kopf[sektionen_uebersicht[sekt_z].index_].sh_offset,8)+'  '+
  1070.                    Int2Hex(laenge,8)+'  '+
  1071.                    Int2Hex(sektionen_kopf[sektionen_uebersicht[sekt_z].index_].sh_addr,8)+'  '+
  1072.                    Int2Hex(programm_kopf[sektionen_uebersicht[sekt_z].index_].p_memsz,8)+'  ');
  1073.  
  1074.           with programm_kopf[sektionen_uebersicht[sekt_z].index_] do
  1075.             begin
  1076.               if (p_flags and PF_R)=PF_R then
  1077.                 DWrite('R')
  1078.               else
  1079.                 DWrite('-');
  1080.               if (p_flags and PF_W)=PF_W then
  1081.                 DWrite('W')
  1082.               else
  1083.                 DWrite('-');
  1084.               if (p_flags and PF_X)=PF_X then
  1085.                 DWrite('X')
  1086.               else
  1087.                 DWrite('-');
  1088.               DWrite('   ');
  1089.             end;
  1090.  
  1091.           DWriteLn(sektionen_namen[sekt_z{,1}]);
  1092.  
  1093.           if laenge>0 then
  1094.             Seek(d2,programm_kopf[sektionen_uebersicht[sekt_z].index_].p_offset);
  1095.  
  1096.           if (laenge>0) and (programm_kopf[sektionen_uebersicht[sekt_z].index_].p_vaddr>0) then
  1097.             if (FilePos(d2) mod 4096)<>(programm_kopf[sektionen_uebersicht[sekt_z].index_].p_vaddr mod 4096) then
  1098.               begin
  1099.                 WriteLn('internal bug: filepos=$',
  1100.                         Int2Hex(programm_kopf[sektionen_uebersicht[sekt_z].index_].p_offset,8),
  1101.                         ' alignement mismatch to v_addr=$',
  1102.                         Int2Hex(programm_kopf[sektionen_uebersicht[sekt_z].index_].p_vaddr ,8));
  1103.                 RunError(1);
  1104.               end;
  1105.  
  1106.           BlockWrite(d2,speicher_tabelle[sektionen_uebersicht[sekt_z].index_]^,laenge);
  1107.  
  1108.         end;
  1109.  
  1110.     BlockWrite(d2,pk2,elf_kopf.e_phentsize*elf_kopf.e_phnum);
  1111.  
  1112.     Close(d2);
  1113.     // Writeln('Success.');
  1114.     // memleaks...
  1115.   end;
  1116.  
  1117. //███████████████████████████████████████████████████████████████████████
  1118.  
  1119. function RPos(C: Char; const S: string): LongInt;
  1120. begin
  1121.   Result := Length(S);
  1122.   while (Result > 0) and (S[Result] <> C) do Dec(Result);
  1123. end;
  1124.  
  1125. procedure show_usage;
  1126.   begin
  1127.     WriteLn;
  1128.     WriteLn('Usage: PE2ELF [-v] <infile>[.exe] [<outfile>]');
  1129.     Halt(1);
  1130.   end;
  1131.  
  1132. var
  1133.   param         :word;
  1134.  
  1135. begin
  1136.   WriteLn('PE2ELF * Veit Kannegieser * 1999.07.28..2000.05.10');
  1137.  
  1138.   param:=1;
  1139.   while Pos('-',ParamStr(param))<>0 do
  1140.     begin
  1141.       case UpCase(ParamStr(param)[2]) of
  1142.         'V':verbose:=true;
  1143.       else
  1144.         show_usage;
  1145.       end;
  1146.       Inc(param);
  1147.     end;
  1148.  
  1149.   InFile := ParamStr(param);
  1150.   if InFile = '' then
  1151.     show_usage;
  1152.  
  1153.   Inc(param);
  1154.  
  1155.   if RPos('.', InFile) = 0 then InFile := InFile + '.exe';
  1156.   OutFile := ParamStr(param);
  1157.   if OutFile = '' then OutFile := InFile;
  1158.   Delete(Outfile, RPos('.', OutFile), 255);
  1159.  
  1160.   WriteLn('Converting PE file ''', InFile, ''' to ELF...');
  1161.  
  1162.   lade_pe;
  1163.   rechne;
  1164.   schreibe_elf;
  1165. end.
  1166.  
  1167.