[英]How do I list the symbols in a .so file
如何列出從 .so 文件導出的符號? 如果可能的話,我還想知道它們的來源(例如,如果它們是從靜態庫中提取的)。
我正在使用 gcc 4.0.2,如果這有所作為的話。
列出符號的標准工具是nm
,您可以像這樣簡單地使用它:
nm -gD yourLib.so
如果您想查看 C++ 庫的符號,請添加“-C”選項來對符號進行分解(分解后的可讀性更高)。
nm -gDC yourLib.so
如果你的 .so 文件是 elf 格式,你有兩個選擇:
要么objdump
( -C
對分解 C++ 也很有用):
$ objdump -TC libz.so
libz.so: file format elf64-x86-64
DYNAMIC SYMBOL TABLE:
0000000000002010 l d .init 0000000000000000 .init
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 free
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __errno_location
0000000000000000 w D *UND* 0000000000000000 _ITM_deregisterTMCloneTable
或者使用readelf
:
$ readelf -Ws libz.so
Symbol table '.dynsym' contains 112 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000002010 0 SECTION LOCAL DEFAULT 10
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND free@GLIBC_2.2.5 (14)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __errno_location@GLIBC_2.2.5 (14)
4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable
如果你的.so
文件是 elf 格式,你可以使用 readelf 程序從二進制文件中提取符號信息。 此命令將為您提供符號表:
readelf -Ws /usr/lib/libexample.so
您只應提取在此.so
文件中定義的那些,而不是在它引用的庫中。 在這種情況下,第七列應包含一個數字。 您可以使用簡單的正則表達式提取它:
readelf -Ws /usr/lib/libstdc++.so.6 | grep '^\([[:space:]]\+[^[:space:]]\+\)\{6\}[[:space:]]\+[[:digit:]]\+'
或者,正如Caspin所提議的,:
readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';
objdump -TC /usr/lib/libexample.so
對於共享庫 libNAME.so 必須使用 -D 開關才能在我的 Linux 中查看符號
nm -D libNAME.so
以及其他人報告的靜態庫
nm -g libNAME.a
我一直想知道為什么-fvisibility=hidden和#pragma GCC 可見性似乎沒有任何影響,因為所有符號在nm 下始終可見 - 直到我發現這篇文章將我指向readelf和objdump ,這讓我意識到那里似乎實際上是兩個符號表:
我認為前者包含可以用strip或 -s 開關去除的調試符號,您可以將它們提供給鏈接器或安裝命令。 即使 nm 不再列出任何內容,您導出的符號仍然會被導出,因為它們在 ELF“動態符號表”中,也就是后者。
對於 C++ .so
文件,最終的nm
命令是nm --demangle --dynamic --defined-only --extern-only <my.so>
# nm --demangle --dynamic --defined-only --extern-only /usr/lib64/libqpid-proton-cpp.so | grep work | grep add
0000000000049500 T proton::work_queue::add(proton::internal::v03::work)
0000000000049580 T proton::work_queue::add(proton::void_function0&)
000000000002e7b0 W proton::work_queue::impl::add_void(proton::internal::v03::work)
000000000002b1f0 T proton::container::impl::add_work_queue()
000000000002dc50 T proton::container::impl::container_work_queue::add(proton::internal::v03::work)
000000000002db60 T proton::container::impl::connection_work_queue::add(proton::internal::v03::work)
來源: https ://stackoverflow.com/a/43257338
對於 Android .so
文件,NDK 工具鏈附帶了其他答案中提到的所需工具: readelf
、 objdump
和nm
。
您可以使用 binutils 工具鏈中的nm -g
工具。 然而,它們的來源並不總是容易獲得。 而且我什至不確定這些信息是否總能被檢索到。 也許objcopy
揭示了更多信息。
/編輯:該工具的名稱當然是nm
。 標志-g
用於僅顯示導出的符號。
嘗試將 -l 添加到 nm 標志以獲取每個符號的來源。 如果庫是用調試信息 (gcc -g) 編譯的,這應該是源文件和行號。 正如康拉德所說,目標文件/靜態庫此時可能是未知的。
nm -g 列出extern 變量,它不是必需的導出符號。 任何非靜態文件范圍變量(在 C 中)都是外部變量。
nm -D 將列出動態表中的符號,您可以通過 dlsym 找到它的地址。
納米--版本
GNU 納米 2.17.50.0.6-12.el5 20061020
如果您只想知道是否存在符號,您可以使用
objdump -h /path/to/object
或列出調試信息
objdump -g /path/to/object
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.