Как мне перечислить символы в файле .so

Как мне указать символы, экспортируемые из файла .so? Если возможно, я также хотел бы знать их источник (например, если они извлечены из статической библиотеки).

Я использую gcc 4.0.2, если это имеет значение.

Платформа имеет значение. Apple предоставляет GCC 4.0, но его nm не отвечает на некоторые параметры, такие как -D и -g (IIRC).

jww 13.09.2015 11:50

Это ничего не печатает в Mac OS.

IgorGanapolsky 10.05.2016 17:05

@jww, потому что это BSD nm, а не GNU nm.

OrangeDog 03.08.2016 20:00
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
521
3
412 564
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

Вы можете использовать инструмент nm -g из набора инструментов binutils. Однако их источник не всегда доступен. и я даже не уверен, что эту информацию всегда можно получить. Возможно, objcopy раскрывает дополнительную информацию.

/ EDIT: название инструмента, конечно, nm. Флаг -g используется для отображения только экспортированных символов.

Ответ принят как подходящий

Стандартный инструмент для перечисления символов - nm, вы можете использовать его просто так:

nm -gD yourLib.so

Если вы хотите видеть символы библиотеки C++, добавьте опцию «-C», которая разоблачает символы (это намного более читабельно).

nm -gDC yourLib.so

Если ваш файл .so имеет формат elf, у вас есть два варианта:

Либо objdump (-C также полезен для разборки кода C++):

$ objdump -TC libz.so

libz.so:     file format elf64-x86-64

DYNAMIC SYMBOL TABLE:
0000000000002010 l    d  .init  0000000000000000              .init
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 free
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 __errno_location
0000000000000000  w   D  *UND*  0000000000000000              _ITM_deregisterTMCloneTable

Или используйте readelf:

$ readelf -Ws libz.so
Symbol table '.dynsym' contains 112 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000002010     0 SECTION LOCAL  DEFAULT   10
     2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND free@GLIBC_2.2.5 (14)
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __errno_location@GLIBC_2.2.5 (14)
     4: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTable

Однако это не всегда работает с файлами .so, и поэтому вам, возможно, придется использовать решение «readelf», упомянутое в другом ответе.

Brooks Moses 14.12.2010 02:53

Отличный ответ, но я не получаю сигнатуры функций от nm, objdump или readelf. Вы знаете, как я могу получить сигнатуру функции (параметры)?

Kevin Parker 21.06.2012 02:07

Обратите внимание, что в версиях nm для OS X отсутствует опция -C для разметки символов. Вместо этого можно использовать фильтрацию C++. Пример сценария здесь: v8.googlecode.com/svn/branches/bleeding_edge/tools/mac-nm nm -g /usr/lib/libstdc++.6.dylib | С ++ filter -p -i

fredbaba 13.06.2013 01:13

Обратите внимание, что readelf -Ws покажет вам символы все, а nm -g покажет только внешние видимые символы. Это может сбивать с толку, если вы исследуете несколько файлов символов и начинаете менять команды местами.

Andrew B 27.05.2014 19:32

Я бы также добавил в список objectdump -TC. В отличие от readelf -Ws, он не показывает искаженные имена.

Yan Foto 04.08.2015 22:26

Для тех, кто ищет, что означают числа в скобках в конце каждой строки, см. это описание.

Ioannis Filippidis 15.04.2017 15:39

@BrooksMoses Для файлов .so может потребоваться добавить --dynamic в командную строку nm.

user7610 06.01.2018 03:09

Как и readelf, objdump нуждается в флаге -W, иначе он может обрезать символ, но в отличие от readelf, objdump может распутывать символы без внешнего инструмента.

nonsensickle 22.03.2018 10:28

nm -g mylib.so дал nm: mylib.so: no symbols. Для справки: unix.stackexchange.com/questions/282616/…

jozxyqk 13.09.2019 21:45

Обычно это не работает для файлов .so в Linux - вам нужно указать -D или --dynamic.

