为了理解编译过程,我试图获得一个简单程序的可执行文件,分别编译和链接。
#include<stdio.h>
int main(void)
{
printf("Hello! This is a test prgoram.\n");
return 0;
}
同
gcc -o hello hello.c
一切顺利,产生了预期输出所需的可执行文件。
ldd你好
制作:
linux-vdso.so.1 => (0x00007ffce53ee000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f923498b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9234d55000)
然后分别尝试每一步:
cpp -v hello.c> hello.i
为了获得预处理的输出,那么,
gcc -S hello.i
为了获得汇编代码,那么,
as -o hello.o hello.s
获取目标代码。直到这一步都显然没问题,但是,
ld --verbose -o hello hello.o -lc -l:ld-linux-x86-64.so.2
我有:
attempt to open hello.o succeeded
hello.o
attempt to open //usr/local/lib/x86_64-linux-gnu/libc.so failed
attempt to open //usr/local/lib/x86_64-linux-gnu/libc.a failed
attempt to open //lib/x86_64-linux-gnu/libc.so failed
attempt to open //lib/x86_64-linux-gnu/libc.a failed
attempt to open //usr/lib/x86_64-linux-gnu/libc.so succeeded
opened script file //usr/lib/x86_64-linux-gnu/libc.so
opened script file //usr/lib/x86_64-linux-gnu/libc.so
attempt to open /lib/x86_64-linux-gnu/libc.so.6 succeeded
/lib/x86_64-linux-gnu/libc.so.6
attempt to open /usr/lib/x86_64-linux-gnu/libc_nonshared.a succeeded
attempt to open /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 succeeded
/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
attempt to open //usr/local/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 failed
attempt to open //usr/local/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 failed
attempt to open //lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 succeeded
-l:ld-linux-x86-64.so.2 (//lib/x86_64-linux-gnu/ld-linux-x86-64.so.2)
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400280
显然它成功打开了库和目标文件,但未能将它们全部链接。
版本:
gcc版本5.4.0 20160609(Ubuntu 5.4.0-6ubuntu1~16.04.9)GNU ld(Ubuntu的GNU Binutils)2.26.1
我在这个架构中遗漏了某些东西(库,选项等)吗?
问候。
您必须使用stubstart.S
构建和链接您的程序,_start
提供.globl _start
_start:
call main
movl $1, %eax
xorl %ebx, %ebx
int $0x80
入口点,如下所示
$ gcc -c stubstart.S -o stubstart.o
$ ld --verbose -o hello hello.o stubstart.o -lc -l:ld-linux-x86-64.so.2
qazxswpoi
我使用@melpomene提到的详细信息,最后使用collect2包装器得到了所需的结果:
/ usr / lib / gcc / x86_64-linux-gnu / 5 / collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/5/liblto_plugin.so -plugin-opt = / usr / lib / gcc / x86_64- linux-gnu / 5 / lto-wrapper -plugin-opt = -fresolution = / tmp / ccVm3XOm.res -plugin-opt = -pass-through = -lgcc -plugin-opt = -pass-through = -lgcc_s -plugin- opt = -pass-through = -lc -plugin-opt = -pass-through = -lgcc -plugin-opt = -pass-through = -lgcc_s --sysroot = / --build-id --eh-frame-hdr -m elf_x86_64 --hash-style = gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -z relro -o hello / usr / lib / gcc / x86_64-linux- gnu / 5 /../../../ x86_64-linux-gnu / crt1.o /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux- gnu / crti.o /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o -L / usr / lib / gcc / x86_64-linux-gnu / 5 -L / usr / lib / gcc / x86_64- linux-gnu / 5 /../../../ x86_64-linux-gnu -L / usr / lib / gcc / x86_64-linux-gnu / 5 /../../../../ lib -L / lib / x86_64-linux-gnu -L / lib /../ lib -L / usr / lib / x86_64-linux-gnu -L / usr / lib /../ lib -L / usr / lib / gcc /x86_64-linux-gnu/5/../../ .. hello.o -lgcc --as-needed -lgcc_s --no-as-needed -lc - lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o / usr / lib / gcc / x86_64-linux-gnu / 5 / .. /../../x86_64-linux-gnu/crtn.o --verbose
如后所述,需要crt库。