Возврат таблицы символов общей библиотеки

Например:

void* sdl_library = dlopen("libSDL.so", RTLD_LAZY);
void* initializer = dlsym(sdl_library,"SDL_Init");

При условии отсутствия ошибок инициализатор укажет на функцию SD_Init в общей библиотеке libSDK.so.

Однако для этого необходимо знать, что существует символ "SDL_Init".

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

4 ответа

Решение

Для этого нет функции libc. Тем не менее, вы можете написать один самостоятельно (хотя код несколько сложен).

В Linux dlopen() фактически возвращает адрес link_map структура, в которой есть член с именем l_addr это указывает на базовый адрес загруженного разделяемого объекта (при условии, что ваша система не рандомизирует размещение разделяемой библиотеки, и что ваша библиотека не была предварительно связана).

В Linux верный способ найти базовый адрес (адрес Elf*_Ehdr) использовать dl_iterate_phdr() после dlopen()в библиотеке.

Имея заголовок ELF, вы должны иметь возможность перебирать список экспортируемых символов (динамическую таблицу символов), сначала найдя Elf*_Phdr типа PT_DYNAMIC, а затем найти DT_SYMTAB, DT_STRTAB записи и итерации по всем символам в таблице динамических символов. использование /usr/include/elf.h чтобы направлять вас.

Кроме того, вы можете использовать libelf, но я не могу вам помочь, поскольку у меня нет предыдущего опыта работы с ним.

В заключение отметим, что упражнение несколько бесполезно: вы получите список определенных функций, но вы не будете знать, как их вызывать (какие параметры они ожидают), так какой смысл?

Я не думаю, что есть опубликованный API для этого. Вы можете использовать инструмент nm из binutils или изучить его исходный код: http://sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/?cvsroot=src

http://sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/nm.c?rev=1.63&content-type=text/x-cvsweb-markup&cvsroot=src

(очевидно, предполагая, эльф)

Boost.DLL предлагает эту функцию через library_info::symbols функция. Адаптировано из учебника по запросам библиотек для символов:

// Class `library_info` can extract information from a library
boost::dll::library_info inf(libpath);

// Getting exported symbols
std::vector<std::string> exports = inf.symbols();

// Printing symbols
for (std::size_t j = 0; j < exports.size(); ++j) {
    std::cout << exports[j] << std::endl;
}

Обратите внимание, что это работает только для символов, nmсписки без--dynamic флаг, т.е. .symtabраздел. Похоже, что некоторые библиотеки не экспортируют символы в этом разделе. Я открыл запрос функции для поддержки возврата к.dynsym раздел в таком случае.

Можно использовать команду linux nm: http://man.yolinux.com/cgi-bin/man2html?cgi_command=nm

void *dlsym(void *restrict handle, const char *restrict name);

Возвращаемое значение

Если handle не ссылается на действительный объект, открытый dlopen (), или если именованный символ не может быть найден ни в одном из объектов, связанных с handle, dlsym () должен вернуть NULL. Более подробная диагностическая информация должна быть доступна через dlerror ().

(Источник: http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html)

Другими словами, если символ не найден, dlsym() вернусь NULL, Не уверен, что это то, что вы ищете, но это самый простой способ, который я могу найти.

Другие вопросы по тегам