微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么有些重定位是 .text + addend 而不是符号名称 + addend?

如何解决为什么有些重定位是 .text + addend 而不是符号名称 + addend?

为什么 ELF 文件中的一些重定位条目是 symbol name + addend,而另一些是 section + addend?我希望消除一些困惑,并对 ELF 有更深入的了解。以下是我的调查。

我有一个非常简单的 C 文件test.c

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>

static void func1(void)
{
    fprintf(stdout,"Inside func1\n");
}

// ... a couple other simple *static* functions

int main (void)
{
    func1();

    // ... call some other functions

    exit(EXIT_SUCCESS);
}

然后我将它编译成一个目标文件

clang -O0 -Wall -g -c test.c -o test.o

如果查看带有 readelf -r test.o 的重定位,我会看到引用我的静态函数的条目如下(该条目选自 .rela.debug_info 部分):

Offset            Info              Type         Symbol's Value    Symbol's Name + Addend
...
000000000000006f  0000000400000001  R_X86_64_64  0000000000000000 .text + b0
...

为什么将这些函数称为 section + addend 而不是 symbol name + addend?我看到 .symtab函数的条目使用 readelf -s test.o:

Num: Value            Size Type Bind  Vis     Ndx Name
  ...
  2: 00000000000000b0 31   FUNC LOCAL DEFAULT 2   func1
  ...

此外,当我反汇编目标文件时(通过 objdump -d),我看到函数在那里并且没有被优化为 main 或任何东西。

如果我不将函数设为静态然后查看重定位,当类型为 R_X86_64_64 时,我会看到与以前相同的内容,但我也会看到使用符号名称加上类型为 R_X86_64_PC32 的加数。例如在 .rela.text 中:

Offset            Info              Type           Symbol's Value    Symbol's Name + Addend
...
00000000000000fe  0000001200000002  R_X86_64_PC32  0000000000000000  func1 + 1c
...

如果更多示例/readelf 输出会有所帮助,请告诉我。感谢您抽出时间阅读本文。

解决方法

为什么这些函数被称为节+加数而不是符号名称+加数?

不能保证静态函数的函数名称在链接时出现。您可以使用例如删除它们 Option Explicit Sub LoopThroughFiles() Dim strFile As String,strPath As String,Num As Long,LR As Integer Dim lngStart,lngEnd As Long strPath = "M:\B\XML\" strFile = Dir(strPath & "*.xml") Num = 0 lngStart = 2 'considering row 1 has headers. if not change it to 1. While strFile <> "" ActiveWorkbook.XmlMaps("A").Import URL:= _ (strPath & strFile) strFile = Dir Num = Num + 1 lngEnd = Cells(Rows.Count,"AI").End(xlUp).Row Range("AI" & lngStart & ":AI" & lngEnd).Value = strFile lngStart = lngEnd + 1 Wend MsgBox "This code ran successfully for " & Num & " XML file(s)",vbInformation End Sub objcopy --strip-unneeded,结果仍将链接。

我看到 objcopy --strip-symbol 中函数的条目使用 .symtab

我相信保留它们的唯一原因是为了帮助调试,并且链接器根本不使用它们。但是我没有通过查看链接器源来验证这一点,所以没有回答这个 related question

,

Eli Bendersky 的博客也在 his blog post 中提到了这一点。来自标题为“额外功劳:为什么需要调用重新定位?”的部分:

简而言之,当 ml_util_func 是全局的时,它可能会在可执行文件或其他共享库中被覆盖,因此在链接我们的共享库时,链接器不能假设偏移量已知并对其进行硬编码 [12 ]。它使对全局符号的所有引用都可重定位,以允许动态加载器决定如何解析它们。这就是为什么将函数声明为 static 会有所不同 - 因为它不再是全局的或导出的,链接器可以在代码中对其偏移进行硬编码。

应该阅读完整的帖子以获得完整的上下文,但我想我会在这里分享它,因为它提供了比我的问题更好的例子,并加强了 Employed Russian 给出的解决方案。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。