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

  1. procedure naechste_seite;
  2.   begin
  3.     // !!!!! vielleicht löst es ein paar Probleme ...
  4.     inc(adressposition,4096);
  5.   end;
  6.  
  7. var
  8.   _plt_dateiposition,           _plt_adressposition,
  9.   _rel_plt_dateiposition,       _rel_plt_adressposition,
  10.   _got_dateiposition,           _got_adressposition,
  11.   _dynamic_dateiposition,       _dynamic_adressposition,
  12.   _dynsym_dateiposition,        _dynsym_adressposition,
  13.   _dynsymstr_dateiposition,     _dynsymstr_adressposition,
  14.   _dynsymstrhash_dateiposition, _dynsymstrhash_adressposition,
  15.   resource_dateiposition        ,resource_adressposition:longint;
  16.  
  17.   _plt_laenge,
  18.   _rel_plt_laenge,
  19.   _dynamic_laenge,
  20.   _dynsym_laenge,
  21.   resource_laenge,
  22.   hash_tabelle_laenge:longint;
  23.  
  24.   luecke_dateiposition,luecke_adressposition,luecke_laenge,_got_laenge:longint;
  25.  
  26.  
  27.  
  28.  
  29. procedure Speichere_in_der_DYNAMIC_Tabelle(_d_tag,_d_val:word);
  30.   begin
  31.     Inc(anzahl_dynamic_eintraege);
  32.     ReallocMem(dynamic_speicher,anzahl_dynamic_eintraege*SizeOf(Elf32_Dyn_type));
  33.     with dynamic_speicher^[anzahl_dynamic_eintraege-1] do
  34.       begin
  35.         d_tag:=_d_tag;
  36.         d_val:=_d_val;
  37.       end;
  38.   end;
  39.  
  40.  
  41. (***************************************************************************)
  42.  
  43. var
  44.   symboltabelle_gefuellt:longint;
  45.  
  46. procedure Symboltabelleneintrag(const _name,_value:word;const _info:byte;const _shindex:smallword);
  47.   begin
  48.     Inc(symboltabelle_gefuellt);
  49.     ReallocMem(symboltabelle,symboltabelle_gefuellt*SizeOf(Elf32_Sym_type));
  50.     with symboltabelle^[symboltabelle_gefuellt-1] do
  51.       begin
  52.         st_name           :=_name;      // Stringtabellenindex
  53.         st_value          :=_value;     // Adressen,..
  54.         st_size           :=0;          // unwichtig
  55.         st_info           :=_info;      // bind/type
  56.         st_other          :=0;          // undefiniert
  57.         st_shndx          :=_shindex;   // auf welche Sektion bezogen
  58.       end;
  59.   end;
  60.  
  61. (***************************************************************************)
  62.  
  63. var
  64.   symbolstringtabelle_laenge:longint;
  65.   symbolstringtabelle_eintraege:longint;
  66.   _dynamic_st_index,_global_offset_table_st_index:longint;
  67.  
  68. function Speichere_in_der_SymbolStringTabelle(const sym_name:string):longint;
  69.   var
  70.     p:pointer;
  71.   begin
  72.     // hier kann noch um ein paar Byte gefeilt werden
  73.     // wenn Teilzeichenketten genutzt werden ..
  74.     Result:=symbolstringtabelle_laenge;
  75.     ReallocMem(symbolstringtabelle,symbolstringtabelle_laenge+Length(sym_name)+1);
  76.     Move(sym_name[1],symbolstringtabelle^[symbolstringtabelle_laenge],Length(sym_name));
  77.     Inc(symbolstringtabelle_laenge,Length(sym_name));
  78.     symbolstringtabelle^[symbolstringtabelle_laenge]:=#0;
  79.     Inc(symbolstringtabelle_laenge);
  80.     Inc(symbolstringtabelle_eintraege);
  81.   end;
  82.  
  83.  
  84. (***************************************************************************)
  85. (***************************************************************************)
  86.  
  87. procedure import_umrechnung;
  88.   type
  89.     pe_Import_Directory_Entry=
  90.       packed record
  91.         IMPORT_FLAGS            :longint;
  92.         TIME_DATE_STAMP         :longint;
  93.         MAJOR_VERSION,
  94.         MINOR_VERSION           :smallword;
  95.         NAME_RVA                :longint;
  96.         IMPORT_LOOKUP_TABLE_RVA :longint;
  97.         //??IMPORT_ADDRESS_TABLE_RVA:longint;
  98.       end;
  99.  
  100.     temp_import_typ=
  101.       record
  102.         wo,                     // Aufrufer
  103.         sym_index:longint;      // Index in der Symboltabelle
  104.       end;
  105.  
  106.     temp_import_tabelle_typ=array[1..100000000] of temp_import_typ;
  107.  
  108.  
  109.   var
  110.     p,p2,off:longint;
  111.     temp_import_tabelle_z:^temp_import_tabelle_typ;
  112.     temp_import_tabelle_gefuellt:longint;
  113.  
  114.     z,z2:longint;
  115.     gefunden:boolean;
  116.  
  117.     plt_index_tabelle:PLongArray;
  118.  
  119.     weitergerueckt:boolean;
  120.  
  121.   (************************************************************************)
  122.  
  123.   procedure Merke_Import(const _wo,_sym_index:longint);
  124.     begin
  125.       Inc(temp_import_tabelle_gefuellt);
  126.       ReallocMem(temp_import_tabelle_z,temp_import_tabelle_gefuellt*SizeOf(temp_import_typ));
  127.       with temp_import_tabelle_z^[temp_import_tabelle_gefuellt] do
  128.         begin
  129.           wo       :=_wo       ;
  130.           sym_index:=_sym_index;
  131.         end;
  132.     end;
  133.  
  134.   (************************************************************************)
  135.  
  136.   procedure Erzeuge_Hash_Tabelle;
  137.  
  138.     type char_z=^char;
  139.  
  140.     function elf_hash(const _name:char_z):longint;
  141.     // Seite 84
  142.       var
  143.         z:char_z;
  144.         g,h:longint;
  145.       begin
  146.         z:=_name;
  147.         h:=0;
  148.         while z^<>#0 do
  149.           begin
  150.             h:=(h shl 4)+Ord(z^);
  151.             Inc(z);
  152.  
  153.             if g=(h and $F0000000) then
  154.               h:=h xor (g shr 24);
  155.  
  156.             h:=h and (not g);
  157.           end;
  158.       end;
  159.  
  160.     var
  161.       nbucket,nchain:longint;
  162.       z,wert:longint;
  163.     begin
  164.       nbucket:=symboltabelle_gefuellt; // kleiner ?
  165.       nchain :=symboltabelle_gefuellt;
  166.  
  167.       // die Länge wurde schon vorher berechnet
  168.       //hash_tabelle_laenge:=4*(1+1+nbucket+nchain);
  169.       GetMem  (hash_tabelle ,hash_tabelle_laenge);
  170.       FillCHar(hash_tabelle^,hash_tabelle_laenge,0);
  171.  
  172.       hash_tabelle^[0]:=nbucket;
  173.       hash_tabelle^[1]:=nchain;
  174.  
  175.       // Eintrag 1 ist reserviert ('')
  176.       for z:=2 to nchain do
  177.         begin
  178.           wert:=elf_hash(@symbolstringtabelle^[symboltabelle^[z-1].st_name]);
  179.           wert:=wert mod nbucket;
  180.           if hash_tabelle^[2+wert]=0 then
  181.             // leerer "Eimer" gefunden
  182.             hash_tabelle^[2+(wert mod nbucket)]:=z-1
  183.           else
  184.             begin
  185.               // voller Eimer -> Verkettung
  186.               while hash_tabelle^[2+nbucket+wert]<>0 do
  187.                 wert:=hash_tabelle^[2+nbucket+wert];
  188.               hash_tabelle^[2+nbucket+wert]:=z-1;
  189.             end;
  190.         end;
  191.  
  192.  
  193.     end;
  194.  
  195.  
  196.   begin
  197.     // mit "leerer" Stringtabelle für Symbole anfangen
  198.     symbolstringtabelle:=nil;
  199.     symbolstringtabelle_eintraege:=0;
  200.     symbolstringtabelle_laenge:=0;
  201.     Speichere_in_der_SymbolStringTabelle(#0);
  202.  
  203.     _dynamic_st_index            :=Speichere_in_der_SymbolStringTabelle('_DYNAMIC');
  204.     _global_offset_table_st_index:=Speichere_in_der_SymbolStringTabelle('_GLOBAL_OFFSET_TABLE_');
  205.  
  206.     temp_import_tabelle_gefuellt:=0;
  207.     temp_import_tabelle_z:=nil;
  208.  
  209.  
  210.     p:=0;
  211.     while p<pe_obj_tab[idata].physical_size do
  212.       with pe_Import_Directory_Entry(import_puffer^[p]) do
  213.         begin
  214.           if NAME_RVA=0 then
  215.             break;
  216.  
  217.           DWriteLn('* '+StrPas(@import_puffer^[NAME_RVA-pe_obj_tab[idata].rva]));
  218.           // "shared object"-name als DT_NEEDED Eintrag abspeichern
  219.           Speichere_in_der_DYNAMIC_Tabelle(
  220.             DT_NEEDED,
  221.             Speichere_in_der_SymbolStringTabelle(
  222.               StrPas(@import_puffer^[NAME_RVA-pe_obj_tab[idata].rva])));
  223.  
  224.  
  225.           p2:=IMPORT_LOOKUP_TABLE_RVA-pe_obj_tab[idata].rva;
  226.           repeat
  227.             off:=Meml[Ofs(import_puffer^[p2])];
  228.             if off=0 then break;
  229.  
  230.             Dec(off,pe_obj_tab[idata].rva);
  231.  
  232.             DWriteLn('+ $'+Int2Hex(p2+pe_obj_tab[idata].rva+pe_kopf.image_base,8)+' : '+
  233.                     StrPas(@import_puffer^[off+2]));
  234.             // Funktion und zu Speicherstelle merken wo sie benutzt wird
  235.             Merke_Import(
  236.               p2+pe_obj_tab[idata].rva+pe_kopf.image_base,
  237.               Speichere_in_der_SymbolStringTabelle(
  238.                 StrPas(@import_puffer^[off+2])));
  239.  
  240.             Inc(p2,4);
  241.           until false;
  242.           Inc(p,SizeOf(pe_Import_Directory_Entry));
  243.         end;
  244.  
  245.     //******************************************************************
  246.     // jetzt ist die Anzahl der Importe bekannt
  247.  
  248.  
  249.     // Länge der Stringtabelle auf 32 Bit-Vielfaches bringen
  250.     Aufrunden(symbolstringtabelle_laenge,4);
  251.  
  252.     // zwischen der Interpreter-Sektion und der .text-Sektion ist noch
  253.     // fast 4096 Byte Platz (Adresse und Datei)
  254.     index_:=sektionen_uebersicht[sekt_interpreter].index_;
  255.     luecke_adressposition:=sektionen_kopf[index_].sh_addr  +sektionen_kopf[index_].sh_size;
  256.     luecke_dateiposition :=sektionen_kopf[index_].sh_offset+sektionen_kopf[index_].sh_size;
  257.     Aufrunden(luecke_adressposition,4);
  258.     Aufrunden(luecke_dateiposition ,4);
  259.     index_:=sektionen_uebersicht[sekt_text].index_;
  260.     luecke_laenge:=sektionen_kopf[index_].sh_addr-luecke_adressposition;
  261.  
  262.  
  263.  
  264.  
  265.     // VP erzeugt schon soetwas ähnliches wie .plt (in .code32)
  266.     // diese Einträge jmp [.idata+xyz] // $ff $25 (.idata+xyz)
  267.     //                jmp [.idata+xzy]
  268.     //                jmp [.idata+yxz]
  269.     //                ...
  270.     // muessen später auf die GOT (Global Offset Table) verweisen
  271.     // jetzt wird erst einmal der Bereich und die Anzahl bestimmt
  272.     p2:=pe_obj_tab[code32].physical_size;
  273.     while code_puffer^[p2-2]=0 do dec(p2); (* $0040xxxx *)
  274.     z:=0;
  275.     while (code_puffer^[p2-6]=$ff) and (code_puffer^[p2-6+1]=$25) do
  276.       begin
  277.         Dec(p2,6);
  278.         Inc(z);
  279.       end;
  280.  
  281.     if z<>temp_import_tabelle_gefuellt then
  282.       abbruch(#7'Error: '+Int2Str(z)+' stubs for imported functions found but '+Int2Str(temp_import_tabelle_gefuellt)+' functions imported');
  283.  
  284.     // die .dynamic-Tabelle kommt nach dem Datensegment
  285.     _dynamic_adressposition:=adressposition;
  286.     _dynamic_dateiposition :=dateiposition ;
  287.     // die .dynamic-Tabelle enthält jetzt schon anzahl_dynamic_eintraege Einträge
  288.     // außerdem kommen noch hinzu:
  289.     // DT_HASH,DT_STRTAB,DT_SYMTAB,DT_STRSZ,DT_REL,DT_RELSZ,DT_RELENT,DT_NULL
  290.     _dynamic_laenge:=SizeOf(Elf32_Dyn_type)*(anzahl_dynamic_eintraege+8);
  291.     Inc(adressposition,_dynamic_laenge);
  292.     Inc(dateiposition ,_dynamic_laenge);
  293.  
  294.     // die .got kommt nach .dynamic
  295. naechste_seite;
  296.     _got_adressposition:=adressposition;
  297.     _got_dateiposition :=dateiposition ;
  298.     _got_laenge:=(3+temp_import_tabelle_gefuellt)*4;
  299.     Inc(adressposition,_got_laenge);
  300.     Inc(dateiposition ,_got_laenge);
  301.  
  302.     //************************************************
  303.     // .dynsym,.dynstr,.hash,. sind nicht beschreibbar
  304.     Aufrunden(adressposition,4096);
  305.     suche_naechste_passende_adressposition;
  306.  
  307.     // Symbole in der .dynsym-Tabelle:
  308.     //  1 ""
  309.     // +1 "_DYNAMIC"
  310.     // +1 "_GLOBAL_OFFSET_TABLE_"
  311.     // +temp_import_tabelle_gefuellt
  312.     _dynsym_laenge:=(3+temp_import_tabelle_gefuellt)*SizeOf(Elf32_Sym_type);
  313.  
  314.     weitergerueckt:=false;
  315.     // Adresse von .dynsym festlegen
  316.     // wenn möglich in der Lücke von .interp bis .text
  317.     if _dynsym_laenge<=luecke_laenge then
  318.       begin
  319.         _dynsym_adressposition:=luecke_adressposition;
  320.         _dynsym_dateiposition :=luecke_dateiposition ;
  321.         Dec(luecke_laenge        ,_dynsym_laenge);
  322.         Inc(luecke_adressposition,_dynsym_laenge);
  323.         Inc(luecke_dateiposition ,_dynsym_laenge);
  324.       end
  325.     else
  326.       begin
  327.         _dynsym_adressposition:=adressposition;
  328.         _dynsym_dateiposition :=dateiposition ;
  329.         Inc(adressposition,_dynsym_laenge);
  330.         Inc(dateiposition ,_dynsym_laenge);
  331.         weitergerueckt:=true;
  332.       end;
  333.  
  334.     // Adresse von .dynstr festlegen
  335.     // wenn möglich in der Lücke von .interp bis .text
  336.     if symbolstringtabelle_laenge<=luecke_laenge then
  337.       begin
  338.         _dynsymstr_adressposition:=luecke_adressposition;
  339.         _dynsymstr_dateiposition :=luecke_dateiposition ;
  340.         Dec(luecke_laenge        ,symbolstringtabelle_laenge);
  341.         Inc(luecke_adressposition,symbolstringtabelle_laenge);
  342.         Inc(luecke_dateiposition ,symbolstringtabelle_laenge);
  343.       end
  344.     else
  345.       begin
  346.         _dynsymstr_adressposition:=adressposition;
  347.         _dynsymstr_dateiposition :=dateiposition ;
  348.         Inc(adressposition,symbolstringtabelle_laenge);
  349.         Inc(dateiposition ,symbolstringtabelle_laenge);
  350.         weitergerueckt:=true;
  351.       end;
  352.  
  353.     // Adresse von .hash festlegen
  354.     // Länge der Hash-Tabelle (siehe erzeuge_hash_tabelle)
  355.     hash_tabelle_laenge:=4*(1+1+2*(3+temp_import_tabelle_gefuellt));
  356.     // wenn möglich in der Lücke von .interp bis .text
  357.     if hash_tabelle_laenge<=luecke_laenge then
  358.       begin
  359.         _dynsymstrhash_adressposition:=luecke_adressposition;
  360.         _dynsymstrhash_dateiposition :=luecke_dateiposition ;
  361.         Dec(luecke_laenge        ,hash_tabelle_laenge);
  362.         Inc(luecke_adressposition,hash_tabelle_laenge);
  363.         Inc(luecke_dateiposition ,hash_tabelle_laenge);
  364.       end
  365.     else
  366.       begin
  367.         _dynsymstrhash_adressposition:=adressposition;
  368.         _dynsymstrhash_dateiposition :=dateiposition ;
  369.         Inc(adressposition,hash_tabelle_laenge);
  370.         Inc(dateiposition ,hash_tabelle_laenge);
  371.         weitergerueckt:=true;
  372.       end;
  373.  
  374.     _rel_plt_laenge:=temp_import_tabelle_gefuellt*SizeOf(Elf32_Rel_type);
  375.     GetMem  (rel_plt_speicher ,_rel_plt_laenge);
  376.     FillChar(rel_plt_speicher^,_rel_plt_laenge,0);
  377.     // Adresse von .rel.plt festlegen
  378.     // wenn möglich in der Lücke von .interp bis .text
  379.     if _rel_plt_laenge<=luecke_laenge then
  380.       begin
  381.         _rel_plt_adressposition:=luecke_adressposition;
  382.         _rel_plt_dateiposition :=luecke_dateiposition ;
  383.         Dec(luecke_laenge        ,_rel_plt_laenge);
  384.         Inc(luecke_adressposition,_rel_plt_laenge);
  385.         Inc(luecke_dateiposition ,_rel_plt_laenge);
  386.       end
  387.     else
  388.       begin
  389.         _rel_plt_adressposition:=adressposition;
  390.         _rel_plt_dateiposition :=dateiposition ;
  391.         Inc(adressposition,_rel_plt_laenge);
  392.         Inc(dateiposition ,_rel_plt_laenge);
  393.         weitergerueckt:=true;
  394.       end;
  395.  
  396.     // Reseourcen passen am besten hierher:
  397.     // auch "nur Lesen" (kein Ausführen,Schreiben)
  398.     if sektionen_uebersicht[sekt_resource].vorhanden then
  399.       begin
  400.         resource_laenge:=pe_obj_tab[res].physical_size;
  401.         if resource_laenge<=luecke_laenge then
  402.           begin
  403.             resource_adressposition:=luecke_adressposition;
  404.             resource_dateiposition :=luecke_dateiposition ;
  405.             Dec(luecke_laenge        ,resource_laenge);
  406.             Inc(luecke_adressposition,resource_laenge);
  407.             Inc(luecke_dateiposition ,resource_laenge);
  408.           end
  409.         else
  410.           begin
  411.             resource_adressposition:=adressposition;
  412.             resource_dateiposition :=dateiposition ;
  413.             Inc(adressposition,resource_laenge);
  414.             Inc(dateiposition ,resource_laenge);
  415.             weitergerueckt:=true;
  416.           end;
  417.       end;
  418.  
  419.  
  420.     // .plt ist ausführbar -> muß auf eine neue Speicherseite
  421.     if weitergerueckt then
  422.       begin
  423.         Aufrunden(adressposition,4096);
  424.         suche_naechste_passende_adressposition;
  425.       end;
  426.  
  427.     // Länge der .plt-Sektion ausrechnen
  428.     // .plt hat .plt0 und plt1..plt(Anzahl Importe) Einsprungstellen
  429.     GetMem(plt_index_tabelle,4*(temp_import_tabelle_gefuellt+1));
  430.     // .plt ist kleiner als $10*(anzahl_importe+1)
  431.     GetMem  (plt_speicher ,(temp_import_tabelle_gefuellt+1)*$10);
  432.     FillChar(plt_speicher^,(temp_import_tabelle_gefuellt+1)*$10,0);
  433.  
  434.     _plt_laenge:=0;
  435.     // .plt0:
  436.     //          push offset got[4]      // $ff $35 (got+4)
  437.     //          jmp got[8]              // $ff $25 (got+8)
  438.     plt_index_tabelle^[0]:=_plt_laenge;
  439.     plt_speicher^[$0]:=$ff;
  440.     plt_speicher^[$1]:=$35;
  441.     longint_z(@plt_speicher^[$2])^:=_got_adressposition+4;
  442.     plt_speicher^[$6]:=$ff;
  443.     plt_speicher^[$7]:=$25;
  444.     longint_z(@plt_speicher^[$8])^:=_got_adressposition+8;
  445.     Inc(_plt_laenge,6+6);
  446.  
  447.  
  448.     for z:=1 to temp_import_tabelle_gefuellt do
  449.       begin
  450.         plt_index_tabelle^[z]:=_plt_laenge;
  451.         //.pltx_: (x>=1)
  452.         //      push (x-1)*2                       (A)
  453.         //      jmp .plt0                          (B)
  454.  
  455.         // je 2 Varianten für (A) und (B):
  456.  
  457.         //      $6a shortint((x-1)*8)              (A1)
  458.         //      $eb shortint(.plt0-.pltx_-2-2)     (B1)
  459.  
  460.         //      $68 longint((x-1)*8)               (A2)
  461.         //      $e9 longint(.plt0-.pltx_-5-5       (B2)
  462.  
  463.         if (z-1)*8<=127 then
  464.           begin (* A1 *)
  465.             plt_speicher^[_plt_laenge+0]:=$6a;
  466.             plt_speicher^[_plt_laenge+1]:=(z-1)*8;
  467.             Inc(_plt_laenge,2);
  468.           end
  469.         else
  470.           begin (* A2 *)
  471.             plt_speicher^[_plt_laenge+0]:=$68;
  472.             longint_z(@plt_speicher^[_plt_laenge+1])^:=(z-1)*8;
  473.             Inc(_plt_laenge,5);
  474.           end;
  475.  
  476.         if plt_index_tabelle^[0]-_plt_laenge-2>=-128 then
  477.           begin (* B1 *)
  478.             plt_speicher^[_plt_laenge+0]:=$eb;
  479.             shortint(plt_speicher^[_plt_laenge+1]):=plt_index_tabelle^[0]-_plt_laenge-2;
  480.             Inc(_plt_laenge,2);
  481.           end
  482.         else
  483.           begin (* B2 *)
  484.             plt_speicher^[_plt_laenge+0]:=$e9;
  485.             longint_z(@plt_speicher^[_plt_laenge+1])^:=plt_index_tabelle^[0]-_plt_laenge-5;
  486.             Inc(_plt_laenge,5);
  487.           end;
  488.  
  489.         // entsprechende "Relokation" erzeugen
  490.         with rel_plt_speicher^[z-1] do
  491.           begin
  492.             r_offset:=_got_adressposition+(3+z-1)*4; // die ersten 3 Einträge in der GOT sind reserviert
  493.             r_info  :=(z-1+3) shl 8                    // die ersten 3 Einträge in der Symboltabelle sind reserviert
  494.                      +R_386_JMP_SLOT;
  495.           end;
  496.  
  497.         longint_z(@plt_speicher^[z*$10+$c])^:=-$10*(z+1);
  498.       end;
  499.     Aufrunden(_plt_laenge,4); // auf 32 bit ausrichten
  500.  
  501.     // jetzt ist die Länge von .plt bekannt
  502.     // Suche nach freiem Adressraum
  503.  
  504.     // zwischen der .text-Sektion und der nächsten Seitengrenze ist
  505.     // vielleicht noch etwas Platz (an der Adresse und in der Datei)
  506.     index_:=sektionen_uebersicht[sekt_text].index_;
  507.     luecke_adressposition:=sektionen_kopf[index_].sh_addr  +sektionen_kopf[index_].sh_size;
  508.     luecke_dateiposition :=sektionen_kopf[index_].sh_offset+sektionen_kopf[index_].sh_size;
  509.     Aufrunden(luecke_adressposition,4);
  510.     Aufrunden(luecke_dateiposition ,4);
  511.     luecke_laenge:=luecke_adressposition and (4096-1);
  512.     if luecke_laenge=4096 then
  513.       luecke_laenge:=0;
  514.  
  515.     // Adresse von .plt festlegen
  516.     // wenn möglich in der Lücke
  517.     if _plt_laenge<=luecke_laenge then
  518.       begin
  519.         _plt_adressposition:=luecke_adressposition;
  520.         _plt_dateiposition :=luecke_dateiposition ;
  521.         Dec(luecke_laenge        ,_plt_laenge);
  522.         Inc(luecke_adressposition,_plt_laenge);
  523.         Inc(luecke_dateiposition ,_plt_laenge);
  524.       end
  525.     else
  526.       begin
  527.         _plt_adressposition:=adressposition;
  528.         _plt_dateiposition :=dateiposition ;
  529.         Inc(adressposition,_plt_laenge);
  530.         Inc(dateiposition ,_plt_laenge);
  531.         weitergerueckt:=true;
  532.       end;
  533.  
  534.     // jetzt sind wichtige Adressen bekannt und die _DYNAMIC-Tabelle
  535.     // kann vervollständigt werden
  536.  
  537.     // Adresse der Hash-Tabelle dem Programmlader verraten
  538.     Speichere_in_der_DYNAMIC_Tabelle(DT_HASH,_dynsymstrhash_adressposition);
  539.  
  540.     // ........... Symboltabelle-Zeichenketten ...
  541.     Speichere_in_der_DYNAMIC_Tabelle(DT_STRTAB,_dynsymstr_adressposition);
  542.  
  543.     // ........... Symboltabelle ...
  544.     Speichere_in_der_DYNAMIC_Tabelle(DT_SYMTAB,_dynsym_adressposition);
  545.  
  546.     // Länge des Bereiches DT_STRTAB^
  547.     Speichere_in_der_DYNAMIC_Tabelle(DT_STRSZ,symbolstringtabelle_laenge);
  548.  
  549.     // Adresse des "Relokationen"
  550.     Speichere_in_der_DYNAMIC_Tabelle(DT_REL,_rel_plt_adressposition);
  551.     // Gesamtlänge
  552.     Speichere_in_der_DYNAMIC_Tabelle(DT_RELSZ,_rel_plt_laenge);
  553.     // Länge eines Eintrages
  554.     Speichere_in_der_DYNAMIC_Tabelle(DT_RELENT,SizeOf(Elf32_Rel_type));
  555.  
  556.     // Ende der _DYNAMIC-Tabelle
  557.     Speichere_in_der_DYNAMIC_Tabelle(DT_NULL,0);
  558.  
  559.  
  560.  
  561.     //**********************************************************************
  562.     // neue Symboltabelle
  563.     symboltabelle:=nil;
  564.     symboltabelle_gefuellt:=0;
  565.  
  566.     // Symboltabelleneintraege 0..2
  567.     // 0: "undefiniert"   name,value,info,shindex
  568.     Symboltabelleneintrag(
  569.       0,
  570.       0,
  571.       0,SHN_UNDEF);
  572.  
  573.     // 1: "_DYNAMIC" - Adresse von ".dynamic"
  574.     Symboltabelleneintrag(
  575.       _dynamic_st_index,
  576.       _dynamic_adressposition,
  577.       (STB_GLOBAL shl 4)+STT_OBJECT,SHN_ABS);
  578.  
  579.     // 2: "_GLOBAL_OFFSET_TABLE_"
  580.     Symboltabelleneintrag(
  581.       _global_offset_table_st_index,
  582.       _got_adressposition,
  583.       (STB_GLOBAL shl 4)+STT_OBJECT,SHN_ABS);
  584.  
  585.  
  586.     // die ersten 3 Einträge in der Symboltabelle sind schon benutzt
  587.     // die ersten 3 Einträge in der GOT sind auch reserviert
  588.     // im .plt-Bereich sind die ersten $10 Byte schon benutzt
  589.     GetMem(got_speicher   ,3*4+4*temp_import_tabelle_gefuellt);
  590.     FillChar(got_speicher^,3*4+4*temp_import_tabelle_gefuellt,0);
  591.     got_speicher^[0]:=_dynamic_adressposition;
  592.     got_speicher^[1]:=0;
  593.     got_speicher^[2]:=0;
  594.  
  595.     // off=Adresse des Code32-Segmentes wo VP schon soetwas wie .plt anlegt
  596.     off:=sektionen_kopf[sektionen_uebersicht[sekt_text].index_].sh_addr;
  597.     for z:=1 to temp_import_tabelle_gefuellt do
  598.       begin
  599.  
  600.         // .plt+$10*x+6 ist die Adresse die erstmal zum Programmlader springt
  601.         got_speicher^[z-1+3]:=_plt_adressposition+plt_index_tabelle^[z];
  602.  
  603.         // suche den Aufruf im code32-Bereich
  604.         gefunden:=false;
  605.         for z2:=1 to temp_import_tabelle_gefuellt do
  606.           if longint_z(@code_puffer^[p2+(z2-1)*6+2])^=temp_import_tabelle_z^[z].wo then
  607.             begin
  608.               gefunden:=true;
  609.  
  610.               // Code so umstricken, das jetzt auf die GOT verwiesen wird
  611.               longint_z(@code_puffer^[p2+(z2-1)*6+2])^:=_got_adressposition+(z-1+3)*4;
  612.  
  613.               Symboltabelleneintrag(
  614.                 temp_import_tabelle_z^[z].sym_index,
  615.                 off+p2+(z2-1)*6,
  616.                 (STB_GLOBAL shl 4)+STT_FUNC,SHN_UNDEF);
  617.  
  618.               break; (* z2 *)
  619.             end;
  620.  
  621.         if not gefunden then
  622.           Abbruch(#7'Error: caller of imported function '
  623.                  +StrPas(@symbolstringtabelle^[temp_import_tabelle_z^[z].sym_index])
  624.                  +' not found');
  625.  
  626.       end;
  627.  
  628.     Erzeuge_Hash_Tabelle;
  629.  
  630.     // die temp_import_tabelle wird nicht mehr benötigt
  631.     FreeMem(temp_import_tabelle_z);
  632.     anzahl_importe:=temp_import_tabelle_gefuellt;
  633.  
  634.     FreeMem(plt_index_tabelle);
  635.   end;
  636.  
  637.