An ELF file contains the following parts:
- ELF header. Points to the position of the section header table and the program header table.
- Section header table (optional on executable). Each has
e_shnum
section headers, each pointing to the position of a section. - N sections, with
N <= e_shnum
(optional on executable) - Program header table (only on executable). Each has
e_phnum
program headers, each pointing to the position of a segment. - N segments, with
N <= e_phnum
(only on executable)
The order of those parts is not fixed: the only fixed thing is the ELF header that must be the first thing on the file: Generic docs say:
Although the figure shows the program header table immediately after the ELF header, and the section header table following the sections, actual files may differ. Moreover, sections and segments have no specified order. Only the ELF header has a fixed position in the file.
In pictures: sample object file with three sections:
+-------------------+
| ELF header |---+
+---------> +-------------------+ | e_shoff
| | |<--+
| Section | Section header 0 |
| | |---+ sh_offset
| Header +-------------------+ |
| | Section header 1 |---|--+ sh_offset
| Table +-------------------+ | |
| | Section header 2 |---|--|--+
+---------> +-------------------+ | | |
| Section 0 |<--+ | |
+-------------------+ | | sh_offset
| Section 1 |<-----+ |
+-------------------+ |
| Section 2 |<--------+
+-------------------+
But nothing (except sanity) prevents the following topology:
+-------------------+
| ELF header |---+ e_shoff
+-------------------+ |
| Section 1 |<--|--+
+---------> +-------------------+ | |
| | |<--+ | sh_offset
| Section | Section header 0 | |
| | |------|---------+
| Header +-------------------+ | |
| | Section header 1 |------+ |
| Table +-------------------+ |
| | Section header 2 |---+ | sh_offset
+---------> +-------------------+ | sh_offset |
| Section 2 |<--+ |
+-------------------+ |
| Section 0 |<---------------+
+-------------------+
But some newbies may prefer PNGs :-)