Вот пример файла сборки, test.s
.global main
main:
mov __progname@GOT, %eax // failed to compile
mov __progname@GOT(%ebx), %eax //succeed to compile
Я попытался скомпилировать его с флагом -pie
, но не удалось.
$ gcc -pie -o test test.s
osboxes@osboxes:/mnt/hgfs/VM_Shared/Reassemblabla/src$ gcc -pie -o test test.s
/usr/bin/ld: /tmp/ccPGMLlH.o: direct GOT relocation R_386_GOT32X against `__progname' without base register can not be used when making a shared object
/usr/bin/ld: failed to set dynamic section sizes: File format not recognized
collect2: error: ld returned 1 exit status
Сказана ошибка. В круговой двоичной записи доступ к записи GOT
доступен только через базовый регистр.
Вопрос.
Я не знаю, почему компилятор жалуется, как указано выше.
В частности, почему адресация __progname@GOT
не разрешена для двоичного кода пирога?
Мое мнение.
Загрузчик знает адрес __progname@GOT
во время загрузки кругового двоичного файла.
Итак, загрузчик может просто написать этот адрес в месте __progname@GOT
во время загрузки.
Это то, что загрузчик может сделать.
Поэтому я не могу понять, почему компилятор настаивает на доступе к регистру, например
mov __progname@GOT(%ebx), %eax
.