This is a follow up post of the Part 1 An Intro to ELF File Format.
We’ve seen the section headers in section header table above, now we discuss sections in detail.
Below are a list of commonly seen section types. (Note that this is not a complete list)
- NULL: this marks the section header as inactive. It does not have an associated section.
- PROGBITS: program content, including code, data, debugging info etc.
- SYMTAB and DYNSYM: the section holds a symbol table. SYMTAB provides symbols for link editing and dynamic linking. DYNSYM holds only a minimal set of dynamic linking symbols.
- STRTAB: holds a string table.
- RELA: relocation entries with explicit addends.
- REL: relocation entries without explicit addends.
- DYNAMIC: information for dynamic linking.
- HASH: holds a symbol hash table for looking up the symbol in a ELF file quickly.
- NOTE: information that marks the file.
- NOBITS: like PROGBITS, but without occupying space in the file. Used for BSS data allocated at program load time.
We can see the section type from the section header screenshots above. For example, the .interp is a section of type PROGBITS.
Sections also have flags associated with them. Below is a list of commonly seen flags.
- WRITE (W): the section contains data that is writable when loaded.
- ALLOC (A): the section occupies memory when the program is loaded.
- EXECINSTR (X): the section contains executable machine code.
- MERGE (M): the data in the section may be merged to eliminate duplication.
- STRINGS (S): the data in the section contain null-terminated character strings.
Below is a list of commonly seen sections.
|.bss||NOBITS||ALLOC and WRITE||holds uninitialized data. The system initializes the data with zeros before the program starts to run.|
|.comment||PROGBITS||MERGE and STRINGS||some remarks about the file|
|.data||PROGBITS||ALLOC and WRITE||holds initialized data.|
|.debug||PROGBITS||holds information for symbolic debugging|
|.dynamic||DYNAMIC||ALLOC (WRITE, processor specific)||holds dynamic linking info.|
|.dynstr||STRTAB||ALLOC||strings needed by dynamic linking, most commonly the names associated with dynamic linking symbol table entries|
|.dynsym||DYNSYM||ALLOC||symbol table for dynamic linking|
|.fini||PROGBITS||ALLOC and EXEC||process termination code|
|.got||PROGBITS||ALLOC and WRITE||Global Offset Table (GOT).|
|.hash||HASH||ALLOC||symbol hash table|
|.init||PROGBITS||ALLOC and EXEC||process initialization code|
|.interp||PROGBITS||ALLOC on if file has a loadable segment that includes relocation||path name of a program interpreter.|
|.plt||PROGBITS||ALLOC and EXEC||Procedure Linkage Table (PLT)|
|.rel<name>||REL||ALLOC on if file has a loadable segment that includes relocation||relocation info, <name> indicates the section to which the relocations apply|
|.rela<name>||RELA||ALLOC on if file has a loadable segment that includes relocation||relocation info, <name> indicates the section to which the relocations apply|
|.strtab||STRTAB||ALLOC on if the file has a loadable segment that includes the symbol string table||strings. Most commonly the strings that represent the names associated with symbol table entries.|
|.symtab||SYMTAB||ALLOC on if file has a loadable segment that includes the symbol table||symbol table.|
|.text||PROGBITS||ALLOC and EXEC||executable code of a program|
Executable and shared object ELF files statically represent programs. A system needs to use these files to create dynamic representation (process image) in order to execute the program. A process image consists of segments which holds text, data ,stack etc created from the segments in ELF files.
We can get various information about segments of ELF file from its program headers. Below is a screenshot of program headers in test executable file.
$ readelf -l test
Each record has several fields.
- Type: the segment type.
- Offset: the location of the first byte of the segment with respect to the beginning of the file
- VirtAddr: the virtual address of the first byte of the segment in memory
- PhysAddr: only make sure on systems where physical addressing is relevant.
- FileSiz: segment size in number of bytes in file image of the segment
- MemSiz: segment size in number of bytes in memory image of the segment.
- Flg: flags
- Align: memory alignment. Values 0 or 1 means no alignment is needed. Otherwise, VirtAddr%Align == Offset%Align
Below is a list of commonly seen segment types in ELF files.
- NULL: unused
- LOAD: a loadable segment.
- DYNAMIC: dynamic linking info
- INTERP: the segment specifies the path to an interpreter. If present, must proceed any loadable segment.
- NOTE: location and size of auxiliary info.
- PHDR: specifies the size and location of the program header itself, both in file image and memory image of the program.
A segment consists of one or more sections. The two most commonly seen segments are the text segment and the data segment (both are of LOAD type).
A text segment contains read-only instructions and data. It usually includes the following sections: .text, .rodata, .hash, .dynsym, .dynstr, .plt, .rel.got. In the screenshot above, the third entry (with LOAD type) is a text segment.
A data segment contains writable data and instructions. It usually includes the following sections: .data, .dynamic, .got, .bss. In the screenshot above, the fourth entry (with LOAD type) is a text segment.
1. System V Application Binary Interface, Apr 2001 http://refspecs.linuxbase.org/elf/gabi4+/contents.html
2. The ELF Object File Format: Introduction. 1995. http://www.linuxjournal.com/article/1059?page=0,0
3. The ELF Object File Format by Dissection. 1995. http://www.linuxjournal.com/article/1060