Подтвердить что ты не робот

Как я могу сказать, что-то вроде objdump, если объект файл был создан с -fPIC?

Как я могу сказать, что-то вроде objdump, если объект файл был создан с помощью -fPIC?

4b9b3361

Ответ 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, я думаю, редко используется.