在Debian上链接依赖于位置的程序集

时间:2017-03-20 14:51:18

标签: linux gcc assembly clang x86-64

我无法在Debian 9上使用GCC链接依赖于位置的程序集。以下是程序集中的hello.s文件:

  .section .rodata
hello_str:
  .string "Hello world"
  .text
  .globl main
main:
  xor %rdi, %rdi
  mov $hello_str, %rdi
  call puts      # puts("Hello world");
  xor %rax, %rax # return 0;
  ret

运行gcc hello.s后,收到以下错误:

$ gcc hello.s
/usr/bin/ld: /tmp/ccDvqMUc.o: relocation R_X86_64_32S against `.rodata' 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

clang hello.s生成可执行文件:

$ clang hello.s
$ file ./a.out 
./a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=ca2f0204d60b5fc197b95c5ccb626a9dfb355a9b, not stripped
$ ./a.out
Hello world

当我将hello.s转换为与位置无关的代码并将其存储到hello-pic.s文件中时:

  .section .rodata
hello_str:
  .string "Hello world"
  .text
  .globl main
main:
  xor %rdi, %rdi
  leaq hello_str(%rip), %rdi
  call puts@PLT  # puts("Hello world");
  xor %rax, %rax # return 0;
  ret

然后gcc hello-pic.s生成一个可执行文件(file命令的输出和生成的a.out可执行文件的输出与clang的{​​{1}}相同

我不能在其他Linux机箱(Ubuntu,CentOS)上重现这个问题,这让我相信Debian上的GCC是用一些非标准标志构建的。如果是,那么基本原理是什么?如何强制GCC链接与位置相关的代码?随附的是我目前安装的CPU架构和相关软件包:

hello.s

1 个答案:

答案 0 :(得分:0)

与其他发行版一样,Debian 9似乎默认启用了PIE(出于安全原因):

For the stretch release, the Debian version of the GNU GCC 6 compiler now defaults
to compiling "position independent executables" (PIE).

要恢复旧行为,您需要将-no-pie添加到CFLAGS