"load address" 和 "relocation address" 有什么区别?

What is the difference between "load address" and "relocation address"?

关于 ldAT (...) 指令,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.

我一直在搜索,但没有找到 "load address" 和 "relocation address" 的明确定义。

我知道当目标文件链接在一起时,代码是 "relocated" 跳转地址等被重写以指向组合机器代码中的正确偏移量。那么 "relocation address" 是结果目标代码中一个部分开始的偏移量吗?如果是这样,一个部分的 "load address" 怎么可能有所不同?

如果这 2 个地址不同,链接器的输出会受到怎样的影响?

差异是至关重要的。重定位地址是段中所有重定位的加数。因此,如果它与加载地址不同,则该部分中的任何内容都不会真正起作用——该部分内的所有重定位都将被解析为错误的值。

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

然后使用它,因为它被加载在这里很自然。这种技术称为覆盖。

我想,例子已经很清楚了。

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

Every ... output section has two addresses. The first is the VMA, or virtual memory address. This is the address the section will have when the output file is run. The second is the LMA, or load memory address. This is the address at which the section will be loaded. In most cases the two addresses will be the same. An example of when they might be different is when a data section is loaded into ROM, and then copied into RAM when the program starts up (this technique is often used to initialize global variables in a ROM based system). In this case the ROM address would be the LMA, and the RAM address would be the VMA.

引自:https://www.sourceware.org/binutils/docs/ld/Basic-Script-Concepts.html#Basic-Script-Concepts

这意味着在像这样的部分声明中:

section [address] [(type)] :
  [AT(lma)]
  [ALIGN(section_align) | ALIGN_WITH_INPUT]
  [SUBALIGN(subsection_align)]
  [constraint]
  {
    output-section-command
    output-section-command
    …
  } [>region] [AT>lma_region] [:phdr :phdr …] [=fillexp]

[address] is the VMA and [AT(lma)] is the LMA.