用像这样的程序
int main()
{
return 0;
}
- 并且您静态链接,系统上的某些库是否会链接到最终的二进制文件中。
- 并且动态链接,运行时会加载库吗?
从本质上讲,即使是最简单的程序也总是需要一个库,如果是这样,为什么?我问这个问题是因为我认为任何想要执行的东西的规范入口点实际上是 _start (我认为它在一个库中,即 glibc)。也许我不明白 _start 在设置方面到底做了什么,所以那里的任何指针也会有帮助。
答案1
如果您想用标准可移植 C 语言编写程序,您当然需要一些运行时来调用main()
首先调用该函数的运行时。
但如果您不关心这一点,您可以省去任何库,并直接通过内联汇编进行系统调用。例如。对于 x86-64:
$ cat q.c
#include <sys/syscall.h>
void _start(void){
__asm__( "syscall" : : "D"(0), "a"(SYS_exit) );
}
$ cc -O2 -static -nostdlib -nostartfiles -Wall q.c -o q
$ strace ./q
execve("./q", ["./q"], 0x7fffc72d8d20 /* 39 vars */) = 0
exit(0) = ?
+++ exited with 0 +++
您必须至少执行一次系统调用,即_exit(2)
,除非“最简单的程序”可以接受崩溃退出,在这种情况下,空文件也可以;-):
$ > foo.c
$ cc -static -nostdlib -nostartfiles -Wall foo.c -o ./foo
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
$ ./foo
Segmentation fault
我认为任何想要执行的事情的规范入口点实际上是
_start
它没有任何规范;_start
是链接器将使用的默认名称;您可以使用-e sym
选项(-Wl,-e,sym
with gcc
)将其指向其他地方。