Si je me souviens bien, l'un des problèmes d'origine avec le format a.out est qu'il ne supportait que trois sections :texte, données et bss. ELF autorise n'importe quel nombre (ou au moins beaucoup plus). Le format d'en-tête a.out était très simple, quelque chose comme :
word <magic>
word <text size>
word <data size>
word <bss size>
Le format ELF, en revanche, a des en-têtes de section, avec des noms, des tailles, etc.
Avoir plus de sections permet les sections standard, mais nous donne également des sections const, des sections de constructeur et même une section par fonction, si nous le voulons.
Le a.out
forçait les bibliothèques partagées à occuper une place fixe en mémoire. Si vous vouliez distribuer une bibliothèque partagée a.out, vous deviez enregistrer son espace d'adressage. C'était bon pour les performances, mais cela n'a pas évolué du tout. Voyez par vous-même à quel point c'était délicat (linuxjournal).
En revanche, dans ELF, les bibliothèques partagées peuvent être chargées n'importe où dans la mémoire, et peuvent même sembler être à des adresses différentes pour différentes applications exécutées sur le même ordinateur (le code étant toujours effectivement chargé à un seul endroit de la mémoire physique) ! Pour ce faire, dans l'architecture IA-32, un registre (%ebx) doit être sacrifié. Une référence plus complète montrant que les bibliothèques partagées sont devenues plus compliquées dans ELF, mais c'était une complexité côté compilateur, par opposition à côté programmeur.