Это старая версия этой страницы, сохранённая Mkostoevr(обсуждение | вклад) в 16:29, 31 марта 2018(уточнение по поводу секции .shstrtab). Она может серьёзно отличаться от текущей версии.
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 заголовка. В настоящее время значение данного бита должно быть 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
Связанные с файлом флаги, зависящие от процессора. При их отсутствии это поле содержит 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
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 определяют отсутствие выравнивания. В противном случае должно быть положительной двойкой в определённой степени.
Таблица заголовков секций
Таблица заголовков секций содержит атрибуты секций файла. Данная таблица необходима только компоновщику, исполняемые файлы в наличии этой таблицы не нуждаются (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
0x1
Разрешение на запись.
SHF_ALLOC
0x2
Секция занимает память во время выполнения процесса. Некоторые служебные секции не загружаются в память при загрузке объектного файла, для таких секций данный флаг отключается.
SHF_EXECINSTR
0x4
Секция содержит исполняемые машинные инструкции.
SHF_MERGE
0x10
Данные в секции могут быть объединены для устранения дублирования. Если флаг SHF_STRINGS не установлен, элементы данных в секции имеют одинаковый размер. Размер одного элемента указывается в поле sh_entsize. Если флаг SHF_STRINGS установлен, секция состоит из массивов символов с завершающим нулём и размер одного символа указывается в поле sh_entsize.
SHF_STRINGS
0x20
Секция состоит из массивов символов с завершающим нулём. Размер одного символа указывается в поле sh_entsize.
SHF_INFO_LINK
0x40
Поле sh_info данного заголовка секции содержит индекс элемента таблицы заголовков секций.
SHF_LINK_ORDER
0x80
Особые требования по расположению. Требования применяются, если поле sh_link этого заголовка секции ссылается на другую секцию (связанная секция). Если поле sh_link связанной секции не содержит 0, в выходном файле текущая секция должна располагаться в том же порядке относительно связанной секции, что и связанная секция относительно секции, с которой она связана.
SHF_OS_NONCONFORMING
0x100
Секция требует специальной, зависящей от операционной системы, обработки для предотвращения некорректного поведения.
SHF_GROUP
0x200
Секция - элемент (возможно, единственный) группы секций
SHF_TLS
0x400
Секция содержит Thread-Local Storage, каждый поток будет иметь собственную копию данной секции.
SHF_COMPRESSED
0x800
Секция содержит сжатые данные.
SHF_MASKOS
0x0ff00000
Все биты, включенные в это поле, определяют зависящие от операционной системы значения
SHF_MASKPROC
0xf0000000
Все биты, включенные в это поле, определяют зависящие от процессора значения
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).