ELF (англ.Executable and Linkable Format — формат исполнимых и компонуемых файлов) — формат двоичных файлов, используемый во многих современных UNIX-подобных операционных системах, таких как FreeBSD, Linux, Solaris и др. Также этот формат используется и во многих других системах.
Стандарт формата ELF изначально был разработан и опубликован компанией USL как часть двоичного интерфейса приложений операционной системы UNIX System V[1]. Затем он был выбран комитетом TIS и развит в качестве переносимого формата для различных операционных систем, работающих на 32-разрядной аппаратной архитектуре Intel x86.[2] ELF быстро набрал популярность и, после того как компания HP расширила формат и опубликовала стандарт ELF-64, распространился и на 64-разрядных платформах.[3]
Типы
Стандарт формата ELF различает несколько типов файлов:
Перемещаемый файл — хранит инструкции и данные, которые могут быть связаны с другими объектными файлами. Результатом такой связи может быть разделяемый объектный файл или исполняемый файл. К этому типу относятся объектные файлы статических библиотек.
Разделяемый объектный файл — также содержит инструкции и данные и может быть связан с другими перемещаемыми файлами и разделяемыми объектными файлами, в результате чего будет создан новый объектный файл, либо при запуске программы на выполнение операционная система может динамически связать его с исполняемым файлом программы, в результате чего будет создан исполняемый образ программы. В последнем случае речь идет о разделяемых библиотеках.
Исполняемый файл — содержит полное описание, позволяющее системе создать образ процесса. В том числе: инструкции, данные, описание необходимых разделяемых объектных файлов и необходимую символьную и отладочную информацию.
Формат
Каждый ELF файл состоит из следующих частей:
Заголовок файла
Заголовок файла (ELF Header) имеет фиксированное расположение в начале файла и содержит общее описание структуры файла и его основные характеристики, такие как: тип, версия формата, архитектура процессора, виртуальный адрес точки входа, размеры и смещения остальных частей файла. Заголовок имеет размер 52 байта для 32-битных файлов или 64 для 64-битных. Данное различие обуславливается тем, что в заголовке файла содержится три поля, имеющих размер указателя, который составляет 4 и 8 байт для 32- и 64-битных процессоров соответственно. Такими полями являются e_entry, e_phoff и e_shoff.
Поля заголовка файла ELF
Размер
Поле
Описание
ELF32
ELF64
16
e_ident[16]
Массив байт, каждый из которых определяет общую характеристику файла. Первые четыре байта в массиве определяют сигнатуру файла и всегда должны содержать 0x7f0x450x4c0x46 соответственно.
Значение байт
Индекс
Название
Описание
0
EI_MAG0
Часть сигнатуры файла.
Название
HEX
DEC
ASCII
ELFMAG0
0x7f
127
DEL
1
EI_MAG1
Часть сигнатуры файла.
Название
HEX
DEC
ASCII
ELFMAG1
0x45
69
'E'
2
EI_MAG2
Часть сигнатуры файла.
Название
HEX
DEC
ASCII
ELFMAG2
0x4c
76
'L'
3
EI_MAG3
Часть сигнатуры файла.
Название
HEX
DEC
ASCII
ELFMAG3
0x46
70
'F'
4
EI_CLASS
Определяет класс объектного файла.
Название
Значение
Описание
ELFCLASSNONE
0
Некорректный класс
ELFCLASS32
1
32-битный объектный файл
ELFCLASS64
2
64-битный объектный файл
5
EI_DATA
Определяет зависимый от процессора метод кодирования данных.
Определяет версию ELF заголовка. В настоящее время значение данного бита должно быть EV_CURRENT.
Название
Значение
EV_CURRENT
1
7
EI_OSABI
Определяет специфичные для операционной системы или ABI расширения, используемые в файле. У некоторых полей в других структурах ELF файла имеются флаги и поля, значение которых зависит от операционной системы или ABI; интерпретация этих полей определяется значением данного байта. Если объектный файл не использует расширений, рекомендуется, чтобы этот байт был установлен в 0. Если значение для этого байта находится в диапазоне от 64 до 255, то его интерпретация зависит от значения поля e_machine ELF заголовка. В этом диапазоне каждая архитектура может определить свой набор значений.
Т. н. padding bytes (набивка). Зарезервированные для будущего использования элементы массива e_ident. Обычно устанавливаются в 0. Программы для чтения объектных файлов должны игнорировать их.
Номер версии формата. На данный момент корректным считается только одно значение.
Название
Значение
Описание
EV_NONE
0
Некорректное значение
EV_CURRENT
1
Текущая версия
4
8
e_entry
Виртуальный адрес точки входа, которому система передает управление при запуске процесса. Если у файла нет точки входа, это поле содержит 0.
4
8
e_phoff
Смещение таблицы заголовков программы от начала файла в байтах. Если у файла нет таблицы заголовков программы, это поле содержит 0.
4
8
e_shoff
Смещение таблицы заголовков разделов от начала фйла в байтах. Если у файла нет таблицы заголовков разделов, это поле содержит 0.
4
e_flags
Связанные с файлом флаги, зависящие от процессора.
2
e_ehsize
Размер заголовка файла в байтах.
2
e_phentsize
Размер одного заголовка программы. Все заголовки программы имеют одинаковый размер.
2
e_phnum
Число заголовков программы. Если у файла нет таблицы заголовков программы, это поле содержит 0.
2
e_shentsize
Размер одного заголовка секции. Все заголовки секций имеют одинаковый размер.
2
e_shnum
Число заголовков секций. Если у файла нет таблицы заголовков секций, это поле содержит 0.
2
e_shstrndx
Индекс заголовка секции в таблице секций, указывающей на таблицу названий секций. Если файл не содержит таблицы названий секций, это поле содержит 0.
Таблица заголовков программы
Таблица заголовков программы содержит заголовки, каждый из которых описывает отдельный сегмент программы и его атрибуты либо другую информацию, необходимую операционной системе для подготовки программы к исполнению.
Данная таблица может располагаться в любом месте файла, её местоположение (смещение относительно начала файла) описывается в поле e_phoff заголовка ELF.
Поля заголовка программы
Размер
Поле
Описание
ELF32
ELF64
4
p_type
Тип сегмента, который описывает данный заголовок, или каким образом интерпретировать значения полей этого заголовка.
Название
Значение
Описание
PT_NULL
0
Заголовок не используется, остальные поля не определены. Данный тип позволяет включать в таблицу заголовков программы файла игнорируемые элементы.
PT_LOAD
1
Загружаемый сегмент, описываемый полями p_filesz и p_memsz. Байты из файла отражаются на сегменте в памяти. Если размер сегмента в памяти (p_memsz) больше размера сгемента в файле (p_filesz), дополнительные байты заполняются нулями (они следуют сразу за определенными в сегменте байтами). Размер сегмента в файле (p_filesz) не может быть больше размера сегмента в памяти (p_memsz). Заголовки программы загружаемых сегментов располагаются в таблице заголовков программ в порядке возрастания значения поля p_vaddr.
PT_DYNAMIC
2
Заголовок программы предоставляет информацию о динамической компоновке.
PT_INTERP
3
Заголовок программы предоставляет размер и местоположение пути (строки в стиле C с завершающим нулём) для запуска в качестве интерпретатора. Этот тип сегмента имеет смысл только для исполняемых файлов (хотя он может быть и в разделяемом объектном файле); он не может встречаться более одного раза в файле. Если заголовок такого типа присутствует, он должен предшествовать любому заголовку программы загружаемого сегмента.
PT_NOTE
4
Заголовок программы определяет местоположение и размер вспомогательной информации.
PT_SHLIB
5
Этот тип сегмента зарезервирован, но его смысл не определён. Программы, содержащие заголовок программы этого типа, не соответствуют ABI.
PT_PHDR
6
Заголовок программы, если он присутствует, определяет местоположение и размер самой таблицы заголовков программы, как в файле, так и в образе памяти программы. Этот тип сегмента не может встречаться более одного раза в файле. Более того, он может встретиться только при наличии в файле таблицы заголовков программы. Если заголовок такого типа присутствует, он должен предшествовать любому заголовку программы загружаемого сегмента.
PT_TLS
7
Заголовок программы определяет шаблон Thread-Local Storage. Загрузчики ELF не должны поддерживать эту запись в таблице заголовков программ.
PT_LOOS - PT_HIOS
1610612736 - 1879048191
Зависимые от операционной системы значения.
PT_LOPROC - PT_HIPROC
1879048192 - 2147483647
Зависимые от процессора значения.
4
p_flags
Флаги, относящиеся к сегменту (для ELF64).
Название
Значение
Описание
PF_X
0x1
Разрешение на исполнение
PF_W
0x2
Разрешение на запись
PF_R
0x4
Разрешение на чтение
PF_MASKOS
0x0ff00000
Все биты, включенные в это поле, определяют зависящие от операционной системы значения
PF_MASKPROC
0xf0000000
Все биты, включенные в это поле, определяют зависящие от процессора значения
4
8
p_offset
Смещение сегмента от начала файла.
4
8
p_vaddr
Виртуальный адрес сегмента в памяти.
4
8
p_paddr
Физический адрес сегмента (для систем, в которых он важен).
4
8
p_filesz
Размер сегмента в файле. Может быть нулевым.
4
8
p_memsz
Размер сегмента в памяти. Может быть нулевым.
4
p_flags
Флаги, относящиеся к сегменту (для ELF32) (возможные значения см. выше).
4
8
p_align
Выравнивание сегмента. 0 и 1 определяют отсутствие выравнивания. В противном случае должно быть положительной двойкой в определённой степени.
Здесь может располагаться отдельный раздел. Помогите Википедии, написав его.(31 декабря 2016)
Содержимое разделов и сегментов
Сегменты содержат данные, необходимые для исполнения файла, а разделы содержат информацию для линковки и обработку relocation. Каждый байт в файле может относиться не более чем к одной секции.