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.
nm
, bukan GNU nm
.
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.
nm
, bukan GNU nm
.
Jawaban:
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
( -C
juga 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
readelf -Ws
akan menunjukkan semua simbol, dan nm -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. Sebaliknya readelf -Ws
, itu tidak menunjukkan nama-nama yang hancur.
.so
file, Anda mungkin perlu menambahkan --dynamic
ke nm
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:
readelf -Ws /usr/lib/libexample.so
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:
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}';
objdump -TC /usr/lib/libexample.so
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.
Untuk .so
file C ++ , nm
perintah 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)
Untuk Android .so
file, toolchain NDK dilengkapi dengan alat-alat yang diperlukan yang disebutkan dalam jawaban yang lain: readelf
, objdump
dan nm
.
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. Mungkin objcopy
mengungkapkan informasi lebih lanjut.
/ EDIT: Nama alat ini tentu saja nm
. Bendera -g
digunakan 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 --versi
GNU nm 2.17.50.0.6-12.el5 20061020
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
nm
tidak menanggapi beberapa opsi, seperti-D
dan-g
(IIRC).