其實問題的本質是對elf格式的理解問題,因為是查看so庫的符號表發現的問題。
事情起因是這樣的,由於我的一個程序編譯的時候出現了undefined reference to “XXX”的錯誤,需要鏈接特定的so庫,發現用nm [file]找不到“XXX”函數符號,結果用readelf -s [file] 就找到了。其實問題是我對so理解的不深刻。
一般來說,對於一個so庫有兩個符號表,一個是“正常的”(在.symtab和.strtab節中)。一個是動態的(.dynsym和.dynstr節中)。如果這個兩個表被移除,那么so庫就完全沒有用了。動態符號表的符號只被用於動態加載器運行時的加載。而“正常”的符號表,一般是用來調試的,里面的函數符號,是沒有被導出的(一般是一些靜態函數),所以不可能被外部程序使用。“正常”的符號表里面的函數符號,也不會在動態符號表中。
可以用 nm -D
和 readelf -s這兩個命令來顯示一個so文件的動態符號表信息。鏈接器去查找的也是動態符號表中的函數符號.
readelf -s 出來的函數符號意義解釋:
考慮一下輸出:
符號表 .symtab
包含了一下1203個入口項:
Num: Value Size Type Bind Vis Ndx Name
310: a0008120 0 NOTYPE GLOBAL DEFAULT ABS _gp
734: a0000010 32 OBJECT GLOBAL DEFAULT 77 v
818: 9d000018 496 FUNC GLOBAL DEFAULT 71 main
849: a0000124 4 OBJECT GLOBAL DEFAULT 78 phrase
955: a0000000 9 OBJECT GLOBAL DEFAULT 77 peppers
1020: a000023c 192 OBJECT GLOBAL DEFAULT 80 bins
Num:
= 符號序號Value
= 符號的地址Size
= 符號的大小Type
= 符號類型:Func
= Function,Object
,File
(source file name),Section
= memory section,Notype
= untyped absolute symbol or undefinedBind
=GLOBAL
綁定意味着該符號對外部文件的可見.LOCAL
綁定意味着該符號只在這個文件中可見.WEAK
有點像GLOBAL, 該符號可以被重載.Vis
= Symbols can be default, protected, hidden or internal.Ndx
= The section number the symbol is in. ABS means absolute: not adjusted to any section address's relocationName
= symbol name
references:
http://stackoverflow.com/questions/9961473/nm-vs-readelf-s
http://stackoverflow.com/questions/3065535/what-are-the-meanings-of-the-columns-displayed-by-readelf
http://osily.lofter.com/post/161c56_3dfd53