當您列出靜態庫的符號表時,如nm mylib.a
,每個符號旁邊顯示的8位十六進制是什麼意思?那是代碼中每個符號的相對位置嗎?nm命令中的「符號值」是什麼意思?
另外,多個符號可以具有相同的符號值嗎?所有符號值爲00000000的一堆不同的符號是否有問題?
當您列出靜態庫的符號表時,如nm mylib.a
,每個符號旁邊顯示的8位十六進制是什麼意思?那是代碼中每個符號的相對位置嗎?nm命令中的「符號值」是什麼意思?
另外,多個符號可以具有相同的符號值嗎?所有符號值爲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 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處的一個文本段符號。
對於有多個符號放在同一個地址的單個文件,看起來也許是也許可以。畢竟,它只是用於確定數據塊位置和大小的表格中的一個條目。但我不確定。我從來沒有見過多個符號參考之前一節的同一部分。任何知道此事的人都可以參加。:-)
希望這有助於一些。
十六進制數字是可以找到符號的目標文件的內存偏移量。這實際上就是目標代碼中的字節數。
鏈接器使用該值查找並複製符號的值。如果將-S
選項添加到nm
,您會看到它的佈局方式,它會顯示每個符號的值的大小。
nm顯示符號的值。庫或對象文件中的某些符號可能僅顯示爲零,因爲它們尚未賦予值。他們會在鏈接時間獲得他們的實際價值。
一些符號代碼符號,有些數據等鏈接符號值之前,它駐留在部分往往偏移,
如果你用'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