gcc – “加载地址”和“重定位地址”有什么区别?

关于ld的AT(…)指令,this source表示:

AT(ldadr)
AT关键字后面的表达式ldadr指定节的加载地址.默认(如果不使用AT关键字)是使加载地址与重定位地址相同.此功能旨在使构建ROM映像变得容易.

我一直在搜索,但没有找到“加载地址”和“重定位地址”的含义的明确定义.

我知道当目标文件链接在一起时,代码被“重新定位”,因为重写了跳转地址等,以指向组合机器代码中的正确偏移量.那么“重定位地址”是一个部分开始的结果对象代码中的偏移量?如果是这样,一个部分的“加载地址”怎么可能是不同的?

如果这两个地址不同,链接器的输出如何受到影响?

最佳答案
差异至关重要.重定位地址是对部分中所有重定位的加数.因此,如果它与加载地址不同,则本节中没有任何内容真正起作用 – 内部的所有重定位将被解析为错误的值.

那么为什么我们需要这样的技术呢?没有那么多的应用程序,但假设(from here)你在你的架构上有非常快的内存在0x1000

然后你可以采取两个部分来重定位地址0x1000:

.text0 0x1000 : AT (0x4000) { o1/*.o(.text) }
__load_start_text0 = LOADADDR (.text0);
__load_stop_text0 = LOADADDR (.text0) + SIZEOF (.text0);
.text1 0x1000 : AT (0x4000 + SIZEOF (.text0)) { o2/*.o(.text) }
__load_start_text1 = LOADADDR (.text1);
__load_stop_text1 = LOADADDR (.text1) + SIZEOF (.text1);
. = 0x1000 + MAX (SIZEOF (.text0), SIZEOF (.text1));

现在在运行时继续,当你需要text1时,自己管理它,从其实际加载地址复制到正确的地址:

extern char __load_start_text1, __load_stop_text1;
memcpy ((char *) 0x1000, &__load_start_text1,
      &__load_stop_text1 - &__load_start_text1);

然后使用它,因为它自然地加载到这里.这种技术称为叠加.

我想,例子很清楚.

转载注明原文:gcc – “加载地址”和“重定位地址”有什么区别? - 代码日志