【发布时间】:2020-02-21 08:37:48
【问题描述】:
我正在学习链接器在 Linux 中的工作原理。以我的代码为例:
// main.c
int printf(const char *format, ...);
void func1(int i)
{
printf("%d\n", i);
}
int main(void)
{
func1(1);
return 0;
}
我执行命令gcc -c main.c,得到一个名为main.o的obj文件。
然后我执行命令objdump -r main.o,输出如下:
main.o: file format elf64-x86-64
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000000000000011 R_X86_64_32 .rodata
000000000000001b R_X86_64_PC32 printf-0x0000000000000004
000000000000002c R_X86_64_PC32 func1-0x0000000000000004
RELOCATION RECORDS FOR [.eh_frame]:
OFFSET TYPE VALUE
0000000000000020 R_X86_64_PC32 .text
0000000000000040 R_X86_64_PC32 .text+0x0000000000000022
如果我是对的,objdump -r 将向我们展示 obj 文件中的所有重定位表。在这种情况下,printf 和func1 都被放入重定位表中。
printf在这个C文件中没有定义,所以需要重定位,但是为什么func1也可以在重定位表中找到呢?按照我的理解,func1 应该很好定义,可以在.text 部分找到,不需要重新定位,对吧?
【问题讨论】:
-
函数也是全局的,所以每个函数都会在 C 中获得一个重定位条目,除了你创建的那些
static,但遗憾的是我还不知道更深层次的细节。 -
@Eraklon 全局变量和函数
main不在重定位表中。 -
main 是一个入口点,它不是一个普通函数
-
@Eraklon 好的,所以我想我有点误解什么是“重定位表”。可能所有全局函数都必须在链接时重新定位。
标签: c linux compilation linker objdump