Oracle® Solaris 11.2 链接程序和库指南

退出打印视图

更新时间: 2014 年 7 月
 
 

程序装入(特定于处理器)

系统创建或扩充进程映像时,系统会以逻辑方式将文件的段复制到虚拟内存段。系统以物理方式读取文件的时间和可能性取决于程序的执行行为、系统负载等。

除非进程在执行过程中引用了逻辑页,否则进程不需要物理页。进程通常会保留许多页面不对其进行引用。因此,延迟物理读取可以提高系统性能。要实际达到这种效率,可执行文件和共享目标文件必须具有文件偏移和虚拟地址同余(以页面大小为模数)的段映像。

32 位段的虚拟地址和文件偏移对模数 64 K (0x10000) 同余。64 位段的虚拟地址和文件偏移对模数 1 MB (0x100000) 同余。通过将各段与最大页面大小对齐,无论物理页大小如何,文件都适合进行分页。

缺省情况下,64 位 SPARC 程序与 0x100000000 的起始地址链接。整个程序位于 4 GB 以上的地址空间内,包括其文本、数据、堆、栈和共享目标文件依赖项。这有助于确保 64 位程序正确,因为如果程序截断其任何指针,则程序在其最低有效的 4 GB 地址空间中将出现错误。尽管 64 位程序在 4 GB 以上的地址空间内进行链接,但您仍可以使用 mapfile 和链接编辑器的 –M 选项,链接 4 GB 以下的地址空间内的程序。请参见 /usr/lib/ld/sparcv9/map.below4G

下图显示了 SPARC 版本的可执行文件。

图 13-1  SPARC: 可执行文件(64 K 对齐)

image:SPARC 可执行文件布局示例。

下表定义了上图中可装入段的各元素。

表 13-4  SPARC: ELF 程序头段(64 K 对齐)
成员
文本
数据
p_type
PT_LOAD
PT_LOAD
p_offset
0x0
0x4000
p_vaddr
0x10000
0x24000
p_paddr
未指定
未指定
p_filesize
0x3a82
0x4f5
p_memsz
0x3a82
0x10a4
p_flags
PF_R + PF_X
PF_R + PF_W + PF_X
p_align
0x10000
0x10000

下图显示了 x86 版本的可执行文件。

图 13-2  32-bit x86: 可执行文件(64 K 对齐)

image:x86 可执行文件布局示例。

下表定义了上图中可装入段的各元素。

表 13-5  32-bit x86: ELF 程序头段(64 K 对齐)
成员
文本
数据
p_type
PT_LOAD
PT_LOAD
p_offset
0x0
0x4000
p_vaddr
0x8050000
0x8064000
p_paddr
未指定
未指定
p_filesize
0x32fd
0x3a0
p_memsz
0x32fd
0xdc4
p_flags
PF_R + PF_X
PF_R + PF_W + PF_X
p_align
0x10000
0x10000

此示例的文件偏移和虚拟地址以文本和数据的最大页面大小为模数同余。根据页面大小和文件系统块大小,最多可有四个文件页包含混合文本或数据。

  • 第一个文本页包含 ELF 头、程序头表和其他信息。

  • 最后一个文本页包含数据起始部分的副本。

  • 第一个数据页包含文本结尾的副本。

  • 最后一个数据页可以包含与运行的进程无关的文件信息。从逻辑上而言,系统会强制执行内存权限,如同每个段是完整而独立的一样。为确保地址空间中的每个逻辑页都具有单独一组权限,各段的地址会进行调整。在前面的示例中,包含文本结尾和数据起始部分的文件区域映射了两次:一次映射到文本的虚拟地址,另一次映射到数据的与之不同的虚拟地址。


注 - 前面的示例反映了对文本段取整的典型的 Oracle Solaris OS 二进制文件。

数据段结尾要求对未初始化的数据进行特殊处理,系统将其定义为从零值开始。如果文件的最后一个数据页包含不属于逻辑内存页的信息,则必须将无关数据设置为零,而不是设置为可执行文件的未知内容。

其他三页中的混合内容逻辑上不是进程映像的一部分。没有指定系统是否会清除这些混合内容。以下各图中显示了此程序的内存映像,假定页面大小为 4 KB (0x1000)。为简单起见,这些图仅对一种页面大小进行说明。

图 13-3  32-bit SPARC: 进程映像段

image:SPARC 进程映像段示例。

图 13-4  x86: 进程映像段

image:x86 进程映像段示例。

可执行文件和共享目标文件在段装入的某个方面有所不同。可执行文件段通常包含绝对代码。为使进程正确执行,段必须位于用于创建可执行文件的虚拟地址处。系统会使用未更改的 p_vaddr 值作为虚拟地址。

另一方面,共享目标文件段通常包含与位置无关的代码。使用此代码,段的虚拟地址在不同进程之间会进行更改,而不会使执行行为无效。

尽管系统会为各个进程选择虚拟地址,但仍会保持各段之间的相对位置。由于与位置无关的代码在各段之间使用相对地址,因此内存中虚拟地址之间的差值必须与文件中虚拟地址之间的差值匹配。

以下各表显示针对多个进程可能指定的共享目标文件虚拟地址,从而说明了固定的相对位置。此外,这些表中还包括基本地址计算。

表 13-6  32-bit SPARC: ELF 共享目标文件段地址示例
来源
文本
数据
基本地址
文件
0x0
0x4000
0x0
进程 1
0xc0000000
0xc0024000
0xc0000000
进程 2
0xc0010000
0xc0034000
0xc0010000
进程 3
0xd0020000
0xd0024000
0xd0020000
进程 4
0xd0030000
0xd0034000
0xd0030000
表 13-7  32-bit x86: ELF 共享目标文件段地址示例
来源
文本
数据
基本地址
文件
0x0
0x4000
0x0
进程 1
0x8000000
0x8004000
0x80000000
进程 2
0x80081000
0x80085000
0x80081000
进程 3
0x900c0000
0x900c4000
0x900c0000
进程 4
0x900c6000
0x900ca000
0x900c6000