Positsioonist sõltumatu kood

Positsioonist sõltumatu kood (ingl PICPosition-Independent Code) on selline masinkood, mida saab kasutada olenemata mäluaadressist, millel see paikneb.[1] Seda kasutatakse enamiku jagatud teekide juures, et sama teeki saaks laadida erinevate protsesside aadressiruumides erinevatele virtuaalaadressidele. Vastasel juhul võiks ilma teegi koodi muutmata tekkida olukord, kus ühe protsessi mäluruumis tuleks mitu teeki samale aadressile laadida.[1] Positsioonist sõltumatut koodi kasutati ka vanematel arvutitel ja tänapäeval manussüsteemidel, millel puudub mäluhaldusplokk (MMU), et vältida vajadust laadimisaegse ümberpaigutamise (lükke) järele, mis muidu tekiks üheainsa aadressiruumi kasutamisest ja muudaks programmide käivitamist aeglasemaks.[2]

Lisaks võimaldab positsioonist sõltumatu kood rakendada aadressiruumi juhustust (ASLR), mis aitab tõrjuda osasid puhvri ületäitumist ära kasutavaid rünnakuid.[3] Sel põhjusel soovitavad näiteks iOS ja macOS kõik rakendused positsioonist sõltumatuna kompileerida[4] ning Android alates versioonist 5 nõuab, et kõik rakendused kasutaksid positsioonist sõltumatut koodi[5].

Tehniline lahendus muuda

Positsioonist sõltumatu kood teeb kõik pöördumised konstantsete mäluaadresside poole globaalse nihetetabeli (GOT) kaudu.[6]-fpic Globaalne nihetetabel ise asub enamasti koodist kindlal kaugusel, nii et kood saab selle leidmiseks liita konstandi enda asukohale (programmiloendurile). Alternatiivina on osadel süsteemidel globaalse nihketabeli aadress eelnevalt kokkulepitud registrisse laetud.[2]

Globaalse nihketabeli genereerib linkur. Igat sümbolit (seega igat mäluaadressi) on seal vaid ühe korra, kuna kõikide kokku lingitavate funktsioonide kohta koostatakse üks tabel, millest on duplikaadid eemaldatud. Samas ühe käivitatava programmi koosseisu kuuluvatel jagatud teekidel on igaühel omaenda globaalne nihetetabel. Selle tabeli ja koodi omavaheline suhteline nihe sõltub muuhulgas tabeli ja koodi pikkustest, kuid määratakse kindlaks linkimise käigus. Seejärel sisestab linkur vastavad suhtelise nihke konstandid ka kõikidesse kohtadesse koodi sektsioonides, kus mõne välise aadressi poole pöördumiseks globaalset nihetetabelit kasutatakse.[2]

Dünaamiline laadur (tavaliselt operatsioonisüsteemi osa) täidab globaalse nihketabeli programmi käivitamisel, salvestades sinna nõutud sümbolite absoluutsed aadressid.[6]-fpic

Protseduuride lingituse tabel (PLT) muuda

Protseduuride lingituse tabel on hüppetabel, mida vahel kasutatakse väliste funktsioonide kutsumiseks positsioonist sõltumatu koodi puhul. Sellisel juhul kasutatakse globaalset nihetetabelit vaid globaalsete muutujate leidmiseks. PLT kasutamisel võib lisavõimalusena rakendada laiska väärtustamist (nõudmisel väärtustamist), kus iga välise funktsiooni absoluutne aadress kantakse tabelisse alles selle funktsiooni esmakordsel väljakutsel.[7]

Protseduuride lingituse tabeli kasutamine on valikuline, selle asemel võib ka kutsutavate funktsioonide aadressid laadida globaalsest nihetetabelist. Protseduuride lingituse tabelit mittekasutav kood on efektiivsem, kuna eemaldatud on meetodi maketid ning globaalse nihetetabeli kaudu toimuvaid laadimisi on võimalik optimeerida. Sel juhul ei ole aga võimalik kasutada laiska linkimist ning kõik välised sümbolid on vaja lahendada laadimise ajal.[6]-fno-plt

Miinused muuda

Kuigi kood ise laadimisaegset ümberpaigutamist ei vaja, on seda vaja teha globaalsele nihetetabelile, mis võib suurte teekide puhul olla üpris mahukas töö. Olenevalt konkreetsest platvormist on positsioonist sõltumatu kood ka suurem ja võtab rohkem ruumi, kuna funktsioonide ja andmete poole pöördumiseks on vaja teha iga kord lisasamm.[2]

Lisaks nõuab positsioonist sõltumatu kood eraldi tuge platvormilt ja kompilaatorilt ning töötab seetõttu ainult osades arvutites.[6]-fpic

Viited muuda

  1. 1,0 1,1 Roos, Meelis. "Mäluhaldus 2" (PDF). Tartu Ülikool. Lk 7. Originaali (PDF) arhiivikoopia seisuga 26.02.2018. Vaadatud 26.02.2018.
  2. 2,0 2,1 2,2 2,3 John R. Levine (1999). Linkers and Loaders, peatükk 8: Loading and overlays (inglise). San Francisco: Morgan Kaufmann. ISBN 1-55860-496-0. Originaali arhiivikoopia seisuga 11. veebruar 2012. Vaadatud 1. mail 2018.
  3. "Oracle® LinuxSecurity Guide for Release 6". Oracle Corporation. 3.15.1 Address Space Layout Randomization. Vaadatud 06.03.2018.
  4. "iOS Developer Library". Apple Inc. Vaadatud 06.03.2018.
  5. "Security Enhancements in Android 5.0  -  Android Open Source Project". Google Inc. Originaali arhiivikoopia seisuga 27.02.2017. Vaadatud 06.03.2018.
  6. 6,0 6,1 6,2 6,3 "Using the GNU Compiler Collection (GCC), peatükk 3.16: Options for Code Generation Conventions" (inglise). Free Software Foundation, Inc. Vaadatud 04.03.2018.
  7. Jan Hubička, Andreas Jaeger, Michael Matz, Mark Mitchell (2013). System V Application Binary Interface (PDF).{{raamatuviide}}: CS1 hooldus: mitu nime: autorite loend (link)