- How can I look inside a Linux .so or .a object and see what functions they contain?
- 2 Answers 2
- How do I list the symbols in a .so file
- 11 Answers 11
- How to List the Symbols in a .So File
- nm — show file that declares a symbol in a .so file
- How do I find out what all symbols are exported from a shared object?
- How can I look inside a Linux .so or .a object and see what functions they contain?
- How to list all externally-undefined symbols of a static library on Linux?
- 2 Answers 2
- How do I find out what all symbols are exported from a shared object?
- 9 Answers 9
How can I look inside a Linux .so or .a object and see what functions they contain?
The linker can presumably do this, so is there a command-line tool to list functions in object files and tell me the names of functions and their signatures?
2 Answers 2
For a shared library, you have to use:
Without the -D , nm dumps debug symbols; -D refers to the dynamic symbols that are actually used for dynamic linking. From Ubuntu 12 session:
$ nm /lib/i386-linux-gnu/libc.so.6 nm: /lib/i386-linux-gnu/libc.so.6: no symbols $ nm -D /lib/i386-linux-gnu/libc.so.6 | tail 0011fc20 T xdr_wrapstring 001202c0 T xdrmem_create 00115540 T xdrrec_create 001157f0 T xdrrec_endofrecord 00115740 T xdrrec_eof 00115690 T xdrrec_skiprecord 00120980 T xdrstdio_create 00120c70 T xencrypt 0011d330 T xprt_register 0011d450 T xprt_unregister
On this system libc.so is stripped of debug symbols, so nm shows nothing; but of course there are symbols for the dynamic linking mechanism revealed by nm -D .
For a .a archive or .o object file, just nm . The symbols are the symbols; if these files are stripped, these objects cannot be used for linking.
Exported sumbols are indicated by a T . Required symbols that must be loaded from other shared objects have a U . Note that the symbol table does not include just functions, but exported variables as well.
Or if you only want to see exported symbols, add the —defined-only flag. eg: nm -D —defined-only /lib/libtest.so
How do I list the symbols in a .so file
How do I 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 platform makes a difference. Apple provides a GCC 4.0, but its nm does not respond to some options, like -D and -g (IIRC).
11 Answers 11
The standard tool for listing symbols is nm , you can use it simply like this:
If you want to see symbols of a C++ library, add the «-C» option which demangle the symbols (it’s far more readable demangled).
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
$ 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
How to List the Symbols in a .So File
The standard tool for listing symbols is nm , you can use it simply like this:
If you want to see symbols of a C++ library, add the «-C» option which demangle the symbols (it’s far more readable demangled).
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
$ 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
nm — show file that declares a symbol in a .so file
If I compile this file into a shared object file, file.so, I should get a «U» for the get_data symbol
You are mistaken: since nothing references get_data , you wouldn’t in fact get a U for it.
To answer your question: the info that file.cpp referenced get_data symbol is gone, unless you compiled file.cpp with debugging info.
If you did, you could use objdump -dS file.so to find that file.cpp is where the reference originates.
How do I find out what all symbols are exported from a shared object?
Do you have a «shared object» (usually a shared library on AIX), a UNIX shared library, or a Windows DLL? These are all different things, and your question conflates them all 🙁
- For an AIX shared object, use dump -Tv /path/to/foo.o .
- For an ELF shared library, use readelf -Ws —dyn-syms /path/to/libfoo.so , or (if you have GNU nm) nm -D /path/to/libfoo.so .
- For a non-ELF UNIX shared library, please state which UNIX you are interested in.
- For a Windows DLL, use dumpbin /EXPORTS foo.dll .
How can I look inside a Linux .so or .a object and see what functions they contain?
you can do nm Linux.so and it’ll show the functions and variables inside the .so file.
How to list all externally-undefined symbols of a static library on Linux?
So that I can find out all external symbol dependencies of this library.
2 Answers 2
ld -r -o deleteme.o --whole-archive libfoo.a nm -C --undefined-only deleteme.o # `-C` if you might have C++ archive members rm deleteme.o
extern void two(void); void one()
extern void three(void); void two()
Make a static library libonetwo.a :
$ gcc -Wall -c one.c two.c $ ar rcs libonetwo.a one.o two.o
nm parses the static library as if it were just a commandline list of its members:
$ nm --undefined-only libonetwo.a one.o: U _GLOBAL_OFFSET_TABLE_ U two two.o: U _GLOBAL_OFFSET_TABLE_ U three
So incrementally link them all into a temporary object file:
$ ld -r -o deleteme.o --whole-archive libonetwo.a
Then see the residual undefined symbols of that object file and delete it:
$ nm --undefined-only deleteme.o && rm deleteme.o U _GLOBAL_OFFSET_TABLE_ U three
There is no single command (that I know of) that will do that.
But it’s trivial to construct two commands, one for all undefined, and one for all defined symbols, and then show only the difference between them.
First nm prints only defined symbols. Second nm prints only undefined symbols (which may be defined in another file in the same library).
The comm -13 prints only lines from second nm which do not occur in the output from the first nm .
How do I find out what all symbols are exported from a shared object?
All symbols in the object are exported — even the «internal» functions. You just have to declare them to the compiler so that they’ll be ready for the linker. This is usually done with a header file, like Ryan Fox said below.
Chris Lutz is mistaken: not all symbols are exported from relocatable object files, much less from shared libraries.
9 Answers 9
Do you have a «shared object» (usually a shared library on AIX), a UNIX shared library, or a Windows DLL? These are all different things, and your question conflates them all 🙁
- For an AIX shared object, use dump -Tv /path/to/foo.o .
- For an ELF shared library, use readelf -Ws —dyn-syms /path/to/libfoo.so , or (if you have GNU nm) nm -D /path/to/libfoo.so .
- For a non-ELF UNIX shared library, please state which UNIX you are interested in.
- For a Windows DLL, use dumpbin /EXPORTS foo.dll .
Very helpful, good to have such overview. nm also works on MacOSX, except the -D option. Or brew install binutils and use the GNU version via gnm . For GNU nm , —demangle is also useful. Also gobjdump .
Actually, you can work both with shared libraries, dlls, and object filles from a single utility just fine, see this answer.
I suppose there is no API to do this in runtime, right? I’ve found that on windows you have GetProcAddress() but you can’t use it without actually executing the library (which is very dangerous if the parent app has too much access rights).
objdump is another good one on linux.
If it is a Windows DLL file and your OS is Linux then use winedump:
$ winedump -j export pcre.dll Contents of pcre.dll: 229888 bytes Exports table: Name: pcre.dll Characteristics: 00000000 TimeDateStamp: 53BBA519 Tue Jul 8 10:00:25 2014 Version: 0.00 Ordinal base: 1 # of functions: 31 # of Names: 31 Addresses of functions: 000375C8 Addresses of name ordinals: 000376C0 Addresses of names: 00037644 Entry Pt Ordn Name 0001FDA0 1 pcre_assign_jit_stack 000380B8 2 pcre_callout 00009030 3 pcre_compile .
On *nix check nm. On windows use the program Dependency Walker
Specifically, nm —defined-only -g something.so will print the symbols that are both defined in the library and extern symbols, which is probably what the OP wants.
GNU nm lists the symbols from object files objfile. If no object files are listed as arguments, nm assumes the file a.out.
The cross-platform way (not only cross-platform itself, but also working, at the very least, with both *.so and *.dll ) is using reverse-engineering framework radare2. E.g.:
$ rabin2 -s glew32.dll | head -n 5 [Symbols] vaddr=0x62afda8d paddr=0x0005ba8d ord=000 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=glew32.dll___GLEW_3DFX_multisample vaddr=0x62afda8e paddr=0x0005ba8e ord=001 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=glew32.dll___GLEW_3DFX_tbuffer vaddr=0x62afda8f paddr=0x0005ba8f ord=002 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=glew32.dll___GLEW_3DFX_texture_compression_FXT1 vaddr=0x62afdab8 paddr=0x0005bab8 ord=003 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=glew32.dll___GLEW_AMD_blend_minmax_factor
As a bonus, rabin2 recognizes C++ name mangling, for example (and also with .so file):
$ rabin2 -s /usr/lib/libabw-0.1.so.1.0.1 | head -n 5 [Symbols] vaddr=0x00027590 paddr=0x00027590 ord=124 fwd=NONE sz=430 bind=GLOBAL type=FUNC name=libabw::AbiDocument::isFileFormatSupported vaddr=0x0000a730 paddr=0x0000a730 ord=125 fwd=NONE sz=58 bind=UNKNOWN type=FUNC name=boost::exception::~exception vaddr=0x00232680 paddr=0x00032680 ord=126 fwd=NONE sz=16 bind=UNKNOWN type=OBJECT name=typeinfoforboost::exception_detail::clone_base vaddr=0x00027740 paddr=0x00027740 ord=127 fwd=NONE sz=235 bind=GLOBAL type=FUNC name=libabw::AbiDocument::parse
Works with object files too:
$ g++ test.cpp -c -o a.o $ rabin2 -s a.o | head -n 5 Warning: Cannot initialize program headers Warning: Cannot initialize dynamic strings Warning: Cannot initialize dynamic section [Symbols] vaddr=0x08000149 paddr=0x00000149 ord=006 fwd=NONE sz=1 bind=LOCAL type=OBJECT name=std::piecewise_construct vaddr=0x08000149 paddr=0x00000149 ord=007 fwd=NONE sz=1 bind=LOCAL type=OBJECT name=std::__ioinit vaddr=0x080000eb paddr=0x000000eb ord=017 fwd=NONE sz=73 bind=LOCAL type=FUNC name=__static_initialization_and_destruction_0 vaddr=0x08000134 paddr=0x00000134 ord=018 fwd=NONE sz=21 bind=LOCAL type=FUNC name=_GLOBAL__sub_I__Z4funcP6Animal