3.2 简单的链接脚本示例
很多链接脚本是相当简单的。
最简单的可能是链接脚本只有一条命令:‘SECTION’。可以使用’SECTION’命令描述输出文件的内存布局。
‘SECTION’命令是一个非常强大的命令。这里我们只描述简单的使用。我们需要假设你的程序只包括代码,初始化的数据和未初始化的数据。他们将被分别的放在’.text’, ‘.data’, ‘.bss’ 段中。假设在输入文件中只有这些段出现。
对于这个例子,我们假设代码从0x10000地址被加载,并且数据开始地址是0x8000000。下面的链接脚本实现这些功能:
SECTIONS
{
. = 0x10000;
.text : { *(.text) }
. = 0x8000000;
.data : { *(.data) }
.bss : { *(.bss) }
}
上面的脚本,SECTIONS是SECTIONS命令的关键字,后面的跟随着一些赋值符号和输出段描述,并且用花括号括起来。
在SECTIONS命令内部的第一行,给特殊的符号’.'设置一个值,这个特殊符号是位置计数器。如果没有使用其他方式对这个输出段指定地址(后面章节会描述这些方法),这个段的地址被设置成位置计数器的当前值。之后位置计数器会增加,增加的大小是段的大小。在SECTION命令的开始,位置计数器的值是0。
第二行定义了一个**.text**输出段。这个冒号是必须的,但是现在先忽略它。在输出段名的花括号中,列出除了输入段中可以放在输出段的段名(换句话说,就是输入文件的哪些段放在输出的.text段中)。这个 *
号是匹配任何文件的通配符。 *(.text)
表达式的含义是在所有输入文件中的所有*(.text)
段。第二行的意思就是说把所有输入文件中名为.text
的段放到输出文件的.text
段里面。
因为当输出段.text被定义时位置计数器的值为0x10000,所以链接器会将输出文件中.text
段的地址设置为0x10000。
其余行的意思是在输出文件中定义.data
和.bss
两个段。链接器放置.data
输出段在0x8000000地址处。放置.data
段后,位置计数器的值将变成0x8000000加上.data
段大小。其效果是,在内存中链接器将在.data
段后立即放置.bss
段。
如果有必要,链接器通过增加位置计数器的值来保证每个输出段必要的对齐。在这个例子中,对于.text
和.data
段的地址尽可能的满足了任何对齐约束,除此之外,链接器还可以在.data
和.bss
段之间创建小的间隙(保留空间)。
就是这样!这就是最简单的并且完整的链接脚本。