nm命令中的“符号值”是什么意思?

当你列出静态库的符号表时,例如nm mylib.a ,每个符号旁边显示的8位hex是什么意思? 那是代码中每个符号的相对位置吗?

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

以下是我在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主
                  U printf

对于这个例子,我正在运行Ubuntu Linux 64位; 这就是为什么你看到的8位十六进制数字是16位数字。 🙂

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

反汇编section .text:

 0000000000000000:
    0:55推送%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推%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 ,还有更多的在这里。 您拥有的文件是一个存档; 它包含多个目标文件,每个目标文件都有自己的文本段。 举个例子,这里是我在这里的一个nm对/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 __打印

您会看到多个文本段的条目(由第二列中的T表示)位于地址0x0处,但是每个单独的文件在0x0处只有一个文本段符号。

至于在同一地址有多个符号的单个文件,似乎也许是可能的。 毕竟,这只是用于确定数据块的位置和大小的表格中的条目。 但是我不确定。 我从来没有见过多个符号参考过一节的同一部分。 任何人对此都有更多的了解可以加入。:-)

希望这有助于一些。

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

链接器使用该值来查找并复制符号的值。 如果将-S选项添加到nm ,则可以大致了解它的布局方式,它将显示每个符号的值的大小。

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

一些符号是代码符号,一些是数据等。在链接之前,符号值通常是它所在部分的偏移量,