如何配置gcc默认使用-no-pie选项?

6
我希望在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。
2个回答

4

那么解决方案就是始终使用“-no-pie”吗?如果我在没有配置“--enable-default-pie”的情况下配置gcc,似乎可能会出现问题。 - Aadit M Shah
2
使用 --enable-default-pie 配置的 gcc 是一种安全加固策略,因为它默认构建位置无关二进制文件。默认情况下不构建 pie 二进制文件可能会更不安全,但不应该会导致任何问题。 - ks1322

1
为此,您需要重新编译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,因为通常应该放在rodata部分。你的版本也可以正常工作,但是objdump -d的输出包含了来自msg标签的无意义指令。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接