Для понимания того, почему FreeBSD использует формат elf(5), вам потребуется сначала немного узнать о трех <<доминирующих>> исполняемых форматах для UNIX(R):
Старейший и <<классический>> объектный формат UNIX(R). Он использует короткий и компактный заголовок с магическим числом в начале, которое часто используется для описания формата (смотрите a.out(5) с более подробной информацией). Он содержит три загружаемых сегмента: .text, .data и .bss плюс таблицу символов и таблицу строк.
COFF
Объектный формат SVR3. Заголовок включает таблицу разделов, так что могут быть сегменты кроме .text, .data и .bss.
Наследник формата COFF, поддерживающий множественные сегменты и 32-битные или 64-битные значения. Одно важное замечание: ELF был разработан в предположении что есть только по одному ABI на одну архитектуру. Это предположение совершенно неверно, и не только в мире коммерческих SYSV (в котором есть как минимум три ABI: SVR4, Solaris, SCO).
FreeBSD пытается обойти эту проблему, в частности предоставляя утилиту для оглавления известного исполняемого файла ELF информацией об ABI с которым он совместим. Обратитесь к странице справочника brandelf(1) за более подробной информацией.
FreeBSD имеет произошла из <<классического>> лагеря и
использовала формат a.out(5), технологию опробованную и
проверенную на многих поколениях релизов BSD, до начала ветки
3.X. Хотя собирать и запускать родные бинарные
файлы ELF (и ядро) в системе FreeBSD
можно было несколько раньше, FreeBSD вначале сопротивлялась
<<проталкиванию>> ELF как формата
по умолчанию. Почему? Когда лагерь Linux производил болезненный
переход к ELF, у него не было большого
преимущества перед исполняемым форматом a.out
,
из-за негибкого, основанного на таблице переходов механизма
разделяемых библиотек, что делало создание разделяемых библиотек
очень трудным для поставщиков и разработчиков. Когда доступные
инструменты ELF предоставили решение проблемы
разделяемых библиотек, и появилась некоторая перспектива,
цена перехода была признана допустимой и он был сделан.
Механизм разделяемых библиотек FreeBSD близок по стилю к механизму
разделяемых библиотек SunOSTM от Sun, и поэтому очень прост в
использовании.
Итак, почему так много разных форматов?
Давно, в темном далеком прошлом, оборудование было простым.
Это простое оборудование поддерживало простые, маленькие системы.
a.out
был совершенно адекватен задаче представления
бинарных файлов на таких простых системах (PDP-11). Люди, портировавшие
UNIX(R) с этих простых систем, оставили a.out
формат потому, что он был достаточен для ранних портов UNIX(R) на
архитектуры, подобные Motorola 68k, VAXen, etc.
Затем какой-то смышленый инженер по оборудованию решил, что если
он сможет заставить программы исполнять некоторые трюки, то сможет
несколько упростить дизайн и заставить ядро CPU работать быстрее.
Хотя это было сделано с новым типом оборудования (известного сейчас
как RISC), формат a.out
не подходил для него,
и было разработано множество форматов, чтобы получить
лучшую производительность на таком оборудовании по сравнению с
той, которую мог предоставить простой формат a.out
.
Были изобретены форматы COFF, ECOFF
и некоторые другие малоизвестные форматы, и их ограничения были учтены,
когда все похоже остановились на ELF.
Кроме того, размеры программ стали огромны, а диски (и оперативная
память) остались относительно малы, поэтому появилась концепция
разделяемых библиотек. Система VM также стала более сложной.
Хотя все эти усовершенствования были выполнены с форматом
a.out
, его полезность все больше и больше
уменьшалась с каждым нововведением. К тому же потребовалась
динамическая загрузка во время выполнения, или выгрузка частей
программы после выполнения стартового кода для экономии
памяти или места на диске. Языки усложнялись, и потребовался
автоматический вызов кода перед главной программой. Множество
изменений было внесено в формат a.out
, чтобы
все это появилось, и в основном работало некоторое время. Настал
момент, когда a.out
не смог решить все эти
проблемы без чрезмерного увеличения размера и сложности.
В то время, как ELF решил многие из этих проблем,
перевод этого формата с системы на систему болезнен. Поэтому
формату ELF пришлось подождать, пока не стало
более болезненным оставаться с a.out
, чем
перейти на ELF.
Тем временем, инструменты разработки, от которых произошли инструменты разработки FreeBSD (особенно ассемблер и загрузчик), развивались в двух параллельных направлениях. Направление FreeBSD добавило разделяемые библиотеки и устранило некоторые ошибки. Люди из GNU, написавшие эти программы, переписали их и добавили простую поддержку сборки кросс-компиляторов, подключения различных форматов в будущем и так далее. Многим требовалось собрать кросс-компиляторы для FreeBSD, и это не удалось, поскольку устаревшие исходные тексты FreeBSD для as и ld не подходили для этой задачи. Новый набор инструментов GNU (binutils) поддерживает кросс-компилирование, ELF, разделяемые библиотеки, C++, расширения и т.д. В дополнение, многие поставщики выпустили программы в формате ELF и они хорошо подходят для запуска в FreeBSD.
ELF более выразителен, чем
a.out
, позволяет базовой системе быть более
гибкой. ELF лучше поддерживается, и
предоставляет поддержку кросс-компиляторов, что важно для многих
людей. ELF может быть немного медленнее,
чем a.out
, но замерить это сложно.
Есть также множество деталей, отличающихся для этих двух
форматов, в том как они отображают страницы, обрабатывают
начальный код, и т.д. В этом нет ничего очень важного,
но они различаются. В настоящее время поддержка
a.out
убрана из ядра GENERIC
, и со
временем будет убрана из ядра, как только потребность в запуске
старых программ a.out
останется в прошлом.
Этот, и другие документы, могут быть скачаны с https://download.freebsd.org/ftp/doc/.
По вопросам, связанным с FreeBSD, прочитайте
документацию прежде чем писать в
<questions@FreeBSD.org>.
По вопросам, связанным с этой документацией, пишите в рассылку
<doc@FreeBSD.org>.