Почему dladdr возвращает путь к исполняемому файлу в позиционно-независимом коде на arm-linux?

Я столкнулся с проблемой с dladdr в некоторых моих кодах, которые я кросс-компилировал для arm-linux, используя кросс-компилятор Emdebian g ++ — 4.7 для armhf. Кажется, проблема в том, что если указатель функции, который вы передаете в dladdr, является функцией, которая также вызывается в исполняемом файле, dli_fname вернет путь к исполняемому файлу вместо общей библиотеки, из которой поступил символ.

Пример скомпилирован с помощью:

/usr/bin/arm-linux-gnueabihf-g++-4.7 main.cpp -o main -ldl -fPIC

#include <dlfcn.h>
#include <iostream>
#include <stdio.h>
#include <string>

std::string findLibName(void* funcPtr) {
Dl_info info;
if (dladdr(funcPtr,&info) != 0) {
return std::string(info.dli_fname);
} else {
return "";
}
}

int main() {
printf("printf comes from %s\n",findLibName((void*)printf).c_str());
return 0;
}

Результат: printf исходит от ./main

Если я изменю тело main () на

int main() {
std::cout<<"printf comes from "<<findLibName((void*)printf)<<"\n";
return 0;
}

Результат: printf взят из /lib/arm-linux-gnueabihf/libc.so.6

Я заметил, что если функция, указатель на функцию которой вы передаете в dladdr, вызывается внутри исполняемого файла, запись будет выглядеть следующим образом:

Relocation section '.rel.plt' at offset 0x63c contains 14 entries:
Offset     Info    Type            Sym.Value  Sym. Name
00010be8  00000d16 R_ARM_JUMP_SLOT   00008730   printf

создается в разделе .rel.plt исполняемого файла, и кажется, что dladdr находит этот адрес printf из PLT, а не правильный адрес из libc.so.6, который он найдет через GOT. Dladdr справочная страница предполагает, что компиляция кода, чтобы быть независимым от позиции, должна исправить это, но это не похоже на этот компилятор. Для справки, тот же код, показанный выше, работает, как и ожидалось, в x86_64 Linux с g ++ — 4.7.

3

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]