Для того что бы выяснить какие функции экспортирует закрытая разделяемая библиотека (.so) и на основе этого написать свой C/C++ хидер (.h) воспользуемся двумя командами из пакета binutils. Поскольку формат ELF файлов не отличается для разных архитектур, то можно даже не устанавливать кросс утилиты.
Первая необходимая нам команда - readelf
- позволяет получить самую разнообразную информацию о исполнимом файле или разделяемой библиотеки. Подробности можно узнать man elf
, нас же на данном этапе интересует только таблица символических имён (symbols) библиотеки. Извлечь её можно дав команду
readelf -s -W libyourlibrary.so
Здесь ключ -s
указывает, что нам нужна именно таблица имён (symbols), а ключ -W
заставляет не обрезать выводимые данные под ширину терминала.
Таблицу с именами мы получаем в следующем виде:
Num: Value Size Type Bind Vis Ndx Name
42: 42c11768 24 FUNC GLOBAL DEFAULT 10 _ZNK10CAM_Engine15isCameraRunningEv
43: 00000000 152 FUNC GLOBAL DEFAULT UND _ZN5QFileD1Ev
Имена у которых поле ‘Value’ равно нулю или поле ‘Ndx’ равно UND
являются внешними по отношению к библиотеке, т.е. используются функциями библиотеки, но должны импортироватся из других библиотек. Их нам тоже необходимо будет отсечь.
Само имя функции переменной и т.п. содержится в последнем столбце. Имена используемые чистым C
записываются как есть.
Поскольку в C++
существуют пространства имён, классы, перегрузка функции из имени в таблицы мы можем извлечь много полезной информации. В частности это список параметров.
Имена кодируются специальным образом (mangling) и имеют малочитаемый вид. Что бы расшифровать имя, воспользуемся командой c++filt
.
Что бы отсечь имена не экспортируемые библиотекой, отфильтруем вывод readelf
с помощью скрипта awk
. В итоге мы получаем цепочку команд:
readelf -s -W libezxcameraengine.so | awk '{ if($2) print $8 "\t\t // " $4 }' | c++filt | sort
На выходе мы получим отсортированный список всех функций и переменных в виде пригодном для копирования в заголовочный файл.
К сожалению, не существует простого способа узнать тип возвращаемого значения. Тут поможет анализ бинарного кода, но в большинстве случаев нужный тип можно угадать ;-)
И наконец для имён функций в формате чистого C
необходимые параметры можно узнать только анализом бинарного кода.
Для обзора экспортируемых и используемых функций воспользуемся командой:
readelf -s -W libezxbluetooth.so | c++filt | sort -k 8
Список так же будет отсортирован по именам функций/переменных.
И наконец команда:
objdump -dR libezxbluetooth.so | c++filt
дизассемблирует бинарный код. Это конечно если у вас в системе установлен мультиархитектурный objdump.
Иначе воспользуйтесь дампером из тулкита /arm-eabi/bin/arm-linux-gnueabi-objdump