By zrozumieć czemu FreeBSD używa formatu elf(5), musimy wpierw poznać trzy obecnie "dominujace" formaty plików wykonywalnych w systemach UNIX(R):
Najstarszy i najbardziej "klasyczny" format w Uniksie. Wykorzystuje krótki nagłówek z magicznym numerem na samym początku, często wykorzystywanym do określenia rodzaju pliku (szczegółowy opis dostępny jest w a.out(5)). Na plik składają się trzy segmenty: .text, .data i .bss oraz tablice symboli i ciągów tekstowych.
COFF
Format obiektowy pochodzący z SVR3. W tym formacie sekcja tablic w wchodzi już w skład nagłówka, tak więc możliwe jest zawarcie w pliku więcej sekcji niż tylko .text, .data i .bss.
Następca COFF zawierający wiele dodatkowych sekcji o 32- bądź nawet 64-bitowych wartościach. Jednym, acz wielkim minusem jest fakt, iż przy projektowaniu formatu ELF również założono, że na każdą architekturę sprzętową będzie istniał tylko jeden interfejs ABI. Okazało się natomiast, iż takie założenie jest błędne nawet w świecie komercyjnych SYSV (z którego pochodzą przynajmniej trzy ABI: SVR4, Solaris i SCO).
Sposobem na rozwiązanie tego problemu we FreeBSD są narzędzia do metkowania plików wykonywalnych ELF informacjami, z którymi ABI jest on zgodny. Więcej informacji dostępnych jest w podręczniku systemowym brandelf(1).
System FreeBSD pochodzi z "klasycznego" obozu.
Wykorzystywał on zatem format a.out(5) - technologię
wypróbowaną w wielu pokoleniach systemów BSD i z powodzeniem
stosowaną aż do gałęzi 3.X. Mimo, że skompilowanie i uruchomienie
w sposób natywny plików binarnych ELF (a także
jądra) było możliwe we FreeBSD już od pewnego czasu, Projekt
oficjalnie opierał się przed migracją do formatu ELF
jako podstawowego. Dlaczego? Otóż, gdy obóz linuksowy wykonał ten
bolesny krok ku ELF nie udało się tak łatwo uciec
od formatu a.out
. Wynikało to przede wszystkim
z faktu, iż niezbyt elastyczny plan migracji bazował na mechanizmie
współdzielonych bibliotek, których modyfikacja nastręczała wielu
trudności zarówno producentom sprzętu jak i projektantom. Dopiero od
momentu gdy narzędzia dostępne dla ELF zaoferowały
sposób rozwiązania problemu ze współdzielonymi bibliotekami, zaczęły
być postrzegane ogólnie jako "droga do przodu", a tym
samym koszty migracji mogły zostać uznane za niezbędne do poniesienia.
Mechanizm współdzielonych bibliotek FreeBSD w dużej mierze przypomina
mechanizm z SunOSTM Sun'a i jako taki jest bardzo łatwy w użyciu.
Skąd więc tyle różnych formatów?
W zamierzchłych czasach do dyspozycji był prosty sprzęt komputerowy.
Ów prosty sprzęt obsługiwał mały, prosty system. Stąd też format
a.out
był całkowicie odpowiednim do prezentacji
plików binarnych w tym prostym systemie (PDP-11). Gdy UNIX(R) został
przeniesiony z tego prostego systemu na platformy typu Motorola 68k czy
VAXen, zachowany został format a.out
, zdecydowanie
wystarcząjacy dla wczesnych wersji Uniksa.
Pewien czas później, jakiś bystry inżynier sprzętowy stwierdził
że gdyby potrafił zmusić oprogramowanie do robienia kilku obskurnych
sztuczek, wówczas mógłby pozbyć się kilku bramek z układu scalonego
i zmusić CPU do szybszej pracy. Pomimo, że format a.out
potrafił współpracować z tym nowym rodzajem sprzętu (zwanego wówczas
RISC) to mimo wszystko nie był najlepszym do tego
formatem. Dlatego też rozpoczęto prace nad innymi formatami binarnymi,
które miały osiągnąć lepsze wyniki niż ograniczony, prosty a.out
mógł zaoferować. Stworzone zostały COFF,
ECOFF oraz kilka mniej znanych formatów, nim powstał
ELF.
Kolejnym problemem okazał się wzrost rozmiarów programów przy
względnie małej pojemności dysków oraz pamięci fizycznych, a także
zwiększeniu stopnia skomplikowania pamięci wirtualnej VM. Tak też
narodziła się koncepcja współdzielonych bibliotek. Mimo, że ów postęp
osiągnięty był przy pomocy formatu a.out
zakres
jego przydatności był stale rozciągany, wraz z każdą nową funkcją.
Pojawiła się konieczność dynamicznego wczytywanie pewnych rzeczy już
w trakcie uruchamiania programu czy zapisywania części programu zaraz
po wykonaniu kodu init w pamięci lub przestrzeni wymiany. Również języki
programowania stawały się coraz bardziej wyrafinowane. Wiele poprawek
wprowadzonych do formatu a.out
umożliwiały realizację
kolejnych funkcji, przy czym z reguły działały one tylko przez pewien czas.
Niestety, format a.out stał się z czasem niezdolny do rozwiązywania wszystkich
problemów bez wciąż rozrastającego się narzutu w kodzie i poziomu skomplikowania.
Mimo, że ELF potrafił rozwiązać wiele z ówczesnych problemów,
zmiana formatu binarnego, który generalnie działał, wciąż była wielką uciążliwością.
Dlatego też ELF musiał poczekać aż bardziej bolesnym okazało
się pozostanie przy a.out
niż przejście
do ELF.
Wraz z upływem czasu, narzędzia kompilacyjne, z których FreeBSD wywodzi własne narzędzia (przede wszystkim assembler i loader), wyewoluowały w dwa równoległe projekty. Odmiana FreeBSD dała współdzielone biblioteki oraz poprawki kilku błędów. Ludzie z GNU, którzy oryginalnie napisali te programy, przepisali je na nowo i dodali proste kompilatory wskrośne, pozwalające na pracę w różnych formatach. Nowy pakiet narzędzi GNU (binutils) wspiera kompilowanie wskrośne, format ELF, współdzielone biblioteki, rozszerzenia C++, itp. Dodatkowo, wielu producentów sprzętu przygotowuje binaria ELF. Jest to zatem dobra rzecz dla FreeBSD, że je obsługuje.
Format ELF oferuje większą rozszerzalność niz
a.out
. Narzędzia ELF są lepiej
przygotowywane i oferują kompilację wskrośną, co jest istotne dla wielu
programistów. Co prawda ELF może być trochę wolniejszy
niż a.out
, jednakże próba pomiaru może być trudna.
Istnieje również wiele innych szczegółów różnych dla obydwu formatów,
m.in. sposób mapowania stron, obsługi kodu init itp. Co prawda,
żadne z nich nie jest istotne, jednakże różnice istnieją. Z czasem,
wsparcie dla a.out
zostanie wstrzymane z jadra
GENERIC
i ostatecznie usunięte z jądra gdy tylko
zniknie potrzeba obsługi programów a.out
.
All FreeBSD documents are available for download at https://download.freebsd.org/ftp/doc/
Questions that are not answered by the
documentation may be
sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.