Mit einem Programm wie
int main()
{
return 0;
}
- und Sie statisch linken, wird eine Bibliothek auf Ihrem System in die endgültige Binärdatei gelinkt.
- und Sie verlinken dynamisch, wird eine Bibliothek geladen, wenn sie ausgeführt wird?
Ist im Grunde selbst für die einfachsten Programme immer eine Bibliothek erforderlich, wenn ja, warum? Ich frage, weil ich dachte, der kanonische Einstiegspunkt für alles, was ausgeführt werden möchte, ist eigentlich _start (was ich dachte, war in einer Bibliothek, nämlich glibc). Vielleicht verstehe ich nicht, was _start wirklich in Bezug auf die Einrichtung tut, also wären alle Hinweise dort auch hilfreich.
Akzeptierte Antwort:
Wenn Sie Ihr Programm in Standard-Portable-C schreiben wollen, brauchen Sie natürlich eine Laufzeitumgebung, die main()
aufruft Funktion in erster Linie.
Wem das aber egal ist, der kann auf jede Bibliothek verzichten und Systemaufrufe direkt per Inline-Assemblierung durchführen. Z.B. für 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 +++
Sie müssen mindestens einen Systemaufruf ausführen, nämlich _exit(2)
, es sei denn, das Beenden durch Absturz ist für ein „einfachstes Programm“ akzeptabel, in diesem Fall reicht auch eine leere Datei;-):
$ > 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
Ich dachte, der kanonische Einstiegspunkt für alles, was ausgeführt werden soll, ist eigentlich _start
es ist nichts Kanonisches daran; _start
ist der Standardname, den der Linker verwendet; Sie können es mit -e sym
an eine andere Stelle verweisen Option (-Wl,-e,sym
mit gcc
).