Interested Article - Executable and Linkable Format

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

История

Стандарт формата ELF изначально был разработан и опубликован компанией USL как часть двоичного интерфейса приложений операционной системы UNIX System V . Затем он был выбран комитетом TIS и развит в качестве переносимого формата для различных операционных систем, работающих на 32-разрядной аппаратной архитектуре Intel x86 . ELF быстро набрал популярность и, после того как компания HP расширила формат и опубликовала стандарт ELF-64, распространился и на 64-разрядных платформах.

Типы

Стандарт формата ELF различает несколько типов файлов:

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

Формат

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

Заголовок файла

Заголовок файла (ELF Header) имеет фиксированное расположение в начале файла и содержит общее описание структуры файла и его основные характеристики, такие как: тип, версия формата, архитектура процессора , виртуальный адрес точки входа , размеры и смещения остальных частей файла. Заголовок имеет размер 52 байта для 32-битных файлов или 64 для 64-битных . Данное различие обуславливается тем, что в заголовке файла содержится три поля, имеющих размер указателя, который составляет 4 и 8 байт для 32- и 64-битных процессоров соответственно. Такими полями являются e_entry , e_phoff и e_shoff .

Поля заголовка файла ELF
Размер Название Назначение
ELF

32

ELF

64

16
e_ident[16] Общая характеристика файла.
Байты массива e_ident
Индекс Название Назначение
0 - 3
EI_MAG0 - EI_MAG3 Сигнатура файла: 0x 7f 0x 45 0x 4c 0x 46 .
4
EI_CLASS Класс объектного файла.
Название Значение Описание
ELFCLASSNONE 0 Некорректный класс
ELFCLASS32 1 32-битный объектный файл
ELFCLASS64 2 64-битный объектный файл
5
EI_DATA Зависимый от процессора метод кодирования данных.
Название Значение Описание
ELFDATANONE 0 Некорректный тип
ELFDATA2LSB 1 Little Endian
ELFDATA2MSB 2 Big Endian
6
EI_VERSION Версия ELF заголовка. В настоящее время значение данного байта должно быть EV_CURRENT .
Название Значение
EV_CURRENT 1
7
EI_OSABI Специфичные для операционной системы или ABI расширения, используемые в файле. У некоторых полей в других структурах ELF файла имеются флаги и поля, значение которых зависит от операционной системы или ABI; интерпретация этих полей определяется значением данного байта. Если объектный файл не использует расширений, рекомендуется, чтобы этот байт был установлен в 0 . Если значение для этого байта находится в диапазоне от 64 до 255 , то его интерпретация зависит от значения поля e_machine ELF заголовка. В этом диапазоне каждая архитектура может определить свой набор значений.
Название Значение Описание
ELFOSABI_NONE 0 UNIX System V ABI
ELFOSABI_HPUX 1 HP-UX
ELFOSABI_NETBSD 2 NetBSD
ELFOSABI_GNU 3 Файл использует расширения GNU ELF ( GNU/Linux )
ELFOSABI_SOLARIS 6 Solaris
ELFOSABI_AIX 7 AIX
ELFOSABI_IRIX 8 IRIX
ELFOSABI_FREEBSD 9 FreeBSD
ELFOSABI_TRU64 10 Tru64 UNIX
ELFOSABI_MODESTO 11
ELFOSABI_OPENBSD 12 OpenBSD
ELFOSABI_OPENVMS 13 OpenVMS
ELFOSABI_NSK 14 Kernel
ELFOSABI_AROS 15 Amiga Research OS
ELFOSABI_FENIXOS 16 FenixOS
ELFOSABI_CLOUDABI 17 CloudABI
ELFOSABI_OPENVOS 18
64 - 255 Зависимые от процессора значения
8
EI_ABIVERSION Версия ABI.
9
EI_PAD Т. н. padding bytes (байты заполнения). Зарезервированные для будущего использования элементы массива e_ident . Обычно устанавливаются в 0 . Программы для чтения объектных файлов должны игнорировать их.
10
EI_PAD + 1
11
EI_PAD + 2
12
EI_PAD + 3
13
EI_PAD + 4
14
EI_PAD + 5
15
EI_PAD + 6
2
e_type Тип файла.
Название Значение Описание
ET_NONE 0 Неопределённый
ET_REL 1 Перемещаемый файл
ET_EXEC 2 Исполняемый файл
ET_DYN 3 Совместно используемый объектный файл
ET_CORE 4 Core file
ET_LOOS - ET_HIOS 65024 - 65279 Зависимые от операционной системы значения
ET_LOPROC - ET_HIPROC 65280 - 65535 Зависимые от процессора значения
2
e_machine Архитектура аппаратной платформы, для которой файл создан:
Название Значение Описание
EM_NONE 0x 0 Неопределено
EM_M32 0x 01
EM_SPARC 0x 02 SPARC
EM_386 0x 03 Intel 80386
EM_68K 0x 04
EM_88K 0x 05
EM_IAMCU 0x 06
EM_860 0x 07 Intel 80860
EM_MIPS 0x 08 MIPS
EM_S370 0x 09 IBM_System/370
EM_MIPS_RS3_LE 0x 0A MIPS R3000 Little-endian
0x 0B - 0x 0E Reserved for future use
EM_PARISC 0x 0F Hewlett-Packard PA-RISC
0x 10 Reserved for future use
EM_960 0x 13 Intel 80960
EM_PPC 0x 14 PowerPC
EM_PPC64 0x 15 PowerPC (64-bit)
EM_S390 0x 16 S390 , including S390x
EM_SPU 0x 17 IBM SPU/SPC
0x 18 - 0x 23 Reserved for future use
EM_V800 0x 24
EM_FR20 0x 25 Fujitsu FR20
EM_RH32 0x 26
EM_MCORE и EM_RCE 0x 27 Motorola RCE
EM_ARM 0x 28 ARM (up to ARMv7/Aarch32)
EM_OLD_ALPHA 0x 29
EM_SH 0x 2A SuperH
EM_SPARCV9 0x 2B SPARC Version 9
EM_TRICORE 0x 2C
EM_ARC 0x 2D
EM_H8_300 0x 2E
EM_H8_300H 0x 2F
EM_H8S 0x 30
EM_H8_500 0x 31
EM_IA_64 0x 32 IA-64
EM_MIPS_X 0x 33
EM_COLDFIRE 0x 34
EM_68HC12 0x 35
EM_MMA 0x 36 Fujitsu MMA Multimedia Accelerator
EM_PCP 0x 37 Siemens PCP
EM_NCPU 0x 38 Sony nCPU embedded RISC processor
EM_NDR1 0x 39 Denso NDR1 microprocessor
EM_STARCORE 0x 3A Motorola Star*Core processor
EM_ME16 0x 3B Toyota ME16 processor
EM_ST100 0x 3C STMicroelectronics ST100 processor
EM_TINYJ 0x 3D Advanced Logic Corp. TinyJ embedded processor family
EM_X86_64 0x 3E AMD x86-64
EM_MCST_ELBRUS 0x AF Эльбрус (процессорная архитектура)
EM_TI_C6000 0x 8C
EM_AARCH64 0x B7 ARM 64-bits (ARMv8/Aarch64)
EM_RISCV 0x F3 RISC-V
EM_BPF 0x F7 Berkeley Packet Filter
EM_65816 0x 101 WDC 65C816
4
e_version Номер версии формата. На данный момент корректным считается только одно значение.
Название Значение Описание
EV_NONE 0 Некорректное значение
EV_CURRENT 1 Текущая версия
4
8
e_entry Виртуальный адрес точки входа, которому система передает управление при запуске процесса. Если у файла нет точки входа, это поле содержит 0 .
4
8
e_phoff Смещение таблицы заголовков программы от начала файла в байтах. Если у файла нет таблицы заголовков программы, это поле содержит 0 .
4
8
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

