编译链接

1、链接

        通过链接器可以把一个或多个输入文件合成一个输出文件,输入文件可以是目标文件或链接脚本文件,输出文件可以是目标文件或可执行文件。

        目标文件或可执行文件都有固定的格式,例如在linux/unix操作系统中为elf格式,每个目标文件一般都由若干个sections和符号表组成。对于sections有时把输入文件内的section称为输入section(input section), 把输出文件内的section称为输出section(output sectin)。而每个section都至少包含名字和大小两个信息,大部分section还包含与它相关联的一块数据, 称为section contents(section内容),并且该section可以被标记为loadable(可加载的)或allocatable(可分配的),如果一个section不是“可加载的”或“可分配的”, 那么该section通常包含了调试信息。每个“可加载的”或“可分配的”输出section通常包含两个地址:VMA(virtual memory address虚拟内存地址或程序地址空间地址)和LMA(load memory address加载内存地址或进程地址空间地址)。对于符号表(SYMBOL TABLE),包含已定义的符号(对应全局变量和static变量和定义的函数的名字)和未定义符号(未定义的函数的名字和引用但没定义的符号)信息,各个符号的值对应该符号的地址。可以通过命令objdump -h查看目标文件各个section的头部信息,通过命令nm查看目标文件的符号列表,通过objdump -f命令查看目标文件的整体头部摘要信息。

2、链接脚本

        每一个链接过程都由链接脚本(linker script, 一般以lds作为文件的后缀名)控制. 链接脚本主要用于规定如何把输入文件内的section放入输出文件内, 并控制输出文件内各部分在程序地址空间内的布局。

        ld链接器有自己的默认脚本,可以通过命令ld --verbose查看,连接选项-r和-N可以影响默认的连接脚本,-T选项用以指定自己的链接脚本, 它将代替默认的连接脚本。你也可以使用<暗含的连接脚本>以增加自定义的链接命令.

  • 脚本格式

链接脚本由一系列命令组成, 每个命令由一个关键字(一般在其后紧跟相关参数)或一条对符号的赋值语句组成。 命令由分号‘;’分隔开。文件名或格式名内如果包含分号';'或其他分隔符, 则要用引号‘"’将名字全称引用起来。 否则无法处理含引号的文件名。/* */之间的是注释。

链接脚本的格式如下,它的的核心部分是段(Section)

SECTIONS{

...

secname    start    ALIGN(align)    (NOLOAD)    :    AT(ldadr)    {contents}    >region    :   phdr     =fill

...

}

说明:

secname 和 contents是必须的,前者用来命名这个段,后者用来确保代码中什么部分放在这个段中。

start 是这个端的重定位地址,也称为运行地址。如果代码中有位置有关指令,程序运行时,这个段必须放在这个地址上。

ALIGN(align):指定运行地址对齐要求

(NOLOAD):告诉加载器,运行的时候不用加载这个段,这个选项在有操作系统的情况下才有意义。

AT(ldadr):指定这个段的在编译出来的映像文件中的地址——加载地址(load address)。如果不使用这个选项,则加载地址等于运行地址。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值