Relocation — obyekt fayldagi kod yoki ma’lumot ichidagi manzilga bog‘liq qiymatlarni bo‘limlar va symbollarga yakuniy manzil berilgach tuzatish jarayonidir. Kompilyator alohida modulni yaratganda boshqa funksiyaning yoki hatto o‘z bo‘limining yakuniy xotira manzilini bilmasligi mumkin. U tuzatiladigan joy va hisoblash qoidasini relocation yozuvi sifatida qoldiradi.
Relocation yozuvi
Yozuv odatda tuzatiladigan offset, relocation turi, tegishli symbol va ba’zan addend deb ataluvchi qo‘shimcha qiymatni saqlaydi. Linker sectionlarni joylashtirib, symbol manzilini aniqlagach formula bo‘yicha yangi qiymat hisoblaydi va kerakli bit maydoniga yozadi. Tur formulani, maydon kengligini va overflow shartini belgilaydi; u protsessor ISA’si hamda obyekt formatiga xos bo‘ladi.
Absolute relocation symbolning to‘liq manzilini yozishi mumkin. PC-relative relocation esa maqsad bilan joriy ko‘rsatma orasidagi farqni kodlaydi. Nisbiy murojaat kod xotiraning boshqa joyiga ko‘chirilganda ham o‘z kuchini saqlashi va kichikroq maydonga sig‘ishi mumkin. Biroq maqsad juda uzoq bo‘lsa branch diapazoni yetmasligi, linker trampoline yoki boshqa ko‘rsatma ketma-ketligi yaratishi mumkin.
Statik va dinamik bosqich
Statik linklashda ko‘p relocationlar executable yaratilayotganda to‘liq hal qilinadi. Shared libraryning yuklanish manzili runtime’gacha noma’lum bo‘lsa, ayrim yozuvlar dynamic loaderga qoldiriladi. Loader modul xotiraga xaritalangach import qilingan symbollarni topadi va dinamik relocationlarni bajaradi.
Position-independent code imkon qadar mutlaq manzildan qochadi. Global Offset Table ma’lumot symbollarining runtime manzillarini jadval orqali beradi, Procedure Linkage Table esa tashqi funksiya chaqiruvini dinamik resolver bilan bog‘laydi. Lazy binding funksiyani birinchi chaqiruvda hal qilishi, eager binding esa dastur boshlanishida barcha nomlarni tekshirishi mumkin. Har bir tanlov ishga tushish vaqti, xavfsizlik va xato aniqlanish vaqtiga ta’sir qiladi.
Xatolar va xavfsizlik
Relocation overflow hisoblangan qiymat ajratilgan maydonga sig‘maganda yuz beradi. Bunga juda katta kod modeli, uzoq symbol yoki noto‘g‘ri relocation turi sabab bo‘lishi mumkin. Undefined symbol esa manzil hisoblash uchun ta’rif topilmaganini bildiradi. Noto‘g‘ri ISA, ABI yoki position-independent bayroq bilan aralashtirilgan obyektlar ham linker diagnostikasiga olib keladi.
Runtime relocation yoziladigan sahifalarni talab qilishi mumkin. Xavfsiz loader tuzatishdan keyin kodni read-execute holatiga o‘tkazadi va relocation jadvalining o‘zini tekshiradi. RELRO kabi himoyalar ayrim bog‘lash jadvallarini ishga tushishdan keyin faqat o‘qiladigan qiladi. Matn bo‘limiga ko‘p dinamik tuzatish kiritish sahifalarni ulashishni kamaytiradi va yoziladigan kod oynasini yaratishi mumkin, shu sababli PIC afzal.
Obyekt tahlil vositalari relocation offseti, turi va symbolini ko‘rsatadi. Bu ma’lumot disassembly bilan birga o‘qilganda hali to‘ldirilmagan chaqiruv yoki manzilning yakuniy ma’nosini tushuntiradi. Linker map fayli esa section joylashuvi va hal qilingan symbollarni umumiy manzil xaritasida ko‘rsatadi.
Reproducible build bilan aloqasi
Relocation natijasi section tartibi, hizalanish, linker skripti va symbol tanloviga bog‘liq. Bir xil manbadan bitma-bit bir xil binar olish uchun bu kirishlar, obyektlar tartibi va build identifikatori deterministik bo‘lishi kerak. Incremental linker oldingi joylashuvni saqlab buildni tezlashtirishi mumkin, ammo yakuniy release odatda toza link bilan tekshiriladi. Firmware va kernel kabi belgilangan manzil talab qiladigan tizimlarda linker script sectionlarni aniq diapazonga joylashtiradi; relocation diapazoni va xotira xaritasi build vaqtida tekshiriladi. Load address kutilganidan farq qilsa, mutlaq murojaatlar jiddiy xato beradi.
Bog‘liq tushunchalar
Object file, Linker, Loader, Symbol, Position-independent code, GOT, PLT