Como listar os símbolos em um arquivo .so

486

Como listar os símbolos que estão sendo exportados de um arquivo .so? Se possível, eu também gostaria de saber sua fonte (por exemplo, se eles foram extraídos de uma biblioteca estática).

Estou usando o gcc 4.0.2, se isso faz diferença.

Moe
fonte
A plataforma faz a diferença. A Apple fornece um GCC 4.0, mas nmnão responde a algumas opções, como -De -g(IIRC).
jww 13/09/15
Isso não imprime nada no Mac OS.
IgorGanapolsky
3
@ jww porque isso é BSD nm, não GNU nm.
OrangeDog 3/08/16

Respostas:

577

A ferramenta padrão para listar símbolos é nm: você pode usá-lo da seguinte maneira:

nm -gD yourLib.so

Se você quiser ver símbolos de uma biblioteca C ++, adicione a opção "-C" que desmantela os símbolos (é muito mais legível desmontada).

nm -gDC yourLib.so

Se o seu arquivo .so estiver no formato elfo, você terá duas opções:

Qualquer um objdump( -Ctambém é útil para desmantelar 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

Ou use 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
fonte
35
Porém, isso nem sempre funciona com arquivos .so e, portanto, você pode precisar usar a solução "readelf" mencionada em outra resposta.
Brooks Moses
9
Observe que as versões do nm do OS X não possuem a opção '-C' para desmontar os símbolos. c ++ filt pode ser usado em seu lugar. Exemplo de script aqui: v8.googlecode.com/svn/branches/bleeding_edge/tools/mac-nm nm -g /usr/lib/libstdc++.6.dylib | C ++ filt -p -i
fredbaba
5
Observe que readelf -Wsirá mostrar todos os símbolos e nm -gmostra apenas os símbolos visíveis externamente. Isso pode ser confuso se você estiver examinando vários arquivos de símbolos e começar a trocar seus comandos.
Andrew B
3
Eu também adicionaria objectdump -TCà lista. Ao contrário readelf -Ws, ele não mostra os nomes mutilados.
Yan Foto
2
@BrooksMoses Para .soarquivos que você pode precisar adicionar --dynamicà nmlinha de comando.
precisa saber é
84

Se o seu .soarquivo estiver no formato elf, você poderá usar o programa readelf para extrair informações de símbolos do binário. Este comando fornecerá a tabela de símbolos:

readelf -Ws /usr/lib/libexample.so

Você só deve extrair aqueles que estão definidos neste .soarquivo, não nas bibliotecas referenciadas por ele. A sétima coluna deve conter um número nesse caso. Você pode extraí-lo usando uma regex simples:

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

ou, tal como proposto por Caspin ,:

readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';
P Shved
fonte
19
readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $ 8}'; Regexes são impressionantes, mas às vezes um pouco awk vai um longo caminho.
Deft_code 9/03/10
55
objdump -TC /usr/lib/libexample.so
Pavel Lapin
fonte
42

Para bibliotecas compartilhadas libNAME.so, a opção -D era necessária para ver símbolos no meu Linux

nm -D libNAME.so

e para a biblioteca estática conforme relatado por outros

nm -g libNAME.a
cavila
fonte
35

Fiquei me perguntando por que -fvisibility = hidden e #pragma a visibilidade do GCC não parecia ter influência, pois todos os símbolos estavam sempre visíveis com nm - até encontrar este post que me indicava como eu próprio e como objdump , o que me fez perceber que havia parecem ser duas tabelas de símbolos:

  • O que você pode listar com nm
  • O que você pode listar com readelf e objdump

Eu acho que o primeiro contém símbolos de depuração que podem ser removidos com a tira ou a opção -s que você pode fornecer ao vinculador ou ao comando de instalação . E mesmo que nm não liste mais nada, seus símbolos exportados ainda serão exportados porque estão na "tabela de símbolos dinâmicos" do ELF, que é a última.

Peter Remmers
fonte
3
Obrigado! Isso explica porque às vezes "nm" não mostra nenhum símbolo para arquivos .so.
Brooks Moses
10
nm D - permite listar o símbolo dinâmica mesa
pt123
19

Para .soarquivos C ++ , o nmcomando final énm --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)

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

user7610
fonte
11

Tente adicionar -l aos sinalizadores nm para obter a fonte de cada símbolo. Se a biblioteca é compilada com informações de depuração (gcc -g), esse deve ser o arquivo de origem e o número da linha. Como Konrad disse, o arquivo de objeto / biblioteca estática provavelmente é desconhecido neste momento.

Adam Mitz
fonte
11

Para Android .soarquivos, o conjunto de ferramentas NDK vem com as ferramentas necessárias mencionadas em outras respostas: readelf, objdumpe nm.

Adi Shavit
fonte
9

Você pode usar a nm -gferramenta na cadeia de ferramentas binutils. No entanto, sua fonte nem sempre está prontamente disponível. e nem tenho certeza de que essas informações sempre possam ser recuperadas. Talvez objcopyrevele mais informações.

/ EDIT: O nome da ferramenta é claro nm. A bandeira -gé usada para mostrar apenas símbolos exportados.

Konrad Rudolph
fonte
6

nm -g lista a variável externa, que não é necessário símbolo exportado. Qualquer variável de escopo de arquivo não estático (em C) é toda variável externa.

nm -D listará o símbolo na tabela dinâmica, que você pode encontrar pelo endereço dlsym.

nm --versão

GNU nm 2.17.50.0.6-12.el5 20061020

zhaorufei
fonte
1

Se você quer apenas saber se existem símbolos presentes, pode usar

objdump -h /path/to/object

ou para listar as informações de depuração

objdump -g /path/to/object
Craig Ringer
fonte