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

问题描述 投票:4回答:2

关于AT (...)ld状态的this source指令:

AT ( ldadr ) The expression ldadr that follows the AT keyword specifies the load address of the section. The default (if you do not use the AT keyword) is to make the load address the same as the relocation address. This feature is designed to make it easy to build a ROM image.

我一直在搜索,但是没有清楚地定义“加载地址”和“重定位地址”的含义。

我知道,当目标文件链接在一起时,代码被“重定位”在该跳转地址中,以此类推,以指向组合的机器代码内的正确偏移量。那么“重定位地址”是节开始的结果目标代码中的偏移量吗?如果是这样,那么部分的“加载地址”怎么可能有所不同?

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

gcc linker ld
2个回答
1
投票

差异至关重要。重定位地址添加到本节中的所有重定位。因此,如果它与装入地址不同,则本节中的任何内容都无法正常工作-本节中的所有重定位都将解析为错误的值。

那么为什么我们需要这样的技术?没有太多的应用程序,但是假设(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);

然后使用它,因为它被加载

在这里很自然。此技术称为叠加。

我认为,例子很清楚。


0
投票

经过一些搜索,我找到了一个更好的答案:

© www.soinside.com 2019 - 2024. All rights reserved.