![]() |
![]() |
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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 AddressExecutable 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 PermissionsA 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
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
For example, typical text segments have read and execute, but not write permissions. Data segments normally have read, write, and execute permissions. Segment ContentsAn object file segment consists of one or more sections, though this fact is transparent to the program header. Whether the file segment holds one or many sections also is immaterial to program loading. Nonetheless, various data must be present for program execution, dynamic linking, and so on. The diagrams below illustrate segment contents in general terms. The order and membership of sections within a segment can vary. Text segments contain read-only instructions and data. Data segments contain writable data and instructions. See Table 7-16 for a list of all special sections. A PT_DYNAMIC program header element points at the .dynamic section. The .got and .plt sections also hold information related to position-independent code and dynamic linking. The .plt can reside in a text or a data segment, depending on the processor. See Global Offset Table (Processor-Specific) and Procedure Linkage Table (Processor-Specific) for details. The .bss section has the type SHT_NOBITS. Although it occupies no space in the file, it contributes to the segment's memory image. Normally, these uninitialized data reside at the end of the segment, thereby making p_memsz larger than p_filesz in the associated program header element. Program Loading (Processor-Specific)As the system creates or augments a process image, it logically copies a file's segment to a virtual memory segment. When, and if, the system physically reads the file depends on the program's execution behavior, system load, and so forth. A process does not require a physical page unless it references the logical page during execution, and processes commonly leave many pages unreferenced. Therefore, delaying physical reads frequently obviates them, improving system performance. To obtain this efficiency in practice, executable and shared object files must have segment images whose file offsets and virtual addresses are congruent, modulo the page size. Virtual addresses and file offsets for 32-bit segments are congruent modulo 64K (0x10000). Virtual addresses and file offsets for 64-bit segments are congruent modulo 1 megabyte (0x100000). By aligning segments to the maximum page size, the files are suitable for paging regardless of physical page size. By default, 64-bit SPARC programs are linked with a starting address of 0x100000000. The whole program is above 4 gigabytes, including its text, data, heap, stack, and shared object dependencies. This helps ensure that 64-bit programs are correct because the program will fault in the least significant 4 gigabytes of its address space if it truncates any of its pointers. While 64-bit programs are linked above 4 gigabytes, you can still link them below 4 gigabytes by using a mapfile and the -M option to the compiler or link-editor. See /usr/lib/ld/sparcv9/map.below4G. The following figure presents the SPARC version of the executable file. Figure 7-8 SPARC: Executable File (64K alignment) ![]() The following table defines the loadable segment elements for the previous figure. Table 7-38 SPARC: ELF Program Header Segments (64K alignment)
The following figure presents the x86 version of the executable file. Figure 7-9 x86: Executable File (64K alignment) ![]() The following table defines the loadable segment elements for the previous figure. Table 7-39 x86: ELF Program Header Segments (64K alignment)
The example's file offsets and virtual addresses are congruent modulo the maximum page size for both text and data. Up to four file pages hold impure text or data depending on page size and file system block size.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||