5.3.2 · HinglishBuild Systems & Toolchain

Object files — .o - .obj, symbol table, relocation entries

2,061 words9 min readRead in English

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
Figure — Object files — .o  -  .obj, symbol table, relocation entries

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 global

Yeh 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?
Compiled sections (.text/.data/.bss/.rodata), ek symbol table, aur relocation entries.
Ek object file runnable kyun nahi hoti?
Isme abhi bhi placeholder addresses aur undefined symbols hain jo sirf linker resolve aur patch kar sakta hai.
nm output mein U ka kya matlab hai?
Ek undefined symbol — yahaan reference kiya gaya hai lekin kisi doosre object file ya library mein define hai.
Ek relocation entry mein kya chaar cheezein hoti hain?
Section mein offset, referenced symbol, relocation type, aur ek addend.
Absolute relocation formula?
patched value = S + A (symbol address plus addend).
PC-relative relocation formula aur extra −P kyun?
S + A − P; kyunki CPU displacement ko PC mein add karta hai, hume ek address ki jagah distance store karna hota hai.
Ek 32-bit PC-relative call ke liye addend aksar −4 kyun hota hai?
Yeh patch slot P aur next instruction ke beech ke 4 displacement bytes ka hisaab rakhta hai jise CPU apna base maanta hai.
Ek huge uninitialised global se .o file badi kyun nahi hoti?
Woh .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?
Header (missing declaration) ek compiler error hai; undefined reference ek linker error hai matlab koi object/library symbol define nahi karta.
.o aur .obj mein kya farq hai?
Same concept hai; .o Unix/ELF ka naming hai, .obj Windows/COFF ka naming hai.

Connections

Concept Map

assembler stage

contains

contains

contains

records

records

patches bytes for

not runnable, fed to

matches needs to provides

resolves via

produces

enables

Source file .c

Object file .o / .obj

Sections .text .data .bss .rodata

Symbol table

Relocation entries

Defined symbols - provides

Undefined symbols - needs

Linker

Executable a.out

Separate compilation