Pergunta

Como faço para listar os símbolos que estão sendo exportados de um arquivo .so?Se possível, também gostaria de saber a origem deles (por ex.se eles forem extraídos de uma biblioteca estática).

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

Foi útil?

Solução

A ferramenta padrão para listar símbolos é nm, você pode usá-lo simplesmente assim:

nm -g yourLib.so

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

nm -gC yourLib.so

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

Qualquer objdump (-C também é útil para desmontar 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

Outras dicas

Se seu .so arquivo está no formato elf, você pode usar o programa readelf para extrair informações de símbolo do binário.Este comando lhe dará a tabela de símbolos:

readelf -Ws /usr/lib/libexample.so

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 neste caso.Você pode extraí-lo usando um regex simples:

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

ou, como proposto por Caspin,:

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

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

nm -D libNAME.so

e para biblioteca estática conforme relatado por outros

nm -g libNAME.a

Fiquei me perguntando por que -fvisibilidade=oculto e #pragma Visibilidade do CCG não parecia ter qualquer influência, pois todos os símbolos estavam sempre visíveis com nm - até que encontrei esse post que me indicou leia-se e objdump, o que me fez perceber que parece realmente haver dois tabelas de símbolos:

  • Aquele com o qual você pode listar nm
  • Aquele com o qual você pode listar leia-se e objdump

Acho que o primeiro contém símbolos de depuração que podem ser removidos com faixa ou a opção -s que você pode fornecer ao vinculador ou ao instalar comando.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" ELF, que é a última.

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

Para Android .so arquivos, o conjunto de ferramentas do NDK vem com as ferramentas necessárias mencionadas nas outras respostas: readelf, objdump e nm.

Para C++ .so arquivos, o melhor nm comando é 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

Você pode usar o nm -g ferramenta do conjunto 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 objcopy revela mais informações.

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

nm -g lista a variável externa, que não é necessariamente um símbolo exportado.Qualquer variável de escopo de arquivo não estático (em C) são todas variáveis ​​externas.

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

nm --versão

GNUnm 2.17.50.0.6-12.el5 20061020

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

objdump -h /path/to/object

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

objdump -g /path/to/object
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top