How do list the symbols being exported from a .so file. If possible, I\'d also like to know their source (e.g. if they are pulled in from a static library).
I\'m using gcc 4.0.2, if that makes a difference
How do list the symbols being exported from a .so file. If possible, I\'d also like to know their source (e.g. if they are pulled in from a static library).
I\'m using gcc 4.0.2, if that makes a difference
The standard tool for listing symbols is nm
, you can use it simply like this:
nm -g yourLib.so
If you want to see symbols of a C++ library, add the \"-C\" option which demangle the symbols (it\'s far more readable demangled).
nm -gC yourLib.so
If your .so file is in elf format, you have two options:
Either objdump
(-C
is also useful for demangling 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
Or 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
If your .so
file is in elf format, you can use readelf program to extract symbol information from the binary. This command will give you the symbol table:
readelf -Ws /usr/lib/libexample.so
You only should extract those that are defined in this .so
file, not in the libraries referenced by it. Seventh column should contain a number in this case. You can extract it by using a simple regex:
readelf -Ws /usr/lib/libstdc++.so.6 | grep \'^\\([[:space:]]\\+[^[:space:]]\\+\\)\\{6\\}[[:space:]]\\+[[:digit:]]\\+\'
or, as proposed by Caspin,:
readelf -Ws /usr/lib/libstdc++.so.6 | awk \'{print $8}\';
objdump -TC /usr/lib/libexample.so
For shared libraries libNAME.so the -D switch was necessary to see symbols in my Linux
nm -D libNAME.so
and for static library as reported by others
nm -g libNAME.a
I kept wondering why -fvisibility=hidden and #pragma GCC visibility did not seem to have any influence, as all the symbols were always visible with nm - until I found this post that pointed me to readelf and objdump, which made me realize that there seem to actually be two symbol tables:
I think the former contains debugging symbols that can be stripped with strip or the -s switch that you can give to the linker or the install command. And even if nm does not list anything anymore, your exported symbols are still exported because they are in the ELF \"dynamic symbol table\", which is the latter.
Try adding -l to the nm flags in order to get the source of each symbol. If the library is compiled with debugging info (gcc -g) this should be the source file and line number. As Konrad said, the object file / static library is probably unknown at this point.
You can use the nm -g
tool from the binutils toolchain. However, their source is not always readily available. and I\'m not actually even sure that this information can always be retrieved. Perhaps objcopy
reveals further information.
/EDIT: The tool\'s name is of course nm
. The flag -g
is used to show only exported symbols.
For Android .so
files, the NDK toolchain comes with the required tools mentioned in the other answers: readelf
, objdump
and nm
.
For C++ .so
files, the ultimate nm
command is 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)
source: https://stackoverflow.com/a/43257338
nm -g list the extern variable, which is not necessary exported symbol. Any non-static file scope variable(in C) are all extern variable.
nm -D will list the symbol in the dynamic table, which you can find it\'s address by dlsym.
nm --version
GNU nm 2.17.50.0.6-12.el5 20061020