a.out
a.out est un format de fichier utilisé dans les premières versions d'Unix. Il était utilisé pour les fichiers exécutables, les codes objet et, plus tard, les bibliothèques partagées.
À l'origine, le premier programme assembleur sur Unix générait un fichier nommé a.out, signifiant assembler output (production de l'assembleur). Le nom est resté utilisé par certains compilateurs et éditeurs de liens lorsqu'aucun nom de fichier de sortie n'est précisé, même si cet exécutable n'est pas au format a.out[1].
Utilisation
[modifier | modifier le code]Au début du développement de Unix, sur PDP-7, Ken Thompson écrit un programme assembleur qui génère un fichier exécutable de nom fixe : a.out[2]. Le format du fichier est resté similaire lorsque Unix a été porté sur PDP-11. Il apparaît sur la première édition d'Unix[3]. Il a été supplanté par le format COFF dans AT&T Unix System V qui a été supplanté à son tour par le format ELF dans System V Release 4.
Bien que Berkeley Unix ait continué à l'utiliser, les systèmes BSD modernes ont depuis migré vers ELF: NetBSD a changé avec sa version 1.5 et FreeBSD pendant la transition entre sa version 2.2 et 3.0.
Le format a.out n'a pas de support direct des symboles de débugage mais il peut être utilisé avec stabs (en) qui utilise des entrées de table de symbole spécifiques pour stocker les données.
Le noyau Linux utilisait aussi a.out jusqu'à sa version 1.2, où il a été remplacé par ELF[4] (la prise en charge à titre expérimental de ELF a été ajoutée à la version 1.1.52). Cette transition a été plus ou moins due au fait qu'il était difficile de faire des bibliothèques partagées avec ce genre de format qui nécessitait par exemple de devoir enregistrer l'adresse virtuelle à laquelle la bibliothèque était chargée en mémoire pour que le ld.so (en) de Linux puisse connaître la nouvelle adresse de la bibliothèque partagée[5].
Plusieurs versions de BSD ont pu conserver ce format plus longtemps que Linux principalement parce que l'implémentation du a.out des BSD était plus flexible[6]. Minix 3 (en) est passé au format ELF avec la version 3.2.0 et a définitivement abandonné le support du format a.out avec la version 3.2.1, sortie le 21.02.2013.
Le format
[modifier | modifier le code]Il existe plusieurs variantes aux exécutables a.out : OMAGIC, NMAGIC, QMAGIC ou ZMAGIC.
- Le format OMAGIC a des segments contigus après l'en-tête: le segment de texte et de données ne sont pas séparés. Ce format était aussi utilisé pour les fichiers objets.
- Le format NMAGIC est comme le OMAGIC mis à part que le segment de données est chargé dans la page suivant la fin du segment de texte qui, lui, est en lecture seule.
- Le format ZMAGIC ajoute le support de la pagination à la demande (en) (les pages mémoire ne sont chargées que lorsqu'elles sont nécessaires; on parle alors de « Lazy loading »). La taille des segments code et données doit être un multiple de la taille de page.
- Le format QMAGIC permet à l'en-tête d'être dans la même page que le début du segment texte, permettant ainsi d'économiser une page mémoire. Les binaires QMAGIC sont généralement chargés une page avant la fin de l'espace d'adressage virtuel, permettant ainsi d'intercepter les références à un pointeur null lors d'une erreur de segmentation.
Structure
[modifier | modifier le code]Un fichier a.out est découpé en sept sections ; les voici dans l'ordre :
- en-tête exec (« exec header »)
- contient les paramètres utilisés par le noyau pour charger et exécuter le binaire, ainsi que les paramètres utilisés par l'éditeur de liens (ld) pour lier l'exécutable à d'autres. C'est la seule section obligatoire.
- segment de texte (« text segment »)
- contient le code machine et les données qui devront être chargés en mémoire quand le programme devra s'exécuter. Il peut être chargé dans une zone mémoire en lecture seule.
- segment de données (« data segment »)
- contient les données initialisées par le programme lui-même. Il est toujours chargé dans un segment mémoire qui est accessible en écriture.
- réallocation de texte (« text relocations »)
- contient des enregistrements utilisés par l'éditeur de liens pour mettre à jour les pointeurs du segment de texte quand plusieurs exécutables sont liés.
- réallocation de données (« data relocations »)
- comme dans la partie réallocation de texte, mais pour le segment de données.
- table de symboles (« symbol table »)
- table utilisée par l'éditeur de liens pour retrouver l'adresse des variables nommées ou des fonctions (symboles) entre différents binaires.
- table de chaîne (« string table »)
- contient le nom associé à un symbole.
Notes et références
[modifier | modifier le code]- (en) Rupert Wood, « 'What to do with a.out' - sur la mailinglist gcc-help », (consulté le ).
- (en) Thomas J. Bergin Jr et Richard G. Gibson Jr, History of Programming Languages - II, ACM Press, (ISBN 0-201-89502-1, présentation en ligne), chap. XIV (« C Session »)
- (en) [PDF] « a.out — assembler and link editor output », Bell Labs, (consulté le ).
- (en) Daniel Barlow, « The Linux ELF HOWTO (v1.29) », (consulté le ).
- (en) [PDF] Ulrich Drepper, « How To Write Shared Libraries - 1.1 A Little Bit of History », (consulté le ) : « When introducing shared libraries certain design decisions had to be made to work in the limitations of a.out. (...) For all these reasons and more, Linux converted early on to using ELF (Executable Linkage Format) as the binary format. ».
- (en) « BSD Myths: BSD uses the a.out executable format, which is outdated technology » (consulté le ).