Symbol tables (SHT_SYMTAB, SHT_DYNSYM) name the functions
and data of a file; relocation sections (SHT_REL, SHT_RELA)
say how to patch code and data once addresses are known. Structures follow the gABI
chapter 4; relocation types are defined per processor, and this page lists those for
x86-64 and AArch64 from glibc’s elf.h.
Symbol table entry
| Offset 32 | Offset 64 | Type 32 / 64 | Field | Meaning |
|---|---|---|---|---|
0x00 | 0x00 | Word | st_name | Offset of the name in the symbol string table (sh_link); 0 for none. |
0x04 | 0x08 | Addr | st_value | Value, below. |
0x08 | 0x10 | Word / Xword | st_size | Size in bytes, or 0 if none or unknown. |
0x0C | 0x04 | unsigned char | st_info | Binding in the high four bits, type in the low four. |
0x0D | 0x05 | unsigned char | st_other | Visibility in the low two bits; the gABI sets the rest to 0. |
0x0E | 0x06 | Half | st_shndx | Index of the section the symbol is defined in, or a special index. |
An entry is 16 bytes in 32-bit files and 24 bytes in 64-bit files; the 64-bit layout
moves st_info, st_other and st_shndx ahead.
ST_BIND(i) = i >> 4, ST_TYPE(i) = i & 0xF,
ST_INFO(b, t) = (b << 4) + (t & 0xF),
ST_VISIBILITY(o) = o & 0x3.
Entry 0 (STN_UNDEF) is all zeros. Local symbols come first; the
section’s sh_info is the index of the first non-local one.
Binding
| Value | Name | Meaning |
|---|---|---|
0 | STB_LOCAL | Local symbol |
1 | STB_GLOBAL | Global symbol; two definitions are an error |
2 | STB_WEAK | Global with lower precedence: a global or common definition wins; an unresolved weak symbol is 0; weak references do not pull members out of archives |
10–12 | STB_LOOS–STB_HIOS | OS-specific; GNU uses 10 as STB_GNU_UNIQUE |
13–15 | STB_LOPROC–STB_HIPROC | Processor-specific |
Type
| Value | Name | Meaning |
|---|---|---|
0 | STT_NOTYPE | No type |
1 | STT_OBJECT | Data object |
2 | STT_FUNC | Function; in shared objects the linker makes PLT entries for referenced functions |
3 | STT_SECTION | A section |
4 | STT_FILE | Source file name: local, SHN_ABS, before the file’s other local symbols |
5 | STT_COMMON | Uninitialised common block; SHN_COMMON in relocatable files |
6 | STT_TLS | Thread-local entity; st_value is an offset, and only TLS relocations may refer to it |
10–12 | STT_LOOS–STT_HIOS | OS-specific; GNU uses 10 as STT_GNU_IFUNC |
13–15 | STT_LOPROC–STT_HIPROC | Processor-specific |
Visibility
| Value | Name | Meaning |
|---|---|---|
0 | STV_DEFAULT | As the binding says |
1 | STV_INTERNAL | Defined by the processor supplement |
2 | STV_HIDDEN | Not visible to other components |
3 | STV_PROTECTED | Visible to other components but not preemptable |
When visibilities differ, the most constraining wins (protected, then hidden, then
internal). Hidden and internal symbols in relocatable files become local or are
removed when linked. AArch64 uses st_other bit 0x80 as
STO_AARCH64_VARIANT_PCS (glibc).
st_value
- Relocatable files: for
SHN_COMMONsymbols, the alignment; otherwise an offset in the sectionst_shndx. - Executables and shared objects: a virtual address.
SHN_ABS: an absolute value;SHN_UNDEF: undefined, to be resolved by the linker;SHN_XINDEX: the real section index is in theSHT_SYMTAB_SHNDXsection.
Relocation entries
| Offset 32 | Offset 64 | Type 32 / 64 | Field | Meaning |
|---|---|---|---|---|
0x00 | 0x00 | Addr | r_offset | Where to apply it: a byte offset in the section (relocatable files) or a virtual address (executables, shared objects). |
0x04 | 0x08 | Word / Xword | r_info | Symbol index and relocation type. |
0x08 | 0x10 | Sword / Sxword | r_addend | Rela only: the addend. In Rel entries the addend is in the field being patched. |
| Class | Symbol | Type | Pack |
|---|---|---|---|
| 32-bit | r_info >> 8 | r_info & 0xFF | (sym << 8) + type |
| 64-bit | r_info >> 32 | r_info & 0xFFFFFFFF | (sym << 32) + type |
A symbol index of STN_UNDEF means a value of 0. Several relocations at
the same r_offset are composed: intermediate results keep full
precision and only the last is stored. Rel entries are 8 or 16 bytes,
Rela entries 12 or 24.
x86-64 relocation types
| Value | R_X86_64_ | Meaning | Value | R_X86_64_ | Meaning |
|---|---|---|---|---|---|
| 0 | NONE | none | 22 | GOTTPOFF | PC-relative offset to an initial-exec GOT entry |
| 1 | 64 | direct 64-bit | 23 | TPOFF32 | offset in the initial TLS block |
| 2 | PC32 | PC-relative 32-bit signed | 24 | PC64 | PC-relative 64-bit |
| 3 | GOT32 | 32-bit GOT entry | 25 | GOTOFF64 | 64-bit offset to the GOT |
| 4 | PLT32 | 32-bit PLT address | 26 | GOTPC32 | 32-bit signed PC-relative offset to the GOT |
| 5 | COPY | copy the symbol at run time | 27 | GOT64 | 64-bit GOT entry offset |
| 6 | GLOB_DAT | create a GOT entry | 28 | GOTPCREL64 | 64-bit PC-relative offset to a GOT entry |
| 7 | JUMP_SLOT | create a PLT entry | 29 | GOTPC64 | 64-bit PC-relative offset to the GOT |
| 8 | RELATIVE | adjust by the program base | 30 | GOTPLT64 | like GOT64, says a PLT entry is needed |
| 9 | GOTPCREL | 32-bit signed PC-relative offset to the GOT entry | 31 | PLTOFF64 | 64-bit GOT-relative offset to a PLT entry |
| 10 | 32 | direct 32-bit, zero-extended | 32 | SIZE32 | symbol size plus 32-bit addend |
| 11 | 32S | direct 32-bit, sign-extended | 33 | SIZE64 | symbol size plus 64-bit addend |
| 12 | 16 | direct 16-bit, zero-extended | 34 | GOTPC32_TLSDESC | GOT offset for a TLS descriptor |
| 13 | PC16 | 16-bit sign-extended PC-relative | 35 | TLSDESC_CALL | marks a call through a TLS descriptor |
| 14 | 8 | direct 8-bit, sign-extended | 36 | TLSDESC | TLS descriptor |
| 15 | PC8 | 8-bit sign-extended PC-relative | 37 | IRELATIVE | adjust indirectly by the program base |
| 16 | DTPMOD64 | ID of the module holding the symbol | 38 | RELATIVE64 | 64-bit adjust by the program base |
| 17 | DTPOFF64 | offset in the module’s TLS block | 39, 40 | — | reserved |
| 18 | TPOFF64 | offset in the initial TLS block | 41 | GOTPCRELX | relaxable GOT load, no REX prefix |
| 19 | TLSGD | PC-relative offset to two general-dynamic GOT entries | 42 | REX_GOTPCRELX | relaxable GOT load with a REX prefix |
| 20 | TLSLD | PC-relative offset to two local-dynamic GOT entries | 43 | (NUM) | count |
| 21 | DTPOFF32 | offset in the TLS block |
x86-64 also uses SHT_X86_64_UNWIND (0x70000001) and the
dynamic tags DT_X86_64_PLT, DT_X86_64_PLTSZ and
DT_X86_64_PLTENT (DT_LOPROC + 0, 1 and 3).
AArch64 relocation types
| Value | R_AARCH64_ | Meaning |
|---|---|---|
| 0 | NONE | none |
| 257–259 | ABS64, ABS32, ABS16 | direct absolute |
| 260–262 | PREL64, PREL32, PREL16 | PC-relative |
| 263–269 | MOVW_UABS_G0, _G0_NC, _G1, _G1_NC, _G2, _G2_NC, _G3 | MOVZ/MOVK immediate, unsigned absolute |
| 270–272 | MOVW_SABS_G0, _G1, _G2 | MOVN/MOVZ immediate, signed absolute |
| 273 | LD_PREL_LO19 | PC-relative LD immediate |
| 274 | ADR_PREL_LO21 | PC-relative ADR immediate |
| 275, 276 | ADR_PREL_PG_HI21, _NC | page-relative ADRP (checked, unchecked) |
| 277 | ADD_ABS_LO12_NC | ADD immediate, bits 11:0 |
| 278 | LDST8_ABS_LO12_NC | LD/ST, byte |
| 279 | TSTBR14 | TBZ/TBNZ immediate |
| 280 | CONDBR19 | conditional branch immediate |
| 282 | JUMP26 | B immediate |
| 283 | CALL26 | BL immediate |
| 284–286 | LDST16_ABS_LO12_NC, LDST32_…, LDST64_… | LD/ST by access size |
| 287–293 | MOVW_PREL_G0, _G0_NC, _G1, _G1_NC, _G2, _G2_NC, _G3 | PC-relative MOVZ/MOVK |
| 299 | LDST128_ABS_LO12_NC | LD/ST, 128-bit |
| 300–306 | MOVW_GOTOFF_G0, _G0_NC, _G1, _G1_NC, _G2, _G2_NC, _G3 | GOT-relative MOVZ/MOVK |
| 307, 308 | GOTREL64, GOTREL32 | GOT-relative data |
| 309 | GOT_LD_PREL19 | PC-relative GOT load |
| 310 | LD64_GOTOFF_LO15 | GOT-relative LD/ST |
| 311 | ADR_GOT_PAGE | page-relative GOT ADRP |
| 312 | LD64_GOT_LO12_NC | direct GOT LD/ST |
| 313 | LD64_GOTPAGE_LO15 | GOT-page-relative LD/ST |
| 512–516 | TLSGD_ADR_PREL21, TLSGD_ADR_PAGE21, TLSGD_ADD_LO12_NC, TLSGD_MOVW_G1, TLSGD_MOVW_G0_NC | TLS general dynamic |
| 517–522 | TLSLD_ADR_PREL21, TLSLD_ADR_PAGE21, TLSLD_ADD_LO12_NC, TLSLD_MOVW_G1, TLSLD_MOVW_G0_NC, TLSLD_LD_PREL19 | TLS local dynamic |
| 523–527 | TLSLD_MOVW_DTPREL_G2, _G1, _G1_NC, _G0, _G0_NC | DTP-relative MOV |
| 528–530 | TLSLD_ADD_DTPREL_HI12, _LO12, _LO12_NC | DTP-relative ADD |
| 531–538 | TLSLD_LDST8_DTPREL_LO12 to TLSLD_LDST64_DTPREL_LO12_NC: sizes 8, 16, 32, 64, each followed by its _NC form | DTP-relative LD/ST |
| 539–543 | TLSIE_MOVW_GOTTPREL_G1, _G0_NC, TLSIE_ADR_GOTTPREL_PAGE21, TLSIE_LD64_GOTTPREL_LO12_NC, TLSIE_LD_GOTTPREL_PREL19 | TLS initial exec |
| 544–548 | TLSLE_MOVW_TPREL_G2, _G1, _G1_NC, _G0, _G0_NC | TLS local exec, MOV |
| 549–551 | TLSLE_ADD_TPREL_HI12, _LO12, _LO12_NC | TLS local exec, ADD |
| 552–559 | TLSLE_LDST8_TPREL_LO12 to TLSLE_LDST64_TPREL_LO12_NC, as above | TLS local exec, LD/ST |
| 560–566 | TLSDESC_LD_PREL19, TLSDESC_ADR_PREL21, TLSDESC_ADR_PAGE21, TLSDESC_LD64_LO12, TLSDESC_ADD_LO12, TLSDESC_OFF_G1, TLSDESC_OFF_G0_NC | TLS descriptor |
| 567–569 | TLSDESC_LDR, TLSDESC_ADD, TLSDESC_CALL | relaxation hints |
| 570, 571 | TLSLE_LDST128_TPREL_LO12, _NC | TLS local exec, 128-bit LD/ST |
| 572, 573 | TLSLD_LDST128_DTPREL_LO12, _NC | DTP-relative 128-bit LD/ST |
| 1024 | COPY | copy the symbol at run time |
| 1025 | GLOB_DAT | create a GOT entry |
| 1026 | JUMP_SLOT | create a PLT entry |
| 1027 | RELATIVE | adjust by the program base |
| 1028 | TLS_DTPMOD | 64-bit module number |
| 1029 | TLS_DTPREL | 64-bit module-relative offset |
| 1030 | TLS_TPREL | 64-bit TP-relative offset |
| 1031 | TLSDESC | TLS descriptor |
| 1032 | IRELATIVE | STT_GNU_IFUNC relocation |
Values within each group run in the order the names are listed. AArch64 also defines
PT_AARCH64_MEMTAG_MTE (PT_LOPROC + 2) and the dynamic tags
DT_AARCH64_BTI_PLT, DT_AARCH64_PAC_PLT and
DT_AARCH64_VARIANT_PCS (DT_LOPROC + 1, 3 and 5).
Other processors’ relocation types (i386, ARM, RISC-V, PowerPC and the rest) are defined in their own processor supplements and are not listed here.
Sources
- gABI chapter 4: Symbol Table – entry layouts, binding, type, visibility, entry 0, ordering, st_value
- gABI chapter 4: Relocation – Rel and Rela, r_info macros, composition
- glibc elf.h –
STB_GNU_UNIQUE,STT_GNU_IFUNC,STO_AARCH64_VARIANT_PCS, x86-64 and AArch64 relocation types and their comments, x86-64 and AArch64 section, segment and dynamic values