C语言 不使用 libc 编译

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2548486/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:00:31  来源:igfitidea点击:

Compiling without libc

cgccglibcdemolibc

提问by u149796

I want to compile my C-code without the (g)libc. How can I deactivate it and which functions depend on it?

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

I tried -nostdlib but it doesn't help: The code is compilable and runs, but I can still find the name of the libc in the hexdump of my executable.

我试过 -nostdlib 但它没有帮助:代码是可编译和运行的,但我仍然可以在我的可执行文件的十六进制转储中找到 libc 的名称。

回答by ataylor

If you compile your code with -nostdlib, you won't be able to call any C library functions (of course), but you also don't get the regular C bootstrap code. In particular, the real entry point of a program on Linux is not main(), but rather a function called _start(). The standard libraries normally provide a version of this that runs some initialization code, then calls main().

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

Try compiling this with gcc -nostdlib -m32:

尝试编译它gcc -nostdlib -m32

void _start() {

    /* main body of program: call main(), etc */

    /* exit system call */
    asm("movl ,%eax;"
        "xorl %ebx,%ebx;"
        "int  ##代码##x80"
    );
}

The _start()function should always end with a call to exit(or other non-returning system call such as exec). The above example invokes the system call directly with inline assembly since the usual exit()is not available.

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

回答by Thomas Pornin

The simplest way to is compile the C code to object files (gcc -cto get some *.ofiles) and then link them directly with the linker (ld). You will have to link your object files with a few extra object files such as /usr/lib/crt1.oin order to get a working executable (between the entry point, as seen by the kernel, and the main()function, there is a bit of work to do). To know what to link with, try linking with the glibc, using gcc -v: this should show you what normally comes into the executable.

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

You will find that gcc generates code which may have some dependencies to a few hidden functions. Most of them are in libgcc.a. There may also be hidden calls to memcpy(), memmove(), memset()and memcmp(), which are in the libc, so you may have to provide your own versions (which is not hard, at least as long as you are not too picky about performance).

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

Things mightget clearer at times if you look at the produced assembly (use the -Sflag).

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