Формат ELF
ELF (Executable and Linkable Format) — это стандартный формат двоичных файлов, используемый в операционных системах семейства Unix и Linux, а также в некоторых других. Он предназначен для хранения исполняемых программ, объектного кода, разделяемых библиотек и дампов памяти (core-файлов). ELF заменил более ранние форматы, такие как a.out и COFF, и стал основным форматом для большинства современных Unix-подобных систем, включая Linux, FreeBSD, Solaris и многие другие.
История
Формат ELF был разработан в конце 1980-х годов компанией Unix System Laboratories (USL) в рамках работы над операционной системой Unix System V Release 4 (SVR4). Целью создания было преодоление ограничений формата a.out, который не поддерживал динамическую компоновку, разделяемые библиотеки и работу с большими адресными пространствами. Первая спецификация ELF была опубликована в 1990 году.
В 1995 году ELF был принят в качестве стандартного формата для Linux, заменив a.out. Это решение было принято разработчиками ядра Linux (Линус Торвальдс и другие) из-за лучшей поддержки динамической загрузки, многопоточности и кросс-платформенности. С тех пор ELF остаётся основным форматом для Linux, а также используется в FreeBSD (с версии 3.0), NetBSD, OpenBSD, Solaris и многих других системах. В 1999 году ELF был стандартизирован как часть спецификации Tool Interface Standard (TIS).
Структура формата
Файл ELF имеет строгую иерархическую структуру, которая делится на три основные части:
- Заголовок ELF (ELF Header) — находится в начале файла и содержит метаданные о файле в целом.
- Таблица программных заголовков (Program Header Table) — описывает сегменты, необходимые для загрузки файла в память при его выполнении.
- Таблица заголовков секций (Section Header Table) — описывает секции, используемые компоновщиком и отладчиком.
Заголовок ELF
Заголовок ELF начинается с так называемого «магического числа» — последовательности байтов 0x7F E L F (в шестнадцатеричном виде: 7F 45 4C 46). Этот заголовок содержит следующие ключевые поля:
- Класс (Class) — определяет разрядность: 32-битная (
ELFCLASS32) или 64-битная (ELFCLASS64). - Порядок байтов (Data) — указывает порядок следования байтов: little-endian (младший байт первым) или big-endian (старший байт первым).
- Тип (Type) — определяет назначение файла:
ET_REL(перемещаемый объектный файл),ET_EXEC(исполняемый файл),ET_DYN(разделяемая библиотека),ET_CORE(файл дампа памяти). - Архитектура (Machine) — указывает целевую архитектуру процессора (например,
EM_386для x86,EM_X86_64для x86-64,EM_ARMдля ARM). - Точка входа (Entry point) — виртуальный адрес, с которого начинается выполнение программы.
- Смещение таблицы программных заголовков (e_phoff) и смещение таблицы заголовков секций (e_shoff).
Таблица программных заголовков
Эта таблица используется операционной системой для загрузки файла в память. Каждый программный заголовок описывает один сегмент — непрерывную область данных, которая будет загружена в память. Основные типы сегментов:
PT_LOAD— загружаемый сегмент (код, данные).PT_DYNAMIC— информация для динамической компоновки.PT_INTERP— путь к интерпретатору (например,/lib/ld-linux.so.2).PT_NOTE— примечания (например, информация о версии).
Таблица заголовков секций
Эта таблица используется компоновщиком (ld) и отладчиком (gdb). Каждая секция содержит определённый тип данных:
.text— исполняемый машинный код..data— инициализированные глобальные и статические переменные..bss— неинициализированные данные (занимают место в памяти, но не в файле)..rodata— константы (read-only data)..symtab— таблица символов (имена функций и переменных)..strtab— строковые таблицы (имена символов)..debug_*— отладочная информация (в формате DWARF).
Типы файлов ELF
Формат ELF поддерживает несколько типов файлов, которые различаются по своему назначению:
- Перемещаемый файл (Relocatable file,
ET_REL) — объектный файл, полученный после компиляции исходного кода. Он содержит машинный код и данные, но не может быть напрямую выполнен. Для создания исполняемого файла или библиотеки такие файлы объединяются компоновщиком. Примеры:.oфайлы в Linux. - Исполняемый файл (Executable file,
ET_EXEC) — готовый к выполнению файл. Он содержит все необходимые сегменты и точку входа. Примеры:/bin/ls,/usr/bin/gcc. - Разделяемая библиотека (Shared object file,
ET_DYN) — файл, содержащий код и данные, которые могут быть загружены в память несколькими программами одновременно. Примеры:libc.so.6,libpthread.so.0. - Файл дампа памяти (Core file,
ET_CORE) — файл, создаваемый ОС при аварийном завершении программы. Он содержит состояние памяти, регистров и стека на момент сбоя, что используется для отладки.
Применение и значение
ELF является основой для работы операционных систем на базе Linux и Unix. Без этого формата невозможно было бы выполнение программ, загрузка библиотек и отладка. Его ключевые преимущества:
- Кроссплатформенность — поддержка различных архитектур процессоров (x86, ARM, RISC-V, MIPS и др.).
- Гибкость — возможность динамической компоновки, что позволяет обновлять библиотеки без перекомпиляции программ.
- Эффективность — оптимизированная структура для быстрой загрузки и выполнения.
- Расширяемость — поддержка дополнительных секций (например, для отладочной информации).
Инструменты для работы с ELF
Для анализа и модификации файлов ELF существует множество утилит, входящих в состав GNU Binutils:
readelf— отображает информацию о структуре ELF-файла (заголовки, секции, символы).objdump— дизассемблирует код и показывает содержимое секций.nm— выводит список символов (функций и переменных).strip— удаляет отладочную информацию и символы для уменьшения размера файла.ldd— показывает список разделяемых библиотек, необходимых для выполнения программы.
Интересные факты
- Формат ELF используется не только в Unix-подобных системах, но и в некоторых встраиваемых системах (например, на базе ядра FreeRTOS).
- В 64-битной версии ELF (ELF64) размер заголовка увеличен до 64 байт, а адреса — до 8 байт, что позволяет адресовать до 16 эксабайт виртуальной памяти.
- Существуют попытки использовать ELF в Windows (например, проект WSL — Windows Subsystem for Linux), но в самой Windows основным форматом остаётся PE (Portable Executable).
Источники
- TIS Committee. Tool Interface Standard (TIS) Executable and Linking Format (ELF) Specification, Version 1.2, 1995.
- Linux man pages:
elf(5),readelf(1),objdump(1). - Документация GNU Binutils.
- Стандарт System V Application Binary Interface (ABI).
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →