c语言 - X86 64 位汇编 Linux 'Hello World' 链接问题



我正试图跟进这个线程,但不幸的是,它并不能完全解决我的问题。我尝试运行的代码如下:

; File hello.asm
section .data
msg:    db      "Hello World!",0x0a,0
section .text
global main
extern printf
main:
push  rbp
mov   rbp, rsp
lea   rdi, [msg]  ; parameter 1 for printf
xor   eax, eax    ; 0 floating point parameter
call  printf
xor   eax, eax    ; returns 0
pop   rbp
ret

我的系统是debian拉伸:

$ uname -a
Linux <host> 4.8.0-1-amd64 #1 SMP Debian 4.8.7-1 (2016-11-13) x86_64 GNU/Linux

我使用yasm汇编程序如下:

$ yasm -f elf64 -g dwarf2 hello.asm

因为我在上面的源中的入口点是main,它有一个最终的ret指令,所以我想我需要链接到gcc而不是ld -e main:

$ gcc -lc hello.o

然而,我收到以下错误消息:

/usr/bin/ld: hello.o: relocation R_X86_64_32 against `.data' 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

这个错误提到了使用-fPIC重新编译的一些内容,但这是gcc编译器选项,而不是汇编程序yasm的有效选项。所以我不知道在这里该怎么办。

只是为了测试,我尝试与ld:链接

$ ld -e main -lc hello.o

这是成功的,但我在运行时获得了与上面线程中提到的相同的错误

$ ./a.out
bash: ./a.out: No such file or directory       # The file *is* there ...

(根据线程的回答,我尝试将ld二进制文件中提到的.so库与我的系统库进行比较,它们都是/lib64/ld-linux-x86-64.so.2。)

我还试图用_start替换main入口点(暂时忘记了正确退出程序的问题),并用ld -lc hello.o链接,但我得到了与以前相同的错误"没有这样的文件或目录"。我会继续玩这个,但我想我也会问。

任何工作建议(与main_startgccld)将不胜感激。

编辑:根据Jim的建议,我在hello.asm的顶部添加了default rel,当与gcc链接时,我获得了不同的错误消息(与ld -e main -lc没有变化)

$ gcc -lc hello.o
/usr/bin/ld: hello.o: relocation R_X86_64_PC32 against symbol `printf@@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status

第2版:这篇文章与debian stretch:上的故障有关

Linux: 4.8.0-1-amd64 #1 SMP Debian 4.8.7-1 (2016-11-13) x86_64 GNU/Linux
yasm: 1.3.0
gcc: (Debian 6.2.1-5) 6.2.1 20161124
ld: GNU ld (GNU Binutils for Debian) 2.27.51.20161220

根据Jim的评论,我刚刚在debian jessie上测试了相同的代码,它与gcc -lc hello.o和以下版本配合使用非常好

Linux: 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) x86_64 GNU/Linux
yasm: 1.2.0
gcc: (Debian 4.9.2-10) 4.9.2
ld: GNU ld (GNU Binutils for Debian) 2.25

第3版:等待Michael Petch的正式答复:使用gcc -static hello.o解决问题

Debian Stretch中的

GCC默认构建独立于位置的可执行文件,以构建链接到特定地址的可执行程序,就像传统的将-no-pie传递给GCC一样。

或者指定正确的重新定位类型,我不知道如何在yasm中做到这一点。

相关内容

最新更新