With a program like

int main()
   return 0;
  • and you statically link, will some library on your system be linked into the final binary.
  • and you dynamically link, will a library be loaded when it's run?

In essence, is a library always required for even the simplest programs, if so why? I ask because I thought the canonical entry point for anything that wants to be executed is actually _start (which I thought was in a library, namely glibc). Maybe I don't understand what _start really does with regard to setting things up, so any pointers there would be helpful too.

  • 2
    Existence proof: the Linux kernel is a C program that does not load a library. – Jörg W Mittag Dec 14 '19 at 7:53
  • 1
    Note that a static library is in principle just a collection of object files. Instead of linking with a library (and leaving it to the linker to extract the functions you need from the library) you can simply link against the object files directly. Since object files are simply compiled or assembled source files you can also simply first compile (or assemble) the files yourself if you have the sources. You don't need any binaries. (I'm not perfectly sure whether that's different with the runtime lib because interacts low-level with the operating system -- I'm curious to hear comments). – Peter - Reinstate Monica Dec 14 '19 at 11:44

If you want to write your program in standard portable C, you need of course some runtime that calls the main() function in the first place.

But if you don't care about that, you can dispense with any library, and do system calls directly via inline assembly. Eg. for x86-64:

$ cat q.c
#include <sys/syscall.h>
void _start(void){
        __asm__( "syscall" : : "D"(0), "a"(SYS_exit) );
$ cc -O2 -static -nostdlib -nostartfiles -Wall q.c -o q
$ strace ./q
execve("./q", ["./q"], 0x7fffc72d8d20 /* 39 vars */) = 0
exit(0)                                 = ?
+++ exited with 0 +++

You have to do at least one system call, namely _exit(2), unless exit-by-crashing is acceptable for a "simplest program", in which case an empty file will do, too ;-):

$ > foo.c
$ cc -static -nostdlib -nostartfiles -Wall foo.c -o ./foo
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
$ ./foo
Segmentation fault

I thought the canonical entry point for anything that wants to be executed is actually _start

there's nothing canonical about it; _start is the default name the linker will use; you can point it elsewhere with the -e sym option (-Wl,-e,sym with gcc).

| improve this answer | |
  • That's very useful information, I want to give the correct answer, but could you clarify on my question a little: I'm guessing from your answer there's a runtime.so or .a or something like that which gets linked and/or loaded. – Andrew Cina Dec 13 '19 at 23:18
  • 2
    Yes, it is. At least the crt*.o objects will have to be linked in, because they contain the code which ultimately calls main (via a __libc_start_main() wrapper on Linux) – mosvy Dec 13 '19 at 23:32
  • 3
    I think this link can be entertaining: A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux – A.B Dec 14 '19 at 0:04
  • 1
    The *.a files are archives which contain *.o files. You can see their content with the ar tf.They could've put those too in an archive, but they just didn't. As to the *.so files, they're completely different, they're for dynamically linked executables: no part of their content is stored in the executable, but only a reference to them, so that the dynamic linker (elf interpreter) can load them at run time. – mosvy Dec 14 '19 at 0:15
  • 1
    *.o files can only be linked statically. Compiling a simple standard C example like int main(){} on Linux will statically link in the crt*.o files, and either link dynamically to the standard C library (libc.so.*) or pull in quite a lot of stuff from it (just compile it with cc -static -xc - <<<'int main(){}' -o a.out and analyze the executable with objdump -xd a.out). FWIW, even a dynamically linked executable will statically link in stuff from the elf-init.o file from libc.a. – mosvy Dec 19 '19 at 0:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.