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
Get a list of the functions in a shared library?
How can I get a list of the functions defined in a shared object library, or find out if a particular function is defined in one?
2 Answers 2
There are different executable file formats on a *nix system. a.out was a common format some years ago and today its ELF on nearby all major systems.
ELF consists of a headers describing each of the files data sections.
The part you are looking for is the symbol table, where each symbol (function, variable) is mapped to its address.
Shared libraries keep their global symbols in a section called .dynsym
What you are looking for are symbols of the type function and a global binding in this section.
readelf —syms ./libfoo.so will give you a output of the symbols.
On Solaris and FreeBSD theres also elfdump available.
objdump displays also a lot of information about your object file and you can specify a section by using the -j switch.
Use nm with the -D (dynamic) switch:
$ nm -D /usr/lib/libpng.so 00000000 A PNG12_0 w _Jv_RegisterClasses w __cxa_finalize U __fprintf_chk w __gmon_start__ U __longjmp_chk U __memcpy_chk U __snprintf_chk U __stack_chk_fail U _setjmp U abort U crc32 U deflate U deflateEnd U deflateInit2_ U deflateReset U fflush U fread U free U fwrite U gmtime U inflate U inflateEnd U inflateInit_ U inflateReset U malloc U memcmp U memcpy U memset 00003fd0 T png_access_version_number 00016ef0 T png_build_grayscale_palette 00004810 T png_check_sig 0001d2d0 T png_chunk_error 0001d070 T png_chunk_warning 00013390 T png_convert_from_struct_tm 00014a90 T png_convert_from_time_t 000048d0 T png_convert_to_rfc1123 000051b0 T png_create_info_struct 00013040 T png_create_read_struct 00012c20 T png_create_read_struct_2 00014a40 T png_create_write_struct 00014710 T png_create_write_struct_2 00004230 T png_data_freer 00005140 T png_destroy_info_struct 00010eb0 T png_destroy_read_struct 00013da0 T png_destroy_write_struct 0001d0f0 T png_error 0001ca10 T png_free 00004a50 T png_free_data 0001c9d0 T png_free_default .
How to list exported functions in a shared lib on Ubuntu
I have just built a shared lib on Ubuntu, and when I attempt to use the function, the application that loads the library is reporting ‘xxx’ symbol not found. I want to check (i.e. list) the functions that are exported by my library so I can investigate this issue further. Relevant details: OS: Ubuntu 9.10 compiler: gcc 4.4.1 linker: GNU ld 2.20
3 Answers 3
GNU nm lists the symbols from object files objfile. If no object files are listed as arguments, nm assumes the file a.out. [reference]
Thanks for that. It appears my symbol is exported, but undefined (it has a ‘U’ next to the function name). How can a function be exported and yet be undefined (IIRC, a linker option prevents this kind of absurbity). More importantly, what can I do to fix it?
By «Fixing it», I mean how can I ensure that my functions are exported AND DEFINED in the shared library?
Could it be that the undefined symbol is contained in another shared object? Check out Void’s advice.
Were you able to find the root cause for your problem? I am trying to link a FORTRAN-based library and it is showing a function as undefined in the output shared library
For exported functions add —defined-only option, otherwise this way you’ll get imports too. Also, to get only functions and not e.g. something like _edata , you should look for the symbols with T or t in the second column. So, something like this: nm -DCg —defined-only $MY_LIB | grep ‘^[0-9a-f]\+ [Tt] ‘
Is your shared library in the library load path or in the application’s run-time search path? It sounds like the dynamic linker can’t find your library. Try running ldd on your application to see if the library can be found at run-time, e.g.:
$ ldd /usr/bin/less linux-gate.so.1 => (0x0072a000) libncurses.so.5 => /lib/libncurses.so.5 (0x00c68000) libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x007c7000) libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0x00286000) /lib/ld-linux.so.2 (0x002a1000)
See the ld.so(8) man page for additional details on library search paths.