Как мне перечислить символы, экспортируемые из файла .so? Если возможно, я также хотел бы знать их источник (например, если они извлекаются из статической библиотеки).
Платформа имеет значение. Apple предоставляет GCC 4.0, но nmон не отвечает на некоторые параметры, такие как -Dи -g(IIRC).
jww
Это ничего не печатает на Mac OS.
Игорь Ганапольский
3
@jww, потому что это BSD nm, а не GNU nm.
OrangeDog
Ответы:
577
Стандартный инструмент для перечисления символов 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:ValueSizeTypeBindVisNdxName0:00000000000000000 NOTYPE LOCAL DEFAULT UND
1:00000000000020100 SECTION LOCAL DEFAULT 102:00000000000000000 FUNC GLOBAL DEFAULT UND free@GLIBC_2.2.5(14)3:00000000000000000 FUNC GLOBAL DEFAULT UND __errno_location@GLIBC_2.2.5(14)4:00000000000000000 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable
Однако это не всегда работает с файлами .so, поэтому вам, возможно, придется использовать решение "readelf", упомянутое в другом ответе.
Брукс Моисей
9
Обратите внимание, что в версиях OS X nm отсутствует опция -C для разметки символов. C ++ Filter может быть использован вместо. Пример скрипта здесь: v8.googlecode.com/svn/branches/bleeding_edge/tools/mac-nm nm -g /usr/lib/libstdc++.6.dylib | C ++ Filter -p -i
Фредбаба
5
Обратите внимание, что readelf -Wsбудут показаны все символы и nm -gпоказаны только внешне видимые символы. Это может сбивать с толку, если вы изучаете несколько файлов символов и начинаете обмениваться командами.
Андрей Б,
3
Я бы тоже добавил objectdump -TCв список. В отличие от этого readelf -Ws, он не показывает искаженные имена.
Ян Фото
2
@BrooksMoses Для .soфайлов может потребоваться добавить --dynamicв nmкомандную строку.
user7610
84
Если ваш .soфайл в формате elf, вы можете использовать программу readelf для извлечения символьной информации из двоичного файла. Эта команда выдаст вам таблицу символов:
readelf -Ws/usr/lib/libexample.so
Вы должны извлекать только те, которые определены в этом .soфайле, а не в библиотеках, на которые он ссылается. Седьмой столбец должен содержать число в этом случае. Вы можете извлечь его с помощью простого регулярного выражения:
Я продолжал задаваться вопросом, почему -fvisibility = hidden и #pragma Видимость GCC , похоже, не имела никакого влияния, поскольку все символы всегда были видны с nm - пока я не нашел этот пост, который указал мне на readelf и objdump , что заставило меня понять, что там кажется, на самом деле две таблицы символов:
Тот, который вы можете перечислить с нм
Тот, который вы можете перечислить с readelf и objdump
Я думаю, что первый содержит символы отладки, которые можно удалить с помощью strip или переключателя -s, который вы можете передать компоновщику или команде установки . И даже если nm больше ничего не перечисляет, ваши экспортированные символы все еще экспортируются, потому что они находятся в «динамической таблице символов» ELF, которая является последней.
Спасибо! Это объясняет, почему иногда «nm» не отображает символы для файлов .so.
Брукс Моисей
10
nm -D - позволяет вам перечислить динамическую таблицу символов
pt123
19
Для .soфайлов C ++ конечная 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 add0000000000049500 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)
Попробуйте добавить -l к флагам nm, чтобы получить источник каждого символа. Если библиотека скомпилирована с отладочной информацией (gcc -g), это должны быть исходный файл и номер строки. Как сказал Конрад, объектный файл / статическая библиотека на данный момент, вероятно, неизвестны.
Вы можете использовать nm -gинструмент из набора инструментов binutils. Тем не менее, их источник не всегда легко доступен. и я даже не уверен, что эту информацию всегда можно получить. Возможно, objcopyраскрывает дополнительную информацию.
/ EDIT: название инструмента, конечно nm. Флаг -gиспользуется для отображения только экспортированных символов.
nm -g перечисляет внешнюю переменную, которая не является обязательным экспортируемым символом. Любая нестатическая переменная области видимости файла (в C) является внешней переменной.
nm -D перечислит символ в динамической таблице, адрес которой вы можете найти по dlsym.
nm
он не отвечает на некоторые параметры, такие как-D
и-g
(IIRC).nm
, а не GNUnm
.Ответы:
Стандартный инструмент для перечисления символов
nm
, вы можете использовать его просто так:Если вы хотите видеть символы библиотеки C ++, добавьте опцию «-C», которая разбирает символы (она гораздо более читаема).
Если ваш файл .so имеет формат elf, у вас есть два варианта:
Либо
objdump
(-C
также полезно для разборки C ++):Или используйте
readelf
:источник
readelf -Ws
будут показаны все символы иnm -g
показаны только внешне видимые символы. Это может сбивать с толку, если вы изучаете несколько файлов символов и начинаете обмениваться командами.objectdump -TC
в список. В отличие от этогоreadelf -Ws
, он не показывает искаженные имена..so
файлов может потребоваться добавить--dynamic
вnm
командную строку.Если ваш
.so
файл в формате elf, вы можете использовать программу readelf для извлечения символьной информации из двоичного файла. Эта команда выдаст вам таблицу символов:Вы должны извлекать только те, которые определены в этом
.so
файле, а не в библиотеках, на которые он ссылается. Седьмой столбец должен содержать число в этом случае. Вы можете извлечь его с помощью простого регулярного выражения:или, как предложил Каспин ,
источник
источник
Для разделяемых библиотек libNAME.so ключ -D был необходим, чтобы увидеть символы в моем Linux
и для статической библиотеки, как сообщили другие
источник
Я продолжал задаваться вопросом, почему -fvisibility = hidden и #pragma Видимость GCC , похоже, не имела никакого влияния, поскольку все символы всегда были видны с nm - пока я не нашел этот пост, который указал мне на readelf и objdump , что заставило меня понять, что там кажется, на самом деле две таблицы символов:
Я думаю, что первый содержит символы отладки, которые можно удалить с помощью strip или переключателя -s, который вы можете передать компоновщику или команде установки . И даже если nm больше ничего не перечисляет, ваши экспортированные символы все еще экспортируются, потому что они находятся в «динамической таблице символов» ELF, которая является последней.
источник
Для
.so
файлов C ++ конечнаяnm
командаnm --demangle --dynamic --defined-only --extern-only <my.so>
источник: https://stackoverflow.com/a/43257338
источник
Попробуйте добавить -l к флагам nm, чтобы получить источник каждого символа. Если библиотека скомпилирована с отладочной информацией (gcc -g), это должны быть исходный файл и номер строки. Как сказал Конрад, объектный файл / статическая библиотека на данный момент, вероятно, неизвестны.
источник
Для Android
.so
файлов, Набор инструментов NDK поставляется с необходимыми инструментами , упомянутыми в других ответах:readelf
,objdump
иnm
.источник
Вы можете использовать
nm -g
инструмент из набора инструментов binutils. Тем не менее, их источник не всегда легко доступен. и я даже не уверен, что эту информацию всегда можно получить. Возможно,objcopy
раскрывает дополнительную информацию./ EDIT: название инструмента, конечно
nm
. Флаг-g
используется для отображения только экспортированных символов.источник
nm -g перечисляет внешнюю переменную, которая не является обязательным экспортируемым символом. Любая нестатическая переменная области видимости файла (в C) является внешней переменной.
nm -D перечислит символ в динамической таблице, адрес которой вы можете найти по dlsym.
нм - версия
GNU nm 2.17.50.0.6-12.el5 20061020
источник
Если вы просто хотите знать , если есть символы представляют вы можете использовать
или перечислить отладочную информацию
источник