32

ELF

64

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 0x 1 Разрешение на исполнение
PF_W 0x 2 Разрешение на запись
PF_R 0x 4 Разрешение на чтение
PF_MASKOS 0x 0ff00000 Все биты, включенные в это поле, определяют зависящие от операционной системы значения
PF_MASKPROC 0xf 0000000 Все биты, включенные в это поле, определяют зависящие от процессора значения
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 определяют отсутствие выравнивания. В противном случае должно быть положительной двойкой в определённой степени.

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

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

Поля заголовка секции
Размер Название Назначение
ELF

32

ELF

64

4
sh_name Смещение строки, содержащей название данной секции, относительно начала таблицы названий секций.
4
sh_type Тип заголовка.
Название Значение Описание
SHT_NULL 0 Заголовок не используется, остальные поля не определены.
SHT_PROGBITS 1 Секция содержит информацию, определённую программой, её формат и значение определяется программой единолично.
SHT_SYMTAB 2 Секция содержит таблицу символов. В настоящий момент в файле может быть только одна такая секция.
SHT_STRTAB 3 Секция содержит таблицу строк. Файл может иметь множество секций такого типа.
SHT_RELA 4 Секция содержит расширенную информацию о перемещениях. Файл может иметь множество секций такого типа.
SHT_HASH 5 Секция содержит таблицу хэшей символов. В настоящий момент в файле может быть только одна такая секция.
SHT_DYNAMIC 6 Секция содержит информацию о динамической компоновке. В настоящий момент в файле может быть только одна такая секция.
SHT_NOTE 7 Секция содержит информацию, которая каким-то образом отмечает файл.
SHT_NOBITS 8 Секция не занимает места в файле, в противном случае схожа с SHT_PROGBITS .
SHT_REL 9 Секция содержит информацию о перемещениях. Файл может иметь множество секций такого типа.
SHT_SHLIB 10 Данный тип секции определён, но не имеет определённого значения.
SHT_DYNSYM 11 Секция содержит таблицу символов. В настоящий момент в файле может быть только одна такая секция.
SHT_INIT_ARRAY 14 Секция содержит массив указателей на функции инициализации программы. Функции не должны принимать аргументов и чего-либо возвращать.
SHT_FINI_ARRAY 15 Секция содержит массив указателей на функции финализации программы. Функции не должны принимать аргументов и чего-либо возвращать.
SHT_PREINIT_ARRAY 16 Секция содержит массив указателей на функции, вызываемые до вызова функций инициализации программы. Функции не должны принимать аргументов и чего-либо возвращать.
SHT_GROUP 17 В этой секции определяется группа секций. Группа секций представляет собой набор связанных секций, которые должны быть специальным образом обработаны компоновщиком. Такие секции могут быть только в перемещаемых объектных файлах (чьё поле e_type имеет значение ET_REL ). Заголовок, определяющий группу секций, должен находиться в таблице секций до заголовков всех секций, включённых в определяемую группу.
SHT_SYMTAB_SHNDX 18 Секция связана с таблицей символов и необходима в том случае, если любой элемент этой таблицы ссылается на заголовок секции, имеющий индекс SHN_XINDEX (это происходит в том случае, если индекс секции настолько велик, что не вмещается в поле st_shndx ). Секция содержит массив чисел типа Elf32_Word для ELF32 и Elf64_Word для ELF64. Каждый элемент этого массива соответствует записи в таблице символов, и располагается в соответствующем порядке. Эти элементы представляют собой индексы заголовков секций, с которыми связаны соответствующие символы. В том случае, если значение поля st_shndx соответствующего элемента таблицы символов равно SHN_XINDEX , элемент содержит настоящий индекс заголовка секции, в противном случае, элемент содержит 0 .
SHT_LOOS - SHT_HIOS 1610612736 - 1879048191 Зависимые от операционной системы значения.
SHT_LOPROC - SHT_HIPROC 1879048192 - 2147483647 Зависимые от процессора значения.
SHT_LOUSER - SHT_HIUSER 2147483648 - 4294967295 Зависимые от программы значения. Данные значения могут быть использованы обработчиками файлов формата ELF без конфликтов с определёнными в текущий момент значениями.
4
8
sh_flags Атрибуты секции.
Название Значение Описание
SHF_WRITE 0x 1 Разрешение на запись.
SHF_ALLOC 0x 2 Секция занимает память во время выполнения процесса. Некоторые служебные секции не загружаются в память при загрузке объектного файла, для таких секций данный флаг отключается.
SHF_EXECINSTR 0x 4 Секция содержит исполняемые машинные инструкции.
SHF_MERGE 0x 10 Данные в секции могут быть объединены для устранения дублирования. Если флаг SHF_STRINGS не установлен, элементы данных в секции имеют одинаковый размер. Размер одного элемента указывается в поле sh_entsize . Если флаг SHF_STRINGS установлен, секция состоит из массивов символов с завершающим нулём и размер одного символа указывается в поле sh_entsize .

