Only appears in the executable.
Contains information of how the executable should be put into the process virtual memory.
The executable is generated from object files by the linker. The main jobs that the linker does are:
- determine which sections of the object files will go into which segments of the executable.In Binutils, this comes down to parsing a linker script, and dealing with a bunch of defaults.You can get the linker script used with
ld --verbose, and set a custom one with
- do relocation according to the
.rela.textsection. This depends on how the multiple sections are put into memory.
readelf -l hello_world.outgives:
On the ELF header,
e_phentsizetold us that there are 2 program headers, which start at
0x38bytes long each, so they are: and:
Structure represented http://www.sco.com/developers/gabi/2003-12-17/ch5.pheader.html:
Breakdown of the first one:
- 40 0:
01 00 00 00=
PT_LOAD: this is a regular segment that will get loaded in memory.
- 40 4:
05 00 00 00= execute and read permissions. No write: we cannot modify the text segment. A classic way to do this in C is with string literals: https://stackoverflow.com/a/30662565/895245 This allows kernels to do certain optimizations, like sharing the segment amongst processes.
- 40 8:
00TODO: what is this? Standard says:
This member gives the offset from the beginning of the file at which the first byte of the segment resides.But it looks like offsets from the beginning of segments, not file?
- 50 0:
00 00 40 00 00 00 00 00: initial virtual memory address to load this segment to
- 50 8:
00 00 40 00 00 00 00 00: unspecified effect. Intended for systems in which physical addressing matters. TODO example?
- 60 0:
d7 00 00 00 00 00 00 00: size that the segment occupies in memory. If smaller than
p_memsz, the OS fills it with zeroes to fit when loading the program. This is how BSS data is implemented to save space on executable files. i368 ABI says on
The bytes from the file are mapped to the beginning of the memory segment. If the segment’s memory size (p_memsz) is larger than the file size (p_filesz), the ‘‘extra’’ bytes are defined to hold the value 0 and to follow the segment’s initialized area. The file size may not be larger than the memory size.
- 60 8:
d7 00 00 00 00 00 00 00: size that the segment occupies in memory
- 70 0:
00 00 20 00 00 00 00 00: 0 or 1 mean no alignment required. TODO why is this required? Why not just use
p_addrdirectly, and get that right? Docs also say:
p_vaddr should equal p_offset, modulo p_align
The second segment (
.data) is analogous. TODO: why use offset
0x00000000006000d8? Why not just use
Then the:section of the
readelftells us that:
- 0 is the
.textsegment. Aha, so this is why it is executable, and not writable
- 1 is the
TODO where does this information come from? https://stackoverflow.com/questions/23018496/section-to-segment-mapping-in-elf-files