【问题标题】:Why doesn't Elf64 use Elf64_Rel for relocations on 64-bit x86?为什么 Elf64 不使用 Elf64_Rel 在 64 位 x86 上进行重定位?
【发布时间】:2021-08-25 18:46:38
【问题描述】:

https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-54839.html#chapter7-2 状态:

64 位 SPARC 和 64 位 x86 仅使用 Elf64_Rela 重定位条目。因此,r_addend 成员用作重定位加数。 x86 仅使用 Elf32_Rel 重定位条目。要重定位的字段包含加数。

存在一个Elf64_Rel 结构,那么为什么不在 64 位 x86 目标上使用它呢?不使用Elf64_Rela 只是在这里浪费空间,因为预重定位地址只是被忽略了(或者至少从我在测试中看到的总是0)?

注意:r_addendElf64_Rel 中被省略,而不是简单地未使用。

【问题讨论】:

    标签: x86 x86-64 elf relocation


    【解决方案1】:

    存在一个 Elf64_Rel 结构,为什么不在 64 位 x86 目标上使用它?

    x86_64 上,有几个可能的memory models。默认使用small memory model,不需要任何64位重定位。

    如果使用-mcmodel=large 编译,则将使用 64 位重定位

    【讨论】:

    • 你能解释一下为什么mov eax, [rel foo + 12] 不能在目标文件的机器代码中使用rel32 来保存+12,而是使用保留该元数据的重定位类型分别地?它是否试图处理像mov eax, [rel foo + huge_offset] 这样的情况,其中代码在数组末尾的范围内,但不在foo 符号本身的范围内,所以rel32 字段不够大?
    • @PeterCordes 据我所知,你是对的。汇编mov eax, [rel symbol + 0x1122334455667788]得到8b 05 00 00 00 00,反汇编成mov eax, dword [rip+0x0],重定位入口为2: symbol+0x1122334455667784,显然不能放入rel32。但是,汇编程序在可能的情况下却不这样做,这对我来说确实很奇怪。我觉得通过存储 Elf64_Rel 的列表和 Elf64_Rel 的单独列表可以节省一点空间。
    • @the4naves:是的。很少会链接符号+偏移量在范围内(对于 rel32 或 abs32)但符号不在范围内的可执行文件(或库)。这可能只会发生在将大数据部分放在.text 之前的链接器脚本中,并且可能使用利用symbol+2G 将在范围内的知识的手写asm,即使symbol 不能被认为是。 gcc -mcmodel=medium 只会假设任何大型数组都需要使用 64 位绝对地址来引用。
    猜你喜欢
    • 2011-11-11
    • 2015-04-03
    • 1970-01-01
    • 2011-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-22
    相关资源
    最近更新 更多