Каждый элемент в секции сравнивается с другими элементами в секциях с тем же именем, типом и флагами. Элементы, которые будут иметь одинаковые значения во время выполнения программы, могут быть объединены. Перемещения, ссылающиеся на элементы таких секций, должны быть разрешены соответствующим образом. Перед объединением все элементы секции должны быть проанализированы для определения того, будут ли значения фактически идентичными во время выполнения.

Подобное объединение не является обязательным требованием для соответствия ABI.

SHF_STRINGS 0x 20 Секция состоит из массивов символов с завершающим нулём. Размер одного символа указывается в поле sh_entsize .
SHF_INFO_LINK 0x 40 Поле sh_info данного заголовка секции содержит индекс элемента таблицы заголовков секций.
SHF_LINK_ORDER 0x 80 Особые требования по расположению. Требования применяются, если поле sh_link этого заголовка секции ссылается на другую секцию (связанная секция). Если поле sh_link связанной секции не содержит 0 , в выходном файле текущая секция должна располагаться в том же порядке относительно связанной секции, что и связанная секция относительно секции, с которой она связана.
SHF_OS_NONCONFORMING 0x 100 Секция требует специальной, зависящей от операционной системы, обработки для предотвращения некорректного поведения.
SHF_GROUP 0x 200 Секция - элемент (возможно, единственный) группы секций
SHF_TLS 0x 400 Секция содержит Thread-Local Storage, каждый поток будет иметь собственную копию данной секции.
SHF_COMPRESSED 0x 800 Секция содержит сжатые данные. Данный флаг применяется только к секциям, память под которые не выделяется при загрузке объектного файла в память. Флаг не используется в комбинации с SHF_ALLOC . Данный флаг также неприменим к секциям, имеющим тип SHT_NOBITS .

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

