Keywords: Symbol Table | Shared Library | nm Tool | ELF Format | Dynamic Linking
Abstract: This article provides a comprehensive guide to listing symbols in .so files on Linux using nm, objdump, and readelf tools. It covers exporting symbols, handling C++ name mangling, and identifying symbol sources. Through practical examples, the article demonstrates tool usage and output interpretation, helping developers understand shared library symbol tables and dynamic linking mechanisms.
Overview of Symbol Listing Tools
In Linux development environments, analyzing symbols in shared libraries (.so files) is crucial for debugging and reverse engineering. Symbol tables record information about identifiers such as functions and variables, including names, types, binding attributes, and visibility. By examining symbol tables, developers can understand library interfaces, dependencies, and symbol origins.
Basic Usage of the nm Tool
nm (name list) is a standard tool in the GNU Binutils package, specifically designed to display symbol tables of object files. For shared library analysis, the most commonly used option combination is nm -gD yourLib.so.
Where:
- The
-goption shows only externally visible symbols - The
-Doption displays the dynamic symbol table (particularly important for shared libraries)
For C++ libraries, due to name mangling mechanisms, raw symbol names are difficult to read. In such cases, add the -C option for demangling:
nm -gDC yourLib.so
Name mangling is a compiler mechanism to support function overloading, encoding function names, parameter types, and other information into unique identifiers. Demangling reverses this process, restoring encoded names to readable C++ identifiers.
Advanced Analysis of ELF Format Files
Shared libraries on Linux typically use the ELF (Executable and Linkable Format) format. For ELF files, in addition to the nm tool, the following two more powerful tools can be used:
The objdump Tool
objdump provides more detailed binary file analysis capabilities. The command to view the dynamic symbol table is:
objdump -TC libz.so
Example output analysis:
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
Key field explanations:
Value: Symbol address,0000000000000000indicates undefined symbolsType: Symbol type (FUNC for functions, NOTYPE for no type)Bind: Binding attribute (GLOBAL, WEAK, LOCAL)Ndx: Section index, UND indicates undefinedName: Symbol name, may include version information
The readelf Tool
readelf is specifically designed for ELF file analysis, providing the most detailed symbol information:
readelf -Ws libz.so
Example output:
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
readelf provides more complete symbol attribute information:
Size: Symbol size in bytesVis: Visibility attribute (DEFAULT, HIDDEN, PROTECTED)Version: Symbol version information (e.g., GLIBC_2.2.5)
Symbol Origin Identification Techniques
Identifying symbol origins is essential for understanding library dependencies and build processes. By analyzing symbol tables, you can determine whether symbols are:
- Locally defined: Non-zero Value field indicates definition within the library
- External dependencies: Zero Value and UND Ndx indicate dependency on external libraries
- Static library imports: Binding attributes and section information can infer static library origins
Symbols imported from static libraries typically exhibit these characteristics:
- Visible in dynamic symbol tables but actually merged during linking
- May retain naming characteristics of the original static library
- Can be further confirmed through build process debug information
Practical Application Scenarios
In actual development, symbol analysis tools are commonly used for:
- API exploration: Understanding interfaces provided by third-party libraries
- Dependency analysis: Identifying external dependencies of libraries
- Debugging assistance: Resolving symbol conflicts and linking errors
- Reverse engineering: Analyzing functionality and structure of binary libraries
By combining these tools, developers can comprehensively grasp symbol information in shared libraries, providing strong support for software development and maintenance.