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).
Platforma robi różnicę. Apple udostępnia GCC 4.0, ale nmnie reaguje na niektóre opcje, takie jak -Di -g(IIRC).
jww
Nie drukuje nic w systemie Mac OS.
IgorGanapolsky
3
@jww, ponieważ to jest BSD nm, a nie GNU nm.
OrangeDog,
Odpowiedzi:
575
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( -Cprzydaje 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: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
Jednak nie zawsze działa to z plikami .so, więc może być konieczne użycie rozwiązania „readelf” wspomnianego w innej odpowiedzi.
Brooks Moses
9
Zauważ, że nm nm w OS X w wersji OS nie ma opcji „-C” dla symboli rozgraniczających. Zamiast tego można użyć filtru c ++. Przykładowy skrypt tutaj: v8.googlecode.com/svn/branches/bleeding_edge/tools/mac-nm nm -g /usr/lib/libstdc++.6.dylib | c ++ filt -p -i
fredbaba
5
Zauważ, że readelf -Wspokażą ci wszystkie symbole i pokażą nm -gtylko symbole widoczne z zewnątrz. Może to być mylące, jeśli przeglądasz wiele plików symboli i zaczynasz zamieniać swoje polecenia.
Andrew B
3
Dodałbym również objectdump -TCdo listy. W przeciwieństwie do readelf -Wstego, nie pokazuje zniekształconych nazw.
Yan Foto
2
@BrooksMoses W przypadku .soplików konieczne może być dodanie --dynamicdo nmwiersza poleceń.
user7610
84
Jeśli .soplik 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 .sopliku, 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:
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:
Ten, który możesz wymienić za pomocą nm
Ten, który możesz wymienić za pomocą readelf i objdump
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ą.
Dziękuję Ci! To wyjaśnia, dlaczego czasami „nm” nie wyświetla żadnych symboli dla plików .so.
Brooks Moses
10
nm -D - pozwala wyświetlić listę dynamicznych tablic symboli
pt123
19
W przypadku .soplików C ++ ostatecznym nmpoleceniem 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 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)
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.
Możesz użyć nm -gnarzę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 objcopyujawnia dalsze informacje.
/ EDYCJA: Nazwa narzędzia to oczywiście nm. Flaga -gsł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
nie reaguje na niektóre opcje, takie jak-D
i-g
(IIRC).nm
, a nie GNUnm
.Odpowiedzi:
Standardowym narzędziem do wyświetlania symboli jest to
nm
, że możesz go użyć w następujący sposób:Jeśli chcesz zobaczyć symbole biblioteki C ++, dodaj opcję „-C”, która rozplątuje symbole (jest znacznie bardziej czytelna, rozplątana).
Jeśli plik .so ma format elf, masz dwie opcje:
Albo
objdump
(-C
przydaje się również do demontażu C ++):Lub użyj
readelf
:źródło
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 doreadelf -Ws
tego, nie pokazuje zniekształconych nazw..so
plików konieczne może być dodanie--dynamic
donm
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: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:lub, jak zaproponował Caspin :
źródło
źródło
W przypadku bibliotek współużytkowanych libNAME. Więc przełącznik -D był konieczny, aby zobaczyć symbole w moim systemie Linux
i dla biblioteki statycznej zgłoszonej przez innych
źródło
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ą.
źródło
W przypadku
.so
plików C ++ ostatecznymnm
poleceniem jestnm --demangle --dynamic --defined-only --extern-only <my.so>
źródło: https://stackoverflow.com/a/43257338
źródło
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.
źródło
Dla Android
.so
plików Toolchain NDK pochodzi z wymaganymi narzędzi wymienionych w innych odpowiedzi:readelf
,objdump
inm
.źródło
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żeobjcopy
ujawnia dalsze informacje./ EDYCJA: Nazwa narzędzia to oczywiście
nm
. Flaga-g
służy do wyświetlania tylko eksportowanych symboli.źródło
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
źródło
Jeśli chcesz tylko wiedzieć, czy są obecne symbole, których możesz użyć
lub aby wyświetlić informacje o debugowaniu
źródło