Positsioonist sõltumatu kood

Positsioonist sõltumatu kood (ingl PIC – Position-Independent Code) on selline masinkood, mida saab kasutada olenemata mäluaadressist, millel see paikneb. 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. 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.
Lisaks võimaldab positsioonist sõltumatu kood rakendada aadressiruumi juhustust (ASLR), mis aitab tõrjuda osasid puhvri ületäitumist ära kasutavaid rünnakuid. Sel põhjusel soovitavad näiteks iOS ja macOS kõik rakendused positsioonist sõltumatuna kompileerida ning Android alates versioonist 5 nõuab, et kõik rakendused kasutaksid positsioonist sõltumatut koodi.

Tehniline lahendus

Positsioonist sõltumatu kood teeb kõik pöördumised konstantsete mäluaadresside poole globaalse nihetetabeli (GOT) kaudu.⁻ᶠᵖⁱᶜ 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.
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.
Dünaamiline laadur (tavaliselt operatsioonisüsteemi osa) täidab globaalse nihketabeli programmi käivitamisel, salvestades sinna nõutud sümbolite absoluutsed aadressid.⁻ᶠᵖⁱᶜ

Protseduuride lingituse tabel (PLT)

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.
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.⁻ᶠⁿᵒ⁻ᵖˡᵗ

Miinused

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.
Lisaks nõuab positsioonist sõltumatu kood eraldi tuge platvormilt ja kompilaatorilt ning töötab seetõttu ainult osades arvutites.⁻ᶠᵖⁱᶜ