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)链接器脚本的PROVIDE、PROVIDE_HIDDEN关键字。
2 GNU链接器(LD):PROVIDE、PROVIDE_HIDDEN关键字介绍
2.1 PROVIDE、PROVIDE_HIDDEN关键字
在某些情况下,链接器脚本想要实现类似于__weak关键字的功能,也就是没被链接过程中任何object文件定义且符号被引用时,符号定义才会生效。
举个例子,传统链接器定义了exext符号,而ANSI C需要把etext当做一个函数名使用且不报错。PROVIDE关键字就可以用来定义符号etext,只有当它被引用且ANSI C未定义才生效。语法如下:
PROVIDE(symbol = expression)
以下是一个使用 PROVIDE 定义 etext 的例子:
SECTIONS
{
.text :
{
*(.text)
_etext = .;
PROVIDE(etext = .);
}
}
在这个例子中,如果程序重定义了_etext(下划线开头),链接器会提示重定义错误(和链接脚本的_etext符号重复了)[实测并不会报告错误]。而如果程序定义etext(不以下划线开头),链接器会使用程序中的定义。如果引用了etext但没有定义它,链接器就会使用在链接器脚本中的定义。
PROVIDE_HIDDEN关键字功能和PROVIDE关键字类似。
实测即使重复定义也不会报告错误(可能新版链接器取消了这种情况下的报错):
链接脚本中的定义:
C中的定义:
编译没有报错: