Como faço para listar os símbolos em um arquivo .so

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

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

    A ferramenta padrão para listar símbolos é o 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 demangle os símbolos (é muito mais legível demangled).

     nm -gC yourLib.so 

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

    Ou objdump ( -C também é útil para demarcar o C ++):

     $ objdump -TC libz.so libz.so: file format elf64-x86-64 DYNAMIC SYMBOL TABLE: 0000000000002010 ld .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 o 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 

    Se o seu arquivo .so estiver no formato elf, você pode usar o programa readelf para extrair informações de símbolos 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 arquivo .so , não nas bibliotecas referenciadas por ele. A sétima coluna deve conter um número neste caso. Você pode extraí-lo usando uma 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 -visibilidade = oculto e #pragmaGCC visibilidade não parece ter qualquer influência, como todos os símbolos eram sempre visíveis com nm – até que encontrei este post que me apontou para readelf e objdump , o que me fez perceber que há parece realmente ser duas tabelas de símbolos:

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

    Eu acho que o primeiro contém símbolos de debugging que podem ser removidos com strip 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 são exportados porque estão na “tabela de símbolos dynamics” do ELF, que é o último.

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

    Você pode usar a ferramenta nm -g do toolchain binutils. No entanto, sua fonte nem sempre está prontamente disponível. e na verdade não tenho certeza se essa informação pode ser sempre recuperada. Talvez objcopy revele mais informações.

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

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

    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 irá listar o símbolo na tabela dinâmica, que você pode achar que é o endereço da dlsym.

    nm –version

    GNU nm 2.17.50.0.6-12.el5 20061020

    Para arquivos C ++ .so , o comando nm final é nm --demangle --dynamic --defined-only --extern-only

     # 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