ELF ( — формат исполнимых и компонуемых файлов) — формат исполняемых двоичных файлов, используемый во многих современных UNIX-подобных операционных системах, таких как FreeBSD, Linux, Solaris и др.

История Стандарт формата ELF изначально был разработан и опубликован компанией как часть двоичного интерфейса приложений операционной системы UNIX System VSystem V Application Binary Interface Edition 4.1 (1997-03-18). Затем он был выбран комитетом и развит в качестве переносимого формата для различных операционных систем, работающих на 32-разрядной аппаратной архитектуре Intel x86.Спецификация ELF ELF быстро набрал популярность и, после того как компания HP расширила формат и опубликовала стандарт ELF-64, распространился и на 64-разрядных платформах.ELF-64 Object File Format

Типы Стандарт формата ELF различает несколько типов файлов: Перемещаемый файл — хранит инструкции и данные, которые могут быть связаны с другими объектными файлами. Результатом такой связи может быть совместно используемый объектный файл или исполняемый файл. К этому типу относятся объектные файлы статических библиотек. Совместно используемый объектный файл — также содержит инструкции и данные и может быть связан с другими перемещаемыми файлами и совместно используемыми объектными файлами, в результате чего будет создан новый объектный файл, либо при запуске программы на выполнение операционная система может динамически связать его с исполняемым файлом программы, в результате чего будет создан исполняемый образ программы. В последнем случае речь идет о совместно используемых библиотеках. Исполняемый файл — содержит полное описание, позволяющее системе создать образ процесса. В том числе: инструкции, данные, описание необходимых совместно используемых объектных файлов и необходимую символьную и отладочную информацию.

Формат Каждый ELF файл состоит из следующих частей:

