请阅读【嵌入式开发学习必备专栏 之 ARM GCC 编译专栏】
文章目录
- .linkonce 段详细介绍
- GOT 全局偏移表
.linkonce 段详细介绍
.gnu.linkonce.t
是一个链接器区段,用于存放那些只需要链接一次的函数或者符号。区段名称后面通常跟着函数或者符号的名字。
关于linkonce
的概念,GCC文档给出的解释是:“某些情况下,编译器为了优化而生成的代码项,不必在每一个包含了相同代码的编译单元中都出现。编译器将这些代码项放在.linkonce
区段中,链接器在链接时只保留一份。”
linkonce
区段有几种类型:
.gnu.linkonce.b.*
(用于未初始化的全局变量);.gnu.linkonce.d.*
(用于已初始化的全局变量);.gnu.linkonce.r.*
(用于常量数据);.gnu.linkonce.t.*
(用于文本,也就是可执行代码)等。
例如,如果你有一个函数 foo
,GCC可能将其编译到.gnu.linkonce.t.foo
区段中,如果链接时发现其它对象文件也有.gnu.linkonce.t.foo
,那么链接器只会保留其中一份。
这主要用于C++中的inline
函数或模板函数,通常情况下,每一个使用到这些函数的源文件都会生成一份函数的实例,但是链接时只需要保留一份即可。这样可以减少目标文件的大小,提高链接效率。
GOT 全局偏移表
GOT,全称为全局偏移表(Global Offset Table),是用于实现动态链接的一种数据结构。它主要用于存储运行时的全局数据地址。
在ARM架构下,由于PC相对寻址的范围有限(一般只有4MB),所以对于大部分的全局变量或者函数,尤其是在大型程序中,其地址往往超出了这个范围,无法直接进行寻址。
这时候就需要GOT来解决这个问题。编译器和链接器会把这些全局数据的地址存储在一个特殊的表结构——GOT中,然后通过PC寄存器相对GOT的偏移来访问这些全局数据,从而突破了PC寻址的范围限制。
总的来说,在ARM GCC中,GOT的主要作用就是帮助实现程序的动态链接,使得程序可以在运行时正确地找到全局数据的地址。