| dladdr(3) | Library Functions Manual | dladdr(3) |
dladdr, dladdr1 - транслирует адрес в информацию о символе
Dynamic linking library (libdl, -ldl)
#define _GNU_SOURCE #include <dlfcn.h>
int dladdr(const void *addr, Dl_info *info);
int dladdr1(const void *addr, Dl_info *info, void **extra_info,
int flags);
Функция dladdr() определяет, в каком из загруженных общих объектов приложения расположен адрес, указанный в addr. Если объект находится, то dladdr() возвращает информацию об общем объекте и символе, который относится к адресу addr. Данная информация возвращается в виде структуры Dl_info:
typedef struct {
const char *dli_fname; /* путь к общему объекту, который
содержит адрес */
void *dli_fbase; /* начальный адрес, по которому расположен
общий объект */
const char *dli_sname; /* имя символа, к которому относится
адрес addr */
void *dli_saddr; /* точный адрес символа с
именем dli_sname */
} Dl_info;
Если символ, соответствующий адресу addr, не найден, то dli_sname и dli_saddr устанавливаются в NULL.
Функция dladdr1() подобна dladdr(), но возвращает дополнительную информацию в аргументе extra_info. Возвращаемая информация зависит от значения, указанного в flags, которое может быть одним из:
struct link_map {
ElfW(Addr) l_addr; /* Difference between the
address in the ELF file and
the address in memory */
char *l_name; /* Absolute pathname where
object was found */
ElfW(Dyn) *l_ld; /* Dynamic section of the
shared object */
struct link_map *l_next, *l_prev;
/* Chain of loaded objects */
/* Plus additional fields private to the
implementation */
};
typedef struct {
Elf64_Word st_name; /* имя символа */
unsigned char st_info; /* тип символа и привязка */
unsigned char st_other; /* видимость символа */
Elf64_Section st_shndx; /* номер раздела */
Elf64_Addr st_value; /* значение символа */
Elf64_Xword st_size; /* размер символа */
} Elf64_Sym;
| Значение | описание |
| STT_NOTYPE | тип символа не указан |
| STT_OBJECT | символ является объектом данных |
| STT_FUNC | символ является объектом кода |
| STT_SECTION | символ, связанный с разделом |
| STT_FILE | Symbol's name is filename |
| STT_COMMON | символ является объектом общих данных |
| STT_TLS | символ является объектом локальных данных нити |
| STT_GNU_IFUNC | символ является объектом скрытого кода |
| Значение | описание |
| STB_LOCAL | локальный символ |
| STB_GLOBAL | глобальный символ |
| STB_WEAK | символ со слабой привязкой |
| STB_GNU_UNIQUE | уникальный символ |
| Значение | описание |
| STV_DEFAULT | правила видимости символов по умолчанию |
| STV_INTERNAL | скрытый класс, зависящий от процессора |
| STV_HIDDEN | Символ недоступен в других модулях |
| STV_PROTECTED | невыгружаемый, не экспортируется |
При успешном выполнении эти функции возвращают ненулевое значение. Если адрес, указанный в addr, мог бы совпасть с общим объектом, но не с символом в общем объекте, то полям info->dli_sname и info->dli_saddr присваивается значение NULL.
Если адрес, указанный addr, мог бы совпасть с общим объектом, то эти функции возвращают 0. В этом случае сообщение об ошибке не доступно через dlerror(3).
Описание терминов данного раздела смотрите в attributes(7).
| Интерфейс | Атрибут | Значение |
| dladdr(), dladdr1() | Безвредность в нитях | MT-Safe |
GNU.
Solaris.
Иногда указатели на функции, передаваемые в dladdr(), могут вас удивить. На некоторых архитектурах (в частности, i386- и x86-64), dli_fname и dli_fbase могут указывать на объект, из которого вызывалась функция dladdr(), даже если функция, использовавшаяся как аргумент, должна быть из динамически скомпонованной библиотеки.
Проблема в том, что указатель на функцию по прежнему ищется во время компиляции, но всего лишь указывает на раздел plt (таблицу компоновки процедур) первоначального объекта (которая размещает вызов после запроса динамического компоновщика на поиск символа). Чтобы обойти это, вы можете попробовать скомпилировать независимый от размещения код: в этом случае компилятор больше не сможет подготовить указатель во время компиляции и gcc(1) создаст код, который просто загрузит конечный адрес символа из got (глобальной таблицы смещений) при запуске до передачи его в dladdr().
dl_iterate_phdr(3), dlinfo(3), dlopen(3), dlsym(3), ld.so(8)
Русский перевод этой страницы руководства разработал(и) Yuri Kozlov <yuray@komyakino.ru>, Иван Павлов <pavia00@gmail.com> и Kirill Rekhov <krekhov.dev@gmail.com>
Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.
Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу списка рассылки русских переводчиков.
| 2 мая 2024 г. | Справочные страницы Linux 6.9.1 |