Заголовок файла Заголовок файла (ELF Header) имеет фиксированное расположение в начале файла и содержит общее описание структуры файла и его основные характеристики, такие как: тип, версия формата, архитектура процессора, виртуальный адрес точки входа, размеры и смещения остальных частей файла. Заголовок имеет размер 52 байта для 32-битных файлов или 64 для 64-битных. Данное различие обуславливается тем, что в заголовке файла содержится три поля, имеющих размер указателя, который составляет 4 и 8 байт для 32- и 64-битных процессоров соответственно. Такими полями являются e_entry, e_phoff и e_shoff. + Поля заголовка файла ELF Размер Название НазначениеELF 32ELF 6416 e_ident Общая характеристика файла. +Байты массива e_identИндексНазваниеНазначение0 - 3EI_MAG0 - EI_MAG3Сигнатура файла: .4EI_CLASSКласс объектного файла. НазваниеЗначениеОписаниеELFCLASSNONE0Некорректный классELFCLASS32132-битный объектный файлELFCLASS64264-битный объектный файл5EI_DATAЗависимый от процессора метод кодирования данных. НазваниеЗначениеОписаниеELFDATANONE0Некорректный типELFDATA2LSB1Little EndianELFDATA2MSB2Big Endian6EI_VERSIONВерсия ELF заголовка. В настоящее время значение данного байта должно быть EV_CURRENT. НазваниеЗначениеEV_CURRENT17EI_OSABIСпецифичные для операционной системы или ABI расширения, используемые в файле. У некоторых полей в других структурах ELF файла имеются флаги и поля, значение которых зависит от операционной системы или ABI; интерпретация этих полей определяется значением данного байта. Если объектный файл не использует расширений, рекомендуется, чтобы этот байт был установлен в 0. Если значение для этого байта находится в диапазоне от 64 до 255, то его интерпретация зависит от значения поля e_machine ELF заголовка. В этом диапазоне каждая архитектура может определить свой набор значений. НазваниеЗначениеОписаниеELFOSABI_NONE0UNIX System V ABIELFOSABI_HPUX1HP-UXELFOSABI_NETBSD2NetBSDELFOSABI_GNU3Файл использует расширения GNU ELF (GNU/Linux)ELFOSABI_SOLARIS6SolarisELFOSABI_AIX7AIXELFOSABI_IRIX8IRIXELFOSABI_FREEBSD9FreeBSDELFOSABI_TRU6410Tru64 UNIXELFOSABI_MODESTO11ModestoELFOSABI_OPENBSD12OpenBSDELFOSABI_OPENVMS13OpenVMSELFOSABI_NSK14Non-Stop KernelELFOSABI_AROS15Amiga Research OSELFOSABI_FENIXOS16FenixOSELFOSABI_CLOUDABI17CloudABIELFOSABI_OPENVOS18OpenVOS64 - 255Зависимые от процессора значения8EI_ABIVERSIONВерсия ABI.9EI_PADТ. н. padding bytes (байты заполнения). Зарезервированные для будущего использования элементы массива e_ident. Обычно устанавливаются в 0. Программы для чтения объектных файлов должны игнорировать их.10EI_PAD + 111EI_PAD + 212EI_PAD + 313EI_PAD + 414EI_PAD + 515EI_PAD + 6 2 e_type Тип файла. НазваниеЗначениеОписаниеET_NONE0НеопределённыйET_REL1Перемещаемый файлET_EXEC2Исполняемый файлET_DYN3Совместно используемый объектный файлET_CORE4Core fileET_LOOS - ET_HIOS65024 - 65279Зависимые от операционной системы значенияET_LOPROC - ET_HIPROC65280 - 65535Зависимые от процессора значения 2 e_machine Архитектура аппаратной платформы, для которой файл создан: НазваниеЗначениеОписаниеEM_NONEНеопределеноEM_M32AT&T WE 32100EM_SPARCSPARCEM_386Intel 80386EM_68KMotorola 68000 (M68k)EM_88KMotorola 88000 (M88k)EM_IAMCUIntel MCUEM_860Intel 80860EM_MIPSMIPSEM_S370IBM System/370EM_MIPS_RS3_LEMIPS R3000 Little-endian - Reserved for future useEM_PARISCHewlett-Packard PA-RISCReserved for future useEM_960Intel 80960EM_PPCPowerPCEM_PPC64PowerPC (64-bit)EM_S390S390, including S390xEM_SPUIBM SPU/SPC - Reserved for future useEM_V800NEC V800EM_FR20Fujitsu FR20EM_RH32TRW RH-32EM_MCORE и EM_RCEMotorola RCEEM_ARMARM (up to ARMv7/Aarch32)EM_OLD_ALPHADigital AlphaEM_SHSuperHEM_SPARCV9SPARC Version 9EM_TRICORESiemens TriCore embedded processorEM_ARCArgonaut RISC CoreEM_H8_300Hitachi H8/300EM_H8_300HHitachi H8/300HEM_H8SHitachi H8SEM_H8_500Hitachi H8/500EM_IA_64IA-64EM_MIPS_XStanford MIPS-XEM_COLDFIREMotorola ColdFireEM_68HC12Motorola M68HC12EM_MMAFujitsu MMA Multimedia AcceleratorEM_PCPSiemens PCPEM_NCPUSony nCPU embedded RISC processorEM_NDR1Denso NDR1 microprocessorEM_STARCOREMotorola Star*Core processorEM_ME16Toyota ME16 processorEM_ST100STMicroelectronics ST100 processorEM_TINYJAdvanced Logic Corp. TinyJ embedded processor familyEM_X86_64AMD x86-64EM_MCST_ELBRUSЭльбрус (процессорная архитектура)EM_TI_C6000TMS320C6000 FamilyEM_AARCH64ARM 64-bits (ARMv8/Aarch64)EM_RISCVRISC-VEM_BPFBerkeley Packet FilterEM_65816WDC 65C816 4 e_version Номер версии формата. На данный момент корректным считается только одно значение. НазваниеЗначениеОписаниеEV_NONE0Некорректное значениеEV_CURRENT1Текущая версия 48 e_entry Виртуальный адрес точки входа, которому система передает управление при запуске процесса. Если у файла нет точки входа, это поле содержит 0. 48 e_phoff Смещение таблицы заголовков программы от начала файла в байтах. Если у файла нет таблицы заголовков программы, это поле содержит 0. 48 e_shoff Смещение таблицы заголовков секций от начала файла в байтах. Если у файла нет таблицы заголовков секций, это поле содержит 0. 4 e_flags Связанные с файлом флаги, зависящие от процессора. При их отсутствии это поле содержит 0. 2 e_ehsize Размер заголовка файла в байтах (52 для 32-битных файлов и 64 для 64-битных). 2 e_phentsize Размер одного заголовка программы. Все заголовки программы имеют одинаковый размер (32 для 32-битных файлов и 56 для 64-битных). 2 e_phnum Число заголовков программы. Если у файла нет таблицы заголовков программы, это поле содержит 0. 2 e_shentsize Размер одного заголовка секции. Все заголовки секций имеют одинаковый размер (40 для 32-битных файлов и 64 для 64-битных). 2 e_shnum Число заголовков секций. Если у файла нет таблицы заголовков секций, это поле содержит 0. 2 e_shstrndx Индекс записи в таблице заголовков секций, описывающей таблицу названий секций (обычно эта таблица называется .shstrtab и представляет собой отдельную секцию). Если файл не содержит таблицы названий секций, это поле содержит 0.

