Sections are the linking view of an ELF file: code, data, symbol tables, relocations
and so on, each described by an entry in the section header table at
e_shoff. Object files need the table; programs may leave it out. Each
section is one contiguous range of the file (possibly empty); sections do not overlap,
and the file may also contain bytes that belong to no section. The types used here are
on the ELF header page.
Section header
| Offset 32 | Offset 64 | Type 32 / 64 | Field | Meaning |
|---|---|---|---|---|
0x00 | 0x00 | Word | sh_name | Offset of the name in the section name string table (e_shstrndx). |
0x04 | 0x04 | Word | sh_type | Section type. |
0x08 | 0x08 | Word / Xword | sh_flags | Flags. |
0x0C | 0x10 | Addr | sh_addr | Address of the section’s first byte in the process image, or 0. Must be a multiple of sh_addralign. |
0x10 | 0x18 | Off | sh_offset | File offset of the contents. For SHT_NOBITS, where it would be. |
0x14 | 0x20 | Word / Xword | sh_size | Size in bytes (a SHT_NOBITS section takes no file space whatever its size). |
0x18 | 0x28 | Word | sh_link | A section index; meaning by type, below. |
0x1C | 0x2C | Word | sh_info | Extra information; meaning by type. |
0x20 | 0x30 | Word / Xword | sh_addralign | Alignment: 0 or 1 for none, otherwise a power of two. |
0x24 | 0x38 | Word / Xword | sh_entsize | Size of each entry for sections that are tables of fixed-size entries, else 0. |
Each header is 40 bytes in 32-bit files and 64 bytes in 64-bit files.
Section header 0
The first entry is reserved and zero (SHT_NULL), except that its
sh_size holds the real number of sections when e_shnum is 0,
its sh_link the real e_shstrndx when that is
SHN_XINDEX, and (on Linux) its sh_info the real number of
program headers when e_phnum is PN_XNUM.
Special section indexes
| Value | Name | Meaning |
|---|---|---|
0x0000 | SHN_UNDEF | Undefined, missing or meaningless section reference |
0xFF00 | SHN_LORESERVE | Start of the reserved range |
0xFF00–0xFF1F | SHN_LOPROC–SHN_HIPROC | Processor-specific |
0xFF00, 0xFF01 | SHN_BEFORE, SHN_AFTER | Solaris ordering values (glibc) |
0xFF20–0xFF3F | SHN_LOOS–SHN_HIOS | Operating-system-specific |
0xFFF1 | SHN_ABS | Absolute values, not changed by relocation |
0xFFF2 | SHN_COMMON | Common symbols (unallocated C externals, FORTRAN COMMON) |
0xFFFF | SHN_XINDEX | Escape: the real index is held elsewhere |
0xFFFF | SHN_HIRESERVE | End of the reserved range |
No section header table entries exist for the reserved indexes.
sh_type
| Value | Name | Contents |
|---|---|---|
0 | SHT_NULL | Inactive header |
1 | SHT_PROGBITS | Data defined by the program |
2 | SHT_SYMTAB | Symbol table |
3 | SHT_STRTAB | String table |
4 | SHT_RELA | Relocations with explicit addends |
5 | SHT_HASH | Symbol hash table |
6 | SHT_DYNAMIC | Dynamic linking information |
7 | SHT_NOTE | Notes |
8 | SHT_NOBITS | Like PROGBITS but takes no file space (for example .bss) |
9 | SHT_REL | Relocations without explicit addends |
10 | SHT_SHLIB | Reserved, semantics unspecified |
11 | SHT_DYNSYM | Minimal symbol table for dynamic linking |
12, 13 | — | Not defined |
14 | SHT_INIT_ARRAY | Array of initialisation function pointers |
15 | SHT_FINI_ARRAY | Array of termination function pointers |
16 | SHT_PREINIT_ARRAY | Array of pre-initialisation function pointers |
17 | SHT_GROUP | Section group |
18 | SHT_SYMTAB_SHNDX | Extended section indexes for a symbol table |
19 | SHT_RELR | Relative relocations in compact form (glibc; not in the gABI page read) |
0x60000000–0x6FFFFFFF | SHT_LOOS–SHT_HIOS | Operating-system-specific, including: |
0x6FFFFFF5 | SHT_GNU_ATTRIBUTES | GNU attributes |
0x6FFFFFF6 | SHT_GNU_HASH | GNU hash table |
0x6FFFFFF7 | SHT_GNU_LIBLIST | GNU library list |
0x6FFFFFF8 | SHT_CHECKSUM | Checksum |
0x6FFFFFFA | SHT_SUNW_move | Sun move table |
0x6FFFFFFB | SHT_SUNW_COMDAT | Sun COMDAT |
0x6FFFFFFC | SHT_SUNW_syminfo | Sun symbol information |
0x6FFFFFFD | SHT_GNU_verdef | Version definitions (.gnu.version_d) |
0x6FFFFFFE | SHT_GNU_verneed | Version requirements (.gnu.version_r) |
0x6FFFFFFF | SHT_GNU_versym | Version symbol table (.gnu.version) |
0x70000000–0x7FFFFFFF | SHT_LOPROC–SHT_HIPROC | Processor-specific, for example 0x70000001 SHT_X86_64_UNWIND (x86-64 unwind information, glibc) |
0x80000000–0xFFFFFFFF | SHT_LOUSER–SHT_HIUSER | Reserved for applications |
sh_flags
| Value | Name | Meaning |
|---|---|---|
0x1 | SHF_WRITE | Writable while the program runs |
0x2 | SHF_ALLOC | Occupies memory while the program runs |
0x4 | SHF_EXECINSTR | Contains executable instructions |
0x10 | SHF_MERGE | Data may be merged to remove duplicates |
0x20 | SHF_STRINGS | Holds zero-terminated strings (with SHF_MERGE) |
0x40 | SHF_INFO_LINK | sh_info holds a section index |
0x80 | SHF_LINK_ORDER | Keep the order relative to the section in sh_link |
0x100 | SHF_OS_NONCONFORMING | Needs OS-specific handling; a linker that does not know it must reject the file |
0x200 | SHF_GROUP | Member of a section group (relocatable files only) |
0x400 | SHF_TLS | Thread-local storage |
0x800 | SHF_COMPRESSED | Compressed; not for allocated or NOBITS sections |
0x0FF00000 | SHF_MASKOS | Reserved for the OS, including 0x200000 SHF_GNU_RETAIN (glibc) |
0xF0000000 | SHF_MASKPROC | Reserved for the processor, including 0x40000000 SHF_ORDERED and 0x80000000 SHF_EXCLUDE (glibc, Solaris) |
sh_link and sh_info
| sh_type | sh_link | sh_info |
|---|---|---|
SHT_DYNAMIC | The string table its entries use | 0 |
SHT_HASH | The symbol table it hashes | 0 |
SHT_REL, SHT_RELA | The symbol table | The section the relocations apply to |
SHT_SYMTAB, SHT_DYNSYM | The string table | One more than the index of the last local symbol |
SHT_GROUP | The symbol table | Index of the symbol whose name is the group’s signature |
SHT_SYMTAB_SHNDX | The symbol table | 0 |
String tables
A string table is a series of zero-terminated strings, referred to by byte offset.
Its first byte (offset 0) and its last byte are zero; offset 0 means no name. An empty
table has sh_size 0. An offset may point into the middle of a string, so
strings can be shared.
Section groups
A SHT_GROUP section is an array of Words: a flags word,
then the section header indexes of its members, each of which has
SHF_GROUP set.
| Value | Name | Meaning |
|---|---|---|
0x1 | GRP_COMDAT | A COMDAT group: if several files have a group with the same signature, the linker keeps one |
0x0FF00000 | GRP_MASKOS | Reserved for the OS |
0xF0000000 | GRP_MASKPROC | Reserved for the processor |
Compressed sections
A section with SHF_COMPRESSED starts with a compression header, then
the compressed data. Relocations refer to offsets in the uncompressed data.
| Offset 32 | Offset 64 | Type 32 / 64 | Field | Meaning |
|---|---|---|---|---|
0x00 | 0x00 | Word | ch_type | Compression algorithm, below. |
| — | 0x04 | — / Word | ch_reserved | 64-bit files only. |
0x04 | 0x08 | Word / Xword | ch_size | Size of the uncompressed data. |
0x08 | 0x10 | Word / Xword | ch_addralign | Alignment of the uncompressed data. |
| Value | Name | Algorithm |
|---|---|---|
1 | ELFCOMPRESS_ZLIB | zlib |
2 | ELFCOMPRESS_ZSTD | Zstandard (glibc; not in the gABI page read) |
0x60000000–0x6FFFFFFF | ELFCOMPRESS_LOOS–HIOS | Operating-system-specific |
0x70000000–0x7FFFFFFF | ELFCOMPRESS_LOPROC–HIPROC | Processor-specific |
Special sections
Section names the gABI reserves, with their types and flags.
| Name | Type | Flags |
|---|---|---|
.bss | SHT_NOBITS | ALLOC + WRITE |
.comment | SHT_PROGBITS | none |
.data, .data1 | SHT_PROGBITS | ALLOC + WRITE |
.debug | SHT_PROGBITS | none; names starting .debug are reserved |
.dynamic | SHT_DYNAMIC | ALLOC; WRITE is processor-specific |
.dynstr | SHT_STRTAB | ALLOC |
.dynsym | SHT_DYNSYM | ALLOC |
.fini | SHT_PROGBITS | ALLOC + EXECINSTR |
.fini_array | SHT_FINI_ARRAY | ALLOC + WRITE |
.got | SHT_PROGBITS | processor-specific |
.hash | SHT_HASH | ALLOC |
.init | SHT_PROGBITS | ALLOC + EXECINSTR |
.init_array | SHT_INIT_ARRAY | ALLOC + WRITE |
.interp | SHT_PROGBITS | ALLOC if in a loadable segment |
.line | SHT_PROGBITS | none |
.note | SHT_NOTE | none |
.plt | SHT_PROGBITS | processor-specific |
.preinit_array | SHT_PREINIT_ARRAY | ALLOC + WRITE |
.relname, .relaname | SHT_REL, SHT_RELA | ALLOC if in a loadable segment; name is the section relocated |
.rodata, .rodata1 | SHT_PROGBITS | ALLOC |
.shstrtab | SHT_STRTAB | none |
.strtab | SHT_STRTAB | ALLOC if in a loadable segment |
.symtab | SHT_SYMTAB | ALLOC if in a loadable segment |
.symtab_shndx | SHT_SYMTAB_SHNDX | ALLOC if its symbol table is |
.tbss | SHT_NOBITS | ALLOC + WRITE + TLS |
.tdata, .tdata1 | SHT_PROGBITS | ALLOC + WRITE + TLS |
.text | SHT_PROGBITS | ALLOC + EXECINSTR |
The gABI also names older processor-specific sections (.sdata,
.tdesc, .sbss, .lit4, .lit8,
.reginfo, .gptab, .liblist,
.conflict). Linux’s elf(5) adds .gnu.version,
.gnu.version_d, .gnu.version_r, .note.ABI-tag,
.note.gnu.build-id, .note.GNU-stack,
.note.openbsd.ident, .ctors and .dtors.
Sources
- gABI chapter 4: Sections – section header, index 0, special indexes, types 0–18, flags, sh_link/sh_info, layout rules, groups, compression, special sections
- gABI chapter 4: String Table
- glibc elf.h –
SHT_RELR, GNU and Sun section types,SHT_X86_64_UNWIND,SHF_GNU_RETAIN,SHF_ORDERED,SHF_EXCLUDE,ELFCOMPRESS_ZSTD,SHN_BEFORE/SHN_AFTER - elf(5) – GNU special sections and the
PN_XNUMrule