6

Как вывести список символов из .so файла?

1

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

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

5 ответ(ов)

8

Стандартным инструментом для просмотра символов является 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
0

Команда objdump -TC /usr/lib/libexample.so используется для вывода информации о символах (то есть, функциях и переменных), содержащихся в динамической библиотеке `lib

0

Для получения информации о символах в разделяемой библиотеке libNAME.so необходимо использовать ключ -D:

nm -D libNAME.so

Что касается статической библиотеки, как уже упоминали другие, следует применить ключ -g:

nm -g libNAME.a

Это позволит просмотреть глобальные символы в статической библиотеке.

0

Я долго думал, почему флаги -fvisibility=hidden и #pragma GCC visibility не оказывают никакого влияния, поскольку все символы всегда были видны при использовании nm, пока не наткнулся на статью, которая указала мне на readelf и objdump. Это помогло мне осознать, что существует на самом деле две таблицы символов:

  • Таблица, которую можно просмотреть с помощью nm
  • Таблица, которую можно просмотреть с помощью readelf и objdump

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

0

Для работы с .so файлами на C++, в частности для получения информации о символах, вы можете использовать команду nm с набором опций:

nm --demangle --dynamic --defined-only --extern-only <my.so>

Эта команда позволит вам увидеть только определенные и внешние символы из динамической библиотеки. Например, для библиотеки libqpid-proton-cpp.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)

Если вас интересуют версии символов, также добавьте флаг --with-symbol-versions.

Источник: ссылка на StackOverflow.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь