Linker — bir yoki bir nechta object file va library’ni birlashtirib, executable, shared library yoki boshqa yakuniy binary artifact yaratadigan dastur.
Compiler yoki assembler har source faylni alohida object file’ga aylantirishi mumkin. Object fayllardagi tashqi symbol manzillari hali to‘liq aniqlanmagan bo‘ladi. Linker ularni topadi, sectionlarni joylashtiradi va relocationlarni hisoblaydi.
Object file
Object file tarkibida:
mavjud.
Misol:
main.o
math.o
utils.o
Linker ularni bitta executablega birlashtiradi.
Symbol
Symbol function yoki data obyektini bildiradi.
Misollar:
Symbol:
- defined;
- undefined;
- local;
- global;
- weak
bo‘lishi mumkin.
Symbol resolution
main.o ichida calculate_total chaqiriladi, ammo function math.oda yaratilgan.
Linker undefined symbolni boshqa object yoki library’dagi definition bilan bog‘laydi.
Definition topilmasa:
undefined reference
xatosi chiqadi.
Duplicate symbol
Bir xil strong global symbol bir nechta object’da aniqlansa linker qaysi birini tanlashni bilmaydi.
Natija:
multiple definition
xatosi.
Static, namespace yoki source dizayni bilan nom collisioni bartaraf etiladi.
Weak symbol
Weak symbol default implementation berishi mumkin.
Strong definition mavjud bo‘lsa u ustun keladi.
Runtime hook va platformaga xos override uchun ishlatiladi.
Semantika object format va platformaga bog‘liq.
Relocation
Object code’dagi instruction yoki data final manzilga bog‘liq bo‘lishi mumkin.
Relocation yozuvi:
- qaysi joy;
- qaysi symbol;
- relocation turi;
- addend
haqida ma’lumot beradi.
Linker final addressni hisoblab binary’ni patch qiladi yoki dynamic loader uchun relocation qoldiradi.
Section placement
Linker bir xil turdagi sectionlarni birlashtiradi.
Masalan:
- barcha
.text; .rodata;.data;.bss.
Ularning virtual address, file offset, permission va alignmentini belgilaydi.
Linker script
Linker script sectionlar qayerda joylashishini boshqaradi.
Embedded tizimda:
aniq ko‘rsatiladi.
Noto‘g‘ri script code’ni mavjud bo‘lmagan yoki writable bo‘lmagan regionga joylashtirishi mumkin.
Static library
Static library object fayllar arxivi.
Unixda ko‘pincha .a, Windowsda .lib formatida.
Linker faqat kerakli object modullarni executable ichiga qo‘shadi.
Natija runtime’da ushbu library file’ga bog‘liq bo‘lmaydi.
Shared library
Shared library runtime’da bir nechta program tomonidan ishlatilishi mumkin.
Formatlar:
.so;.dll;.dylib.
Executable ichida library code to‘liq nusxalanmaydi. Import va dynamic linking ma’lumoti saqlanadi.
Static linking
Afzalliklari:
- deployment sodda;
- runtime dependency kam;
- ma’lum library versiyasi binary ichida;
- single-file artifact.
Kamchiliklari:
- binary katta;
- library security fix uchun qayta build;
- memory sharing kamayishi;
- ayrim litsenziya shartlari.
Dynamic linking
Afzalliklari:
Kamchiliklari:
Link order
Static librarylar bilan command line tartibi muhim bo‘lishi mumkin.
Linker chapdan o‘ngga unresolved symbol asosida archive memberlarni oladi.
Library noto‘g‘ri joyda bo‘lsa definition mavjud bo‘lsa ham unresolved error chiqishi mumkin.
Group option circular dependency’ni qayta ko‘rib chiqishi mumkin.
Name mangling
C++ function overload va namespace symbol nomiga encode qilinadi.
Misol source nomi binary symbol’da murakkab ko‘rinishi mumkin.
extern "C" C linkage ishlatib manglingni o‘zgartiradi.
Compilerlar ABI mos bo‘lishi kerak.
Position-independent code
Shared library turli virtual addressga yuklanishi mumkin.
PIC absolute address o‘rniga relative addressing va tablelardan foydalanadi.
Bu relocation soni va writable code page’larni kamaytiradi.
GOT va PLT
ELF dynamic linkingda:
sifatida ishlatiladi.
Lazy bindingda function manzili birinchi chaqiriqda yechilishi mumkin.
Link-time optimization
LTO compilerga object chegaralaridan tashqarida optimization qilish imkonini beradi.
Compiler IR object yoki alohida metadata’da saqlanadi.
Link bosqichida:
- cross-module inline;
- dead code elimination;
- whole-program analysis
bajariladi.
Build vaqt va memory sarfi oshishi mumkin.
Dead code elimination
Function yoki data hech qayerdan reachable bo‘lmasa linker section garbage collection orqali olib tashlashi mumkin.
Har function alohida sectionga joylashtirilsa aniqlik oshadi.
Reflection yoki dynamic lookup bilan ishlatiladigan symbolni noto‘g‘ri olib tashlamaslik kerak.
Incremental linking
Katta loyiha har buildda to‘liq relink qilinsa vaqt ko‘p ketadi.
Incremental linker faqat o‘zgargan qismlarni yangilashga intiladi.
Development build tezlashadi, release build to‘liq optimallashtirilishi mumkin.
Map file
Linker map fayli:
- symbol address;
- section hajmi;
- qaysi object;
- memory region;
- discarded section
ni ko‘rsatadi.
Embedded firmware hajmi va memory overflowni tahlil qilishda foydali.
Debug symbol
Linker turli object debug ma’lumotini final binaryga birlashtiradi yoki alohida debug file yaratadi.
Production binary strip qilinishi mumkin, ammo crash tahlili uchun build IDga mos symbol serverda saqlanadi.
Dynamic linker
Linker bilan dynamic loader aralashmasligi kerak.
Build vaqtida linker executable yaratadi.
Runtime’da dynamic loader shared librarylarni topadi, map qiladi va qolgan relocationlarni bajaradi.
Diagnostika
Link xatosida:
- undefined symbol;
- duplicate definition;
- library order;
- architecture;
- ABI;
- static/dynamic variant;
- search path;
- linker script;
- relocation overflow;
- symbol visibility
tekshiriladi.
32-bit object va 64-bit object bir executablega oddiy tarzda birlashtirilmaydi.
Bog‘liq tushunchalar
Object file, Symbol, Relocation, Static library, Shared library, Dynamic linking, Linker script, LTO, Loader, ABI