Как я могу сказать, что-то вроде objdump
, если объект файл был создан с помощью -fPIC
?
Как я могу сказать, что-то вроде objdump, если объект файл был создан с -fPIC?
Ответ 1
Ответ зависит от платформы. На большинстве платформ, если вывод из
readelf --relocs foo.o | egrep '(GOT|PLT|JU?MP_SLOT)'
пуст, то либо foo.o
не был скомпилирован с -fPIC
, либо foo.o
не содержит кода, в котором -fPIC
имеет значение.
Ответ 2
Мне просто нужно было сделать это на цели PowerPC, чтобы найти, какой общий объект (.so) строился без -fPIC. То, что я сделал, было выполнено readelf -d libMyLib1.so и искать TEXTREL. Если вы видите TEXTREL, один или несколько исходных файлов, которые составляют ваш .so, не были созданы с -fPIC. Вы можете заменить readelf на elfdump, если это необходимо.
например.
[[email protected] lib]$ readelf -d libMyLib1.so | grep TEXT # Bad, not -fPIC
0x00000016 (TEXTREL)
[[email protected] lib]$ readelf -d libMyLib2.so | grep TEXT # Good, -fPIC
[[email protected] lib]$
И чтобы помочь людям искать решения, ошибка, которую я получал, когда я запускал свой исполняемый файл, был следующим:
[email protected]:/# ./program: error while loading shared libraries: /usr/lib/libMyLi
b1.so: R_PPC_REL24 relocation at 0x0fc5987c for symbol 'memcpy' out of range
Я не знаю, распространяется ли эта информация на все архитектуры.
Источник: blogs.oracle.com/rie
Ответ 3
Я предполагаю, что вы действительно хотите знать, является ли общая библиотека составлена из объектных файлов, скомпилированных с -fPIC.
Как уже упоминалось, если есть TEXTREL, то -fPIC не использовался.
Существует отличный инструмент под названием scanelf, который может показать вам символы, которые вызвали переходы .text.
Дополнительную информацию можно найти на HOWTO Найти и исправить .text Relocations TEXTRELs.
Ответ 4
readelf -a *.so | grep Flags Flags: 0x50001007, noreorder, pic, cpic, o32, mips32
Это должно работать большую часть времени.
Ответ 5
-fPIC означает, что код сможет выполнять в адресах, отличающихся от адреса, который был скомпилирован.
Чтобы сделать это, disasambler будет выглядеть так.
call get_offset_from_compilation_address
get_offset_from_compilation_address: pop ax
sub ax, ax , &get_offset_from_compilation_address
теперь в ax у нас есть смещение, которое нам нужно добавить к любому доступу к памяти.
load bx, [ax + var_address}
Ответ 6
Еще один вариант, чтобы отличить ли ваша программа от wit -fPIC:
при условии, что ваш код имеет параметр -g3 -gdwarf-2 при компиляции.
другой формат отладки gcc также может содержать информацию о макросе:
Обратите внимание, что следующий синтаксис $'..' предполагает bash
echo $' main() { printf("%d\\n", \n#ifdef __PIC__\n__PIC__\n#else\n0\n#endif\n); }' | gcc -fPIC -g3
-gdwarf-2 -o test -x c -
readelf --debug-dump=macro ./test | grep __PIC__
такой метод работает, потому что руководство gcc объявляет, что если используется -fpic, PIC определяется как 1, и если используется -fPIC, PIC равно 2.
Вышеуказанные ответы, проверяя GOT, - лучший способ. Поскольку предварительный запрос -g3 -gdwarf-2, я думаю, редко используется.