Jowell's blog

Getting Started with the nm Command

Introduction

The nm command is a tool that allows you to inspect the symbol table of a binary file on Unix-like systems. It can help us debug and understand the structure of a binary file, especially when linked with libraries. If you are a C/C++ developer, you will likely encounter this command when dealing with shared libraries or static libraries.

Basic Usage

To use the nm command, you can simply run it with the path to the binary file you want to inspect. For example, if you have a binary file named my_program, you can run:

nm your_program

The nm command also supports inspecting shared libraries, static libraries, and object files, as follows:

nm your_shared_library.so
nm your_archive.a
nm your_object_file.o

Note that all the files above are object files, which are files generated by the compiler during the compilation process. We also call them ELF (Executable Linkable Format) files on Unix-like systems, and PE-COFF files on Windows.

Options Exaplained

The following is a collection of common options in the nm command.

Option Meaning
-C Displays symbols without mangling
-D / --dynamic Displays dynamic symbols only
--defined-only Displays defined symbols only
-u / --undefined-only Displays undefined symbols only
-g / --extern-only Displays external symbols only

Outputs Explained

The output of the nm command is a list of symbols in the object files, each with its corresponding address and type. The following is a list of these types.

Type Definition
B/b The symbol living in .bss segment.
D/d The symbol living in .data segment.
T/t The symbol living in .text segment.
U The undefined symbols.
u The global unique symbol.
V/v The symbol of a weak object.
W/w The symbol of a weak symbol that has not been specifically tagged as a weak object symbol.
R/r The symbol living in .rodata segment.

Examples

To retrieve common symbols between two ELF files

Given two ELF files elf1 and elf2, we use these following commands to retrieve common symbols.

nm -CD --defined-only elf1 | awk '{for (i=2; i<=NF; i++) printf $i (i==NF?RS:OFS)}' | sort > output1.txt
nm -CD --defined-only elf2 | awk '{for (i=2; i<=NF; i++) printf $i (i==NF?RS:OFS)}' | sort > output2.txt

common_symbols=$(comm -12 output1.txt output2.txt | grep -v 'W ' | grep -v 'V ' | grep -v 'u ')

#nm #tutorial