Program Loading (Processor-Specific)

As the system creates or augments a process image, the system 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 the process references the logical page during execution. Processes commonly leave many pages unreferenced. Therefore, delaying physical reads can improve system performance. To obtain this efficiency in practice, dynamic objects 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 Mbyte (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 located 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 the program truncates any of its pointers. While 64-bit programs are linked above 4 gigabytes, you can still link programs below 4 gigabytes by using a mapfile and the -M option to the link-editor. See /usr/lib/ld/sparcv9/map.below4G.

The following figure presents the SPARC version of the dynamic executable.

SPARC: Dynamic Executable File (64K alignment)


SPARC dynamic executable file layout example.

The following table defines the loadable segment elements for the previous figure.

Table 15-4 SPARC: ELF Program Header Segments (64K alignment)

Member Text Data

p_type

PT_LOAD

PT_LOAD

p_offset

0x0

0x4000

p_vaddr

0x10000

0x24000

p_paddr

Unspecified

Unspecified

p_filesize

0x3a82

0x4f5

p_memsz

0x3a82

0x10a4

p_flags

PF_R + PF_X

PF_R + PF_W + PF_X

p_align

0x10000

0x10000

The following figure presents the x86 version of the dynamic executable.

32-bit x86: Dynamic Executable File (64K alignment)


x86 dynamic executable layout example.

The following table defines the loadable segment elements for the previous figure.

Table 15-5 32-bit x86: ELF Program Header Segments (64K alignment)

Member Text Data

p_type

PT_LOAD

PT_LOAD

p_offset

0x0

0x4000

p_vaddr

0x8050000

0x8064000

p_paddr

Unspecified

Unspecified

p_filesize

0x32fd

0x3a0

p_memsz

0x32fd

0xdc4

p_flags

PF_R + PF_X

PF_R + PF_W + PF_X

p_align

0x10000

0x10000

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.

  • The first text page contains the ELF header, the program header table, and other information.

  • The last text page holds a copy of the beginning of data.

  • The first data page has a copy of the end of text.

  • The last data page can contain file information not relevant to the running process. Logically, the system enforces the memory permissions as if each segment were complete and separate The segments addresses are adjusted to ensure that each logical page in the address space has a single set of permissions. In the previous examples, the region of the file holding the end of text and the beginning of data is mapped twice: at one virtual address for text and at a different virtual address for data.

Note:

The previous examples reflect typical Oracle Solaris OS binaries that have their text segments rounded.

The end of the data segment requires special handling for uninitialized data, which the system defines to begin with zero values. If a file's last data page includes information not in the logical memory page, the extraneous data must be set to zero, not the unknown contents of the executable file.

Impurities in the other three pages are not logically part of the process image. Whether the system expunges these impurities is unspecified. The memory image for this program is shown in the following figures, assuming 4 Kbyte (0x1000) pages. For simplicity, these figures illustrate only one page size.

32-bit SPARC: Process Image Segments


SPARC process image segments example.

x86: Process Image Segments


x86 process image segments example.

One aspect of segment loading differs between dynamic executables and position-independent executables and shared objects. Dynamic executable segments typically contain absolute code. For the process to execute correctly, the segments must reside at the virtual addresses used to create the executable file. The system uses the p_vaddr values unchanged as virtual addresses.

On the other hand, position-independent executables and shared object segments typically contain position-independent code. This code enables a segment's virtual address change between different processes, without invalidating execution behavior.

Though the system chooses virtual addresses for individual processes, it maintains the relative positions of the segments. Because position-independent code uses relative addressing between segments, the difference between virtual addresses in memory must match the difference between virtual addresses in the file.

The following tables show possible shared object virtual address assignments for several processes, illustrating constant relative positioning. The tables also include the base address computations.

Table 15-6 32-bit SPARC: ELF Example Shared Object Segment Addresses

Source Text Data Base Address

File

0x0

0x4000

0x0

Process 1

0xc0000000

0xc0024000

0xc0000000

Process 2

0xc0010000

0xc0034000

0xc0010000

Process 3

0xd0020000

0xd0024000

0xd0020000

Process 4

0xd0030000

0xd0034000

0xd0030000

Table 15-7 32-bit x86: ELF Example Shared Object Segment Addresses

Source Text Data Base Address

File

0x0

0x4000

0x0

Process 1

0x8000000

0x8004000

0x80000000

Process 2

0x80081000

0x80085000

0x80081000

Process 3

0x900c0000

0x900c4000

0x900c0000

Process 4

0x900c6000

0x900ca000

0x900c6000