When to use --dynamic option in nm

szli picture szli · Mar 11, 2013 · Viewed 8.1k times · Source

Sometimes when I do nm on a .so file (for example, libstdc++.so.6), it says no symbols, and I need to use nm --dynamic. But for some other .so files, I can see the symbols without --dynamic.

The doc says:

Display the dynamic symbols rather than the normal symbols. This is only meaningful for dynamic objects, such as certain types of shared libraries.

But it is confusing... what "types" of shared libraries need --dynamic? How is this determined? During the compilation of the library? I thought all shared libraries are dynamic (I mean, can be dynamically loaded during run time), but seems that my understanding is not quite right.

Answer

Tuxdude picture Tuxdude · Mar 11, 2013

It could very well possible that if your symbol is not exported from your shared library, it would end up in the normal symbol table instead of the dynamic symbol table.

There are many types of symbols in ELF files.

  • symbols part of the Normal Symbol table. This is the output from mere nm libabc.so or objdump --syms libabc.so. These symbols are only used during static linking.

  • symbols part of the Dynamic Symbol table. This is the output from nm --dynamic libabc.so or objdump --dynamic-syms libabc.so. Dynamic symbol table is the one used by the run-time linker/loader which binds the symbols between the ELF file which refers them and the ELF file which defines them. It is also used by the static linker, while linking a shared library with an application which requires it. This is the component which helps in showing all the undefined symbol errors during linking.

  • Hidden symbols - these are the symbols which have been marked using _attribute_ ((visibility("hidden"))). These symbols are not exported outside and can only be used within the library. The visibility is checked during the linking step, and hence is enforced only for shared libraries. The default visibility is public, i.e. the symbols are exported unless otherwise specified. The behavior can be modified using the -fvisibility=default|internal|hidden|protected.

Set the default ELF image symbol visibility to the specified option—all symbols will be marked with this unless overridden within the code. Using this feature can very substantially improve linking and load times of shared object libraries, produce more optimized code, provide near-perfect API export and prevent symbol clashes. It is strongly recommended that you use this in any shared objects you distribute. Despite the nomenclature, default always means public ie; available to be linked against from outside the shared object. protected and internal are pretty useless in real-world usage so the only other commonly used option will be hidden. The default if -fvisibility isn't specified is default, i.e., make every symbol public—this causes the same behavior as previous versions of GCC.

An overview of these techniques, their benefits and how to use them is at http://gcc.gnu.org/wiki/Visibility.

To answer your question when would you use the --dynamic option of nm, it would be when you want to list all the symbols exported by your shared library, and the only ones that are available to the ELF images which reference them.