Jak wyświetlić listę symboli eksportowanych z pliku .so? Jeśli to możliwe, chciałbym również poznać ich źródło (np. Czy są pobierane z biblioteki statycznej).
Używam gcc 4.0.2, jeśli to robi różnicę.
nm
, a nie GNU nm
.
Jak wyświetlić listę symboli eksportowanych z pliku .so? Jeśli to możliwe, chciałbym również poznać ich źródło (np. Czy są pobierane z biblioteki statycznej).
Używam gcc 4.0.2, jeśli to robi różnicę.
nm
, a nie GNU nm
.
Odpowiedzi:
Standardowym narzędziem do wyświetlania symboli jest to nm
, że możesz go użyć w następujący sposób:
nm -gD yourLib.so
Jeśli chcesz zobaczyć symbole biblioteki C ++, dodaj opcję „-C”, która rozplątuje symbole (jest znacznie bardziej czytelna, rozplątana).
nm -gDC yourLib.so
Jeśli plik .so ma format elf, masz dwie opcje:
Albo objdump
( -C
przydaje się również do demontażu 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
Lub użyj 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
pokażą ci wszystkie symbole i pokażą nm -g
tylko symbole widoczne z zewnątrz. Może to być mylące, jeśli przeglądasz wiele plików symboli i zaczynasz zamieniać swoje polecenia.
objectdump -TC
do listy. W przeciwieństwie do readelf -Ws
tego, nie pokazuje zniekształconych nazw.
.so
plików konieczne może być dodanie --dynamic
do nm
wiersza poleceń.
Jeśli .so
plik jest w formacie elf, możesz użyć programu readelf do wyodrębnienia informacji o symbolu z pliku binarnego. To polecenie wyświetli tabelę symboli:
readelf -Ws /usr/lib/libexample.so
Powinieneś wyodrębnić tylko te, które są zdefiniowane w tym .so
pliku, a nie w bibliotekach, do których się on odwołuje. W tym przypadku siódma kolumna powinna zawierać liczbę. Możesz go wyodrębnić, używając prostego wyrażenia regularnego:
readelf -Ws /usr/lib/libstdc++.so.6 | grep '^\([[:space:]]\+[^[:space:]]\+\)\{6\}[[:space:]]\+[[:digit:]]\+'
lub, jak zaproponował Caspin :
readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';
objdump -TC /usr/lib/libexample.so
Zastanawiałem się, dlaczego -fvisibility = ukryty i #pragma widoczność GCC nie miała żadnego wpływu, ponieważ wszystkie symbole były zawsze widoczne za pomocą nm - dopóki nie znalazłem tego postu, który wskazał mi readelf i objdump , co uświadomiło mi, że tam jest wydają się być dwiema tablicami symboli:
Myślę, że ten pierwszy zawiera symbole debugowania, które można usunąć przy pomocy strip lub przełącznika -s, który możesz podać linkerowi lub komendzie instalacyjnej . I nawet jeśli nm już niczego nie wymienia, wyeksportowane symbole są nadal eksportowane, ponieważ znajdują się w „dynamicznej tablicy symboli” ELF, która jest tą ostatnią.
W przypadku .so
plików C ++ ostatecznym nm
poleceniem jestnm --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)
Spróbuj dodać -l do flag nm, aby uzyskać źródło każdego symbolu. Jeśli biblioteka jest skompilowana z informacjami debugowania (gcc -g), powinien to być plik źródłowy i numer linii. Jak powiedział Konrad, plik obiektowy / biblioteka statyczna jest prawdopodobnie w tym momencie nieznany.
Dla Android .so
plików Toolchain NDK pochodzi z wymaganymi narzędzi wymienionych w innych odpowiedzi: readelf
, objdump
i nm
.
Możesz użyć nm -g
narzędzia z łańcucha narzędzi binutils. Jednak ich źródło nie zawsze jest łatwo dostępne. i nie jestem nawet pewien, czy zawsze można odzyskać te informacje. Być może objcopy
ujawnia dalsze informacje.
/ EDYCJA: Nazwa narzędzia to oczywiście nm
. Flaga -g
służy do wyświetlania tylko eksportowanych symboli.
nm -g wypisuje zmienną zewnętrzną, która nie jest koniecznym eksportowanym symbolem. Każda niestatyczna zmienna zakresu pliku (w C) jest zmienną zewnętrzną.
nm -D wyświetli symbol w dynamicznej tabeli, którą można znaleźć pod adresem dlsym.
nm - wersja
GNU nm 2.17.50.0.6-12.el5 20061020
Jeśli chcesz tylko wiedzieć, czy są obecne symbole, których możesz użyć
objdump -h /path/to/object
lub aby wyświetlić informacje o debugowaniu
objdump -g /path/to/object
nm
nie reaguje na niektóre opcje, takie jak-D
i-g
(IIRC).