Home / Alt manpages / x86_64-linux-gnu-gcc-nm-13(1)

  • x86_64-linux-gnu-gcc-nm-13(1)
  • User command
  • linux

Inspect GCC and LTO Objects with gcc-nm-13

You will use the GCC 13 gcc-nm wrapper to list symbols from an object file, then see why it is useful for objects produced with link-time optimisation (LTO). The wrapper passes the appropriate GCC plugin option to nm; it is not a different symbol format or a compiler replacement.

Allow about ten minutes. You need GCC 13, GNU Binutils and a shell. The commands below only read object files or create disposable build artefacts in a working directory. They do not need sudo. Do not run them in a source tree with uncommitted generated files unless you know where the output will go.

The examples were checked with package versions gcc-13 13.3.0-6ubuntu2~24.04.1, gcc-13-x86-64-linux-gnu 13.3.0-6ubuntu2~24.04.1 and binutils 2.42-4ubuntu2.10. The installed wrapper reports the GNU nm implementation supplied by the local toolchain, so your version string and diagnostic paths may differ.

1. Check the wrapper you will run

The four names in this guide are aliases for the same GCC 13 wrapper on the tested system. Check the command selected by your PATH and read its version:

$ command -v x86_64-linux-gnu-gcc-nm-13
/usr/bin/x86_64-linux-gnu-gcc-nm-13
$ x86_64-linux-gnu-gcc-nm-13 --version
GNU nm (GNU Binutils) 2.47.20260726

That version line describes nm, because gcc-nm is a wrapper. If the command is missing, install or repair the GCC and Binutils packages through your normal system-management process. Do not substitute an unrelated nm binary just to make the example continue.

Checkpoint

You have a GCC-targeted wrapper and know which executable will receive your options.

2. Build a small ordinary object

Use a disposable source file with one global function, one global variable and one private variable. Replace the path if you already have an object you want to inspect:

$ cat > /tmp/gcc-nm-demo.c <<'EOF'
int exported_value = 42;
static int hidden_value = 7;
int add_values(int left, int right) { return left + right + hidden_value; }
EOF
$ gcc-13 -c -O0 -o /tmp/gcc-nm-demo.o /tmp/gcc-nm-demo.c

The redirection creates or replaces /tmp/gcc-nm-demo.c. This is deliberate, but check the path before pasting it. The compiler writes the object named by -o; it does not alter the source.

Now list the symbols:

$ x86_64-linux-gnu-gcc-nm-13 /tmp/gcc-nm-demo.o
0000000000000000 T add_values
0000000000000000 D exported_value
0000000000000004 d hidden_value

The exact addresses can change with compiler options and target details. The useful parts here are the names and type letters. Uppercase T and D identify global text and data symbols; lowercase d identifies a local data symbol. gcc-nm accepts the normal nm options, so -g limits the display to external symbols and -P selects a portable, one-line format:

$ x86_64-linux-gnu-gcc-nm-13 -P -g /tmp/gcc-nm-demo.o
add_values T 0 20
exported_value D 0 4

Checkpoint

The wrapper can inspect an ordinary ELF object and the output changes when you apply a documented nm option.

3. Create an LTO object

GCC's -flto stores compiler information for link-time optimisation in the object. It is still an object file, but a plain symbol reader may not know how to interpret it. Compile the same source with LTO:

$ gcc-13 -flto -c -o /tmp/gcc-nm-demo-lto.o /tmp/gcc-nm-demo.c
$ file /tmp/gcc-nm-demo-lto.o
/tmp/gcc-nm-demo-lto.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

The wording from file can vary. The important check is that the command identifies a relocatable ELF object and exits successfully. The file is not an executable and cannot be run directly.

Inspect it with the wrapper:

$ x86_64-linux-gnu-gcc-nm-13 /tmp/gcc-nm-demo-lto.o
00000000 T add_values
00000000 D exported_value

This is the practical reason to use the GCC wrapper. It supplies the appropriate --plugin option to nm, allowing the Binutils reader to understand GCC's LTO object. The command lists the symbols relevant to the object; do not expect the output to match an unoptimised object byte for byte.

4. Reproduce and interpret the plain-nm failure

Run an unwrapped nm against the LTO object only as a diagnostic comparison:

$ nm /tmp/gcc-nm-demo-lto.o
nm: /tmp/gcc-nm-demo-lto.o: plugin needed to handle lto object
0000000000000001 C __gnu_lto_slim

The exact path and ordering may differ. The useful signal is plugin needed to handle lto object. The small __gnu_lto_slim entry is not a substitute for the source symbols. It shows that plain nm has not interpreted the LTO payload correctly.

Do not fix this by copying a random plugin into a system directory. GNU Binutils documents --plugin as the mechanism for loading support for extra object types. gcc-nm packages the compiler-specific choice so that normal inspection does not depend on a hand-maintained global plugin directory.

Checkpoint

If ordinary objects work but an LTO object reports that a plugin is needed, switch to the matching GCC wrapper before investigating the object itself.

5. Narrow the output for a real inspection

Start broad, then narrow the result for the question you are answering. These read-only commands do not change the object:

$ x86_64-linux-gnu-gcc-nm-13 -g /path/to/object.o
$ x86_64-linux-gnu-gcc-nm-13 -u /path/to/object.o
$ x86_64-linux-gnu-gcc-nm-13 -C /path/to/object.o
$ x86_64-linux-gnu-gcc-nm-13 -A /path/to/one.o /path/to/two.o
  • -g shows external symbols only.
  • -u shows undefined symbols, useful for spotting unresolved dependencies.
  • -C demangles supported low-level names, which helps with C++ output.
  • -A prefixes each symbol with its input file when comparing several objects.

Pass paths as separate arguments and quote paths containing spaces. Keep shell options before the object names. If you need machine-readable processing, use -P and treat names as data rather than parsing the human-oriented default layout.

6. Clean up without touching source

The demo created three temporary files. Remove only those exact files after you have finished checking the output:

$ rm -f /tmp/gcc-nm-demo.c /tmp/gcc-nm-demo.o /tmp/gcc-nm-demo-lto.o
$ test ! -e /tmp/gcc-nm-demo.c && echo "demo files removed"
demo files removed

This cleanup is irreversible for those temporary files, so do not broaden the command to a directory or replace the paths with a wildcard. If you used an existing object instead, there is nothing to undo: gcc-nm only reads its input.

Done means

  • You confirmed the installed GCC 13 wrapper and its Binutils version.
  • You used normal nm options through gcc-nm-13 on an ordinary object.
  • You inspected a GCC LTO object successfully with the wrapper.
  • You can recognise the plain-nm plugin diagnostic.
  • You kept inspection unprivileged and removed only the disposable demo files.