Dynamic loader — executable ishga tushganda yoki dastur talab qilganda shared librarylarni jarayon xotirasiga joylashtirib, dinamik bog‘lanishlarni bajaradigan operatsion tizim komponentidir. U executable metadata’sidan kerakli modullarni topadi, segmentlarni virtual xotiraga xaritalaydi, relocation va symbol resolutionni bajaradi, so‘ng boshqaruvni dastur kirish nuqtasiga beradi.
Ishga tushirish ketma-ketligi
Kernel executable formatini tekshiradi va unda ko‘rsatilgan interpreter yoki loaderni ishga tushiradi. Loader asosiy faylning dependency ro‘yxatini o‘qib, har kutubxona uchun qidiruv qoidalarini qo‘llaydi. Topilgan fayl arxitektura va ABI’ga mos bo‘lishi kerak. Uning transitive dependenciyalari ham rekursiv yuklanadi.
Segmentlar kod uchun read-execute, o‘zgarmas ma’lumot uchun read-only, yoziladigan data uchun read-write ruxsatlarda xaritalanadi. BSS uchun faylda bayt saqlanmasdan nol bilan to‘ldirilgan virtual sahifalar ajratiladi. Address space layout randomization modullar bazaviy manzilini ishga tushirishlar orasida o‘zgartirishi mumkin.
Relocation va symbol
Loader link vaqtida hal bo‘lmagan dinamik relocationlarni hisoblaydi. Symbol qidirish tartibi platforma, visibility, version va load scope’ga bog‘liq. Bir xil nom bir nechta modulda bo‘lsa, interposition qoidasi qaysi ta’rif tanlanishini belgilaydi. Noto‘g‘ri versiya tanlansa, funksiya nomi mavjud bo‘lsa ham ABI mos kelmasligi mumkin.
Lazy binding tashqi funksiyaning manzilini birinchi chaqiruvda topadi; eager yoki now binding barcha importlarni avval tekshiradi. Eager usul startup vaqtini oshirishi mumkin, evaziga xato erta chiqadi va GOT yozuvlarini tezroq read-only qilish imkonini beradi. RELRO singari himoyalar bog‘lash tugagach jadval qismlarini o‘zgartirishni cheklaydi.
Talab bo‘yicha modullar
Dastur runtime API orqali plugin yoki optional modulni yuklashi mumkin. Loader handle qaytaradi, dastur esa symbol nomi bilan funksiya manzilini oladi. Har bir murojaatdan keyin xato holati tekshiriladi. Modulni unload qilishdan oldin uning kodi, thread-local storage’i, callbacklari va obyektlariga hech kim murojaat qilmayotgani kafolatlanadi.
Xavfsizlik va diagnostika
Qidiruv yo‘li current directory yoki foydalanuvchi yozishi mumkin bo‘lgan katalogni ustun qo‘ysa, library hijacking yuz beradi. Privileged dasturlar environment-based override’larni cheklaydi. Paket imzosi, fayl ownership’i va katalog ruxsatlari tekshiriladi. Kutubxona nomini faqat ishonchli konfiguratsiyadan olish ma’qul.
Loader diagnostikasi qaysi fayl tanlanganini, dependency daraxtini, symbol qidiruvi va relocation xarajatini ko‘rsatishi mumkin. Bunday tracing productionda katta va maxfiy yo‘llarni ochishi mumkin, shuning uchun qisqa muddat va himoyalangan jurnal bilan ishlatiladi. Startup sekin bo‘lsa, modul soni, relocation hajmi va disk I/O profiler orqali o‘lchanadi.
+## Constructor va TLS
Shared library yuklanganda uning initialization funksiyalari asosiy main dan oldin bajarilishi mumkin. Constructorlar orasidagi tartib turli modullar bo‘ylab har doim kafolatlanmaydi; biri boshqasining hali tayyor bo‘lmagan global holatiga tayansa startup xatosi yuz beradi. Minimal initialization va explicit start API bu bog‘liqlikni kamaytiradi. Thread-local storage uchun loader har threadga modulga tegishli joy ajratadi; modul kech yuklanganda mavjud threadlar ham hisobga olinadi. Forkdan keyin faqat bitta thread qolgan jarayonda loader lock holati muhim bo‘lishi mumkin. Signal handler ichida dinamik yuklash kabi async-signal-unsafe amallar bajarilmaydi.
Loader cache kutubxona nomini tez topishga yordam beradi, ammo yangi fayl o‘rnatilganda cache yangilanmasa eski yo‘l tanlanishi mumkin. Paket tranzaksiyasi fayl, symlink va cache’ni izchil yangilaydi. Yarim o‘rnatilgan holat keyingi process startupini buzmasligi kerak.
Bog‘liq tushunchalar
Dynamic linking, Shared library, Loader, Relocation, Symbol resolution, ASLR, ABI