Jak wyświetlić listę symboli w pliku .so

485

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ę.

Moe
źródło
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:    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
źródło
35
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:

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}';
P Shved
źródło
19
readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print 8 $}'; wyrażenia regularne są niesamowite, ale czasami mały awk przechodzi długą drogę.
deft_code
55
objdump -TC /usr/lib/libexample.so
Pavel Lapin
źródło
42

W przypadku bibliotek współużytkowanych libNAME. Więc przełącznik -D był konieczny, aby zobaczyć symbole w moim systemie Linux

nm -D libNAME.so

i dla biblioteki statycznej zgłoszonej przez innych

nm -g libNAME.a
Cavila
źródło
35

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ą.

Peter Remmers
źródło
3
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 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)

źródło: https://stackoverflow.com/a/43257338

użytkownik7610
źródło
11

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.

Adam Mitz
źródło
11

Dla Android .soplików Toolchain NDK pochodzi z wymaganymi narzędzi wymienionych w innych odpowiedzi: readelf, objdumpi nm.

Adi Shavit
źródło
9

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.

Konrad Rudolph
źródło
6

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

zhaorufei
źródło
1

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
Craig Ringer
źródło