我的汇编程序,链接-lc就会无法运行?
我在32位的ubuntu1604上面做了个很小的实验:$ cat g.s
.section .text
.globl _start
_start:
movl $1,%eax
int $0x80只是一个exit调用而已,别的什么也没有。
$ as g.s -o g.o && ld g.o -o g
$ g没有问题。但是如果我试图链接-lc就会有问题。
$ as g.s -o g.o && ld g.o -o g -lc
$ gbash: ./g: 没有那个文件或目录
我本来想尝试一下在汇编代码里面去调用call printf/call exit这样的c函数的。
但是发现即使什么也不掉用,光是链接的话,都会导致生成的2进制程序无法运行。
这看起来非常奇怪,我ldd看了一下,都能找到的:
$ ldd g
linux-gate.so.1 =>(0xb7756000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7582000)
/usr/lib/libc.so.1 => /lib/ld-linux.so.2 (0x8003e000)为什么运行就不行了? ./g运行也是不行,同样的错。
我最后尝试了一下带着调试信息来编译,并且用gdb来运行,如下所示:
$ as -g g.s -o g.o && ld g.o -o g -lc
$ gdb g
...
(gdb) list
1 .section .text
2 .globl _start
3 _start:
4 movl $1,%eax
5 int $0x80
(gdb) b 3
Breakpoint 1 at 0x80480ff: file g.s, line 3.
(gdb) r
Starting program: /home/x/cpp/g
/bin/bash: /home/x/cpp/g: 没有那个文件或目录
During startup program exited with code 127.看起来,gdb能够抓到这个错误,也就是During startup program existed。刚启动就退出了,shell还没有来得及执行它,所以shell说找不到这个程序,对吧。
但是原因是什么呢? 大侠给点解释吧,我觉得从gas汇编的程序去链接c运行时库应该是个很普通的场景啊,这个错误如何更正?
本帖最后由 MMMIX 于 2016-09-24 16:42 编辑
回复 1# cdsfiui
$ as g.s -o g.o && ld g.o -o g -lc
$ g
bash: ./g: 没有那个文件或目录
这个非常有迷惑性的错误是 kernel 报出来的,找不到正确的 loader (i.e. dynamic linker).
这看起来非常奇怪,我ldd看了一下,都能找到的:
$ ldd g
linux-gate.so.1 =>(0xb7756000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7582000)
/usr/lib/libc.so.1 => /lib/ld-linux.so.2 (0x8003e000)
loader 呢? 用 readelf -Wl g 看看具体的 loader 是啥,是否正确。
总之还是一句话,多看看 gcc 的例子,不要自己瞎试。
MMMIX 发表于 2016-09-24 16:33
回复 1# cdsfiui
$ readelf -Wl g
Elf 文件类型为 EXEC (可执行文件)
入口点 0x80480ff
共有 5 个程序头,开始于偏移量 52
程序头:
Type Offset VirtAddr PhysAddr FileSiz MemSizFlg Align
PHDR 0x000034 0x08048034 0x08048034 0x000a0 0x000a0 R E 0x4
INTERP 0x0000d4 0x080480d4 0x080480d4 0x00013 0x00013 R 0x1
LOAD 0x000000 0x08048000 0x08048000 0x00108 0x00108 R E 0x1000
LOAD 0x000108 0x08049108 0x08049108 0x00068 0x00068 RW0x1000
DYNAMIC 0x000108 0x08049108 0x08049108 0x00068 0x00068 RW0x4
Section to Segment mapping:
段节...
00
01 .interp
02 .interp .hash .dynsym .dynstr .text
03 .dynamic
04 .dynamic
回复 3# cdsfiui
loader 明显不对嘛,你看看正常的可执行文件 loader 是啥。另外,也可以看看 gcc 在链接的时候是怎么指定 loader 的。 MMMIX 发表于 2016-09-25 14:50
回复 3# cdsfiui
loader 明显不对嘛,你看看正常的可执行文件 loader 是啥。另外,也可以看看 gcc 在链 ...
这个loader明显不对是怎么看出来的? 我看这个loader和普通c文件被gcc编译之后ldd看到的loader是同一个啊
本帖最后由 MMMIX 于 2016-09-26 15:05 编辑
回复 5# cdsfiui
这个loader明显不对是怎么看出来的?
$ ldd /bin/ls
...
/lib64/ld-linux-x86-64.so.2 (0x00005599b730f000)
...
$ readelf -Wl /bin/ls
...
INTERP 0x000238 0x0000000000000238 0x0000000000000238 0x00001c 0x00001c R 0x1
...
正常情况下的 loader 。
页:
[1]