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).
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.init0000000000000000 DF *UND*0000000000000000 GLIBC_2.2.5 free0000000000000000 DF *UND*0000000000000000 GLIBC_2.2.5 __errno_location0000000000000000 w D *UND*0000000000000000 _ITM_deregisterTMCloneTable
Ou use readelf:
$ readelf -Ws libz.soSymbol table '.dynsym' contains 112 entries:Num:ValueSizeTypeBindVisNdxName0:00000000000000000 NOTYPE LOCAL DEFAULT UND1: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
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:
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.
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 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)
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.
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.
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
não responde a algumas opções, como-D
e-g
(IIRC).nm
, não GNUnm
.Respostas:
A ferramenta padrão para listar símbolos é
nm
: você pode usá-lo da seguinte maneira: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).
Se o seu arquivo .so estiver no formato elfo, você terá duas opções:
Qualquer um
objdump
(-C
também é útil para desmantelar C ++):Ou use
readelf
:fonte
readelf -Ws
irá mostrar todos os símbolos enm -g
mostra 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.objectdump -TC
à lista. Ao contrárioreadelf -Ws
, ele não mostra os nomes mutilados..so
arquivos que você pode precisar adicionar--dynamic
ànm
linha de comando.Se o seu
.so
arquivo 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:Você só deve extrair aqueles que estão definidos neste
.so
arquivo, 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:ou, tal como proposto por Caspin ,:
fonte
fonte
Para bibliotecas compartilhadas libNAME.so, a opção -D era necessária para ver símbolos no meu Linux
e para a biblioteca estática conforme relatado por outros
fonte
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:
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.
fonte
Para
.so
arquivos C ++ , onm
comando final énm --demangle --dynamic --defined-only --extern-only <my.so>
fonte: https://stackoverflow.com/a/43257338
fonte
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.
fonte
Para Android
.so
arquivos, o conjunto de ferramentas NDK vem com as ferramentas necessárias mencionadas em outras respostas:readelf
,objdump
enm
.fonte
Você pode usar a
nm -g
ferramenta 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. Talvezobjcopy
revele mais informações./ EDIT: O nome da ferramenta é claro
nm
. A bandeira-g
é usada para mostrar apenas símbolos exportados.fonte
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
fonte
Se você quer apenas saber se existem símbolos presentes, pode usar
ou para listar as informações de depuração
fonte