【问题标题】:"relocation R_X86_64_32S against `.bss' can not be used when making a shared object”“在制作共享对象时,不能使用针对 `.bss' 的重定位 R_X86_64_32S”
【发布时间】:2017-04-10 18:55:59
【问题描述】:

我在这方面绝对是绿色的,但是在课堂上,老师给了我们他写的文件,他只是为了让我们运行它,然后它工作得很好,但是当我尝试在家里做它时(我在 VirtualBox 上使用 Linux)并使用:

nasm -f elf64 hello.asm -o hello.o
gcc hello.o -o hello

我收到错误“在制作共享对象时无法使用针对 `.bss' 的重定位 R_X86_64_32S;使用 -fPIC 重新编译”。有人可以解释一下如何使其工作吗?

global main
extern printf

section .data
napis:      db ' Hello world! - po raz %ld',10,0

liczba_iteracji: equ 5

section .bss
licznik: resb 1

section .text

main:

push    rbp
mov rbp,rsp

mov byte [licznik],0

petla:              ;naiwna!

inc byte [licznik]

mov rdi, qword napis
mov rsi, qword [licznik]
mov rax, 0
call    printf

cmp byte [licznik],liczba_iteracji
jnz petla

mov rsp,rbp
pop rbp

mov rax,1           ;SYS_EXIT
mov rbx,0
int 80h

【问题讨论】:

标签: linux assembly x86-64 nasm linker-errors


【解决方案1】:

你需要确定你写的是position independent code。 PIC 的想法是,要使代码真正与位置无关,您至少需要一个间接级别。这种间接级别是 IP 相对寻址,如果这还不够,您将需要第二层,即全局偏移表或 GOT。

在 NASM 中,您会发现 DEFAULT REL 指令很有用。

【讨论】:

  • PIE 可执行文件不需要通过 GOT 间接访问自己的函数/变量;那只是为了支持符号插入。 gcc -fPIC 意味着共享库符号插入,但现代默认 gcc -fpie -pie 只需要避免 32 位绝对寻址。所以是的,default rel32-bit absolute addresses no longer allowed in x86-64 Linux?
【解决方案2】:

我遇到了同样的问题。 GCC 给出这个错误的原因是因为它假设(这里是 6.3.0 版)您正在构建一个共享对象(显然,您不是),因此 .bss 的存在使它变得疯狂。因此,您可以通过传递 -static 选项来解决此问题:gcc hello.o -static -o hello(在我的情况下有效),或者使用 Clang 作为链接器:clang hello.o -o hello。后者没有投诉。

【讨论】:

  • PIE 可执行文件实际上 ELF 共享对象。 32-bit absolute addresses no longer allowed in x86-64 Linux? 更好的解决方法是尽可能避免使用 32 位绝对寻址,方法是使用 default rel,或者使用 -fno-pie -no-pie,如果在某些情况下您的代码可以使用绝对寻址更高效。
猜你喜欢
  • 1970-01-01
  • 2018-06-19
  • 2017-07-23
  • 2016-06-06
  • 1970-01-01
  • 2020-01-26
  • 2019-02-03
  • 2018-08-12
  • 2018-09-01
相关资源
最近更新 更多