如何配置 gcc 默认使用 -no-pie?
How to configure gcc to use -no-pie by default?
我想在 Linux 上编译以下程序:
.global _start
.text
_start:
mov , %rax
mov , %rdi
mov $msg, %rsi
mov , %rdx
syscall
mov , %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.
我想只是不要用 --enable-default-pie
配置 gcc。
查看此博客 post:http://nanxiao.me/en/gccs-enable-enable-default-pie-option-make-you-stuck-at-relocation-r_x86_64_32s-against-error/, and Arch patch that enabled pie by default: 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 , %rax
movq , %rdi
leaq msg(%rip), %rsi
movq , %rdx
syscall
movq , %rax
xorq %rdi, %rdi
syscall
.section .rodata
msg:
.ascii "Hello World!\n"
(我添加 .section .rodata
只是因为通常这应该放在 rodata 部分。您的版本工作正常,但 objdump -d
的输出包含来自 msg
标签的无意义指令。)
我想在 Linux 上编译以下程序:
.global _start
.text
_start:
mov , %rax
mov , %rdi
mov $msg, %rsi
mov , %rdx
syscall
mov , %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.
我想只是不要用 --enable-default-pie
配置 gcc。
查看此博客 post:http://nanxiao.me/en/gccs-enable-enable-default-pie-option-make-you-stuck-at-relocation-r_x86_64_32s-against-error/, and Arch patch that enabled pie by default: 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 , %rax
movq , %rdi
leaq msg(%rip), %rsi
movq , %rdx
syscall
movq , %rax
xorq %rdi, %rdi
syscall
.section .rodata
msg:
.ascii "Hello World!\n"
(我添加 .section .rodata
只是因为通常这应该放在 rodata 部分。您的版本工作正常,但 objdump -d
的输出包含来自 msg
标签的无意义指令。)