whu*_*ala 5 c binary linker gcc elf
// foo.c
int main() { return 0; }
Run Code Online (Sandbox Code Playgroud)
当我编译上面的代码时,我注意到一些符号位于*ABS*:
$ gcc foo.c
$ objdump -t a.out | grep ABS
0000000000000000 l df *ABS* 0000000000000000 crtstuff.c
0000000000000000 l df *ABS* 0000000000000000 foo.c
0000000000000000 l df *ABS* 0000000000000000 crtstuff.c
0000000000000000 l df *ABS* 0000000000000000
Run Code Online (Sandbox Code Playgroud)
看起来它们是一些调试符号,但调试信息不是存储在类似.debug_info部分的地方吗?
根据man objdump:
*ABS* 如果该部分是绝对的(即不与任何部分连接)
我不明白,因为这里没有给出例子。
这里的问题显示了一种有趣的方式来传递一些额外的符号*ABS*by --defsym。但我认为通过传递宏可能会更容易。
那么这个*ABS*部分是什么,什么时候有人会使用它?
编辑:
绝对符号不会被重新定位,它们的虚拟地址(在您给出的示例中为 0000000000000000)是固定的。
我写了一个演示,但似乎可以修改绝对符号的地址。
$ gcc foo.c
$ objdump -t a.out | grep ABS
0000000000000000 l df *ABS* 0000000000000000 crtstuff.c
0000000000000000 l df *ABS* 0000000000000000 foo.c
0000000000000000 l df *ABS* 0000000000000000 crtstuff.c
0000000000000000 l df *ABS* 0000000000000000
Run Code Online (Sandbox Code Playgroud)
// foo.c
#include <stdio.h>
extern char foo;
int main()
{
printf("%p\n", &foo);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果您查看其他符号,您可能会发现索引(或节名称,如果读者为您进行映射)代替*ABS*。这是节标题表中的节索引。它指向定义该符号的节的节标题(SHN_UNDEF如果在您正在查看的对象中未定义该符号,则为(零))。因此,符号的值(虚拟地址)将按照加载期间调整其包含部分的相同值进行调整。(这个过程称为重定位SHN_ABS。)对于绝对符号(具有特殊的值)则不然st_shndx。绝对符号不会被重新定位,它们的虚拟地址(0000000000000000在您给出的示例中)是固定的。
此类绝对符号有时用于存储一些元信息。特别是,编译器可以创建符号名称等于其编译的翻译单元名称的符号。链接或运行程序不需要这些符号,它们仅适用于人类和二进制处理工具。
至于你的问题,即它没有存储在.debug_info部分中的原因(以及为什么即使没有指定调试开关也会发出此信息),答案是它是一个单独的东西;它只是符号表( .symtab)。当然,调试也需要它,但它的主要目的是链接对象 ( .o) 文件。默认情况下,它保留在链接的可执行文件/库中。你可以用 摆脱它strip。
我在这里写的大部分内容都在man 5 elf.
我不认为你正在做的事情(使用--defsym)是受支持/应该与动态链接一起工作的。查看编译器输出 ( gcc -S -masm=intel),我看到了这一点
lea rsi, foo[rip]
Run Code Online (Sandbox Code Playgroud)
或者,如果我们查看objdump -M intel -rD a.out(链接 来-q保留重定位),我们会看到同样的事情:rip- 相对寻址用于获取 的地址foo。
113d: 48 8d 35 ab ad 00 00 lea rsi,[rip+0xadab] # beef <foo>
1140: R_X86_64_PC32 foo-0x4
Run Code Online (Sandbox Code Playgroud)
编译器不知道它将是一个绝对符号,因此它会生成它所执行的代码(与普通符号一样)。rip是指令指针,所以取决于.text程序被映射到内存后所在段的基地址ld.so。
我发现这个答案揭示了绝对符号的正确用例。