Введение

Формат исполняемого файла

Общий объектный формат (COFF) — это формат для исполняемых файлов, объектного кода и общих библиотек, используемых в системах Unix. Он был представлен в Unix System V, заменил ранее использовавшийся формат a.out и послужил основой для расширенных спецификаций, таких как XCOFF и ECOFF, прежде чем был в значительной степени вытеснен ELF, представленным с SVR4. COFF и его варианты продолжают использоваться в некоторых Unix-подобных системах, в Microsoft Windows (Portable Executable), в средах UEFI и в некоторых системах встраиваемой разработки.

История

Оригинальный формат файла объектов Unix a.out не способен адекватно поддерживать общие библиотеки, идентификацию файлов других форматов или явную привязку адресов. По мере развития Unix-подобных систем как внутри AT&T, так и за её пределами, возникали различные решения этих и других проблем. COFF был представлен в 1983 году в UNIX System V от AT&T для 32-битных платформ, отличных от VAX, таких как 3B20. Улучшения по сравнению с существующим форматом a.out от AT&T включали произвольные секции, явные объявления процессора и явную привязку адресов. Однако, конструкция COFF была одновременно слишком ограниченной и не полностью специфицированной: существовало ограничение на максимальное количество секций, на длину имён секций и включенных исходных файлов, а символическая отладочная информация не могла поддерживать реальные языки программирования, такие как C, не говоря уже о более новых языках, таких как C++, или новых процессорах. В результате все реальные реализации COFF неизбежно нарушали стандарт. Это привело к многочисленным расширениям COFF. IBM использовала формат XCOFF в AIX; DEC, SGI и другие – ECOFF; а множество портов SysV и цепочек инструментов, предназначенных для встраиваемых систем, создавали собственные, несовместимые варианты. С выпуском SVR4 компания AT&T заменила COFF на ELF. Хотя расширенные версии COFF продолжают использоваться для некоторых Unix и Unix-подобных платформ, в основном во встраиваемых системах, возможно, наиболее широкое распространение формат COFF получил сегодня в формате Portable Executable (PE) от Microsoft. Разработанный для Windows NT, формат PE (иногда записывается как PE/COFF) использует заголовок COFF для объектных файлов и как компонент заголовка PE для исполняемых файлов.

Особенности

Основным улучшением COFF по сравнению с a.out стало введение нескольких именованных секций в объектном файле. Разные объектные файлы могли содержать разное количество и типы секций.

Символическая информация для отладки

Символическая информация для отладки COFF состоит из символических (строковых) имен для программных функций и переменных, а также информации о номерах строк, используемой для установки точек останова и трассировки выполнения. Символические имена хранятся в таблице символов COFF. Каждая запись в таблице символов включает имя, класс хранения, тип, значение и номер секции. Короткие имена (8 символов или меньше) хранятся непосредственно в таблице символов, более длинные имена – как смещение в таблице строк, расположенной в конце COFF-объекта. Классы хранения описывают тип сущности, которую представляет символ, и могут включать внешние переменные (C EXT), автоматические (стековые) переменные (C AUTO), регистровые переменные (C REG), функции (C FCN) и многие другие. Тип символа описывает интерпретацию значения сущности символа и включает значения для всех типов данных C. При компиляции с соответствующими опциями COFF-объектный файл содержит информацию о номерах строк для каждой возможной точки останова в текстовом разделе объектного файла. Информация о номерах строк представлена в двух формах: в первой, для каждой возможной точки останова в коде, запись в таблице номеров строк содержит адрес и соответствующий номер строки. Во второй форме запись указывает на запись в таблице символов, представляющую начало функции, что позволяет установить точку останова по имени функции. Важно отметить, что COFF не поддерживал представление номеров строк или отладочных символов для подключаемых исходных файлов, таких как файлы заголовков, что делало информацию об отладке COFF практически бесполезной без несовместимых расширений.

Относительный виртуальный адрес

Когда генерируется COFF-файл, обычно неизвестно, по какому адресу в памяти он будет загружен. Виртуальный адрес, по которому будет загружен первый байт файла, называется базовым адресом образа. Остальная часть файла не обязательно загружается в непрерывный блок, а в различные секции. Относительные виртуальные адреса (RVA) не следует путать со стандартными виртуальными адресами. Относительный виртуальный адрес – это виртуальный адрес объекта из файла после его загрузки в память, уменьшенный на базовый адрес образа файла. Если бы файл отображался в память непосредственно с диска, RVA совпадал бы со смещением в файле, но такое происходит довольно редко. Следует отметить, что термин RVA используется только для объектов внутри файла образа. После загрузки в память к базовому адресу образа прибавляется значение, и используются обычные виртуальные адреса.

Проблемы

Заголовок файла COFF хранит дату и время создания объектного файла в виде 32-битного двоичного целого числа, представляющего собой количество секунд, прошедших с начала эпохи Unix – 1 января 1970 года 00:00:00 UTC. Даты, наступающие после 19 января 2038 года, не могут быть сохранены в этом формате, что является проявлением проблемы 2038 года.