【发布时间】:2020-08-09 10:30:56
【问题描述】:
我正在尝试在 Linux(Ubuntu 18.04 LTS)中组装和链接这个微小的 x86 汇编代码:
;hello.asm
global _start
extern scanf, printf, exit
section .data
read_name db '%255s', 0
msg db 'Hello, %s', 0
section .text
_start:
sub esp, 256
push esp
push read_name
call scanf
add esp, 8
push esp
push msg
call printf
add esp, 264
push dword 0
call exit
我正在使用nasm 组装和ld 链接。正如您可能知道的那样,代码使用 C 函数,因此它必须链接到 glibc。由于我的代码使用的是_start,而不是main,因此我决定链接到共享库会更好,因为如果链接了二进制文件,C 运行时需要一些启动代码才能在_start 中运行静态的。
问题是我无法让我的代码链接,很可能是因为我没有使用正确的 glibc .so。这是我组装和链接的方式:
nasm -f elf32 hello.asm
ld hello.o -o hello -dynamic-linker /lib/libc.so.6 -lc -m elf_i386
创建了输出文件,但是当我尝试运行它时,我得到了:
./hello
bash: ./hello: No such file or directory
快速搜索了一下,原来这些都是我电脑上的libc.sos:
locate libc.so
/lib/x86_64-linux-gnu/libc.so.6
/snap/core/8268/lib/i386-linux-gnu/libc.so.6
/snap/core/8268/lib/x86_64-linux-gnu/libc.so.6
/snap/core/8689/lib/i386-linux-gnu/libc.so.6
/snap/core/8689/lib/x86_64-linux-gnu/libc.so.6
/snap/core18/1668/lib/i386-linux-gnu/libc.so.6
/snap/core18/1668/lib/x86_64-linux-gnu/libc.so.6
/usr/lib/x86_64-linux-gnu/libc.so
谁能告诉我如何链接到 glibc? (对于 64 位代码,我也遇到了同样的问题)
【问题讨论】:
-
链接使用
gcc -nostartfiles -m32 -o hello hello.o。请注意,如果您直接调用ld,则将库文件本身放在命令行上是错误的。仅将库作为-l操作数提供。所以ld -m elf_i386 -o hello hello.o -lc应该可以解决问题。 -
谢谢! GCC 命令有效,但 LD 仍然会产生一个“幽灵”文件,在尝试运行它时找不到该文件。你为什么不发布你的答案? (顺便说一句,如果我使用 64 位目标文件而不是
-m32,则 gcc 会给我一个错误) -
尝试
ldd hello看看它试图拉入哪些共享库并发布结果。如果未找到其中任何一个,则可能会出现“没有此类文件或目录”错误消息。也可能是不正确的解释器。 -
找到了罪魁祸首,它试图链接
linux-gate.so.1,但是locate没有显示任何相关信息。但是,我不知道该怎么办。 -
@DarkAtom
linux-gate.so.1是 vDSO。简短的解释:它是由 Linux 内核自动提供的,实际上并不存在于磁盘上。还缺少其他一些东西让你无法开始它。