Таблица заголовков программы Таблица заголовков программы содержит заголовки, каждый из которых описывает отдельный сегмент программы и его атрибуты либо другую информацию, необходимую операционной системе для подготовки программы к исполнению. Данная таблица может располагаться в любом месте файла, её местоположение (смещение относительно начала файла) описывается в поле e_phoff заголовка ELF.

При анализе структуры заголовка программы можно обнаружить различное местоположение поля p_flags для 32- и 64-битных ELF файлов. Данное различие обуславливается выравниванием структуры для увеличения эффективности обработки. +Поля заголовка программыРазмерНазваниеНазначениеELF 32ELF 644p_typeТип сегмента, который описывает данный заголовок, или каким образом интерпретировать значения полей этого заголовка. НазваниеЗначениеОписаниеPT_NULL0Заголовок не используется, остальные поля не определены. Данный тип позволяет включать в таблицу заголовков программы файла игнорируемые элементы.PT_LOAD1Загружаемый сегмент, описываемый полями p_filesz и p_memsz. Байты из файла отражаются на сегменте в памяти. Если размер сегмента в памяти (p_memsz) больше размера сегмента в файле (p_filesz), дополнительные байты заполняются нулями (они следуют сразу за определенными в сегменте байтами). Размер сегмента в файле (p_filesz) не может быть больше размера сегмента в памяти (p_memsz). Заголовки программы загружаемых сегментов располагаются в таблице заголовков программ в порядке возрастания значения поля p_vaddr.PT_DYNAMIC2Заголовок программы предоставляет информацию о динамической компоновке.PT_INTERP3Заголовок программы предоставляет размер и местоположение пути (строки в стиле C с завершающим нулём) для запуска в качестве интерпретатора. Этот тип сегмента имеет смысл только для исполняемых файлов (хотя он может быть и в совместно используемом объектном файле); он не может встречаться более одного раза в файле. Если заголовок такого типа присутствует, он должен предшествовать любому заголовку программы загружаемого сегмента.PT_NOTE4Заголовок программы определяет местоположение и размер вспомогательной информации.PT_SHLIB5Этот тип сегмента зарезервирован, но его смысл не определён. Программы, содержащие заголовок программы этого типа, не соответствуют ABI.PT_PHDR6Заголовок программы, если он присутствует, определяет местоположение и размер самой таблицы заголовков программы, как в файле, так и в образе памяти программы. Этот тип сегмента не может встречаться более одного раза в файле. Более того, он может встретиться только при наличии в файле таблицы заголовков программы. Если заголовок такого типа присутствует, он должен предшествовать любому заголовку программы загружаемого сегмента.PT_TLS7Заголовок программы определяет шаблон Thread-Local Storage. Загрузчики ELF не должны поддерживать эту запись в таблице заголовков программ.PT_LOOS - PT_HIOS1610612736 - 1879048191Зависимые от операционной системы значения.PT_LOPROC - PT_HIPROC1879048192 - 2147483647Зависимые от процессора значения.4p_flagsФлаги, относящиеся к сегменту (для ELF64). +НазваниеЗначениеОписаниеPF_XРазрешение на исполнениеPF_WРазрешение на записьPF_RРазрешение на чтениеPF_MASKOSВсе биты, включенные в это поле, определяют зависящие от операционной системы значенияPF_MASKPROCВсе биты, включенные в это поле, определяют зависящие от процессора значения48p_offsetСмещение сегмента от начала файла.48p_vaddrВиртуальный адрес сегмента в памяти, куда должен быть загружен сегмент при отображении в память.48p_paddrФизический адрес сегмента (для систем, в которых он важен).48p_fileszРазмер сегмента в файле. Может быть нулевым.48p_memszРазмер сегмента в памяти. Может быть нулевым.4p_flagsФлаги, относящиеся к сегменту (для ELF32) (возможные значения см. выше).48p_alignВыравнивание сегмента. 0 и 1 определяют отсутствие выравнивания. В противном случае должно быть положительной двойкой в определённой степени.

Таблица заголовков секций