Keyboard Shortcuts

Ctrl+K
Open search
Esc
Close search / dialog
↑
Back to top

Relocation Types

18 minintermediateModule 6: RelocationsContinues from relocation-entries

Why This Matters

The relocation type determines how the linker computes the value to patch into the binary. Different types produce different addressing modes — absolute addresses, PC-relative offsets, GOT entries, PLT calls. Choosing the wrong type means broken code.

Understanding relocation types explains why position-independent code (PIC) works differently from non-PIC, and why shared libraries use different call mechanisms than executables.

A Simple Model

There are two fundamental ways to reference a symbol:

PC-relative is the default for modern code because it's position-independent — the code works at any address without patching.

The Actual Detail

The most common x86-64 relocation types:

TypeValueFormulaUsage
R_X86_64_641S + AAbsolute 64-bit address (data references)
R_X86_64_PC322S + A - P32-bit PC-relative (call/jmp in non-PIC)
R_X86_64_PLT324L + A - P32-bit PC-relative via PLT (function calls)
R_X86_64_GOTPCRELX41G + GOT + A - PPC-relative to GOT entry (optimized PIC)
R_X86_64_3210S + A (truncated)32-bit absolute (non-PIE, low memory)

Where:

Key differences between R_X86_64_PC32 and R_X86_64_PLT32:

A Real Example

# Non-PIE executable -- uses R_X86_64_PLT32
# test.c: helper() returns 42, caller() calls helper()
$ gcc -no-pie -c test.c
$ readelf -rW test.o
00000000000a  000300000004  R_X86_64_PLT32  0000000000000000  helper - 4

# PIE executable -- uses R_X86_64_GOTPCRELX (optimized PIC)
$ gcc -pie -c test.c
$ readelf -rW test.o
00000000000a  000300000029  R_X86_64_GOTPCRELX  0000000000000000  helper - 8

The PLT32 relocation generates a direct call instruction. The GOTPCRELX relocation generates a lea + call *reg sequence that goes through the GOT for lazy binding.

Try It

# Compare relocation types: PIE vs non-PIE
# compare.c: calls an external function

# Non-PIE: PLT32
gcc -no-pie -c compare.c
readelf -rW compare.o | grep external

# PIE: GOTPCRELX  
gcc -pie -c compare.c
readelf -rW compare.o | grep external

# See the generated assembly difference
gcc -no-pie -S compare.c -o - | grep call
gcc -pie -S compare.c -o - | grep call

Check Your Understanding

What does R_X86_64_PLT32 compute?

Apply It

Why does PIE code use R_X86_64_GOTPCRELX instead of R_X86_64_PLT32?

Connect

Static relocations are resolved at link time. But shared libraries also need dynamic relocations — patches applied by ld.so at load time. That's the next concept.

Sort by Complexity

Sort the relocation types from simplest (least work at link time) to most complex (most work):

R_X86_64_64 — absolute 64-bit address (S + A)⋮⋮
R_X86_64_GOTPCRELX — GOT entry + linker relaxation⋮⋮
R_X86_64_PLT32 — PLT entry (L + A - P)⋮⋮
R_X86_64_RELATIVE — base + addend (dynamic relocation)⋮⋮
← Swipe to navigate →