没有libc编译

时间:2010-03-30 20:32:48

标签: c gcc glibc demo libc

我想在没有(g)libc的情况下编译我的C代码。如何停用它以及哪些功能依赖于它?

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

2 个答案:

答案 0 :(得分:65)

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

尝试使用gcc -nostdlib -m32

进行编译
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()不可用。

答案 1 :(得分:6)

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

你会发现gcc生成的代码可能与一些隐藏的函数有一些依赖关系。他们中的大多数都在libgcc.a。对于{lib}中的memcpy()memmove()memset()memcmp(),可能还会隐藏调用,因此您可能需要提供自己的版本(不是很难,至少只要你对表现不太挑剔就可以了。)

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