链接程序和库指南

映射示例

以下示例是用户定义的 mapfile。示例中左边的号码用于教学演示。实际上只有号码右边的信息会出现在 mapfile 中。


示例 9–1 用户定义的 Mapfile

    1.  elephant : .data : peanuts.o *popcorn.o; 

    2.  monkey : $PROGBITS ?AX; 

    3.  monkey : .data; 

    4.  monkey = LOAD V0x80000000 L0x4000; 

    5.  donkey : .data; 

    6.  donkey = ?RX A0x1000; 

    7.  text = V0x80008000;

在此示例中处理四个单独的段。隐式声明的段 elephant(第 1 行)从文件 peanuts.opopcorn.o 中接收所有 .data 节。请注意,*popcorn.o 与可以提供给链接编辑的任何 popcorn.o 文件相匹配。该文件无需位于当前目录中。另一方面,如果将 /var/tmp/peanuts.o 提供给链接编辑,则不会与 peanuts.o 相匹配,因为它没有前缀 *

隐式声明的段 monkey(第 2 行)接收既有 $PROGBITS 属性又有可分配且可执行属性 (?AX) 的节,同时还接收所有尚未存在于段 elephant 中且名为 .data(第 3 行)的节。进入 monkey 段的 .data 节无需是 $PROGBITS 节或可分配且可执行的节,因为输入 section_typesection_flags 值的行与 section_name 值所在的行不是同一个行。

如第 2 行的 $PROGBITS“与” ?AX 所示,相同行中的属性之间存在“与”关系。如第 2 行的 $PROGBITS ?AX“或”第 3 行的 .data 所示,相同段不同行的属性之间存在“或”关系。

monkey 段在第 2 行中隐式声明为:segment_type 值为 LOADsegment_flags 值为 RWX,未指定 virtual_addressphysical_addresslengthalignment 值(使用缺省值)。在第 4 行中,monkeysegment_type 值设置为 LOAD。由于 segment_type 属性值未发生更改,因此不会发出任何警告。virtual_address 值设置为 0x80000000 并且最大 length 值设置为 0x4000

第 5 行隐式声明 donkey 段。入口条件指定为将所有 .data 节路由到此段。实际上,没有任何节进入此段,因为第 3 行中 monkey 的入口条件会捕获所有这些节。在第 6 行中,segment_flags 值设置为 ?RX 并且 alignment 值设置为 0x1000。由于这两个属性值都发生了更改,因此会发出警告。

第 7 行将文本段的 virtual_address 值设置为 0x80008000

为了进行说明,用户定义的 mapfile 示例设计为会发出警告。如果要更改指令的顺序以避免发出警告,请使用以下示例:

    1.  elephant : .data : peanuts.o *popcorn.o; 

    4.  monkey = LOAD V0x80000000 L0x4000; 

    2.  monkey : $PROGBITS ?AX; 

    3.  monkey : .data; 

    6.  donkey = ?RX A0x1000; 

    5.  donkey : .data; 

    7.  text = V0x80008000;

以下 mapfile 示例使用段内节的排序:

    1.  text = LOAD ?RXN V0xf0004000; 

    2.  text | .text; 

    3.  text | .rodata; 

    4.  text : $PROGBITS ?A!W; 

    5.  data = LOAD ?RWX R0x1000;

此示例中处理了 textdata 段。第 1 行声明 text 段的 virtual_address0xf0004000,并且没有将 ELF 头或任何程序头作为此段的地址计算的一部分包括在内。第 2 行和第 3 行启用段内节排序,并指定 .text.rodata 节是此段中的前两个节。结果是 .text 节的虚拟地址为 0xf0004000,并且 .rodata 节紧跟该地址之后。

构成 text 段的任何其他 $PROGBITS 节位于 .rodata 节之后。第 5 行声明 data 段并指定其虚拟地址必须从 0x1000 字节边界开始。构成 data 段的第一个节还驻留在文件映像内的 0x1000 字节边界上。