0 参考资料
GNU-LD-v2.30-中文手册.pdf
GNU linker.pdf
1 前言
一个完整的编译工具链应该包含以下4个部分:
(1)编译器
(2)汇编器
(3)链接器
(4)lib库
在GNU工具链中,对应的是:
(1)编译器:GCC(GNU Compiler Collection,GNU编译器套件)
(2)汇编器:GAS(GNU Assembler,GNU汇编器)
(3)链接器:LD(GNU Linker,GNU链接器)
(4)lib库:glibc(GNU C Library,GNU C 库)
本文介绍GNU链接器(LD)链接器脚本中分区命令、输出分区、输入分区定义。
2 GNU链接器(LD):分区命令、输出分区、输入分区定义
2.1 分区命令
SECTIONS(分区)命令告诉链接器如何把输入分区映射到输出分区。
SECTIONS命令格式如下:
SECTIONS
{
sections-command
sections-command
…
}
sections-command可以是以下内容之一:
(1)ENTRY命令(设置入口点)
(2)符号赋值操作
(3)输出分区描述
(4)重叠描述
2.2 输出分区定义
输出分区的定义格式如下:
section [address] [(type)] :
[AT(lma)]
[ALIGN(section_align) | ALIGN_WITH_INPUT]
[SUBALIGN(subsection_align)]
[constraint]
{
output-section-command
output-section-command
…
} [>region] [AT>lma_region] [:phdr :phdr …] [=fillexp] [,]
一般来说,输出分区不会使用到这么多可选属性。
说明:
section:输出分区名称。分区名可以由任意字符组成,如果分区名包含特殊字符(如逗号)则必须使用双引号包围起来。/DISCARD/这个特别的输出分区名称可用来丢弃输入分区,任何被指定到名为/DISCARD/的输出分区的输入分区都不会包含到输出文件中。
address:可选。输出分区的VMA(虚拟内存地址),如果提供则会将输出分区运行地址分配到指定的存储空间。
>region:可选。输出分区分配的存储区域,如果输出分区被添加进存储region,则输出分区起始地址就是存储区域region中首个空闲地址。
output-section-command可以是以下命令中的一个:
(1)符号赋值
(2)输入分区描述
(3)直接包含的数据值
(4)一个特殊的输出分区关键字
AT>lma_region:可选。指定输出分区加载内存地址。
:phdr :phdr …:可选。将一个输出分区放到一个或多个段上(由PHDRS命令定义的段)
2.3 输入分区定义
输入分区是依赖输出分区而存在的,输出分区定义来告诉链接器将分区分配到哪个存储器,而输入分区定义则告诉链接器这个存储区域的分配细则。
一个输入分区定义由一个文件名和一个可选的分区名列表组成,例如想要包含所有.text段到输入分区,可以这样写:
*(.text)
以下是一个实例:
这里的是个通配符,它会匹配所有符合要求的文件。
关于通配符的用法如下:
‘’:匹配任何个数的字符
‘?’:匹配任何单个字符
‘[chars]’:匹配chars中的任何一个字符,'-'可以用来表示一个范围内的字符,例如[a-z]
‘’:引用后面的字符
例如,想要包含所有的.text段,则需要可以写*(.text),包含所有的.data段和.bss段则可以写*(.data)、*(.bss)
如果想从通配符匹配的文件中排查某个文件,可以使用EXCLUDE_FILE,例子如下:
EXCLUDE_FILE (*crtend.o *otherfile.o) *(.ctors)
这个例子会将除 crtend.o 和 otherfile.o 之外所有文件中的.ctors 段包含到输入分区。
下面是一个更复杂的使用通配符的例子:
SECTIONS {
.text : { *(.text) }
.DATA : { [A-Z]*(.data) }
.data : { *(.data) }
.bss : { *(.bss) }
}
此链接器脚本最终会将所有的.text段放到.text输出分区,将所有大写字母开头的文件中的.data段放到.DATA输出分区,将其它所有非大写字母开头文件中的.data段放入.data输出分区,将所有的.bss段放到.bss输出分区。
2.4 一个简单的分区、输出分区、输入分区定义
SECTIONS
{
. = 0x10000;
.text : { *(.text) }
. = 0x8000000;
.data : { *(.data) }
.bss : { *(.bss) }
}
解析如下: