Как мне перечислить символы, экспортируемые из файла .so? Если возможно, я также хотел бы знать их источник (например, если они извлекаются из статической библиотеки).
Я использую gcc 4.0.2, если это имеет значение.
nm
, а не GNU nm
.
Как мне перечислить символы, экспортируемые из файла .so? Если возможно, я также хотел бы знать их источник (например, если они извлекаются из статической библиотеки).
Я использую gcc 4.0.2, если это имеет значение.
nm
, а не GNU nm
.
Ответы:
Стандартный инструмент для перечисления символов 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
readelf -Ws
будут показаны все символы и nm -g
показаны только внешне видимые символы. Это может сбивать с толку, если вы изучаете несколько файлов символов и начинаете обмениваться командами.
objectdump -TC
в список. В отличие от этого readelf -Ws
, он не показывает искаженные имена.
.so
файлов может потребоваться добавить --dynamic
в nm
командную строку.
Если ваш .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 $8}';
objdump -TC /usr/lib/libexample.so
Я продолжал задаваться вопросом, почему -fvisibility = hidden и #pragma Видимость GCC , похоже, не имела никакого влияния, поскольку все символы всегда были видны с nm - пока я не нашел этот пост, который указал мне на readelf и objdump , что заставило меня понять, что там кажется, на самом деле две таблицы символов:
Я думаю, что первый содержит символы отладки, которые можно удалить с помощью strip или переключателя -s, который вы можете передать компоновщику или команде установки . И даже если nm больше ничего не перечисляет, ваши экспортированные символы все еще экспортируются, потому что они находятся в «динамической таблице символов» ELF, которая является последней.
Для .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 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
Попробуйте добавить -l к флагам nm, чтобы получить источник каждого символа. Если библиотека скомпилирована с отладочной информацией (gcc -g), это должны быть исходный файл и номер строки. Как сказал Конрад, объектный файл / статическая библиотека на данный момент, вероятно, неизвестны.
Вы можете использовать nm -g
инструмент из набора инструментов binutils. Тем не менее, их источник не всегда легко доступен. и я даже не уверен, что эту информацию всегда можно получить. Возможно, objcopy
раскрывает дополнительную информацию.
/ EDIT: название инструмента, конечно nm
. Флаг -g
используется для отображения только экспортированных символов.
nm -g перечисляет внешнюю переменную, которая не является обязательным экспортируемым символом. Любая нестатическая переменная области видимости файла (в C) является внешней переменной.
nm -D перечислит символ в динамической таблице, адрес которой вы можете найти по dlsym.
нм - версия
GNU nm 2.17.50.0.6-12.el5 20061020
Если вы просто хотите знать , если есть символы представляют вы можете использовать
objdump -h /path/to/object
или перечислить отладочную информацию
objdump -g /path/to/object
nm
он не отвечает на некоторые параметры, такие как-D
и-g
(IIRC).