Man elf (5) формат виконуваних і компонованих файлів (elf)

В заголовки визначений формат ELF для виконуваних двійкових файлів. До таких файлів відносяться звичайні виконувані файли, що переміщуються об'єктні файли, core-файли і загальні об'єкти.

Виконуваний файл у форматі ELF складається з заголовка ELF, таблиці заголовків програми або таблиці заголовків розділів (або обох таблиць). Тема ELF завжди розташований на початку файлу. Розташування таблиці заголовків програми і таблиці заголовків розділів задається в заголовку ELF. У цих двох таблицях описується все інше вміст файлу.

Даний заголовки описує вищезазначені заголовки у вигляді структур C, а також включає опис структур динамічних розділів, розділів переміщень і таблиць символів.

Для кожної N-бітної архітектури використовується відповідний тип (N = 32,64; ElfN може бути Elf32 або Elf64; uintN_t може бути uint32_t або uint64_t):

(Зауваження: В * BSD використовується трохи інша термінологія. Так, Elf64_Half --- подвоєний Elf32_Half. А Elf64Quarter --- uint16_t. Щоб не плутатися, далі ці типи замінені на їх явні типи.)

Всі структури даних цього формату файлів слідують «природному» розміром і принципам вирівнювання відповідного класу. Якщо потрібно, структури даних містять явно зазначені наповнювачі (padding) для вирівнювання по 4-м байтам для 4-байтових об'єктів, для доведення розміру структур до кратного 4-м і т. Д.

Тема ELF описується типом Elf32_Ehdr або Elf64_Ehdr.

Таблиця заголовків програми виконуваного або спільно використовуваного об'єктного файлу являє собою масив структур, кожна з яких описує сегмент або містить іншу інформацію, необхідну системі для підготовки програми до виконання. Сегмент об'єктного файлу містить один або більше розділів. Заголовки програми потрібні тільки для виконуваних і спільно використовуваних об'єктних файлів. Розмір заголовків програми вказується у файлі в заголовку ELF в полях e_phentsize і e_phnum. Тема програми ELF описується типом Elf32_Phdr або Elf64_Phdr. в залежності від архітектури:

Основною відмінністю між 32-бітовим і 64-бітовим програмним заголовком в структурі є розташування поля p_flags.

По таблиці заголовків розділів можна знайти розташування всіх розділів у файлі. Вона являє собою масив структур Elf32_Shdr або Elf64_Shdr. На початок таблиці заголовків розділів в файлі вказує поле e_shoff заголовка ELF (в байтах). У e_shnum міститься кількість елементів таблиці заголовків розділів. У e_shentsize міститься розмір кожного елемента в байтах.

Індекс елемента в таблиці заголовків розділів вказує в цей масив. Деякі індекси елемента в таблиці заголовків розділів зарезервовані: початковий елемент і індекси від SHN_LORESERVE і до SHN_HIRESERVE. Початковий елемент використовується в розширеннях ELF для e_phnum. e_shnum and e_strndx; в інших випадках, кожне поле початкового елемента дорівнює нулю. В об'єктному файлі немає розділів з цими спеціальними індексами:

Тема розділу має наступну структуру:

Істотної різниці між 32-бітними і 64-бітними заголовками розділів немає.

Програма і керуюча інформація міститься в різних розділах:

У розділах з таблицями рядків містяться символьні послідовності, що завершуються null, які зазвичай називаються рядками. Об'єктний файл використовує ці рядки для імен символів та розділів. Він посилається на рядок за допомогою індексу в розділі таблиці рядків. У першому байті з нульовим індексом задається байт null ( '\ 0'). Подібно до цього, для забезпечення завершення null всіх рядків останній байт таблиці рядків також містить байт null.

У таблиці символів об'єктного файлу міститься інформація, необхідна для виявлення і переміщення певних в програмі символів і посилань. Індекс таблиці символів вказує на елемент з цього масиву.

32-бітна і 64-бітна версії мають однакові поля, різний тільки їх порядок.

st_name У цьому полі міститься індекс на елемент в таблиці рядків символів об'єктного файлу, що містить символьне уявлення імен символів. Якщо значення не дорівнює нулю, то це індекс таблиці рядків, по якому визначається ім'я символу. Інакше таблиця символів не має імені. st_value У цьому полі міститься значення відповідного символу. st_size З багатьма символами зв'язуються певні розміри. Це поле має значення нуль, якщо символ не має розміру або його розмір невідомий. st_info У цьому полі задається тип символу і атрибути прив'язки: STT_NOTYPE Тип символу не визначений. STT_OBJECT Символ відповідає об'єкт даних. STT_FUNC Символ відповідає функція або інший виконуваний код. STT_SECTION Символ відповідає розділ. Елементи таблиці символів цього типу існують, перш за все, для переміщення і зазвичай мають прив'язки STB_LOCAL. STT_FILE За угодою, ім'я символу призначається відповідно до імені файлу вихідного коду для відповідного об'єктного файлу. Файловий символ має прив'язки STB_LOCAL. його індекс розділу SHN_ABS. і він передує іншим символом STB_LOCAL файлу, якщо він є. STT_LOPROC Всі значення, починаючи з цього і більше, по STT_HIPROC включно, зарезервовані для процесорної-орієнтованої семантики. STT_HIPROC Всі значення, починаючи з цього і менше, за STT_LOPROC включно, зарезервовані для процесорної-орієнтованої семантики. STB_LOCAL Локальні символи невидимі поза об'єктного файлу, що містить їх визначення. Локальні символи з тими ж іменами можуть існувати в декількох файлах не заважаючи один одному. STB_GLOBAL Глобальні символи видимі у всіх об'єктних файлах після об'єднання. Визначення глобального символу в одному файлі буде вирішувати невизначену посилання в іншому файлі для того ж символу. STB_WEAK Слабкі символи (weak symbols) схожі на глобальні символи, але їх визначення мають менший пріоритет. STB_LOPROC Всі значення, починаючи з цього і більше, по STB_HIPROC включно, зарезервовані для процесорної-орієнтованої семантики. STB_HIPROC Всі значення, починаючи з цього і менше, за STB_LOPROC включно, зарезервовані для процесорної-орієнтованої семантики. Макроси для упаковки і розпаковування полів прив'язки і типу: ELF32_ST_BIND (info) або ELF64_ST_BIND (info) витягують прив'язку з значення st_info. ELF32_ST_TYPE (info) або ELF64_ST_TYPE (info)
витягають тип із значення st_info. ELF32_ST_INFO (bind, type) або ELF64_ST_INFO (bind, type)
перетворять прив'язку і тип в значення st_info. st_other Цим полем визначається видимість символу. STV_DEFAULT Правила видимості символів за замовчуванням. STV_INTERNAL Прихований клас, що залежить від процесора. STV_HIDDEN Символ недоступний в інших модулях. STV_PROTECTED невивантажуваного, не експортується.

Ці макроси служать для вилучення типу видимості:

ELF32_ST_VISIBILITY (other) або ELF64_ST_VISIBILITY (other)

st_shndx Кожен елемент таблиці символів "визначено" у ставленні до деякого розділу. Це поле містить відповідний індекс таблиці заголовків розділів.

Переміщення --- це процес з'єднання символьних посилань з символьними визначеннями. Переміщувані файли повинні мати інформацію, яка описує як потрібно змінити їх вміст розділів, щоб дозволити виконуваним і динамічним об'єктним файлів містити коректну інформацію для образу процесу програми. Для цього існують переміщення.

Переміщувані структури, яким не потрібна добавка:

Переміщувані структури, яким потрібна добавка:

У розділі .dynamic міститься кілька структур, в яких міститься інформація по динамічної компонуванні. Полем d_tag ​​контролюється інтерпретація d_un.

Вперше ELF з'явився в System V. Формат ELF є затвердженим стандартом.

Розширення для e_phnum. e_shnum і e_strndx відповідних розширень Linux. Також вони підтримуються в Sun, BSD і AMD64; додаткову інформацію дивіться в розділі "ДИВІТЬСЯ ТАКОЖ".