c - LINUX:是否可以编写不依赖 libc 库的工作程序?

标签 c linux binary dependencies executable

我想知道我是否可以用 C 编程语言编写一个可执行的程序,尽管不使用单个库调用,例如甚至没有 exit()?

如果是这样,它显然根本不依赖于库(libc、ld-linux)。

最佳答案

我怀疑你可以写这样的东西,但最后需要有一个无限循环,因为你不能要求操作系统退出你的进程。你不能做任何有用的事情。

我们从编译一个 ELF 程序开始,查看 ELF 规范并一起制作程序头、程序段和程序所需的其他部分。内核将加载您的代码并跳转到某个初始地址。你可以在那里放置一个无限循环。但是如果不了解一些汇编程序,无论如何从一开始就是没有希望的。

start.S glibc 使用的文件作为起点可能很有用。尝试更改它,以便您可以从中组装一个独立的可执行文件。 start.S 文件是所有 ELF 应用程序的入口点,并且是调用 __libc_start_main 的文件,后者又调用 main。您只需更改它即可满足您的需求。

好的,那是理论上的。但是现在,那有什么实际用途呢?

更新问题的答案

嗯。有一个名为 libgloss 的库,它为打算在嵌入式系统上运行的程序提供了一个最小的接口(interface)。 newlib C 库使用那个作为它的系统调用接口(interface)。一般的想法是 libgloss 是 C 库和操作系统之间的层。因此,它还包含操作系统跳转到的启动文件。这两个库都是 GNU binutils 项目的一部分。我用它们为另一个操作系统和另一个处理器做接口(interface),但似乎没有用于 Linux 的 libgloss 端口,所以如果你调用系统调用,你将不得不自己做,正如其他人已经说过的.

用C编程语言编写程序是绝对可能的。 linux 内核 就是此类程序的一个很好的例子。但用户程序也是可能的。但最低限度需要的是一个运行时库(如果你想做任何严肃的事情)。这样的一个将包含非常基本的功能,如 memcpy、基本宏等。 C 标准有一种称为独立 的特殊一致性模式,它只需要非常有限的一组功能,也适用于内核。实际上,我对 x86 汇编器一无所知,但我已经尝试了一个非常简单的 C 程序:

/* gcc -nostdlib start.c */
int main(int, char**, char**);

void _start(int args)
{
    /* we do not care about arguments for main. start.S in 
     * glibc documents how the kernel passes them though.
     */
    int c = main(0,0,0);

    /* do the system-call for exit. */
    asm("movl   %0,%%ebx\n" /* first argument */
        "movl   $1,%%eax\n" /* syscall 1 */
        "int    $0x80"      /* fire interrupt */
        : : "r"(c) :"%eax", "%ebx");
}

int main(int argc, char** argv, char** env) {
    /* yeah here we can do some stuff */
    return 42;
}

我们很高兴,它实际上编译并运行了:)

关于c - LINUX:是否可以编写不依赖 libc 库的工作程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/524826/

相关文章:

c - 如何正确地将小数扫描到字符

linux - 允许 ip 的 Nginx 配置不起作用 deny all 工作正常

linux - 与 snmp 陷阱混淆

objective-c - 在 obj-c 应用程序中将 appengine blob 用于二进制数据

dns - 二进制数据的 Erlang 错误

java - JNI : getting method id for private method in superclass

c - 这个程序中的 child 将如何运行?

c - 启用模拟以在 C 中对库进行单元测试

c - 在管道上写入和读取未知大小的列表

c - 如何在 C 上将二进制 PORTB 位从 "11010000"镜像到 "00001011"?