Avec un programme comme
int main()
{
return 0;
}
- et que vous établissez un lien statique, une bibliothèque de votre système sera-t-elle liée au binaire final.
- et vous créez un lien dynamique, une bibliothèque sera-t-elle chargée lors de son exécution ?
Essentiellement, une bibliothèque est-elle toujours nécessaire, même pour les programmes les plus simples, si oui, pourquoi ? Je demande parce que je pensais que le point d'entrée canonique pour tout ce qui veut être exécuté est en fait _start (que je pensais être dans une bibliothèque, à savoir glibc). Peut-être que je ne comprends pas ce que _start fait vraiment en ce qui concerne la configuration des choses, donc tout pointeur serait également utile.
Réponse acceptée :
Si vous voulez écrire votre programme en C portable standard, vous avez bien sûr besoin d'un runtime qui appelle le main()
fonction en premier lieu.
Mais si vous ne vous souciez pas de cela, vous pouvez vous passer de n'importe quelle bibliothèque et effectuer des appels système directement via l'assemblage en ligne. Par exemple. pour 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 +++
Vous devez faire au moins un appel système, à savoir _exit(2)
, à moins que la sortie par plantage ne soit acceptable pour un "programme le plus simple", auquel cas un fichier vide fera aussi l'affaire ;-) :
$ > 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
Je pensais que le point d'entrée canonique pour tout ce qui veut être exécuté est en fait
_start
il n'y a rien de canonique là-dedans; _start
est le nom par défaut que l'éditeur de liens utilisera ; vous pouvez le pointer ailleurs avec le -e sym
option (-Wl,-e,sym
avec gcc
).