The compiler doesn’t know where a function or variable will end up, so it leaves a placeholder and writes a relocation: a note telling the linker what to patch. Each section has its own list, found through the section header.
The relocation record
IMAGE_RELOCATION, 10 bytes:
| Offset | Size | Field | Meaning |
|---|---|---|---|
| 0 | 4 | VirtualAddress | The offset in the section of the field to patch. In the first record of a section with LNK_NRELOC_OVFL, this is the real number of relocations. |
| 4 | 4 | SymbolTableIndex | The symbol whose address goes in the field, as a record index in the symbol table, counting auxiliary records. |
| 8 | 2 | Type | How to patch the field, which depends on the machine; see Types. |
The field’s own bytes hold an addend: the compiler puts 4 into a
displacement for example, and the linker adds it to the symbol’s address.
Types
The table lists the types for the four common machines. The prefix of the constant is
IMAGE_REL_AMD64_, IMAGE_REL_I386_, IMAGE_REL_ARM_
or IMAGE_REL_ARM64_.
| Value | x64 | x86 | ARM | ARM64 |
|---|---|---|---|---|
0x0 | ABSOLUTE | ABSOLUTE | ABSOLUTE | ABSOLUTE |
0x1 | ADDR64 | DIR16 | ADDR32 | ADDR32 |
0x2 | ADDR32 | REL16 | ADDR32NB | ADDR32NB |
0x3 | ADDR32NB | BRANCH24 | BRANCH26 | |
0x4 | REL32 | BRANCH11 | PAGEBASE_REL21 | |
0x5 | REL32_1 | REL21 | ||
0x6 | REL32_2 | DIR32 | PAGEOFFSET_12A | |
0x7 | REL32_3 | DIR32NB | PAGEOFFSET_12L | |
0x8 | REL32_4 | SECREL | ||
0x9 | REL32_5 | SEG12 | SECREL_LOW12A | |
0xA | SECTION | SECTION | REL32 | SECREL_HIGH12A |
0xB | SECREL | SECREL | SECREL_LOW12L | |
0xC | SECREL7 | TOKEN | TOKEN | |
0xD | TOKEN | SECREL7 | SECTION | |
0xE | SREL32 | SECTION | ADDR64 | |
0xF | PAIR | SECREL | BRANCH19 | |
0x10 | SSPAN32 | MOV32 | BRANCH14 | |
0x11 | THUMB_MOV32 | REL32 | ||
0x12 | THUMB_BRANCH20 | |||
0x14 | REL32 | THUMB_BRANCH24 | ||
0x15 | THUMB_BLX23 | |||
0x16 | PAIR |
The most common are REL32, a 32-bit distance from the end of the field to
the symbol (with REL32_1 to REL32_5 when that many more bytes
of the instruction follow the field), the 32-bit and 64-bit absolute addresses,
ADDR32NB, a 32-bit address relative to the image base,
and SECREL, the symbol’s offset in its section, used by debug information.
The specification also defines the types of older machines such as MIPS.