2009-12-07 76 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顯示符號的值。庫或對象文件中的某些符號可能僅顯示爲零,因爲它們尚未賦予值。他們會在鏈接時間獲得他們的實際價值。

一些符號代碼符號,有些數據等鏈接符號值之前,它駐留在部分往往偏移,

相關問題