如何解决为什么有些重定位是 .text + addend 而不是符号名称 + addend?
为什么 ELF 文件中的一些重定位条目是 symbol name + addend
,而另一些是 section + addend
?我希望消除一些困惑,并对 ELF 有更深入的了解。以下是我的调查。
#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 举报,一经查实,本站将立刻删除。