Команда Linux nm
nmЭто важный инструмент командной строки в системах Linux, полное название — "Name List". Он используется для отображения информации о символах в бинарных объектных файлах (таких как библиотечные файлы и исполняемые файлы), и является распространённым инструментом для программистов и анализа бинарных файлов.
Основные возможности
- Список символов (функций, переменных и т. д.) в объектных файлах
- Отображать типы и атрибуты символов
- Помогает анализировать проблемы компоновки программ
- Помогает при отладке и обратной разработке
Базовый синтаксис
nm [选项] 文件名
Общие параметры опций
| Опция | Описание |
|---|---|
-a |
Показать все символы, включая отладочные символы |
-g |
Показывать только внешние (глобальные) символы |
-u |
Показывать только неопределённые символы |
-D |
Отображать динамические символы (для разделяемых библиотек) |
-C |
Декодировать имена символов C++ |
-l |
Отображать номера строк, где расположены символы (требуется отладочная информация) |
-S |
Отображать размеры символов |
-t |
Указать формат вывода (d — десятичный, o — восьмеричный, x — шестнадцатеричный) |
--size-sort |
Сортировать по размеру символов |
--defined-only |
Отображать только определённые символы |
Описание типов символов
nmТип символа в выводе обозначается буквой; часто встречаются следующие:
| Type | Описание |
|---|---|
| A | Абсолютный символ, не изменяется во время компоновки |
| B/b | Символ в сегменте неинициализированных данных (сегмент BSS) |
| D/d | Символ в сегменте инициализированных данных |
| T/t | Символ в сегменте кода (T для глобального, t для локального) |
| U | Неопределённый символ (должен быть слинкован из других файлов) |
| W/w | Слабый символ |
| R/r | Символ в сегменте данных только для чтения |
| C | Общий символ |
| I | Косвенная ссылка на другой символ |
Примеры практического применения
Пример 1: Просмотр таблицы символов исполняемого файла
nm /bin/ls
Пример вывода:
0000000000000000 A _IO_stdin_used 0000000000000000 R _fp_hw 0000000000000000 T _init 0000000000000000 W _ITM_deregisterTMCloneTable 0000000000000000 W _ITM_registerTMCloneTable 0000000000000000 W __cxa_finalize 0000000000000000 W __gmon_start__ 0000000000000000 T __libc_csu_fini 0000000000000000 T __libc_csu_init ...
Пример 2: Просмотр только неопределённых символов
nm -u /bin/ls
Пример вывода:
U __ctype_toupper_loc
U __errno_location
U __overflow
U __stack_chk_fail
U __strtoul_internal
U _obstack_begin
U _obstack_newchunk
U abort
U access
...
Пример 3: Просмотр символов программы на C++ (имена после демаглинга)
nm -C my_program
Пример вывода:
0000000000000000 T main 0000000000000000 T std::cout 0000000000000000 T std::basic_ostream<char, std::char_traits >& std::operator<< <std::char_traits >(std::basic_ostream<char, std::char_traits >&, char const*) ...
Пример 4: Просмотр размеров символов и сортировка по размеру
nm -S --size-sort my_library.so
Пример вывода:
0000000000000001 0000000000000001 T func1 0000000000000002 0000000000000002 T func2 0000000000000004 0000000000000004 D global_var 0000000000000008 0000000000000008 B large_buffer ...
Типичные случаи использования
1. Устранение ошибок компоновки
При возникновении ошибки "undefined reference" можно использоватьnmПроверьте, какие символы не определены:
nm -u my_program.o
2. Анализ содержимого файла библиотеки
Просмотрите символы, экспортируемые разделяемой библиотекой:
nm -D libexample.so
3. Сравнение двух версий бинарного файла
Пример
nm new_version > new.txt
diff old.txt new.txt
4. Поиск конкретных символов
nm my_program | grep "main"
Примечания
- Для бинарных файлов, из которых удалены символы,
nmполезная информация может не отображаться - Для бинарных файлов разных архитектур может потребоваться использовать инструмент из набора кросс-компиляции
nm - Динамические символы (в разделяемых библиотеках) нужно просматривать с помощью
-Dопция для просмотра - Для программ на C++ рекомендуется всегда использовать
-Cопцию демагглинга имён символов
Дополнительные советы
Комбинирование с другими инструментами
Пример
objdump -t my_program
# Используйте readelf для просмотра информации о заголовке ELF-файла
readelf -s my_program
Написание скриптов для анализа символов
Пример
# Подсчёт распределения типов символов
nm $1 | awk '{print $2}' | sort | uniq -c | sort -nr
Создание файлов сопоставления символов
nm -n my_program > symbol_map.txt
Итог
nmЭта команда — один из важных инструментов для Linux-разработчиков. Освоив её, вы сможете:
- Лучше понимать структуру программы
- Быстро находить проблемы компоновки
- Анализировать содержимое сторонних библиотек
- Помогает при отладке и обратной разработке
Благодаря базовому использованию и практическим примерам, представленным в этой статье, вы должны были освоитьnmосновной функционал команды. В реальной работе вы можете гибко использовать различные опции и параметры в соответствии с конкретными потребностями.
Другие расширения
Справочник команд Linux