【发布时间】:2021-07-08 14:33:40
【问题描述】:
为什么 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?我使用readelf -s test.o 看到.symtab 中的函数条目:
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 输出会有所帮助,请告诉我。感谢您抽出宝贵时间阅读本文。
【问题讨论】:
标签: c linker clang elf symbol-table