Как настроить 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 этикетка.)

Другие вопросы по тегам