Per quanto ricordo, uno dei problemi originali con il formato a.out è che supportava solo tre sezioni:testo, dati e bss. ELF consente qualsiasi numero (o almeno molti di più). Il formato dell'intestazione a.out era molto semplice, qualcosa del tipo:
word <magic>
word <text size>
word <data size>
word <bss size>
Il formato ELF, al contrario, ha intestazioni di sezione, con nomi, dimensioni, ecc.
Avere più sezioni consente le sezioni standard, ma ci dà anche sezioni const, sezioni costruttore e persino una sezione per funzione, se lo vogliamo.
Il a.out
formato costringeva le librerie condivise ad occupare un posto fisso nella memoria. Se volevi distribuire una libreria condivisa a.out, dovevi registrare il suo spazio degli indirizzi. Questo è stato positivo per le prestazioni, ma non è stato ridimensionato affatto. Guarda tu stesso quanto è stato complicato (linuxjournal).
Al contrario, in ELF, le librerie condivise possono essere caricate ovunque nella memoria e possono anche apparire a indirizzi diversi per diverse applicazioni in esecuzione sullo stesso computer (con il codice ancora effettivamente caricato in un solo posto nella memoria fisica)! Per raggiungere questo obiettivo, nell'architettura IA-32, è necessario sacrificare un registro (%ebx). Un riferimento più completo che mostra che le librerie condivise sono diventate più complicate in ELF, ma quella era complessità lato compilatore, non lato programmatore.