Как настроить gcc на использование -no-pie по умолчанию?
Я хочу скомпилировать следующую программу для Linux:
.global _start
.text
_start:
mov $1, %rax
mov $1, %rdi
mov $msg, %rsi
mov $13, %rdx
syscall
mov $60, %rax
xor %rdi, %rdi
syscall
msg:
.ascii "Hello World!\n"
Тем не менее, это дает мне следующую ошибку компоновщика:
$ gcc -nostdlib hello.s
/usr/bin/ld: /tmp/ccMNQrOF.o: relocation R_X86_64_32S against `.text' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
Я понял, что причина этого не в том, что gcc использует -pie
создать общий объект по умолчанию. Таким образом, используя -no-pie
исправляет это:
$ gcc -no-pie -nostdlib hello.s
$ ./a.out
Hello World!
Как мне настроить gcc для использования -no-pie
по умолчанию? Я использую Arch Linux.
1 ответ
Я думаю, просто не настраивайте GCC с --enable-default-pie
,
Смотрите это сообщение в блоге: http://nanxiao.me/en/gccs-enable-enable-default-pie-option-make-you-stuck-at-relocation-r_x86_64_32s-against-error/, и патч Arch, который включил пирог по умолчанию: https://git.archlinux.org/svntogit/packages.git/commit/trunk?h=packages/gcc&id=5936710c764016ce306f9cb975056e5b7605a65b.
Для этого вам нужно перекомпилировать gcc, чтобы отключить PIE по умолчанию. Или вам понадобится-no-pie
каждый раз, когда вы хотите скомпилировать позиционно-зависимый ассемблерный код.
Однако только для приведенного вами примера лучше использовать относительную адресацию, например label_name(%rip)
.
Относительная адресация позволяет PIE работать правильно.
Я изменил вашу так: (см. leaq
линия)
.global _start
.text
_start:
movq $1, %rax
movq $1, %rdi
leaq msg(%rip), %rsi
movq $13, %rdx
syscall
movq $60, %rax
xorq %rdi, %rdi
syscall
.section .rodata
msg:
.ascii "Hello World!\n"
(Я добавил .section .rodata
просто потому, что обычно это помещается в раздел родаты. Ваша версия работает нормально, но выводobjdump -d
содержит бессмысленные инструкции от msg
этикетка.)