nm Command in Linux

Introduction

In this tutorial, we will delve into the Linux nm command, a crucial utility for displaying symbol table information within object files. This nm command is invaluable for both developers and systemadmin professionals seeking to understand the intricacies of executable file structures. Our focus will be on mastering the nm command to reveal symbol data, refine outputs, and gain deeper insights into executable programs.

This guide includes: An introduction to the nm Command, Displaying Symbol Information within an Executable, and Refining Symbol Information Using nm Options. Following these steps allows comprehensive grasp on the nm command and its practical uses for system administration and software development projects.

Introduction to the nm Command

This section will focus on the Linux nm command, a tool used to display symbol information from object files. Developers and system administrators utilize the nm command to better understand the inner workings of executable files.

Let's begin by creating a basic C program and compiling it into an executable:

cd ~/project
nano hello.c

Insert the following code into the hello.c file:

#include <stdio.h>

int main() {
    printf("Hello, World!\n");
    return 0;
}

Now, compile the program using:

gcc -o hello hello.c

To examine the symbol information for the hello executable, use the nm command:

nm hello

Example output:

0000000000001119 T main
                 U printf

This output tells us that the hello executable includes a symbol named main at address 0x0000000000001119 and references the printf symbol, which is likely part of the C standard library.

The nm command provides numerous options for customizing the output and filtering symbol data. We will explore these options in the subsequent section.

Displaying Symbol Information of an Executable

In this segment, we'll dive into the various options provided by the nm command to present more in-depth symbol information for the hello executable created earlier.

First, examine the output of the base nm command:

nm hello

Example output:

0000000000001119 T main
                 U printf

This output reveals the symbol's name and its corresponding address within the executable. The letter T signifies that main is a global function, while U denotes that printf is an undefined symbol, probably provided by an external library.

To acquire richer detail, utilize the following nm options:

  • nm -A hello: Shows the file name alongside the symbol information.
  • nm -n hello: Sorts the output according to symbol name instead of address.
  • nm -p hello: Displays the output in a more easily readable, post-processed format.
  • nm -C hello: De-mangles C++ symbol names for enhanced readability.

Example output:

hello:0000000000001119 T main
hello:                 U printf

Combine these options to tailor the output even further. For example:

nm -nC hello

Example output:

hello:                 U std::ostream::operator<<(char const*)
hello:0000000000001119 T main

This command sorts symbols by name, with C++ symbols de-mangled to improve readability. This is especially helpful for systemadmin tasks involving C++ code.

The nm command gives ample data about the internal structure of executable files. The command is helpful for developers, system administrators, and security researchers.

Filtering Symbol Information Using nm Options

This part of the tutorial shows how to refine the displayed symbol information of the hello executable using the nm command.

For larger executables, the nm command's output can be difficult to navigate. We can narrow the focus to specific types of symbols using these nm options:

  • nm -D hello: Shows solely the dynamic symbols (those employed by the dynamic linker).
  • nm -T hello: Displays only the static (global) symbols.
  • nm -t <format> hello: Presents the symbol addresses in a chosen format (d for decimal, x for hexadecimal, o for octal).
  • nm --defined-only hello: Only defined symbols (excludes external/undefined symbols).
  • nm --undefined-only hello: Shows only undefined symbols.

For example, showing the dynamic symbols in hexadecimal:

nm -Dt hello

Example output:

0000000000001119 T main
                 U printf

To display just the static (global) symbols:

nm -T hello

Example output:

0000000000001119 T main

Options can be combined for more specific results. Here's how to display only defined symbols in a more readable manner:

nm --defined-only -nC hello

Example output:

hello:0000000000001119 T main

Filtering symbol information is especially useful when dealing with extensive or intricate executables, directing your attention to symbols that matter most.

Summary

This tutorial examined the Linux nm command, used to present symbol table data from object files. We started by constructing a simple C program and turning it into an executable, then we employed the nm command to view the executable's symbol data. We discovered that the nm command offers a variety of options to modify the output and sift through symbol information, which includes showing the file name, sorting the output by symbol name, and showing symbol type and value. This guide afforded practical knowledge of how to analyze an executable file's internal structure with the nm command. Understanding symbol tables is a key skill for any systemadmin.

400+ Linux Commands