Bir .so dosyasındaki sembolleri nasıl listeleyebilirim?


486

Bir .so dosyasından dışa aktarılan sembolleri nasıl listeleyebilirim? Mümkünse, kaynaklarını da bilmek isterim (örneğin statik bir kütüphaneden içeri alınırlarsa).

Bir fark yaratırsa gcc 4.0.2 kullanıyorum.


Platform bir fark yaratıyor. Apple bir GCC 4.0 sağlar, ancak ve (IIRC) nmgibi bazı seçeneklere yanıt vermez . -D-g
jww

Bu, Mac OS'de hiçbir şey yazdırmaz.
IgorGanapolsky

3
@jww çünkü bu BSD nm, GNU değil nm.
OrangeDog

Yanıtlar:


576

Sembolleri listelemek için standart araç nm, basitçe şu şekilde kullanabilirsiniz:

nm -gD yourLib.so

Bir C ++ kütüphanesinin sembollerini görmek istiyorsanız, sembolleri sökmek için "-C" seçeneğini ekleyin (çok daha okunabilir demontaj).

nm -gDC yourLib.so

.So dosyanız elf biçimindeyse, iki seçeneğiniz vardır:

Her ikisi de objdump( -CC ++ demontajı için de yararlıdır):

$ 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

Veya şunu kullanın 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

35
Bu her zaman .so dosyalarıyla çalışmaz ve bu nedenle başka bir yanıtta belirtilen "readelf" çözümünü kullanmanız gerekebilir.
Brooks Moses

9
Nm OS X sürümlerinde, sembollerin demontajı için '-C' seçeneği eksiktir. Bunun yerine c ++ filtresi kullanılabilir. Örnek komut dosyası: v8.googlecode.com/svn/branches/bleeding_edge/tools/mac-nm nm -g /usr/lib/libstdc++.6.dylib | c ++
filtresi

5
Not readelf -Wssize gösterecektir bütün sembolleri ve nm -gsadece harici olarak görünür sembolleri gösterileri. Birden çok sembol dosyasını inceliyor ve komutlarınızı değiştirmeye başlıyorsanız bu durum kafa karıştırıcı olabilir.
Andrew B

3
Ayrıca objectdump -TClisteye eklerdim. Aksine readelf -Ws, karışık isimleri göstermez.
Yan Foto

2
@BrooksMoses .soDosyalar --dynamiciçin nmkomut satırına eklemeniz gerekebilir .
user7610

84

Senin Eğer .sodosya elf formatta, sen ikili özü sembol bilgilere readelf programını kullanabilirsiniz. Bu komut size sembol tablosunu verecektir:

readelf -Ws /usr/lib/libexample.so

Yalnızca bu .sodosyada tanımlananları, başvurduğu kitaplıklarda değil ayıklamanız gerekir. Yedinci sütun bu durumda bir sayı içermelidir. Basit bir normal ifade kullanarak ayıklayabilirsiniz:

readelf -Ws /usr/lib/libstdc++.so.6 | grep '^\([[:space:]]\+[^[:space:]]\+\)\{6\}[[:space:]]\+[[:digit:]]\+'

veya Caspin tarafından önerildiği gibi:

readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';

19
kendini -Ws /usr/lib/libstdc++.so.6 | awk '{print $ 8}'; regexes harika ama bazen biraz awk uzun bir yol gidiyor.
deft_code


42

Paylaşılan kitaplıklar için libNAME.so, Linux'umdaki sembolleri görmek için -D anahtarı gerekliydi

nm -D libNAME.so

ve diğerleri tarafından bildirildiği gibi statik kütüphane için

nm -g libNAME.a

35

Merak ettim neden -fvisibility = gizli ve # Pragma GCC görünürlüğü tüm semboller her zaman görülebilen olduğu gibi, herhangi bir etkiye sahip değildi nm - Beni işaret Bu yayını bulana kadar readelf ve objdump bana fark ettirdi, orada aslında iki sembol tablosu gibi görünüyor :

  • Nm ile listeleyebileceğiniz
  • Kendini ve objdump ile listeleyebileceğiniz

Eski şerit veya -s anahtarı ile bağlayıcı veya install komutuna verilebilir hata ayıklama sembolleri içerdiğini düşünüyorum . Ve nm artık bir şey listelemese bile, dışa aktarılan sembolleriniz hala dışa aktarılır, çünkü bunlar ikincisi olan ELF "dinamik sembol tablosunda "dır.


3
Teşekkür ederim! Bu bazen "nm" nin neden .so dosyaları için herhangi bir sembol göstermediğini açıklar.
Brooks Moses

10
nm -D - dinamik sembol tablosunu listelemenizi sağlar
pt123

19

C ++ .sodosyaları için nihai nmkomutnm --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)

Kaynak: https://stackoverflow.com/a/43257338


11

Her sembolün kaynağını almak için nm bayraklarına -l eklemeyi deneyin. Kütüphane hata ayıklama bilgisi (gcc -g) ile derlenmişse, bu kaynak dosya ve satır numarası olmalıdır. Konrad'ın dediği gibi, nesne dosyası / statik kitaplığı muhtemelen bu noktada bilinmemektedir.


11

Android için .sodosyalar, NDK araç zinciri diğer yanıtlar sözü gerekli araçları ile birlikte gelir: readelf, objdumpve nm.


9

Sen kullanabilirsiniz nm -garaç zinciri binutils gelen aracı. Ancak, kaynakları her zaman mevcut değildir. ve aslında bu bilgilerin her zaman alınabileceğinden bile emin değilim. Belki objcopydaha fazla bilgi ortaya koymaktadır.

/ EDIT: Aracın adı elbette nm. Bayrak -g, yalnızca dışa aktarılan sembolleri göstermek için kullanılır.


6

nm -g dışa aktarılan sembol gerekli olmayan extern değişkenini listeler. Statik olmayan dosya kapsam değişkenlerinin (C cinsinden) tümü extern değişkendir.

nm -D, dinamik tablodaki sembolün adresini dlsym ile bulabileceğiniz bir liste oluşturur.

nm - sürüm

GNU nm 2.17.50.0.6-12.el5 20061020


1

Eğer sadece mevcut semboller olup olmadığını bilmek istiyorsanız

objdump -h /path/to/object

veya hata ayıklama bilgilerini listelemek için

objdump -g /path/to/object
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.