Program Header
An executable or shared object file's program header table is an array of structures, each describing a segment or other information that the system needs to prepare the program for execution. An object file segment contains one or more sections, as described in "Segment Contents".
Program headers are meaningful only for executable and shared object files. A file specifies its own program header size with the ELF header's e_phentsize and e_phnum members..
A program header has the following structure, defined in sys/elf.h:
typedef struct { Elf32_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; Elf32_Word p_memsz; Elf32_Word p_flags; Elf32_Word p_align; } Elf32_Phdr; typedef struct { Elf64_Word p_type; Elf64_Word p_flags; Elf64_Off p_offset; Elf64_Addr p_vaddr; Elf64_Addr p_paddr; Elf64_Xword p_filesz; Elf64_Xword p_memsz; Elf64_Xword p_align; } Elf64_Phdr; |
The elements of this structure are:
- p_type
The kind of segment this array element describes or how to interpret the array element's information. Type values and their meanings are specified in Table 7-35.
- p_offset
The offset from the beginning of the file at which the first byte of the segment resides.
- p_vaddr
The virtual address at which the first byte of the segment resides in memory.
- p_paddr
The segment's physical address for systems in which physical addressing is relevant. Because the system ignores physical addressing for application programs, this member has unspecified contents for executable files and shared objects.
- p_filesz
The number of bytes in the file image of the segment, which can be zero.
- p_memsz
The number of bytes in the memory image of the segment, which can be zero.
- p_flags
Flags relevant to the segment. Type values and their meanings are specified in Table 7-36.
- p_align
Loadable process segments must have congruent values for p_vaddr and p_offset, modulo the page size. This member gives the value to which the segments are aligned in memory and in the file. Values 0 and 1 mean no alignment is required. Otherwise, p_align should be a positive, integral power of 2, and p_vaddr should equal p_offset, modulo p_align. See "Program Loading (Processor-Specific)".
Some entries describe process segments. Other entries give supplementary information and do not contribute to the process image. Segment entries can appear in any order, except as explicitly noted. Defined type values are listed in the following table.
Table 7-35 ELF Segment Types
Name | Value |
---|---|
PT_NULL | 0 |
PT_LOAD | 1 |
PT_DYNAMIC | 2 |
PT_INTERP | 3 |
PT_NOTE | 4 |
PT_SHLIB | 5 |
PT_PHDR | 6 |
PT_LOSUNW | 0x6ffffffa |
PT_SUNWBSS | 0x6ffffffb |
PT_SUNWSTACK | 0x6ffffffa |
PT_HISUNW | 0x6fffffff |
PT_LOPROC | 0x70000000 |
PT_HIPROC | 0x7fffffff |
- PT_NULL
Unused; other members' values are undefined. This type enables the program header table to contain ignored entries.
- PT_LOAD
Specifies a loadable segment, described by p_filesz and p_memsz. 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 can not be larger than the memory size. Loadable segment entries in the program header table appear in ascending order, sorted on the p_vaddr member.
- PT_DYNAMIC
Specifies dynamic linking information. See "Dynamic Section".
- PT_INTERP
Specifies the location and size of a null-terminated path name to invoke as an interpreter. This segment type is mandatory for dynamic executable files and can occur in shared objects. It cannot occur more than once in a file. This type, if present, it must precede any loadable segment entry. See "Program Interpreter" for further information.
- PT_NOTE
Specifies the location and size of auxiliary information. See "Note Section" for details.
- PT_SHLIB
Reserved but has unspecified semantics.
- PT_PHDR
Specifies the location and size of the program header table itself, both in the file and in the memory image of the program. This segment type cannot occur more than once in a file. Moreover, it can occur only if the program header table is part of the memory image of the program. This type, if present, must precede any loadable segment entry. See "Program Interpreter" for further information.
- PT_LOSUNW - PT_HISUNW
Values in this inclusive range are reserved for Sun-specific semantics.
- PT_SUNWBSS
The same attributes as a PT_LOAD element and used to describe a .SUNW_bss section.
- PT_SUNWSTACK
Describes a process stack. Presently only one such element may exist, and only access permissions, as defined in the p_flags field, are meaningful.
- PT_LOPROC - PT_HIPROC
Values in this inclusive range are reserved for processor-specific semantics.
Note - Unless specifically required elsewhere, all program header segment types are optional. A file's program header table can contain only those elements relevant to its contents.
Base Address
Executable and shared object files have a base address, which is the lowest virtual address associated with the memory image of the program's object file. One use of the base address is to relocate the memory image of the program during dynamic linking.
An executable or shared object file's base address is calculated during execution from three values: the memory load address, the maximum page size, and the lowest virtual address of a program's loadable segment. The virtual addresses in the program headers might not represent the actual virtual addresses of the program's memory image. See "Program Loading (Processor-Specific)".
To compute the base address, you determine the memory address associated with the lowest p_vaddr value for a PT_LOAD segment. You then obtain the base address by truncating the memory address to the nearest multiple of the maximum page size. Depending on the kind of file being loaded into memory, the memory address might not match the p_vaddr values.
Segment Permissions
A program to be loaded by the system must have at least one loadable segment, although this is not required by the file format. When the system creates loadable segment memory images, it gives access permissions, as specified in the p_flags member. All bits included in the PF_MASKPROC mask are reserved for processor-specific semantics.
Table 7-36 ELF Segment Flags
Name | Value | Meaning |
---|---|---|
PF_X | 0x1 | Execute |
PF_W | 0x2 | Write |
PF_R | 0x4 | Read |
PF_MASKPROC | 0xf0000000 | Unspecified |
If a permission bit is 0, that bit's type of access is denied. Actual memory permissions depend on the memory management unit, which can vary from one system to another. Although all flag combinations are valid, the system can grant more access than requested. In no case, however, will a segment have write permission unless it is specified explicitly. The following table lists both the exact flag interpretation and the allowable flag interpretation.
Table 7-37 ELF Segment Permissions
Flags | Value | Exact | Allowable |
---|---|---|---|
None | 0 | All access denied | All access denied |
PF_X | 1 | Execute only | Read, execute |
PF_W | 2 | Write only | Read, write, execute |
PF_W + PF_X | 3 | Write, execute | Read, write, execute |
PF_R | 4 | Read only | Read, execute |
PF_R + PF_X | 5 | Read, execute | Read, execute |
PF_R + PF_W | 6 | Read, write | Read, write, execute |
PF_R + PF_W + PF_X | 7 | Read, write, execute | Read, write, execute |
For example, typical text segments have read and execute, but not write permissions. Data segments normally have read, write, and execute permissions.