2008-08-29 2 views
344

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

Я использую GCC 4.0.2, если это делает разницу

+0

Платформа делает разницу. Apple предоставляет GCC 4.0, но его `nm` не отвечает на некоторые параметры, такие как` -D` и `-g` (IIRC). – jww 2015-09-13 08:50:37

+0

Это ничего не выводит на Mac OS. – 2016-05-10 14:05:14

+3

@jww потому что это BSD `nm`, а не GNU` nm`. – OrangeDog 2016-08-03 17:00:16

ответ

419

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

nm -g yourLib.so 

Если вы хотите увидеть символы в C++ библиотеки, добавить «-С» вариант, который demangle символов (это гораздо более читаемо).

nm -gC yourLib.so 

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

Либо 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 [email protected]_2.2.5 (14) 
    3: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (14) 
    4: 0000000000000000  0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable 
+23

Это не всегда работает.поэтому файлы, тем не менее, и поэтому вам, возможно, придется использовать решение «readelf», упомянутое в другом ответе. – 2010-12-13 23:53:22

+0

Отличный ответ - но я не получаю сигнатуры функций от nm, objdump или readelf. Вы знаете, как я могу получить подпись (параметры) функции? – 2012-06-20 22:07:59

+7

Обратите внимание, что в версиях OS X версии nm отсутствует опция «-C» для демонтажа символов. Вместо этого можно использовать фильтр C++. Пример сценария здесь: http://v8.googlecode.com/svn/branches/bleeding_edge/tools/mac-nm nm -g /usr/lib/libstdc++.6.dylib | C++ filt -p -i – fredbaba 2013-06-12 21:13:34

9

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

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

11

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

64

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

readelf -Ws /usr/lib/libexample.so 

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

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

или, как предложенный Caspin,:

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

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

  • Тот, который вы можете получить список с нм
  • тот, который вы можете перечислить с readelf и objdump

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

5

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

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

нм --version

GNU нм 2.17.50.0.6-12.el5 20061020

30

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

nm -D libNAME.so 

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

nm -g libNAME.a 
7

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

3

Для 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

Смежные вопросы