Object files — .o - .obj, symbol table, relocation entries
5.3.2· Coding › Build Systems & Toolchain
WHAT is an object file?
WHY does it exist? Taki hum har source file ko alag-alag compile kar sakein (separate compilation) aur sirf tab relink karein jab zaroorat ho. Ek .c badlo, ek .o recompile karo, relink karo. Fast.
The pipeline (WHERE the .o sits)
file.c --[preprocessor]--> file.i --[compiler]--> file.s --[assembler]--> file.o --[linker]--> a.out

The Symbol Table
HOW to inspect it:
$ nm file.o # symbol table
$ readelf -s file.o # detailed ELF symbols
$ readelf -r file.o # relocation entries
$ objdump -d file.o # disassembly (shows placeholder addrs)
nm output mein, capital letter = global, lowercase = local:
T/t = text(code), D/d = data, B/b = bss, U = undefined.
Relocation Entries — the heart of it
Deriving the relocation formula from first principles
WHY a formula at all? Kyunki jo value likhni hai woh depend karti hai isi baat par ki reference absolute hai (actual address likho) ya PC-relative (patched instruction se ek distance likho).
Maano:
- = symbol ke liye chosen final address,
- = addend (reloc mein stored ek constant, e.g.
-4), - = patch hone wali jagah ka address (woh slot khud).
HOW we got : x86-64 par ek PC-relative branch apna destination aise compute karta hai:
jahaan displacement field ke theek baad wala byte hai. Hum chahte hain (plus koi bhi addend). Addend exactly aise set hota hai ki . Displacement jo hume store karna hai uske liye solve karte hain:
Isliye assembler addend = -4 emit karta hai ek 4-byte field ke liye: woh 4 bytes jo patch slot aur instruction ke end ke beech hain.
Worked Example 1 — a global variable reference (absolute)
Source:
int g; // defined here (goes to .bss)
int *p = &g; // p is in .data, needs address of g.data mein p ke bytes mein &g hona chahiye. Lekin g ka final address compile time par unknown hai.
| step | what happens | Why this step? |
|---|---|---|
| 1 | g → symbol, DEFINED, section .bss |
yeh file g provide karti hai |
| 2 | p → symbol, DEFINED, section .data |
yeh file p provide karti hai |
| 3 | reloc add ki gayi: p ka offset, type R_X86_64_64, symbol g, addend 0 |
p ke 8 bytes g ke address ke liye ek placeholder hain |
| 4 | linker: = g ka address choose karta hai |
ab address pata hai |
| 5 | ko p ke bytes mein likhta hai |
absolute formula |
Worked Example 2 — calling an external function (PC-relative)
Source main.c:
extern int add(int,int);
int main(){ return add(2,3); }| step | what happens | Why this step? |
|---|---|---|
| 1 | add → symbol, UND (undefined) |
main.c reference karta hai lekin add define nahi karta |
| 2 | main → symbol DEFINED in .text |
yeh file main provide karti hai |
| 3 | assembler call <placeholder> emit karta hai reloc ke saath: offset = call opcode ke baad wala byte, type R_X86_64_PLT32, symbol add, addend -4 |
call site ko ek 32-bit PC-relative displacement chahiye |
| 4 | linker add.o ke saath combine karta hai, = add ka address, = patch slot pick karta hai |
addresses ab fix ho gaye |
| 5 | ko 4 displacement bytes mein likhta hai | PC-relative formula |
Why this step (5)? CPU stored displacement ko next instruction ke address mein add karta hai; -4 addend aur us next instruction ke beech ke 4 displacement bytes ka hisaab rakhta hai, taaki jump exactly add par land kare.
Worked Example 3 — .bss saves disk space
int big[1000000]; // uninitialised globalYeh 1 MB zeros hai. .o 1 MB kyun nahi badhta? Kyunki big .bss mein jaata hai, jo sirf ek size record karta hai, actual bytes nahi. OS load time par use zero-fill karta hai. Why this matters: initialised data (.data) file space leta hai; zero-init (.bss) kuch nahi leta.
Common Mistakes
Recall Feynman: explain to a 12-year-old
Socho har code file ek aisa worker hai jo Lego castle ka ek piece banata hai, lekin use nahi pata ki uska piece final castle mein kahan baithega. Toh har worker sticky notes likhta hai: "Maine drawbridge banaya" (defined symbol) aur "Mujhe kisi ka tower chahiye yahaan" (undefined symbol), plus "Mere piece ka darwaza tower ki taraf point karna chahiye — arrow baad mein theek karo" (relocation). Linker woh boss hai jo saare pieces ek jagah rakhta hai, har sticky note padhta hai, aur real arrows draw karta hai. Tabhi castle ek real, khelne layak cheez ban jaata hai.
Flashcards
Ek object file mein teen tarah ka content kya hota hai?
Ek object file runnable kyun nahi hoti?
nm output mein U ka kya matlab hai?
Ek relocation entry mein kya chaar cheezein hoti hain?
Absolute relocation formula?
PC-relative relocation formula aur extra −P kyun?
Ek 32-bit PC-relative call ke liye addend aksar −4 kyun hota hai?
Ek huge uninitialised global se .o file badi kyun nahi hoti?
.bss mein rehta hai, jo sirf ek size store karta hai; bytes load time par zero-fill hoti hain.Header error aur undefined reference mein kya farq hai?
.o aur .obj mein kya farq hai?
.o Unix/ELF ka naming hai, .obj Windows/COFF ka naming hai.Connections
- Linker — symbol resolution and relocation
- ELF and COFF file formats
- Static vs Dynamic Linking
- Compilation Pipeline — preprocess, compile, assemble, link
- Sections — .text .data .bss .rodata
- PC-relative addressing in x86-64
- Name mangling in C++