LINUX: Is it possible to write a working program that does not rely on the libc library?

binary, c, dependencies, executable, linux

Solution

I suspect you could write such a thing, but it would need to have an endless loop at the end, because you can't ask the operation system to exit your process. And you couldn't do anything useful.

Well start with compiling an ELF program, look into the ELF spec and craft together the header, the program segments and the other parts you need for a program. The kernel would load your code and jump to some initial address. You could place an endless loop there. But without knowing some assembler, that's hopeless from the start on anyway.

The `start.S` file as used by glibc may be useful as a start point. Try to change it so that you can assemble a stand-alone executable out of it. That start.S file is the entry point of all ELF applications, and is the one that calls `__libc_start_main` which in turn calls `main`. You just change it so it fits your needs.

Ok, that was theoretical. But now, what practical use does that have?

Answer to the Updated Question

Well. There is a library called `libgloss` that provides a minimal interface for programs that are meant to run on embedded systems. The `newlib` C library uses that one as its system-call interface. The general idea is that libgloss is the layer between the C library and the operation system. As such, it also contains the startup files that the operation system jumps into. Both these libraries are part of the GNU binutils project. I've used them to do the interface for another OS and another processor, but there does not seem to be a libgloss port for Linux, so if you call system calls, you will have to do it on your own, as others already stated.

It is absolutely possible to write programs in the C programming language. The linux kernel is a good example of such a program. But also user programs are possible. But what is minimally required is a runtime library (if you want to do any serious stuff). Such one would contain really basic functions, like memcpy, basic macros and so on. The C Standard has a special conformance mode called freestanding, which requires only a very limited set of functionality, suitable also for kernels. Actually, i have no clue about x86 assembler, but i've tried my luck for a very simple C program:

/* 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;
}

We're happy, it actually compiles and runs :)

Problem

I wonder if I could write a program in the `C`-programming language that is executable, albeit not using a single library call, e.g. not even exit()? If so, it obviously wouldn't depend on libraries (libc, ld-linux) at all.

Original source