Почему VirtAddr сегмента LOAD в моем двоичном файле ELF отображается как 0x0000000000000000? - PullRequest
0 голосов
/ 31 января 2020

Я скомпилировал программу Hello World C, и это информация file:

hello: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=3c4fc3bc82d53281357312935790846333a3c7bc, with debug_info, not stripped

Когда я проверяю информацию заголовка сегмента, я вижу, что VirtAddr для сегмента LOAD указывает на адрес 0x0000000000000000, который определен как NULL. Адрес входа 0x540, который указывает, что он находится в первом сегменте LOAD из двух. Флаг E (execute) и секция .text также отображаются на первый сегмент LOAD. enter image description here

Когда я использую gdb и устанавливаю точку останова в main, я вижу, что адрес меняется, что означает, что адреса были смещены на определенное смещение. Почему это случилось? Я пытался загрузить программу несколько раз, но смещение остается постоянным, что означает отсутствие рандомизации адресов. Я вижу другие вопросы о SO, которые получают адрес загрузки прямо напротив моего. Почему? То же самое происходит, когда я компилирую с -m32. Что-то изменилось по сравнению с linux в последние годы, когда я получил другой вывод из связанного вопроса?

enter image description here

1 Ответ

1 голос
/ 01 февраля 2020

Вы видите 0 для LOAD, потому что ваш ELF не зависит от позиции.

Современные версии G CC генерируют Независимые от позиции исполняемые файлы по умолчанию (если не настроено иначе ). Если исполняемый файл P IE, базовый виртуальный адрес в заголовках ELF установлен на 0. Когда вы запускаете вашу программу в GDB, она временно отключает рандомизацию адресов и загружает вашу программу по адресу 0x0000555555554000.

по умолчанию. Если вы хотите скомпилировать исполняемый файл не-P IE, вы можете использовать -no-pie -fno-pie флаги компиляции.

...