LOAD_SEGMENT / NOTE_SEGMENT / NULL_SEGMENT 指令
SIZE_SYMBOL 属性(仅限 LOAD_SEGMENT)
SYMBOL_SCOPE / SYMBOL_VERSION 指令
下面是用户定义的 mapfile 示例。示例中左边的编号用于教学演示。实际上只有编号右边的信息会出现在 mapfile 中。
此示例说明如何定义段并为其指定输入节。
示例 10-1 基本节到段的分配
1 $mapfile_version 2 2 LOAD_SEGMENT elephant { 3 ASSIGN_SECTION { 4 IS_NAME=.data; 5 FILE_PATH=peanuts.o; 6 }; 7 ASSIGN_SECTION { 8 IS_NAME=.data; 9 FILE_OBJNAME=popcorn.o; 10 }; 11 }; 12 13 LOAD_SEGMENT monkey { 14 VADDR=0x80000000; 15 MAX_SIZE=0x4000; 16 ASSIGN_SECTION { 17 TYPE=progbits; 18 FLAGS=ALLOC EXECUTE; 19 }; 20 ASSIGN_SECTION { 21 IS_NAME=.data 22 }; 23 }; 24 25 LOAD_SEGMENT donkey { 26 FLAGS=READ EXECUTE; 27 ALIGN=0x1000; 28 ASSIGN_SECTION { 29 IS_NAME=.data; 30 }; 31 }; 32 33 LOAD_SEGMENT text { 34 VADDR=0x80008000 35 };
在此示例中处理四个单独的段。每个 mapfile 都以一个 $mapfile_version 声明开始,如行 1 所示。段 elephant(行 2-11)接收来自文件 peanuts.o 或 popcorn.o 的所有数据节。目标文件 popcorn.o 可以来自归档文件,这时归档文件可以具有任意名称。或者,popcorn.o 可以来自具有根基名称 popcorn.o 的任意文件。与此相反,peanuts.o 只能来自具有该确切名称的文件。例如,提供给链接编辑的文件 /var/tmp/peanuts.o 与 peanuts.o 并不匹配。
段 monkey(行 13-23)具有一个虚拟地址 0x80000000 和最大长度 0x4000。此段接收类型为 PROGBITS 且可分配、可执行的所有节,以及尚未在段 elephant 中的名为 .data 的所有节。进入 monkey 段的 .data 节不需要是 PROGBITS 或是可分配、可执行的,因为它们与第 20 行而不是第 16 行上的入口条件相匹配。这表明 ASSIGN_SECTION 属性中的子属性之间存在 and(与)关系,而单个段的不同 ASSIGN_SECTION 属性之间存在 or(或)关系。
donkey 段(行 25-31)指定了非缺省权限标志和对齐方式,并将接受名为 .data 的所有节。但是,此段不会指定任何节,因此,段 donkey 永远不会出现在输出目标文件中。其原因是链接编辑器按照入口条件在 mapfile 中出现的顺序对其进行检查。在此 mapfile 中,段 elephant 接受某些 .data 节,段 monkey 接受其余的所有节,而没有为 donkey 留下任何节。
行 33-35 将 text 段的虚拟地址设置为 0x80008000。text 段是其中一种标准预定义段,如预定义段中所述,因此该语句将修改现有段,而不是创建一个新段。
以下 mapfile 示例将处理预定义的 text 和 data 段、头选项以及排序段中的节。
示例 10-2 预定义节的处理和节到段的分配
1 $mapfile_version 2 2 HDR_NOALLOC; 3 4 LOAD_SEGMENT text { 5 VADDR=0xf0004000; 6 FLAGS=READ EXECUTE; 7 OS_ORDER=.text .rodata; 9 ASSIGN_SECTION { 10 TYPE=PROGBITS; 11 FLAGS=ALLOC !WRITE; 12 }; 13 }; 14 15 LOAD_SEGMENT data { 16 FLAGS=READ WRITE EXECUTE; 17 ALIGN=0x1000; 18 ROUND=0x1000; 19 };
与往常一样,第一行声明要使用的 mapfile 语言版本。HDR_NOALLOC 指令(行 2)指定所获得的目标文件不应在目标文件的第一个可分配段中包含 ELF 头或程序头数组,该段是预定义的 text 段。
行 4-13 中的段指令为 text 段设置虚拟地址和权限标志。该指令还指定名为 .text 的节应放在段的开头,后跟任何名为 .rodata 的节,再后面是所有其他节。最后将可分配、非可写的 PROGBITS 节指定给该段。
行 15-19 中的段指令指定 data 段必须在边界 0x1000 上对齐。其效果是以相同的对齐方式对齐段中的第一个节。段的长度将向上舍入为与对齐方式相同的值的倍数。段权限设置为读取、写入和执行。