The nm command lists symbols from object files, executables, and libraries. It's an essential tool for developers and system administrators who need to:
nm [OPTIONS] [FILE...]
| Option | Description |
|---|---|
-A |
Prefix each line with filename |
-a |
Display all symbols, including debugger-only symbols |
-B |
BSD format output (default on BSD systems) |
-C or --demangle |
Demangle C++ symbol names to human-readable form |
-D or --dynamic |
Display dynamic symbols only (from .dynsym) |
-f format |
Specify output format (bsd, sysv, posix) |
-g or --extern-only |
Display only external (global) symbols |
-l or --line-numbers |
Show filename and line number (if debug info available) |
-n or -v |
Sort numerically by address |
-p |
Don't sort; display in symbol table order |
-P or --portability |
Use POSIX.2 standard output format |
-r or --reverse-sort |
Reverse sort order |
-S or --print-size |
Print size of defined symbols |
-s |
Print archive index |
-t radix |
Print addresses in specified radix (d, o, x) |
-u or --undefined-only |
Display only undefined symbols |
--size-sort |
Sort symbols by size |
--special-syms |
Include special symbols |
nm displays a letter code for each symbol. Uppercase = global/external, lowercase = local:
| Code | Description | Details |
|---|---|---|
A |
Absolute | Value won't change with relocation |
B / b |
BSS segment | Uninitialized data (zero-initialized) |
C |
Common | Uninitialized data (tentative) |
D / d |
Data segment | Initialized data section |
G / g |
Small data | Initialized small objects (some architectures) |
I |
Indirect | Indirect reference to another symbol |
N |
Debugging | Debugging symbol |
R / r |
Read-only | Read-only data section (.rodata) |
S / s |
Small BSS | Uninitialized small objects (some architectures) |
T / t |
Text segment | Code section (functions) |
U |
Undefined | Referenced but not defined (needs linking) |
V / v |
Weak object | Weak symbol that can be overridden |
W / w |
Weak symbol | Can be overridden by strong symbol |
- |
Stabs | Debugging symbol (stabs format) |
? |
Unknown | Unknown symbol type |
# List all symbols in a binary
nm /bin/ls
# List symbols with addresses in hex
nm /bin/bash
# List symbols in a library
nm /usr/lib/x86_64-linux-gnu/libc.so.6
# List symbols in object file
nm program.o
Standard nm output format:
0000000000001234 T main
0000000000002345 t helper_function
U printf
0000000000004000 D global_variable
0000000000005000 b static_variable
Format: [ADDRESS] [TYPE] [NAME]
# Show only undefined symbols (dependencies)
nm -u /bin/ls
# What functions does this program need?
nm -u myprogram
# Undefined symbols with demangling
nm -Cu myprogram
# Show only external/global symbols
nm -g /bin/ls
# What functions does this library export?
nm -gD /usr/lib/libssl.so
# Show dynamic symbols only
nm -D /usr/lib/libc.so.6
# What functions are exported by this shared library?
nm -D --defined-only /usr/lib/libpthread.so.0
# Find specific symbol
nm /bin/bash | grep "main"
# Case-insensitive search
nm /bin/bash | grep -i "read"
# Find all functions starting with "str"
nm /usr/lib/libc.so.6 | grep " T str"
# Count number of functions
nm -D /usr/lib/libc.so.6 | grep " T " | wc -l
# Without demangling (mangled names)
nm mycppprogram
# Output: _Z4funcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
# With demangling (readable names)
nm -C mycppprogram
# Output: func(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
# Show symbol sizes
nm -S myprogram
# Sort by size (find largest symbols)
nm --size-sort -S myprogram
# Sort by size in reverse (largest first)
nm --size-sort -r -S myprogram
# Find bloated functions
nm --size-sort -S mybinary | tail -20
# Show line numbers (requires debug info)
nm -l myprogram
# Sort by address
nm -n myprogram
# Show addresses in decimal
nm -t d myprogram
# Show addresses in octal
nm -t o myprogram
# Process multiple files
nm file1.o file2.o file3.o
# Prefix output with filename
nm -A *.o
# Find symbol across multiple object files
nm -A *.o | grep "my_function"
# Problem: undefined reference to 'foo'
# Solution: Find which library has it
# Check if symbol is defined in your objects
nm -g *.o | grep " T foo"
# Search system libraries
nm -D /usr/lib/x86_64-linux-gnu/*.so | grep " T foo"
# Or use a script
for lib in /usr/lib/x86_64-linux-gnu/*.so*; do
if nm -D "$lib" 2>/dev/null | grep -q " T foo"; then
echo "Found in: $lib"
fi
done
# Find duplicate global symbols across object files
nm -g *.o | grep " T " | awk '{print $3}' | sort | uniq -d
# More detailed duplicate search
for symbol in $(nm -g *.o | grep " T " | awk '{print $3}' | sort | uniq -d); do
echo "Duplicate: $symbol"
nm -A *.o | grep " T $symbol"
done
# Compare symbols between two library versions
nm -D libfoo.so.1 | sort > v1.txt
nm -D libfoo.so.2 | sort > v2.txt
diff v1.txt v2.txt
# Find removed symbols (potential compatibility issues)
diff v1.txt v2.txt | grep "^<"
# Find added symbols
diff v1.txt v2.txt | grep "^>"
# Check if binary has symbols
nm myprogram
# If stripped, you'll get:
# nm: myprogram: no symbols
# Verify with file command
file myprogram
# Compare before and after stripping
nm myprogram > before.txt
strip myprogram
nm myprogram > after.txt 2>&1
diff before.txt after.txt
# List shared library dependencies
ldd /bin/ls
# Check what symbols are used from a specific library
nm -u /bin/ls | grep "printf"
nm -D /usr/lib/libc.so.6 | grep " T printf"
# nm shows symbols, objdump shows disassembly
nm -n myprogram # List symbols by address
objdump -d myprogram # Show disassembly
# Find function, then disassemble it
nm myprogram | grep "my_function"
objdump -d myprogram | grep -A 20 "my_function"
# nm shows symbol names
nm -D mylib.so
# readelf shows detailed symbol table
readelf -s mylib.so
# Compare output
nm -D mylib.so > nm_output.txt
readelf -s mylib.so > readelf_output.txt
#!/bin/bash
# Count functions, variables, and undefined symbols
echo "Functions: $(nm myprogram | grep " T " | wc -l)"
echo "Variables: $(nm myprogram | grep " [DdBb] " | wc -l)"
echo "Undefined: $(nm -u myprogram | wc -l)"
#!/bin/bash
# Report symbols larger than 1KB
nm --size-sort -S myprogram | awk '$2 > 1024 {print $0}'
Continue to: