购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.1.6 ld的常用选项

链接器ld的常用选项如下:

(1)-o outfilename选项。该选项用于告知ld,链接完成后输出的文件名为outfilename。

(2)-L searchdir或者-library-path=searchdir选项。在设置该选项时,链接器会在默认路径或由“-L/-library-path=searchdir”指定的路径下查找库文件。

(3)-l namespec、-l:filename或-library=namespec选项。在生成可执行文件时,使用-l选项可链接指定的库文件。库文件名为libnamespec.so或libnamespec.a。若文件名前有“:”,则直接使用filename作为库文件名。-l与文件名之间的空格不是必需的。

(4)-dynamic-linker选项。该选项用于指定动态链接器的文件名。

(5)@file选项。该选项用于告知ld从该file文件读取命令行选项。例如:

文件linker.ld内容如下:

(6)-shared选项。该选项用于告知ld生成共享库文件。

(7)-M或-map<filename>选项。该选项用于输出与链接符号相关的map信息。例如:

(8)-z keyword选项。keyword主要包括:

①execstack:标记目标文件需要的栈是可执行的。

②noexecstack:标记目标文件不需要可执行的栈,即栈不可执行。

③lazy:当生成可执行文件或者共享库时,使用该关键字告知动态链接器不要在程序装载时确定函数地址,而是要延缓函数调用地址的确定,直到函数第一次调用时才确定被调用函数的实际地址。这一机制称为延迟绑定(Lazy Binding),系统默认使用延迟绑定机制。

④now:当生成可执行文件或者共享库时,使用该关键字告知动态链接器在启动可执行文件时或使用dlopen()函数打开共享库时确定所有符号的地址,而不是延缓确定函数的调用地址。

⑤relro:使用该关键字告知动态链接器在目标文件中生成ELF PT_GNU_RELRO段。

⑥norelro:使用该关键字告知动态链接器在目标文件中不生成ELF PT_GNU_RELRO段。

(9)-pie-pic-executable选项。使用该选项告知动态链接器需要生成与位置无关的可执行文件。

(10)-rpath dir选项。当链接ELF(可执行文件)与共享目标文件时,使用该选项可增加共享库搜索路径,此时链接器会使用-rpath提供的参数定位共享库。如果未使用-rpath,则使用环境变量LD_RUN_PATH定义的路径信息。

(11)-verbose选项。该选项用于显示ld的版本号,并列出支持的链接器,显示哪些输入文件能被打开、而哪些不能,显示链接器使用的默认链接脚本文件。例如:

(12)-T scriptFile选项。当链接器使用链接脚本文件控制多目标文件的节合并及其内存布局时,我们可以使用-T选项指定链接脚本文件进行链接,若不指定,则使用默认的链接脚本文件。选项-T将scriptFile当成链接脚本文件。链接脚本文件是按照AT&T链接命令语言语法编写的文本文件,用于控制链接操作。例如:

读者可以参考https://github.com/0xbigshaq/runtime-unpack/blob/master/src/linking_script.ld,命令行选项‘-r’或r‘-N’会影响默认的链接脚本文件。

链接脚本文件中需要用到的一些术语如下:

①可装载的节。标记为可装载Loadable(LOAD)的节表示当程序运行时,该节的内容应该被装载到内存。虽然没有内容的节可被分配空间,但装载时没有任何内容。既不是可装载的,也不是可分配空间的节一般包含调试信息。

②可分配的节。系统必须为标记为可分配Allocateable(ALLOC)的节分配空间。当该节又是可装载的节时,系统必须将该节的内容装载到分配的空间中。装载的过程一般由装载程序loader完成,loader有时也叫动态链接器,和程序链接器是同一个程序。这也是为什么我们也称链接器为ld。

③VMA(Virtual Memory Address,虚拟内存地址)和LMA(Load Memory Address,装载内存地址)。每个可被装载或分配的节都有两个地址:一个是VMA,该地址是程序运行时的节地址;另一个是LMA,该地址是程序装载时的节地址。在大多数情况下这两个地址是一样的,但下述情况时,这两个地址是不一样的:装载时,.data节被装载进ROM,而当程序开始运行时,.data节内容被复制到RAM,并初始化全局变量。在这种情况下,ROM地址即.data节的LMA,RAM地址即.data节的VMA。

我们可以用如下的脚本文件设置相关节的VMA和LMA,冒号“:”前的为VMA,冒号“:”后AT()内的为LMA。

或者

链接脚本文件示例如下。

基本的链接脚本文件示例如下:

其中,SECTIONS用于告知链接器怎样实现目标文件的节合并及放置。上述链接脚本文件的作用是:合并目标文件abc.o和def.o的.text节并生成输出文件的.text节。我们也可使用通配符实现链接脚本文件的简化。

使用通配符的链接脚本文件示例如下:

多个节使用通配符的链接脚本文件示例如下:

上述链接脚本文件的作用是将.text节放置在0x0处,将.data节放置在0x400处。若没有指定位置,则.text节和.data节紧邻放置。

三个节的链接脚本文件示例如下:

上述链接脚本文件的作用是将.text节放置在0x10000处,将.data节放置在0x8000000处,将.bss节紧邻着.data节放置。

完整的示例如下。该示例包含一个汇编文件hello.asm和一个链接脚本文件linker.script。汇编文件hello.asm的内容如下:

对应的链接脚本文件linker.script的内容如下:

执行如下的命令即可生成并运行可执行文件hello。

从上述运行结果可以看到,.text节被放置在0x200000处,.data节被放置在0x400000处。 xcYKJbQuJ0mxxF5Ql+5jxcQJLkctw1G5qXs9znOlA12Jv4lXmBzH3T6FCF7fOUsH

点击中间区域
呼出菜单
上一章
目录
下一章
×