By Moe

2008-08-29 16:57:47 8 Comments

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.


@Steve Gury 2008-08-29 17:21:08

The standard tool for listing symbols is nm, you can use it simply like this:

nm -gD

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 -gDC

If your .so file is in elf format, you have two options:

Either objdump (-C is also useful for demangling C++):

$ objdump -TC     file format elf64-x86-64

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
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 [email protected]_2.2.5 (14)
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND [email protected]_2.2.5 (14)
     4: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTable

@Brooks Moses 2010-12-13 23:53:22

This doesn't always work with .so files, though, and so you may have to use the "readelf" solution mentioned in another answer.

@Kevin Parker 2012-06-20 22:07:59

Great answer - but I don't get the function signatures from nm, objdump or readelf. Do you know how I can get the function signature (parameters) as well?

@fredbaba 2013-06-12 21:13:34

Note that OS X versions of nm are missing the '-C' option for demangling symbols. c++filt can be used instead. Example script here: nm -g /usr/lib/libstdc++.6.dylib | c++filt -p -i

@Andrew B 2014-05-27 15:32:06

Note that readelf -Ws will show you all symbols, and nm -g shows only the externally visible symbols. This may be confusing if you are examining multiple symbol files and start interchanging your commands.

@Yan Foto 2015-08-04 19:26:23

I would also add objectdump -TC to the list. In contrary to readelf -Ws, it doesn't show the mangled names.

@Ioannis Filippidis 2017-04-15 12:39:38

For those searching for what the numbers in parentheses at the end of each line mean, see this description.

@user7610 2018-01-06 00:09:39

@BrooksMoses For .so files you may need to add --dynamic to nm command line.

@nonsensickle 2018-03-22 07:28:00

Much like readelf, objdump needs the -W flag or it might truncate the symbol but unlike readelf, objdump can demangle the symbols without an external tool.

@jozxyqk 2019-09-13 18:45:19

nm -g gave nm: no symbols. For reference,…

@Chris Dodd 2019-11-24 21:19:55

This generally doesn't work for .so files on Linux -- you need to ad -D or --dynamic

@Craig Ringer 2019-02-08 11:30:53

If you just want to know if there are symbols present you can use

objdump -h /path/to/object

or to list the debug info

objdump -g /path/to/object

@user7610 2018-01-06 00:05:35

For C++ .so files, the ultimate nm command is nm --demangle --dynamic --defined-only --extern-only <>

# nm --demangle --dynamic --defined-only --extern-only /usr/lib64/ | 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)


@Adi Shavit 2014-11-04 15:33:32

For Android .so files, the NDK toolchain comes with the required tools mentioned in the other answers: readelf, objdump and nm.

@cavila 2013-02-06 19:54:44

For shared libraries the -D switch was necessary to see symbols in my Linux

nm -D

and for static library as reported by others

nm -g libNAME.a

@zhaorufei 2010-11-11 07:00:56

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 20061020

@Peter Remmers 2010-09-07 08:55:02

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:

  • The one you can list with nm
  • The one you can list with readelf and objdump

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.

@Brooks Moses 2010-12-13 23:54:04

Thank you! This explains why sometimes "nm" doesn't show any symbols for .so files.

@pt123 2013-07-29 08:31:05

nm -D - lets you list the dynamic symbol table

@P Shved 2009-10-25 10:39:36

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/

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/ | grep '^\([[:space:]]\+[^[:space:]]\+\)\{6\}[[:space:]]\+[[:digit:]]\+'

or, as proposed by Caspin,:

readelf -Ws /usr/lib/ | awk '{print $8}';

@deft_code 2010-03-09 07:34:27

readelf -Ws /usr/lib/ | awk '{print $8}'; regexes are awesome but sometimes a little awk goes a long way.

@Pavel Lapin 2010-01-15 18:25:47

objdump -TC /usr/lib/

@Adam Mitz 2008-08-29 21:22:13

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.

@Konrad Rudolph 2008-08-29 17:07:11

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.

Related Questions

Sponsored Content

20 Answered Questions

[SOLVED] Reference — What does this symbol mean in PHP?

4 Answered Questions

[SOLVED] How to add a default include path for GCC in Linux?

78 Answered Questions

[SOLVED] How do I iterate over the words of a string?

  • 2008-10-25 08:58:21
  • Ashwin Nanjappa
  • 2177770 View
  • 2985 Score
  • 78 Answer
  • Tags:   c++ string split

1 Answered Questions

[SOLVED] The Definitive C++ Book Guide and List

  • 2008-12-23 05:23:56
  • grepsedawk
  • 2362260 View
  • 4243 Score
  • 1 Answer
  • Tags:   c++ c++-faq

28 Answered Questions

[SOLVED] How do you set, clear, and toggle a single bit?

10 Answered Questions

[SOLVED] Improve INSERT-per-second performance of SQLite

28 Answered Questions

[SOLVED] How to automatically generate a stacktrace when my program crashes

24 Answered Questions

[SOLVED] Image Processing: Algorithm Improvement for 'Coca-Cola Can' Recognition

2 Answered Questions

Sponsored Content