Сжатые секции начинаются с заголовка, идентифицирующего алгоритм сжатия.

Поля заголовка сжатой секции
Размер Название Назначение
ELF

32

ELF

64

4 4 ch_type Алгоритм сжатия.
Название Значение Описание
ELFCOMPRESS_ZLIB 1 Данные в секции сжаты с использованием алгоритма Zlib . Сжатые данные следуют сразу после заголовка и до конца секции.
ELFCOMPRESS_LOOS - ELFCOMPRESS_HIOS 1610612736 - 1879048191 Зависимые от операционной системы значения.
ELFCOMPRESS_LOPROC - ELFCOMPRESS_HIPROC 1879048192 - 2147483647 Зависимые от процессора значения.
4 ch_reserved Зарезервировано для будущего использования.
4 8 ch_size Размер в байтах декомпрессированной секции.
4 8 ch_addralign Необходимое для декомпрессированной секции выравнивание.
SHF_MASKOS 0x 0ff00000 Все биты, включенные в это поле, определяют зависящие от операционной системы значения
SHF_MASKPROC 0xf 0000000 Все биты, включенные в это поле, определяют зависящие от процессора значения
4
8
sh_addr Если секция должна быть загружена в память при загрузке объектного файла, это поле указывает адрес, начиная с которого секция будет загружена, в противном случае поле содержит 0 .
4
8
sh_offset Смещение секции от начала файла в байтах. Секции типа SHT_NOBITS не занимают места в файле, для них данное поле содержит концептуальное местоположение в файле.
4
8
sh_size Размер секции в файле. Может быть нулевым.
4
sh_link Индекс ассоциированной секции. Данное поле может иметь различное предназначение в зависимости от типа заголовка.
Интерпретация полей sh_link и sh_info в зависимости от значения поля sh_type
sh_type sh_link sh_info
SHT_DYNAMIC Индекс заголовка секции таблицы строк, которая используется элементами данной секции. 0
SHT_HASH Индекс заголовка секции таблицы символов, к которой относится данная таблица хэшей. 0
SHT_REL , SHT_RELA Индекс заголовка секции ассоциированной таблицы символов. Индекс заголовка секции, к которой должны быть применены данные перемещения.
SHT_SYMTAB , SHT_DYNSYM Индекс заголовка секции ассоциированной таблицы строк. На один больше, чем индекс последнего локального символа ( STB_LOCAL ) в таблице символов.
SHT_GROUP Индекс заголовка секции ассоциированной таблицы символов. Индекс элемента в ассоциированной таблице символов. Имя указанного элемента предоставляет сигнатуру группы секций.
SHT_SYMTAB_SHNDX Индекс заголовка секции ассоциированной секции таблицы символов. 0
4
sh_info Дополнительная информация о секции (возможные значения см. выше).
4
8
sh_addralign Необходимое выравнивание секции.
4
8
sh_entsize Размер в байтах каждой записи (в том случае, если секция содержит массив записей фиксированного размера, в противном случае поле содержит 0 ).

Содержимое секций и сегментов

Утилиты

Существует множество утилит для работы с файлами формата ELF, основные из них содержатся в наборе программных инструментов GNU Binutils :

  • elfedit — изменение заголовка файла ELF, часть набора GNU Binutils.
  • objdump — вывод информации об объектных файлах (в том числе и ELF), часть набора GNU Binutils.
  • readelf — вывод подробной информации об объектном файле формата ELF, часть набора GNU Binutils.
  • elfdump — вывод информации о ELF файле, часть набора GNU Binutils.
  • elfutils — альтернатива для GNU Binutils, официально доступна только для GNU/Linux , но существуют порты на другие операционные системы .
  • file — вывод небольшого количества информации о файлах известных программе форматов (доступна для большинства UNIX-подобных операционных систем ).

См. также

Примечания

  1. от 21 мая 2015 на Wayback Machine Edition 4.1 (1997-03-18)
  2. от 16 июня 2012 на Wayback Machine (англ.)
  3. от 1 июля 2015 на Wayback Machine
  4. . www.freshports.org. Дата обращения: 31 марта 2018. 16 февраля 2018 года.

Ссылки

  • / Крис Касперски // Хакер. – 2005. – № 11/05 (83). – С. 106–110.
  • ELF. Структура файлов
Источник —

Same as Executable and Linkable Format