[OSy] Re: ELF, got a plt

Petr Tuma petr.tuma at mff.cuni.cz
Thu Apr 28 10:34:38 CEST 2005


Dobry den,

> Obsah got je OS/arch specific, ale chcel by som pochopit co moze
> obsahovat got[1],, podla toho co pise ELF je to proste nejake info..

Nerucim za detaily, ale obecne je GOT jen tabulka, ktera obsahuje 
vsechny absolutni adresy, ktere program potrebuje pri svem behu.

Predstavte si, ze napriklad potrebujete prelozit volani procedury FOO. V 
programu napisete neco jako FOO(), coz prekladac prelozi na strojovou 
instrukci CALL. Jenze te instrukci je potreba dat take adresu, kterou ma 
zavolat, a ta uz musi byt proste cislo, kteremu procesor rozumi ...

... a v tom je principialni problem, protoze prekladac obecne nevi, na 
jakych adresach v pameti muze program lezet. To se urci az pri spusteni 
daneho programu. Tento problem se da obejit dvema zpusoby ...

... bud se vi, ze procedura FOO lezi ve stejnem nedelitelnem bloku kodu 
jako instrukce CALL, ktera ji bude volat. Pak muze prekladac spocitat, 
jak daleko od instrukce CALL je procedura FOO a pouzije variantu 
instrukce CALL, ktera umi relativni adresu, tedy CALL 1234 znamena 
"zavolej proceduru, ktera je na adrese o 1234 bajtu dal nez tento CALL".

... a nebo se vi, ze procedura FOO lezi nekde jinde, napriklad v 
dynamicky linkovane knihovne. Pak prekladac nemuze jeji adresu zjistit a 
tak vyhradi jednu polozku GOT pro tuto adresu a pouzije variantu 
instrukce CALL, ktera umi neprimou relativni adresu, tedy CALL 1234 
znamena "zavolej proceduru, jejiz adresu najdes v polozce, jejiz adresa 
je o 1234 bajtu dal nez tento CALL".

(Instrukce jsem psal zjednodusene, na i386 platforme je vetsinou zvykem 
mit adresu GOT v EBX a pouzivat CALL [EBX + GOT_OFFSET], ale snazim se 
popsat hlavne princip ...)

Ve vysledku tedy prekladac vyrobi kod, ktery muze potrebovat, aby 
dynamicky linker pri spousteni kodu vyplnil spravne adresy procedur do 
GOT. Za urcitych situaci se daji najit i jine programove konstrukce, 
ktere by vyzadovaly preklad pomoci GOT, vse zavisi hlavne na tom, jake 
instrukce a jake zpusoby adresace ma k dispozici procesor, pro ktery se 
preklada.

Tak, to byla GOT, ted zbyva jeste PLT :-). Aby to bylo cele mirne 
slozitejsi, prekladac vzdycky nevi, jestli volana procedura bude ve 
stejnem nedelitelnem bloku kodu s instrukcemi, ktere ji volaji. To vi 
zpravidla az staticky linker. Prekladac by se v takove situaci mohl 
chovat pesimisticky, tedy vsechny instrukce CALL prekladat jako neprima 
volani absolutni adresy ulozene v GOT, ale takove volani je mirne 
pomalejsi nez prima volani relativni adresy ...

... prekladac proto vsechny instrukce CALL preklada jako prima volani 
relativni adresy. Pokud pak staticky linker, ktery ma za ukol tuto 
adresu doplnit, zjisti, ze to nejde, protoze adresa procedury nelezi ve 
stejnem bloku jako jeji volani, vygeneruje do bloku, ve kterem je volani 
umisteno, kratky kod, stub, ktery se navenek tvari jako volana procedura 
a uvnitr jen sahne do GOT a zavola tu skutecnou volanou proceduru. A 
tenhle kratky kod se umistuje prave do PLT, kazda polozka PLT je jeden stub.

Opet, mozna jsem se dopustil drobnych nepresnosti, snad to nevadi. Jinak 
clovek, ktery pravdepodobne vidi do ELF jako malokdo, bude pan Jelinek, 
ktery psal program prelink pro Linux, tak az nebudu vedet, odkazu vas na 
nej :-).

> Synchronizacia,, nestane sa, ze bude linker zaroven resolvovat 2x
> naraz ten isty symbol? Vychadzam z toho co pise ELF.

No, vetsina symbolu se resolvuje pri startu aplikace, takze tam tohle 
nehrozi. Nektere symboly se resolvuji pozdeji, napriklad to mohou byt 
prave offsety v GOT ktere pouziva PLT. Tam je pak na dynamickem linkeru, 
aby podobne situace osetril ...

Petr Tuma



More information about the NSWI004 mailing list