[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