Bagaimana cara membuat daftar simbol dalam file .so

486

Bagaimana cara membuat daftar simbol yang diekspor dari file .so? Jika mungkin, saya juga ingin tahu sumbernya (misalnya jika mereka ditarik dari perpustakaan statis).

Saya menggunakan gcc 4.0.2, jika itu membuat perbedaan.

Moe
sumber
Platform membuat perbedaan. Apple menyediakan GCC 4.0, tetapi nmtidak menanggapi beberapa opsi, seperti -Ddan -g(IIRC).
jww
Ini tidak mencetak apa pun di Mac OS.
IgorGanapolsky
3
@jww karena itu BSD nm, bukan GNU nm.
OrangeDog

Jawaban:

577

Alat standar untuk membuat daftar simbol adalah nm, Anda dapat menggunakannya hanya seperti ini:

nm -gD yourLib.so

Jika Anda ingin melihat simbol pustaka C ++, tambahkan opsi "-C" yang menghilangkan simbol (itu jauh lebih mudah dibaca demangled).

nm -gDC yourLib.so

Jika file .so Anda dalam format elf, Anda memiliki dua opsi:

Either objdump( -Cjuga berguna untuk demangling 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

Atau gunakan 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
Steve Gury
sumber
35
Ini tidak selalu bekerja dengan file .so, jadi Anda mungkin harus menggunakan solusi "readelf" yang disebutkan dalam jawaban lain.
Brooks Moses
9
Perhatikan bahwa versi OS X dari nm tidak memiliki opsi '-C' untuk demangling simbol. c ++ filt dapat digunakan sebagai gantinya. Contoh skrip di sini: v8.googlecode.com/svn/branches/bleeding_edge/tools/mac-nm nm -g /usr/lib/libstdc++.6.dylib | c ++ filt -p -i
fredbaba
5
Catatan yang readelf -Wsakan menunjukkan semua simbol, dan nm -ghanya menunjukkan simbol yang terlihat secara eksternal. Ini mungkin membingungkan jika Anda memeriksa beberapa file simbol dan mulai menukar perintah Anda.
Andrew B
3
Saya juga akan menambah objectdump -TCdaftar. Sebaliknya readelf -Ws, itu tidak menunjukkan nama-nama yang hancur.
Yan Foto
2
@BrooksMoses Untuk .sofile, Anda mungkin perlu menambahkan --dynamicke nmbaris perintah.
user7610
84

Jika .sofile Anda dalam format elf, Anda dapat menggunakan program readelf untuk mengekstrak informasi simbol dari biner. Perintah ini akan memberi Anda tabel simbol:

readelf -Ws /usr/lib/libexample.so

Anda hanya perlu mengekstrak yang didefinisikan dalam .sofile ini , bukan di perpustakaan yang dirujuk olehnya. Kolom ketujuh harus berisi angka dalam hal ini. Anda dapat mengekstraknya dengan menggunakan regex sederhana:

readelf -Ws /usr/lib/libstdc++.so.6 | grep '^\([[:space:]]\+[^[:space:]]\+\)\{6\}[[:space:]]\+[[:digit:]]\+'

atau, seperti yang diusulkan oleh Caspin ,:

readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';
P Shved
sumber
19
readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $ 8}'; regex itu luar biasa tapi terkadang sedikit awk berjalan jauh.
deft_code
55
objdump -TC /usr/lib/libexample.so
Pavel Lapin
sumber
42

Untuk pustaka bersama libNAME.so switch -D diperlukan untuk melihat simbol di Linux saya

nm -D libNAME.so

dan untuk perpustakaan statis seperti yang dilaporkan oleh orang lain

nm -g libNAME.a
cavila
sumber
35

Saya terus bertanya-tanya mengapa -fvisibilitas = tersembunyi dan #pragma Visibilitas GCC tampaknya tidak memiliki pengaruh, karena semua simbol selalu terlihat dengan nm - sampai saya menemukan posting ini yang mengarahkan saya ke readelf dan objdump , yang membuat saya menyadari bahwa ada tampaknya sebenarnya dua tabel simbol:

  • Yang bisa Anda daftarkan nm
  • Yang Anda dapat daftar dengan diri sendiri dan objdump

Saya pikir yang pertama berisi simbol debug yang dapat dilucuti dengan strip atau -s yang dapat Anda berikan kepada linker atau perintah instal . Dan bahkan jika nm tidak mencantumkan apa-apa lagi, simbol yang diekspor masih diekspor karena berada dalam "tabel simbol dinamis" ELF, yang merupakan yang terakhir.

Peter Remmers
sumber
3
Terima kasih! Ini menjelaskan mengapa terkadang "nm" tidak menunjukkan simbol apa pun untuk file .so.
Brooks Moses
10
nm -D - memungkinkan Anda membuat daftar tabel simbol dinamis
pt123
19

Untuk .sofile C ++ , nmperintah utamanya adalahnm --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)

sumber: https://stackoverflow.com/a/43257338

pengguna7610
sumber
11

Coba tambahkan -l ke flag nm untuk mendapatkan sumber dari setiap simbol. Jika pustaka dikompilasi dengan info debug (gcc -g) ini harus berupa file sumber dan nomor baris. Seperti Konrad katakan, file objek / pustaka statis mungkin tidak diketahui pada saat ini.

Adam Mitz
sumber
11

Untuk Android .sofile, toolchain NDK dilengkapi dengan alat-alat yang diperlukan yang disebutkan dalam jawaban yang lain: readelf, objdumpdan nm.

Adi Shavit
sumber
9

Anda dapat menggunakan nm -galat dari binchain toolchain. Namun, sumber mereka tidak selalu tersedia. dan saya bahkan tidak yakin bahwa informasi ini selalu dapat diambil. Mungkin objcopymengungkapkan informasi lebih lanjut.

/ EDIT: Nama alat ini tentu saja nm. Bendera -gdigunakan untuk hanya menampilkan simbol yang diekspor.

Konrad Rudolph
sumber
6

nm -g daftar variabel extern, yang tidak perlu simbol yang diekspor. Variabel ruang lingkup file non-statis (dalam C) semuanya adalah variabel eksternal.

nm -D akan mencantumkan simbol dalam tabel dinamis, yang dapat Anda temukan alamatnya dengan dlsym.

nm --versi

GNU nm 2.17.50.0.6-12.el5 20061020

zhaorufei
sumber
1

Jika Anda hanya ingin tahu apakah ada simbol hadir Anda dapat menggunakan

objdump -h /path/to/object

atau untuk mendaftar info debug

objdump -g /path/to/object
Craig Ringer
sumber