2009-12-07 78 views
13

当您列出静态库的符号表时,如nm mylib.a,每个符号旁边显示的8位十六进制是什么意思?那是代码中每个符号的相对位置吗?nm命令中的“符号值”是什么意思?

另外,多个符号可以具有相同的符号值吗?所有符号值为00000000的一堆不同的符号是否有问题?

回答

21

下面是一个代码片段我用C写的:


#include 
#include 

void foo(); 

int main(int argc, char* argv[]) { 
    foo(); 
} 

void foo() { 
    printf("Foo bar baz!"); 
} 

我在该代码上运行了gcc -c foo.c。以下是nm foo.o显示的内容:

 
000000000000001b T foo 
0000000000000000 T main 
       U printf 

对于本例,我运行Ubuntu Linux 64位;这就是为什么你看到的8位数字十六进制数字在这里。 :-)

您看到的十六进制数字是相对于.text.部分开头的目标文件中相关代码的地址。 (假设我们处理从0x0开始的目标文件的部分)。如果您运行objdump -td foo.o,你会看到下面的输出:

 
Disassembly of section .text: 

0000000000000000 : 
    0: 55      push %rbp 
    1: 48 89 e5    mov %rsp,%rbp 
    4: 48 83 ec 10    sub $0x10,%rsp 
    8: 89 7d fc    mov %edi,-0x4(%rbp) 
    b: 48 89 75 f0    mov %rsi,-0x10(%rbp) 
    f: b8 00 00 00 00   mov $0x0,%eax 
    14: e8 00 00 00 00   callq 19 
    19: c9      leaveq 
    1a: c3      retq 

000000000000001b : 
    1b: 55      push %rbp 
    1c: 48 89 e5    mov %rsp,%rbp 
    1f: b8 00 00 00 00   mov $0x0,%eax 
    24: 48 89 c7    mov %rax,%rdi 
    27: b8 00 00 00 00   mov $0x0,%eax 
    2c: e8 00 00 00 00   callq 31 
    31: c9      leaveq 
    32: c3      retq 

请注意,这两个符号行权了,我们在符号表中看到从nm的条目。请记住,如果将此目标文件链接到其他目标文件,这些地址可能会发生变化。另外,请记住,当您将此文件链接到您的系统提供的任何libc时,在0x2c处的callq将会发生变化,因为这是对printf的不完整调用(它不知道它现在在哪里)。

至于你的mylib.a,还有更多的在这里。您拥有的文件是一个档案;它包含多个目标文件,每个目标文件都有自己的文本段。作为一个例子,在这里在这里我对箱的/usr/lib/libm.a纳米的部分

 
e_sinh.o: 
0000000000000000 r .LC0 
0000000000000008 r .LC1 
0000000000000010 r .LC2 
0000000000000018 r .LC3 
0000000000000000 r .LC4 
       U __expm1 
       U __ieee754_exp 
0000000000000000 T __ieee754_sinh 

e_sqrt.o: 
0000000000000000 T __ieee754_sqrt 

e_gamma_r.o: 
0000000000000000 r .LC0 
       U __ieee754_exp 
0000000000000000 T __ieee754_gamma_r 
       U __ieee754_lgamma_r 
       U __rint 

你会看到多个文本段entires - 在第二列剩下由T所示在地址0x0处,但每个单独的文件只有 0x0处的一个文本段符号。

对于有多个符号放在同一个地址的单个文件,看起来也许是也许可以。毕竟,它只是用于确定数据块位置和大小的表格中的一个条目。但我不确定。我从来没有见过多个符号参考之前一节的同一部分。任何知道此事的人都可以参加。:-)

希望这有助于一些。

+0

如果你用'x86_64-w64-mingw32-g ++'编译你的例子,你会看到'nm'有多个引用零地址的符号并且有'A'标记,也就是说,地址不会将来会改变。例如。 '0000000000000000 A __dll__ 0000000000000000 A __dll_characteristics__'。就在这一点上 - [我已经看到有](http://unix.stackexchange.com/q/158162/59928)映射了实际有用的功能。我很好奇,这意味着什么? – 2015-02-11 04:47:16

3

十六进制数字是可以找到符号的目标文件的内存偏移量。这实际上就是目标代码中的字节数。

链接器使用该值查找并复制符号的值。如果将-S选项添加到nm,您会看到它的布局方式,它会显示每个符号的值的大小。

0

nm显示符号的值。库或对象文件中的某些符号可能仅显示为零,因为它们尚未赋予值。他们会在链接时间获得他们的实际价值。

一些符号代码符号,有些数据等链接符号值之前,它驻留在部分往往偏移,

相关问题