gpt4 book ai didi

gcc - ELF动态符号表

转载 作者:行者123 更新时间:2023-12-02 13:53:55 30 4
gpt4 key购买 nike

我有一个关于 ELF 动态符号表的问题。对于 FUNC 类型的符号,我注意到某些二进制文件中的值为 0。但在其他二进制文件中,它具有一些非零值。这两个二进制文件都是由 gcc 生成的,我想知道为什么会出现这种差异?是否有任何编译器选项来控制它?

编辑:这是 readelf --dyn-syms prog1 的输出

Symbol table '.dynsym' contains 5 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
2: 000082f0 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.4 (2)
3: 00008314 0 FUNC GLOBAL DEFAULT UND abort@GLIBC_2.4 (2)
4: 000082fc 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.4

这里“printf”符号的值为82f0,这恰好是printf的plt表条目的地址。

readelf --dyn-syms prog2 的输出

Symbol table '.dynsym' contains 6 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
2: 00000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.4 (2)
3: 00000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.4 (2)
4: 00000000 0 FUNC GLOBAL DEFAULT UND abort@GLIBC_2.4 (2)
5: 00000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.4

此处所有符号的值均为零。

最佳答案

x86_64 SV ABI要求(强调我的):

To allow comparisons of function addresses to work as expected, if an executable file references a function defined in a shared object, the link editor will place the address of the procedure linkage table entry for that function in its associated symbol table entry. This will result in symbol table entries with section index of SHN_UNDEF but a type of STT_FUNC and a non-zero st_value. A reference to the address of a function from within a shared library will be satisfied by such a definition in the executable.

使用我的 GCC,这个程序:

#include <stdio.h>

int main()
{
printf("hello %i\n", 42);
return 0;
}

当直接编译成可执行文件时会生成空值:

 1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)

但是这个程序与printf函数的比较:

#include <stdio.h>

int main()
{
printf("hello %i\n", 42);
if (printf == puts)
return 1;
return 0;
}

生成一个非空值:

 3: 0000000000400410     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)

在.o文件中,第一个程序生成:

000000000014  000a00000002 R_X86_64_PC32     0000000000000000 printf - 4

第二个:

000000000014  000a00000002 R_X86_64_PC32     0000000000000000 printf - 4
000000000019 000a0000000a R_X86_64_32 0000000000000000 printf + 0

差异是由用于获取函数地址的额外 R_X86_64_32 重定位造成的。

关于gcc - ELF动态符号表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32737355/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com