Открыть сервис

Формат 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 имеет строгую иерархическую структуру, которая делится на три основные части:

  1. Заголовок ELF (ELF Header) — находится в начале файла и содержит метаданные о файле в целом.
  2. Таблица программных заголовков (Program Header Table) — описывает сегменты, необходимые для загрузки файла в память при его выполнении.
  3. Таблица заголовков секций (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 поддерживает несколько типов файлов, которые различаются по своему назначению:

  1. Перемещаемый файл (Relocatable file, ET_REL) — объектный файл, полученный после компиляции исходного кода. Он содержит машинный код и данные, но не может быть напрямую выполнен. Для создания исполняемого файла или библиотеки такие файлы объединяются компоновщиком. Примеры: .o файлы в Linux.
  2. Исполняемый файл (Executable file, ET_EXEC) — готовый к выполнению файл. Он содержит все необходимые сегменты и точку входа. Примеры: /bin/ls, /usr/bin/gcc.
  3. Разделяемая библиотека (Shared object file, ET_DYN) — файл, содержащий код и данные, которые могут быть загружены в память несколькими программами одновременно. Примеры: libc.so.6, libpthread.so.0.
  4. Файл дампа памяти (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 →