编译没有libc

我想在没有(g)libc的情况下编译我的C代码。 我怎样才能停用它,哪些function依赖于它?

我尝试了-nostdlib,但没有帮助:代码是可编译的并运行,但是我仍然可以在我的可执行文件的hexdump中findlibc的名称。

如果使用-nostdlib编译代码,则无法调用任何C库函数(当然),但是也不会获得常规C引导代码。 特别是,linux上程序的真正入口点不是main(),而是一个叫做_start()的函数。 标准库通常提供一个运行一些初始化代码的版本,然后调用main()。

尝试用gcc -nostdlib编译这个:

 void _start() { /* main body of program: call main(), etc */ /* exit system call */ asm("movl $1,%eax;" "xorl %ebx,%ebx;" "int $0x80" ); } 

_start()函数应该始终以调用exit(或其他非返回的系统调用,如exec)结束。 上面的例子直接使用内联汇编调用系统调用,因为通常的exit()不可用。

http://blog.ksplice.com/2010/03/libc-free-world/对精确控制gcc的程序输出有很好的描述。;

编辑:他们(ksplice)只是把上面的教程/指南的第2部分。 在这里看到: http : //blog.ksplice.com/2010/04/libc-free-world-2/这主要处理链接器设置,以消除文件中不必要的绒毛。

这里是一个关于优化精灵二进制文件,其中包括剥离stdlibclosures可执行文件的优秀文章: 一个Whirlwind教程创build真正的Teensy ELF可执行文件的Linux

最简单的方法是将C代码编译成目标文件( gcc -c获取一些*.o文件),然后将它们直接链接到链接器( ld )。 为了得到一个可用的可执行文件(在内核看到的入口点和main()函数之间),你必须链接你的目标文件和一些额外的目标文件,比如/usr/lib/crt1.o ,有一些工作要做)。 要知道链接什么,尝试使用gcc -v链接glibc:这应该显示通常进入可执行文件的内容。

你会发现gcc生成的代码可能对一些隐藏的函数有一些依赖关系。 他们大多数在libgcc.amemcpy()memmove()memset()memcmp()在libc中也可能有隐藏的调用,所以你可能需要提供你自己的版本(这并不困难,至less和你一样长对性能不太挑剔)。

如果您查看生成的程序集(使用-S标志),有时可能会变得更清晰。