Каковы различия, сравнивающие PIE, код PIC и исполняемый файл на 64-битной платформе x86 platfomr?
Тест находится на Ubuntu 12.04 64-бит. x86.
Я запутался в концепции "Независимый исполняемый файл Position (PIE) и независимый от положения код (PIC)", и я предполагаю, что они не ортогональны.
Вот мой быстрый эксперимент.
gcc -fPIC -pie quickSort.c -o a_pie.out
gcc -fPIC quickSort.c -o a_pic.out
gcc a.out
objdump -Dr -j .text a.out > a1.temp
objdump -Dr -j .text a_pic.out > a2.temp
objdump -Dr -j .text a_pie.out > a3.temp
И у меня есть следующие выводы.
A. a.out содержит некоторый код PIC, но только поддерживает функции пролога и эпилога libc, как показано ниже:
4004d0: 48 83 3d 70 09 20 00 cmpq $0x0,0x200970(%rip) # 600e48 <__JCR_END__>
В инструкциях по сборке моей простой программы быстрой сортировки я не нашел никаких инструкций PIC.
B. a_pic.out содержит код PIC, и я не нашел никаких инструкций не PIC... В инструкциях моей программы быстрой сортировки все Доступ к глобальным данным осуществляется с помощью инструкций ПОС:
40053b: 48 8d 05 ea 02 00 00 lea 0x2ea(%rip),%rax # 40082c <_IO_stdin_used+0x4>
C. a_pie.out содержит синтаксически идентичные инструкции по сравнению с a_pic.out. Однако адреса памяти раздела a_pie.out .text варьируются от 0x630 до 0xa57, тогда как тот же раздел a_pic.out находится в диапазоне от 0x400410 до 0x400817.
Может ли кто-нибудь дать мне некоторые объяснения этих феноменов? Особенно нахождение C. Опять же, я действительно запутался в PIE против PIC, и понятия не имею, как объяснить вывод C..
Ответы
Ответ 1
Я запутался в концепции "Независимый исполняемый файл Position (PIE) и независимый от положения код (PIC)", и я предполагаю, что они не ортогональны.
Единственное реальное различие между PIE
и PIC
заключается в том, что вам разрешено вводить символы в PIC
, но не в PIE
. Кроме того, они в значительной степени эквивалентны.
Здесь вы можете прочитать о размещении символа .
С. a_pie.out содержит синтаксически идентичные инструкции по сравнению с a_pic.out. Тем не менее, адреса памяти раздела a_pie.out.text варьируются от 0x630 до 0xa57, тогда как один и тот же раздел a_pic.out находится в диапазоне от 0x400410 до 0x400817.
Трудно понять, что вы удивитесь в этом.
Двоичный файл PIE
связан как с общей библиотекой, поэтому его адрес загрузки по умолчанию (.p_vaddr
первого сегмента LOAD
) равен нулю. Ожидается, что что-то переместит эту бинарную страницу от нулевой страницы и загрузит ее на какой-то случайный адрес.
С другой стороны, исполняемый файл не PIE
всегда загружается по его связанному адресу. В Linux адрес по умолчанию для двоичных файлов x86_64
равен 0x400000
, поэтому .text
заканчивается недалеко от него.