簡體   English   中英

如何列出 a.so 文件中的符號

[英]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 下始終可見 - 直到我發現這篇文章將我指向readelfobjdump ,這讓我意識到那里似乎實際上是兩個符號表:

  • 您可以使用nm列出的那個
  • 您可以使用readelfobjdump列出的那個

我認為前者包含可以用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 工具鏈附帶了其他答案中提到的所需工具: readelfobjdumpnm

您可以使用 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM