Foundations — Object files — .o - .obj, symbol table, relocation entries
This page assumes you know nothing about compilers. We build every word the parent note uses, in an order where each idea leans only on the one before it. If a term ever appears before we have earned it, that is a bug — tell no one, just re-read, because it should not happen.
0. The one picture to hold in your head

Look at the figure. On the left, three separate source files each become a separate box of bytes (an object file). None of them is a finished program — each has gaps (the plum question-marks) where an address should go. On the right, the linker lines up all the boxes, decides where everything lives, and fills the gaps. The whole topic is about what is inside one of those left-hand boxes and how the gaps are described.
1. Byte — the atom of everything
Why start here? Because an object file is, physically, just a long row of bytes on disk. Machine code is bytes. Addresses are bytes. Placeholders are bytes. If "byte" is fuzzy, nothing above it can be sharp.
is just the number 18 written in hexadecimal (base 16), a shorthand programmers use because it lines up neatly with bytes. We use it because the tools (readelf, objdump) print offsets that way — see §5.
2. Machine code — bytes the CPU obeys
Why the topic needs it: an object file's .text section is machine code. But some instructions want to say "jump to printf" — and the puncher doesn't yet know where printf sits, so it punches a blank slot there. Those blanks are the reason relocations exist (§7).
3. Address — a number that names a location

The figure shows memory as one long numbered strip. The teal marker is the address of a variable g; the orange marker is the address of a call instruction. The entire drama of linking is choosing these numbers. At compile time they are unknown, so the compiler cannot write them yet.
Why the topic needs it: the parent's symbols and are both addresses (numbers on this strip). We must have the word "address" before we can say what or mean.
4. Section — a labelled shelf inside the file
For the full tour of shelves, see Sections — .text .data .bss .rodata.
5. Offset — position within a section (not yet an address)
Why the topic needs it: a symbol's value field and a relocation's offset field are both offsets, because that is all the compiler can honestly know. This offset-vs-address distinction is the whole reason the file is called relocatable — its contents can be slid to any address later.
6. Symbol & the symbol table — the "offer / need" badges

The figure is the parent's "meetup" idea drawn out. Each object file wears two badges: a teal "I provide" badge (its DEFINED symbols) and an orange "I'm looking for" badge (its UND symbols). The linker's core job (see Linker — symbol resolution and relocation) is to draw a line from every looking-for to exactly one provide.
Why the topic needs it: symbol resolution (matching needs to offers) is half of what a linker does. The other half is relocation, which needs symbols to point at.
7. Relocation entry — a patch instruction
Why the topic needs it: relocations are the entire reason an .o is not runnable. The bytes are real, but the address-slots are hollow until patched.
8. The three address-letters: , , — and the formula
Now every ingredient exists, so the parent's formula stops being magic.

Read the figure left-to-right along the memory strip. The orange bracket is (the patch slot). The instruction ends 4 bytes later at . The teal marker far right is (the target). A PC-relative jump on x86-64 lands at , so to make it land on we must store the distance . Since , that distance is , i.e. with . The addend simply is the "" that measures the slot-to-end gap.
Why two formulas? Because a data pointer wants the actual address (), but a branch instruction hardware-adds its stored number to the next-instruction address, so it wants a displacement (). Same idea, different arithmetic — the type field tells the linker which to use. The mechanics of PC-relative addressing are unpacked in PC-relative addressing in x86-64.
9. Where this all sits in the bigger machine
The object file is one stop on the compilation pipeline. The container format (how sections and tables are laid out on disk) is ELF or COFF. What the linker does next splits into static vs dynamic linking, and if you write C++, symbol names get transformed first by Name mangling in C++.
Read top-down: bits build bytes, bytes build machine code and addresses, those build sections and offsets, which build symbols and relocations, which together with build the patch formula — and all of it feeds the parent topic, Object files.
Equipment checklist
Self-test: cover the right side and answer aloud before revealing.
A byte holds how many distinct values?
What is machine code, in one line?
Address vs offset — the difference?
Which section stores its data as only a size, no bytes?
.bss (zero-initialised globals).