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.
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:ValueSizeTypeBindVisNdxName0:00000000000000000 NOTYPE LOCAL DEFAULT UND
1:00000000000020100 SECTION LOCAL DEFAULT 102:00000000000000000 FUNC GLOBAL DEFAULT UND free@GLIBC_2.2.5(14)3:00000000000000000 FUNC GLOBAL DEFAULT UND __errno_location@GLIBC_2.2.5(14)4:00000000000000000 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable
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:
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.
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 add0000000000049500 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)
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.
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.
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
tidak menanggapi beberapa opsi, seperti-D
dan-g
(IIRC).nm
, bukan GNUnm
.Jawaban:
Alat standar untuk membuat daftar simbol adalah
nm
, Anda dapat menggunakannya hanya seperti ini:Jika Anda ingin melihat simbol pustaka C ++, tambahkan opsi "-C" yang menghilangkan simbol (itu jauh lebih mudah dibaca demangled).
Jika file .so Anda dalam format elf, Anda memiliki dua opsi:
Either
objdump
(-C
juga berguna untuk demangling C ++):Atau gunakan
readelf
:sumber
readelf -Ws
akan menunjukkan semua simbol, dannm -g
hanya menunjukkan simbol yang terlihat secara eksternal. Ini mungkin membingungkan jika Anda memeriksa beberapa file simbol dan mulai menukar perintah Anda.objectdump -TC
daftar. Sebaliknyareadelf -Ws
, itu tidak menunjukkan nama-nama yang hancur..so
file, Anda mungkin perlu menambahkan--dynamic
kenm
baris perintah.Jika
.so
file Anda dalam format elf, Anda dapat menggunakan program readelf untuk mengekstrak informasi simbol dari biner. Perintah ini akan memberi Anda tabel simbol:Anda hanya perlu mengekstrak yang didefinisikan dalam
.so
file ini , bukan di perpustakaan yang dirujuk olehnya. Kolom ketujuh harus berisi angka dalam hal ini. Anda dapat mengekstraknya dengan menggunakan regex sederhana:atau, seperti yang diusulkan oleh Caspin ,:
sumber
sumber
Untuk pustaka bersama libNAME.so switch -D diperlukan untuk melihat simbol di Linux saya
dan untuk perpustakaan statis seperti yang dilaporkan oleh orang lain
sumber
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:
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.
sumber
Untuk
.so
file C ++ ,nm
perintah utamanya adalahnm --demangle --dynamic --defined-only --extern-only <my.so>
sumber: https://stackoverflow.com/a/43257338
sumber
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.
sumber
Untuk Android
.so
file, toolchain NDK dilengkapi dengan alat-alat yang diperlukan yang disebutkan dalam jawaban yang lain:readelf
,objdump
dannm
.sumber
Anda dapat menggunakan
nm -g
alat dari binchain toolchain. Namun, sumber mereka tidak selalu tersedia. dan saya bahkan tidak yakin bahwa informasi ini selalu dapat diambil. Mungkinobjcopy
mengungkapkan informasi lebih lanjut./ EDIT: Nama alat ini tentu saja
nm
. Bendera-g
digunakan untuk hanya menampilkan simbol yang diekspor.sumber
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
sumber
Jika Anda hanya ingin tahu apakah ada simbol hadir Anda dapat menggunakan
atau untuk mendaftar info debug
sumber