linux符號表簡介

2021-08-03 03:43:19 字數 2683 閱讀 5064

既然在鏈結時,需要重定位目標檔案中引用的外部符號,顯然,鏈結器需要知道這些符號的定義在**,為此彙編器在每個目標檔案中建立了乙個符號表,符號表中記錄了這個模組定義的可以提供給其他模組引用的全域性符號。可以使用工具readelf檢視檔案中的符號表,如目標檔案foo2.o的符號表如下:

root@baisheng:~/demo# readelf -s foo2.o

symbol table '.symtab' contains 10 entries:

num:    value  size type    bind   vis      ndx name

0: 00000000     0 notype  local  default  und

1: 00000000     0 file    local  default  abs foo2.c

2: 00000000     0 section local  default    1

3: 00000000     0 section local  default    3

4: 00000000     0 section local  default    4

5: 00000000     0 section local  default    6

6: 00000000     0 section local  default    7

7: 00000000     0 section local  default    5

8: 00000000     4 object  global default    3 foo2

9: 00000000    16 func    global default    1 foo2_func

根據輸出可見,foo2.o符號表包含10個符號。value列表示的是符號的位址。前面我們提到,鏈結時鏈結器才會為符號分配位址,所以我們看到的符號的位址全部是0。size列表示符號對應的實體佔據的記憶體大小,如變數foo2佔據4位元組,函式foo2_func佔據16位元組。type列表示符號的型別,如foo2型別為object,表示變數;foo2_func型別為func,表示函式。bind列表示符號繫結的相關資訊,local表示模組內部符號,對外部不可見;global表示全域性符號,foo2和foo2_func都屬於全域性變數。ndx列表示該符號在哪個段,如foo2在第3個段,即「.data」段,foo2_func在第1個段,即「.text」段。name列表示符號的名稱。

除了模組定義的符號外,符號表中也包括了模組引用的外部符號,如模組hello的符號表如下:

root@baisheng:~/demo# readelf -s hello.o

symbol table '.symtab' contains 11 entries:

num:    value  size type    bind   vis      ndx name

0: 00000000     0 notype  local  default  und

1: 00000000     0 file    local  default  abs hello.c

2: 00000000     0 section local  default    1

3: 00000000     0 section local  default    3

4: 00000000     0 section local  default    4

5: 00000000     0 section local  default    6

6: 00000000     0 section local  default    7

7: 00000000     0 section local  default    5

8: 00000000    33 func    global default    1 main

9: 00000000     0 notype  global default  und foo2

10: 00000000     0 notype  global default  und foo2_func

符號foo2和foo2_func都在模組foo2中定義,對於模組hello來說是外部符號,沒有在任何乙個段中, 所以在列ndx中,foo2和foo2_func的值是und。und是undefined的縮寫,表示符號foo2、foo2_func是未定義的。

在鏈結時,對於模組中引用的外部符號,鏈結器將根據符號表進行符號的重定位。如果我們將符號表刪除了,那麼鏈結器在鏈結時將找不到符號的定義,從而不能進行正確的符號解析。如我們將foo2.o中的符號表刪除,再次進行鏈結,則鏈結器將因找不到符號定義而終止鏈結,如下所示:

root@baisheng:~/demo/tmp# strip foo2.o

root@baisheng:~/demo# gcc -o hello *.o

/usr/bin/ld: error in foo2.o(.eh_frame); no .eh_frame_hdr table will be created.

hello.o: in function 'main':

hello.c:(.text+0xb): undefined reference to 'foo2'

hello.c:(.text+0x1b): undefined reference to 'foo2_func'

collect2: error: ld returned 1 exit status

linux核心符號表

所謂核心符號表就是在核心內部函式或變數中可供外部引用的函式和變數的符號表。在 2.6 核心下,使用以下命令可以看到核心符號表 引用 beyes linux beyes cat proc kallsyms more c0100000 t text c0100000 t startup 32 c0100...

linux核心符號表

所謂核心符號表就是在核心內部函式或變數中可供外部引用的函式和變數的符號表。在 2.6 核心下,使用以下命令可以看到核心符號表 引用 beyes linux beyes cat proc kallsyms more c0100000 t text c0100000 t startup 32 c0100...

Linux核心符號表

1 形成過程 linux核心符號表 proc kallsyms 的形成過程 1 scripts kallsyms.c負責生成system.map 2 kernel kallsyms.c負責生成 proc kallsyms 3 scripts kallsyms.c解析 vmlinux tmp vmli...