Структуры данных объектного
Пример 3.8. Структуры данных объектного модуля ELF (цитируется по elf.h из поставки Linux 2.2.16, перевод комментариев автора)
' Заголовок файла ELF. Находится в начале каждого файла ELF. */
#define El NIDENT (16)
typedef struct
unsigned char e_ident[EI_NIDENT]; /* Магическое число и другая информация */
Elf32_Half e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; Elf32_0ff e_phoff;
Elf32_0ff e_shoff; Elf32_Word e_flags; Elf32_Half e_ehsize; Elf32__Half e_phentsize;
Elf32_Half e_phnum; /* Elf32_Half e_shentsize; Elf32_Half e_shnum; /*
Elf32_Half e^shstrndx; ков секций */
} Elf32 Ehdr;
/* Тип объектного файла */
/* Архитектура */
/* Версия объектного файла */
/* Виртуальный адрес точки входа */
/* Смещение таблицы заголовка программы */
/* в файле */
/* Смещение таблицы заголовков секций в файле */
/* Процессорно-зависимые флаги */
/* Размер заголовка ELF в байтах */
/* Размер элемента */
/* таблицы заголовка программы */
Счетчик элементов таблицы заголовка программы */
/* Размер элемента таблицы заголовков секций */
Счетчик элементов таблицы заголовков программ */
/* Индекс таблицы имен секций в таблице заголов-
/* Поля в массиве e_indent. Макросы Е1_* суть индексы в этом массиве. Макросы, следующие за ка'ждым определением Е1_*, суть значения, которые соответствующий байт может принимать. */
#define EI_MAGO 0 /* Индекс нулевого байта сигнатуры1 */
fdefine ELFMAGO 0x7f /* Значение нулевого байта сигнатуры */
#define EI_MAG1 I /* Индекс первого байта сигнатуры */
#define ELFMAG1 'Е' /* Значение первого байта сигнатуры */
fdefine EI_MAG2 2 /* Индекс второго байта сигнатуры */
#define ELFMAG2 'L' /* Значение второго байта сигнатуры */
#define EI_MAG3 3 /* Индекс третьего байта сигнатуры */
#define ELFMAG3 'F' /* Значение третьего байта сигнатуры */
1 В данном случае — это "магическое число", код, размещаемый в определенном месте (обычно в начале) файла и подтверждающий, что это файл данного формата.
/* объединение идентификационных байтов, для сравнения по словам */ #define ELFMAG "\177ELF" ((define SELFMAG 4
((define EI_CLASS 4 /* Индекс байта, указывающего класс файла */
((define ELFCLASSNONE 0 /* Не определено */
((define ELFCLASS32 1 /* 32-разрядные объекты */
((define ELFCLASS64 2 /* 64-разрядные объекты */ ((define ELFCLASSNUM 3
tdefine EI_DATA 5 /* Индекс байта кодировки данных */
((define ELFDATANONE 0 /* Не определена кодировка данных */
((define ELFDATA2LSB 1 /* Двоичные дополнительные, младший байт первый */
#define ELFDATA2MSB 2 /* Двоичные дополнительные, старший байт первый */
tdefine ELFDATANUM 3
#define EI_VERSION 6 /* Индекс байта версии файла */ /* Значение должно быть EV__CURRENT */
#define EIJDSABI 7 /*. идентификатор OS ABI */
tdefine ELFOSABI_SYSV 0 /* UNIX System V ABI */
«define ELFOSABI_HPUX 1 /* HP-UX */
tdefine ELFOSABI_ARM 97 /* ARM */
#define ELFOSABI_STANDALONE 255 /* Самостоятельное (встраиваемое) приложение * /
#define EI_ABIVERSION 8 /* версия ABI */
#define EI_PAD 9 /* Индекс байтов выравнивания */
/* Допустимые значения для e_type (тип объектного файла). */
#define ETJTONE 0 /* Не указан тип */
#define ET_REL I /* Перемещаемый файл */
#define ET_EXEC 2 /* Исполнимый файл */
#define ET_DYN 3 /* Разделяемьй объектньй файл */
Define ET_CORE 4 /* Образ задачи */
'define ET_NUM 5 /* Количество определенных типов */
e ET_LOPROC OxffOO /* Специфичный для процессора */
ttdefine ET_HIPROC Oxffff /* Специфичный для процессора */ /* Допустимые значения для e_machine (архитектура). */
ttdefine EM_NONE 0 /* Не указана машина */
ttdefine ЕМ_М32 1 /* AT&T WE 32100 */
ttdefine EM_SPARC 2 /* SUN SPARC */
ttdefine EM_386 3 /* Intel 80386 */
ttdefine EM_68K 4 /* Motorola m68k family */
ttdefine EM_88K 5 /* Motorola m88k family */
ttdefine EM__486 6 /* Intel 80486 */
ttdefine EM_860 7 /* Intel 80860 */
ttdefine EM_MIPS 8 /* MIPS R3000 big-endian */
ttdefine EM_S370 9 /* Amdahl */
ttdefine EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */
ttdefine EM RS6000 11 /* RS6000 */
#define EM_PARISC 15 ttdefine EM_nCUBE 16 Idefine EM VPP500 17
/* HPPA */
/* nCUBE */
/* Fujitsu VPP500 */
ttdefine EM_SPARC32PLUS 18 /* Sun's "vSplus" */ ttdefine EM_960 19 /* Intel 80960 */ ttdefine EM PPC 20 /*. PowerPC */
ttdefine ttdefine ttdefine ttdefine ttdefine ttdefine ttdefine ttdefine ttdefine ttdefine ttdefine ttdefine ttdefine ttdefine ttdefine
EM_V800 36 /* NEC V800 series */ EM_FR20 37 /* Fujitsu FR20 */ EM_RH32 38 /* TRW RH32 */ EM_MMA 39 /* Fujitsu MMA */ EM^ARM 40 /* ARM */ EM_FAKE_ALPHA 41 /* Digital Alpha J
EM_SH 42 EM_SPARCV9 43 EMJTRICORE 44 EM_ARC 45 EM_H8_300 46 EM_H8_300H 47 EM_H8S 48 EM_H8_500 49 EM IA 64 50
/* Hitachi SH */ /* SPARC v9 64-bit */ /* Siemens Tricore */ /* Argonaut RISC Core */ /* Hitachi H8/300 */ /* Hitachi H8/300H */ /* Hitachi H8S */ /* Hitachi H8/500 */ /* Intel Merced */
«define EM_MIPS_X 51 /* Stanford MIPS-X */
•define EM^COLDFIRE 52 /* Motorola Coldfire */
«define EM_68HC12 53 /* Motorola M68HC12 */ ((define EM_NUM 54
/* Если необходимо вьщелить неофициальное значение для ЕМ_*, пожалуйста, выделяйте большие случайные числа (0x8523, Oxa7f2, etc.), чтобы уменьшить вероятность пересечения с официальными или не-GNU неофициальными значениями. */
((define EM_ALPHA 0x9026
/* Допустимые значения для e_version (версия). */
Idefine EV_NONE 0 /* Недопустимая версия ELF */ #define EV_CURRENT I /* Текущая версия */ (tdefine EV_NUM 2
/* Элемент таблицы символов. */
typedef struct f
Elf32_Word st_name; /* Имя символа (индекс в таблице строк) */
Elf32_Addr st_value; /* Значение символа */
Elf32_Word st_size; /* Размер символа */
unsigned char st_info; /* Тип и привязка символа */
unsigned char st_other; /* Значение не определено, 0 */
Elf32_Section st_shndx; /* Индекс секции */ ) Elf32_Sym;
'* Секция syminfo, если присутствует, содержит дополнительную информацию о каждом динамическом символе. */
typedef struct I
Elf32_Half si_boundto;/* Прямая привязка, символ, к которому привязан */ Elf32_Half si_flags; /* Флаги символа */
> Elf32 Syminfo;
/*
Допустимые значения для si boundto. */
#define SYMINFO_BT_SELF Oxffff /* tdefine SYMINFO_BT_PARENT Oxfffe /* ttdefine SYMINFO_BT_LOWRESERVE OxffOO /*
/* Возможные битовые маски для si_flags #define SYMINFO_FLG_DIRECT 0x0001 /*
tfdefine SYMINFO_FLG_PASSTHRU 0x0002 /* тора */
tfdefine SYMINFO_FLG_COPY 0x0004 /* tdefine SYMINFO_FLG_LAZYLOAD 0x0008 /*
/* Значения версии Syminfo. */ #define SYMINFO_NONE 0 ttdefine SYMINFO_CURRENT 1 #define SYMINFO NUM 2
Символ привязан к себе */ Символ привязан к родителю */ Начало зарезервированных записей */
Прямо привязываемый символ *•/ Промежуточный символ для трансля-
Символ предназначен для перемещения копированием */ Символ привязан к объекту с отложенной загрузкой */
/* Как извлекать информацию из и включать ее в поле st_info. */
•
#define ELF32_ST_BIND(val) (((unsigned char) (val)) » 4) tfdefine ELF32_ST_TYPE(val) ((val) & Oxf)
ttdefine ELF32_ST_INFO(bind, type) (((bind) « 4) + ((type) & Oxf)) /* Допустимые значения для подполя STJ3IND поля st_info (привязка символов). */
#define STB_LOCAL О ttdefine STB_GLOBAL 1 tdefine STB_WEAK 2 ttdefine STB_NUM 3 #define STB_LOOS 10 #define STB HIOS 12
/* Локальный символ */
/* Глобальный символ */
/* Слабый символ */
/* Кол-во определенных типов. */
/* Начало ОС-зависимых значений */ _ /* Конец ОС-зависимых значений */
#define STB_LOPROC 13 /* Начало процессорно-зависимых значений */ tdefine STB_HIPROC 15 /* Конец процессорно-зависимых значений */
/* Допустимые значения для подполя ST TYPE поля st info (тип символа). */
#define STT_NOTYPE 0 #define STT_OBJECT 1 #define STT FUNC 2
He указан */
Символ — объект данных */
Символ — объект кода */
STT_SECTION 3 /* Символ связан с секцией */
4define STT_FILS 4 /* Имя символа — имя файла */
*define ^тт NUM ^ /* Кол-во определенных типов */
»define STT LOOS 1^ /* Начало ОС-зависимых значений */
«define STT_HIOS 12 /* Конец ОС-зависимых значений */
*define STT_LOPROC 13 /* Начало процессорно-зависимых значений */
«define STT_HIPROC 15 /* Конец процессорно-зависимых значений */
/* Индексы таблицы символов размещены в группах и цепочках хэша в секции кэш-таблицы символов. Это специальное значение индекса указывает на конец цепочки, и означает, что в этой группе более нет символов. */
((define STNJJNDEF 0 /* Конец таблицы. */
/* Элемент таблицы перемещений без добавочного значения (в секциях типа SHT_REL). */
typedef struct (
Elf32_Addr r_offset; /* Адрес */
Elf32_Word r_info; /* Тип перемещения и индекс символа */ } Elf32_Rel;
/* Элемент таблицы перемещений с добавочным значением (в секциях типа SHT_RELA). */
typedef struct (
Elf32_Addr r_offset; /* Адрес */
Elf32_Word r_info; /* Тип перемещения и индекс символа */
Elf32_Sword r_addend; /* Добавочное значение */ ) Elf32_Rela;
'•* Как извлекать информацию из и включать ее в поле r_info. */
#define ELF32_R_SYM(val) ((val) » 8)
Define ELF32_R_TYPE(val) ((val) & Oxff)
#define ELF32_R_INFO(sym, type) (((sym) « 8) + ((type) & Oxff))
/* Типы перемещений для 1386 (формулы взяты из
[docs.sun.com 816-0559-10] - авт.)
А — добавочное значение, используемое при вычислении значения перемещаемого поля.
В — базовый адрес, начиная с которого разделяемый объект загружается в память при исполнении [программы]. Обычно разделяемый объект строится с базовым виртуальным адресом, равным О, но адрес при исполнении иной.
G — смещение записи в глобальной таблице смещений, где адрес перемещаемого символа находится во время исполнения. GOT — адрес глобальной таблицы смещений.
L — местоположение (смещение в секции или адрес) записи символа в процедурной таблице связывания (PLT). PLT перенаправляет вызов функции по настоящему адресу. Редактор связей создает начальную таблицу, а редактор связей времени исполнения модифицирует записи во время исполнения.
Р — местоположение (смещение в секции или адрес) перемещаемого элемента памяти (вычисляется с использованием r_offset).
S — значение символа, индекс которого находится в" элементе таблицы перемещений. */
#define R_386_NONE 0 /* Не перемещать */
ttdefine R__386_32 I /* Прямое 32-разрядное - S + А */
#define R_386_PC32 2 /* 32-разрядное относительно PC-S+A-PV
^define R_386_GOT32 3 /* 32-разрядный элемент GOT - G + А */
#define R_386_PLT32 4 /* 32-разрядный адрес PLT - L + А - Р */
ttdefine R_386_COPY 5 /* Копировать символ при исполнении */
#define R_386_GLOB_DAT 6 Л Создать запись GOT - S*/
#define R_386_JMP_SLOT 7 /* Создать запись PLT - S */
tfdefine R_386_RELATIVE 8 /* Сдвинуть относительно базы программы -
В + А */
tdefine R_386_GOTOFF 9 /* 32-разрядное смещение GOT - S + А - GOT */ ^define R_386_GOTPC 10 /*' 32-разрядное смещение GOT относительно
PC - S + А - GOT */ /* Должна быть последняя запись. */ #define R 386 NUM 11