复制迁移的目的是什么?

zhe*_*jin 5 linker gcc loader relocation dynamic-linking

背景:如果可执行文件具有在共享对象中定义的外部数据引用,则编译器将使用复制重定位并将副本放置在其 .bss 部分中。此站点详细介绍了复制重定位: http://www.shrubbery.net/solaris9ab/SUNWdev/LLM/p22.html#CHAPTER4-84604

然而,我的问题是:

是否可以像共享对象中的外部数据引用一样,通过GOT来实现?可执行文件可以通过其GOT条目间接访问该外部代码,并且该GOT条目可以在运行时填充该符号的真实地址。我不知道为什么GCC不这样实现。复制迁移有什么好处?

AnT*_*AnT 4

在 C 和 C++ 等语言中,具有静态存储持续时间的对象的地址符合地址常量的资格。这意味着从概念上讲,在语言级别,它们被视为在编译时它们的值是“已知的”。

当然,就本案而言,实际情况并非如此。为了反驳编译器-链接器-加载器组合必须实现动态机制,该机制将提供对地址常量的语言级概念的完全支持。直观上,基于完全运行时间接的基于 GOT 的机制比基于加载时重定位的机制离这个概念要远得多。

一方面,C语言被设计为一种不需要动态初始化具有静态存储持续时间的对象的语言,即从概念上讲,没有初始化启动代码,也没有与初始化顺序相关的问题。但在基于 GOT 的实现中,使用此类地址常量初始化全局变量将需要启动代码从 GOT 中提取实际值并将其放入变量中。同时,基于重定位的方法产生了这样的全局变量的完整幻觉:在没有任何启动代码的情况下以正确的值开始其生命周期。

如果您查看重定位机制提供的功能,您会发现它们与地址常量的 C 规范是同步的。[]例如,最终值可能涉及添加固定偏移量,其目的是充当 C和运算符的加载器端实现->,这在 C 地址常量表达式中是允许的。