【问题标题】:What is the use of local symbols in the symbol table of an object file?目标文件符号表中局部符号的用途是什么?
【发布时间】:2021-09-13 17:08:06
【问题描述】:

从问题 (Hiding symbol names in library) 来看,我认为静态函数在使用优化编译时会从目标文件的符号表中删除(可能是因为编译器假定它是发布版本)。下面是来自 (Hiding symbol names in library) 的稍微修改的源代码和编译后的目标文件的符号表。

// compile with gcc -c -O2 -o file.o file.c

extern int a();
extern int b();

static int f_b1(){
return a();
}

static int f_b3(){
return b();
}
test.o:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 test.c
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 l    d  .data  0000000000000000 .data
0000000000000000 l    d  .bss   0000000000000000 .bss
0000000000000000 l    d  .note.GNU-stack        0000000000000000 .note.GNU-stack
0000000000000000 l    d  .comment       0000000000000000 .comment

但是,似乎只是因为 f_b1 和 f_b3 都没有使用而导致这种消失。显然,如果它们被如下的非静态函数调用,它们的符号会重新出现在符号表中(即 objdump -t file.o)。

extern int a();
extern int b();

static int __attribute__ ((noinline)) f_b1(){
return a();
}

static int __attribute__ ((noinline)) f_b2(){
return b();
}

void f_b3(){
    f_b1();
    f_b2();
}
SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 test.c
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 l    d  .data  0000000000000000 .data
0000000000000000 l    d  .bss   0000000000000000 .bss
0000000000000000 l     F .text  0000000000000007 f_b1
0000000000000010 l     F .text  0000000000000007 f_b2
0000000000000000 l    d  .note.GNU-stack        0000000000000000 .note.GNU-stack
0000000000000000 l    d  .eh_frame      0000000000000000 .eh_frame
0000000000000000 l    d  .comment       0000000000000000 .comment
0000000000000000         *UND*  0000000000000000 _GLOBAL_OFFSET_TABLE_
0000000000000000         *UND*  0000000000000000 a
0000000000000000         *UND*  0000000000000000 b
0000000000000020 g     F .text  0000000000000013 f_b3

因此,默认情况下,即使经过优化,编译器似乎也会将静态函数的符号发送到符号表中。那么,这样的局部符号有什么用呢? 在链接阶段真的需要它们(我不明白为什么需要它们,因为调用和跳转是以 eip 相对的方式执行的,不是吗?)?

【问题讨论】:

  • 静态符号在调试过程中非常有用。
  • 是的,我知道这一点。但是,我想知道这是否是编译器发出它的唯一原因。

标签: c linker elf symbol-table


【解决方案1】:

在链接阶段真的需要它们吗

没有。它们只是为了帮助调试。

您可以使用objcopy --strip-unneeded test.o test1.o 确认这一点——符号将被删除,但您仍然可以将test1.o 链接到最终的二进制文件中,就像使用test.o 一样。

【讨论】:

    猜你喜欢
    • 2010-11-05
    • 2011-03-28
    • 2015-10-23
    • 1970-01-01
    • 2018-03-12
    • 2013-03-10
    • 1970-01-01
    相关资源
    最近更新 更多