Chris Dodd 25.11.2019 00:19

Попробуйте добавить -l к флагам nm, чтобы получить источник каждого символа. Если библиотека скомпилирована с отладочной информацией (gcc -g), это должен быть исходный файл и номер строки. Как сказал Конрад, объектный файл / статическая библиотека, вероятно, на данный момент неизвестны.

Если ваш файл .so имеет формат elf, вы можете использовать программу readelf для извлечения символьной информации из двоичного файла. Эта команда предоставит вам таблицу символов:

readelf -Ws /usr/lib/libexample.so

Вы должны извлекать только те, которые определены в этом файле .so, а не в библиотеках, на которые он ссылается. В этом случае седьмой столбец должен содержать число. Вы можете извлечь его с помощью простого регулярного выражения:

readelf -Ws /usr/lib/libstdc++.so.6 | grep '^\([[:space:]]\+[^[:space:]]\+\)\{6\}[[:space:]]\+[[:digit:]]\+'

или, как предложено Каспин:

readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print }';

readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $ 8}'; регулярные выражения - это круто, но иногда небольшая неудача имеет большое значение.

deft_code 09.03.2010 10:34

objdump -TC /usr/lib/libexample.so

Я продолжал задаваться вопросом, почему -fvisibility = скрытый и #pragma Видимость GCC, похоже, не имеют никакого влияния, поскольку все символы всегда были видны с нм - пока я не нашел этот пост, который указал мне на Readelf и objdump, который заставил меня понять, что, похоже, действительно существует символ два таблицы:

  • Тот, который вы можете перечислить с помощью нм
  • Тот, который вы можете указать с помощью Readelf и objdump

Я думаю, что первый содержит символы отладки, которые можно удалить с помощью полоска или переключателя -s, который вы можете передать компоновщику или команде установить. И даже если nm больше ничего не перечисляет, ваши экспортированные символы все равно экспортируются, потому что они находятся в «таблице динамических символов» ELF, которая является последней.

Спасибо! Это объясняет, почему иногда «nm» не показывает никаких символов для файлов .so.

Brooks Moses 14.12.2010 02:54

nm -D - позволяет перечислить динамическую таблицу символов

pt123 29.07.2013 12:31

nm -g перечислить внешнюю переменную, которая не является обязательным для экспортируемого символа. Любая нестатическая переменная области видимости файла (в C) является внешней переменной.

nm -D перечислит символ в динамической таблице, адрес которой вы можете найти с помощью dlsym.

nm --version

GNU nm 2.17.50.0.6-12.el5 20061020

Для разделяемых библиотек libNAME. Поэтому переключатель -D был необходим, чтобы видеть символы в моем Linux

nm -D libNAME.so

и для статической библиотеки, как сообщили другие

nm -g libNAME.a

Для файлов Android .so набор инструментов NDK поставляется с необходимыми инструментами, упомянутыми в других ответах: readelf, objdump и nm.

Для файлов C++ .so последняя команда nm - nm --demangle --dynamic --defined-only --extern-only <my.so>.

# nm --demangle --dynamic --defined-only --extern-only /usr/lib64/libqpid-proton-cpp.so | grep work | grep add
0000000000049500 T proton::work_queue::add(proton::internal::v03::work)
0000000000049580 T proton::work_queue::add(proton::void_function0&)
000000000002e7b0 W proton::work_queue::impl::add_void(proton::internal::v03::work)
000000000002b1f0 T proton::container::impl::add_work_queue()
000000000002dc50 T proton::container::impl::container_work_queue::add(proton::internal::v03::work)
000000000002db60 T proton::container::impl::connection_work_queue::add(proton::internal::v03::work)

источник: https://stackoverflow.com/a/43257338

Если вы просто хотите узнать, есть ли символы настоящее время, вы можете использовать

objdump -h /path/to/object

или чтобы перечислить отладочную информацию

objdump -g /path/to/object

Другие вопросы по теме