没有libc编译

问题描述 投票:51回答:2

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

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

c gcc glibc demo libc
2个回答
67
投票

如果使用-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()不可用。


6
投票

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

你会发现gcc生成的代码可能与一些隐藏的函数有一些依赖关系。他们中的大多数都在libgcc.a。也可能隐藏了对libc中的memcpy()memmove()memset()memcmp()的调用,所以你可能必须提供自己的版本(这并不难,至少只要你对性能不太挑剔)。

如果你看一下生产的组件(使用-S标志),有时可能会更清楚。

© www.soinside.com 2019 - 2024. All rights reserved.