<code>nm</code> is a Unix command used to dump the symbol table and their attributes from a binary executable file (including libraries, compiled object modules, shared-object files, and standalone executables).

The output from <code>nm</code> distinguishes between various symbol types. For example, it differentiates between a function that is supplied by an object module and a function that is required by it. <code>nm</code> is used as an aid for debugging, to help resolve problems arising from name conflicts and C++ name mangling, and to validate other parts of the toolchain.

This command is shipped with a number of later versions of Unix and similar operating systems including Plan 9. The GNU Project ships an implementation of <code>nm</code> as part of the GNU Binutils package.

The etymology is that in the old Version 7 Unix, <code>nm</code>'s manpage used the term name list instead of symbol table.

nm output sample

<syntaxhighlight lang="c">

/*

  • File name: test.c
  • For C code compile with:
  • gcc -c test.c
  • For C++ code compile with:
  • g++ -c test.cpp
  • /

int global_var;

int global_var_init = 26;

static int static_var;

static int static_var_init = 25;

static int static_function()

{

return 0;

}

int global_function(int p)

{

static int local_static_var;

static int local_static_var_init=5;

local_static_var = p;

return local_static_var_init + local_static_var;

}

int global_function2()

{

int x;

int y;

return x+y;

}

  1. ifdef __cplusplus

extern "C"

  1. endif

void non_mangled_function()

{

// I do nothing

}

int main(void)

{

global_var = 1;

static_var = 2;

return 0;

}

</syntaxhighlight>

If the previous code is compiled with the gcc C compiler, the output of the <code>nm</code> command is the following:

<syntaxhighlight lang="console">

  1. nm test.o

0000000a T global_function

00000025 T global_function2

00000004 C global_var

00000000 D global_var_init

00000004 b local_static_var.1255

00000008 d local_static_var_init.1256

0000003b T main

00000036 T non_mangled_function

00000000 t static_function

00000000 b static_var

00000004 d static_var_init

</syntaxhighlight>

When the C++ compiler is used, the output differs:

<syntaxhighlight lang="console">

  1. nm test.o

0000000a T _Z15global_functioni

00000025 T _Z16global_function2v

00000004 b _ZL10static_var

00000000 t _ZL15static_functionv

00000004 d _ZL15static_var_init

00000008 b _ZZ15global_functioniE16local_static_var

00000008 d _ZZ15global_functioniE21local_static_var_init

U __gxx_personality_v0

00000000 B global_var

00000000 D global_var_init

0000003b T main

00000036 T non_mangled_function

</syntaxhighlight>

The differences between the outputs also show an example of solving the name mangling problem by using extern "C" in C++ code.

{| class="wikitable"

|+ Symbol types

|-

! Symbol type

! Description

|-

| A

|Global absolute symbol

|-

| a

| Local absolute symbol

|-

| B

| Global bss symbol

|-

| b

| Local bss symbol

|-

| D

| Global data symbol

|-

| d

| Local data symbol

|-

| f

| Source file name symbol

|-

| R

| Global read-only symbol

|-

| r

| Local read-only symbol

|-

| T

| Global text symbol

|-

| t

| Local text symbol

|-

| U

| Undefined symbol

|}

See also

  • objdump
  • strings

References