Как мне указать символы, экспортируемые из файла .so? Если возможно, я также хотел бы знать их источник (например, если они извлечены из статической библиотеки).
Я использую gcc 4.0.2, если это имеет значение.
Это ничего не печатает в Mac OS.
@jww, потому что это BSD nm, а не GNU nm.





Вы можете использовать инструмент 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», упомянутое в другом ответе.
Отличный ответ, но я не получаю сигнатуры функций от nm, objdump или readelf. Вы знаете, как я могу получить сигнатуру функции (параметры)?
Обратите внимание, что в версиях 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
Обратите внимание, что readelf -Ws покажет вам символы все, а nm -g покажет только внешние видимые символы. Это может сбивать с толку, если вы исследуете несколько файлов символов и начинаете менять команды местами.
Я бы также добавил в список objectdump -TC. В отличие от readelf -Ws, он не показывает искаженные имена.
Для тех, кто ищет, что означают числа в скобках в конце каждой строки, см. это описание.
@BrooksMoses Для файлов .so может потребоваться добавить --dynamic в командную строку nm.
Как и readelf, objdump нуждается в флаге -W, иначе он может обрезать символ, но в отличие от readelf, objdump может распутывать символы без внешнего инструмента.
nm -g mylib.so дал nm: mylib.so: no symbols. Для справки: unix.stackexchange.com/questions/282616/…
Обычно это не работает для файлов .so в Linux - вам нужно указать -D или --dynamic.
Попробуйте добавить -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}'; регулярные выражения - это круто, но иногда небольшая неудача имеет большое значение.
objdump -TC /usr/lib/libexample.so
Я продолжал задаваться вопросом, почему -fvisibility = скрытый и #pragma Видимость GCC, похоже, не имеют никакого влияния, поскольку все символы всегда были видны с нм - пока я не нашел этот пост, который указал мне на Readelf и objdump, который заставил меня понять, что, похоже, действительно существует символ два таблицы:
Я думаю, что первый содержит символы отладки, которые можно удалить с помощью полоска или переключателя -s, который вы можете передать компоновщику или команде установить. И даже если nm больше ничего не перечисляет, ваши экспортированные символы все равно экспортируются, потому что они находятся в «таблице динамических символов» ELF, которая является последней.
Спасибо! Это объясняет, почему иногда «nm» не показывает никаких символов для файлов .so.
nm -D - позволяет перечислить динамическую таблицу символов
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
Платформа имеет значение. Apple предоставляет GCC 4.0, но его
nmне отвечает на некоторые параметры, такие как-Dи-g(IIRC).