1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_ZUCCHINI_TYPE_ELF_H_
6 #define COMPONENTS_ZUCCHINI_TYPE_ELF_H_
7 
8 #include <stdint.h>
9 
10 namespace zucchini {
11 
12 // Structures and constants taken from linux/elf.h and following identical
13 // layout. This is used for parsing of Executable and Linkable Format (ELF).
14 namespace elf {
15 // Supported by MSVC, g++, and clang++. Ensures no gaps in packing.
16 #pragma pack(push, 1)
17 
18 // This header defines various types from the ELF file spec, but no code
19 // related to using them.
20 
21 typedef uint32_t Elf32_Addr;  // Unsigned program address.
22 typedef uint16_t Elf32_Half;  // Unsigned medium integer.
23 typedef uint32_t Elf32_Off;   // Unsigned file offset.
24 typedef int32_t Elf32_Sword;  // Signed large integer.
25 typedef uint32_t Elf32_Word;  // Unsigned large integer.
26 
27 typedef uint64_t Elf64_Addr;   // Unsigned program address.
28 typedef uint16_t Elf64_Half;   // Unsigned medium integer.
29 typedef uint64_t Elf64_Off;    // Unsigned file offset.
30 typedef int32_t Elf64_Sword;   // Signed large integer.
31 typedef uint32_t Elf64_Word;   // Unsigned large integer.
32 typedef int64_t Elf64_Sxword;  // Signed extra large integer.
33 typedef uint64_t Elf64_Xword;  // Unsigned extra large integer.
34 
35 // The header at the top of the file.
36 struct Elf32_Ehdr {
37   unsigned char e_ident[16];
38   Elf32_Half e_type;
39   Elf32_Half e_machine;
40   Elf32_Word e_version;
41   Elf32_Addr e_entry;
42   Elf32_Off e_phoff;
43   Elf32_Off e_shoff;
44   Elf32_Word e_flags;
45   Elf32_Half e_ehsize;
46   Elf32_Half e_phentsize;
47   Elf32_Half e_phnum;
48   Elf32_Half e_shentsize;
49   Elf32_Half e_shnum;
50   Elf32_Half e_shstrndx;
51 };
52 
53 struct Elf64_Ehdr {
54   unsigned char e_ident[16];
55   Elf64_Half e_type;
56   Elf64_Half e_machine;
57   Elf64_Word e_version;
58   Elf64_Addr e_entry;
59   Elf64_Off e_phoff;
60   Elf64_Off e_shoff;
61   Elf64_Word e_flags;
62   Elf64_Half e_ehsize;
63   Elf64_Half e_phentsize;
64   Elf64_Half e_phnum;
65   Elf64_Half e_shentsize;
66   Elf64_Half e_shnum;
67   Elf64_Half e_shstrndx;
68 };
69 
70 // Identification Indexes in header->e_ident.
71 enum IdentificationIndex {
72   EI_MAG0 = 0,        // File identification.
73   EI_MAG1 = 1,        // File identification.
74   EI_MAG2 = 2,        // File identification.
75   EI_MAG3 = 3,        // File identification.
76   EI_CLASS = 4,       // File class.
77   EI_DATA = 5,        // Data encoding.
78   EI_VERSION = 6,     // File version.
79   EI_OSABI = 7,       // Operating system/ABI identification.
80   EI_ABIVERSION = 8,  // ABI version.
81   EI_PAD = 9,         // Start of padding bytes.
82   EI_NIDENT = 16      // Size of e_ident[].
83 };
84 
85 // Values for header->e_ident[EI_CLASS].
86 enum FileClass {
87   ELFCLASSNONE = 0,  // Invalid class.
88   ELFCLASS32 = 1,    // 32-bit objects.
89   ELFCLASS64 = 2     // 64-bit objects.
90 };
91 
92 // Values for header->e_type.
93 enum FileType {
94   ET_NONE = 0,         // No file type
95   ET_REL = 1,          // Relocatable file
96   ET_EXEC = 2,         // Executable file
97   ET_DYN = 3,          // Shared object file
98   ET_CORE = 4,         // Core file
99   ET_LOPROC = 0xFF00,  // Processor-specific
100   ET_HIPROC = 0xFFFF   // Processor-specific
101 };
102 
103 // Values for header->e_machine.
104 enum MachineArchitecture {
105   EM_NONE = 0,       // No machine.
106   EM_386 = 3,        // Intel Architecture.
107   EM_ARM = 40,       // ARM Architecture.
108   EM_X86_64 = 62,    // Intel x86-64 Architecture.
109   EM_AARCH64 = 183,  // ARM Architecture, 64-bit.
110   // Other values skipped.
111 };
112 
113 // A section header in the section header table.
114 struct Elf32_Shdr {
115   Elf32_Word sh_name;
116   Elf32_Word sh_type;
117   Elf32_Word sh_flags;
118   Elf32_Addr sh_addr;
119   Elf32_Off sh_offset;
120   Elf32_Word sh_size;
121   Elf32_Word sh_link;
122   Elf32_Word sh_info;
123   Elf32_Word sh_addralign;
124   Elf32_Word sh_entsize;
125 };
126 
127 struct Elf64_Shdr {
128   Elf64_Word sh_name;
129   Elf64_Word sh_type;
130   Elf64_Xword sh_flags;
131   Elf64_Addr sh_addr;
132   Elf64_Off sh_offset;
133   Elf64_Xword sh_size;
134   Elf64_Word sh_link;
135   Elf64_Word sh_info;
136   Elf64_Xword sh_addralign;
137   Elf64_Xword sh_entsize;
138 };
139 
140 // Values for the section type field in a section header.
141 enum sh_type_values {
142   SHT_NULL = 0,
143   SHT_PROGBITS = 1,
144   SHT_SYMTAB = 2,
145   SHT_STRTAB = 3,
146   SHT_RELA = 4,
147   SHT_HASH = 5,
148   SHT_DYNAMIC = 6,
149   SHT_NOTE = 7,
150   SHT_NOBITS = 8,
151   SHT_REL = 9,
152   SHT_SHLIB = 10,
153   SHT_DYNSYM = 11,
154   SHT_INIT_ARRAY = 14,
155   SHT_FINI_ARRAY = 15,
156   SHT_LOPROC = 0x70000000,
157   SHT_HIPROC = 0x7FFFFFFF,
158   SHT_LOUSER = 0x80000000,
159   SHT_HIUSER = 0xFFFFFFFF
160 };
161 
162 enum sh_flag_masks {
163   SHF_WRITE = 1 << 0,
164   SHF_ALLOC = 1 << 1,
165   SHF_EXECINSTR = 1 << 2,
166   // 1 << 3 is reserved.
167   SHF_MERGE = 1 << 4,
168   SHF_STRINGS = 1 << 5,
169   SHF_INFO_LINK = 1 << 6,
170   SHF_LINK_ORDER = 1 << 7,
171   SHF_OS_NONCONFORMING = 1 << 8,
172   SHF_GROUP = 1 << 9,
173   SHF_TLS = 1 << 10,
174   SHF_COMPRESSED = 1 << 11,
175 };
176 
177 struct Elf32_Phdr {
178   Elf32_Word p_type;
179   Elf32_Off p_offset;
180   Elf32_Addr p_vaddr;
181   Elf32_Addr p_paddr;
182   Elf32_Word p_filesz;
183   Elf32_Word p_memsz;
184   Elf32_Word p_flags;
185   Elf32_Word p_align;
186 };
187 
188 struct Elf64_Phdr {
189   Elf64_Word p_type;
190   Elf64_Word p_flags;
191   Elf64_Off p_offset;
192   Elf64_Addr p_vaddr;
193   Elf64_Addr p_paddr;
194   Elf64_Xword p_filesz;
195   Elf64_Xword p_memsz;
196   Elf64_Xword p_align;
197 };
198 
199 // Values for the segment type field in a program segment header.
200 enum ph_type_values {
201   PT_NULL = 0,
202   PT_LOAD = 1,
203   PT_DYNAMIC = 2,
204   PT_INTERP = 3,
205   PT_NOTE = 4,
206   PT_SHLIB = 5,
207   PT_PHDR = 6,
208   PT_LOPROC = 0x70000000,
209   PT_HIPROC = 0x7FFFFFFF
210 };
211 
212 struct Elf32_Rel {
213   Elf32_Addr r_offset;
214   Elf32_Word r_info;
215 };
216 
217 struct Elf64_Rel {
218   Elf64_Addr r_offset;
219   Elf64_Xword r_info;
220 };
221 
222 struct Elf32_Rela {
223   Elf32_Addr r_offset;
224   Elf32_Word r_info;
225   Elf32_Sword r_addend;
226 };
227 
228 struct Elf64_Rela {
229   Elf64_Addr r_offset;
230   Elf64_Xword r_info;
231   Elf64_Sxword r_addend;
232 };
233 
234 enum elf32_rel_386_type_values {
235   R_386_NONE = 0,
236   R_386_32 = 1,
237   R_386_PC32 = 2,
238   R_386_GOT32 = 3,
239   R_386_PLT32 = 4,
240   R_386_COPY = 5,
241   R_386_GLOB_DAT = 6,
242   R_386_JMP_SLOT = 7,
243   R_386_RELATIVE = 8,
244   R_386_GOTOFF = 9,
245   R_386_GOTPC = 10,
246   R_386_TLS_TPOFF = 14,
247 };
248 
249 enum elf32_rel_x86_64_type_values {
250   R_X86_64_NONE = 0,
251   R_X86_64_64 = 1,
252   R_X86_64_PC32 = 2,
253   R_X86_64_GOT32 = 3,
254   R_X86_64_PLT32 = 4,
255   R_X86_64_COPY = 5,
256   R_X86_64_GLOB_DAT = 6,
257   R_X86_64_JUMP_SLOT = 7,
258   R_X86_64_RELATIVE = 8,
259   R_X86_64_GOTPCREL = 9,
260   R_X86_64_32 = 10,
261   R_X86_64_32S = 11,
262   R_X86_64_16 = 12,
263   R_X86_64_PC16 = 13,
264   R_X86_64_8 = 14,
265   R_X86_64_PC8 = 15,
266 };
267 
268 enum elf32_rel_arm_type_values {
269   R_ARM_RELATIVE = 23,
270 };
271 
272 enum elf64_rel_aarch64_type_values {
273   R_AARCH64_GLOB_DAT = 0x401,
274   R_AARCH64_JUMP_SLOT = 0x402,
275   R_AARCH64_RELATIVE = 0x403,
276 };
277 
278 #pragma pack(pop)
279 
280 }  // namespace elf
281 }  // namespace zucchini
282 
283 #endif  // COMPONENTS_ZUCCHINI_TYPE_ELF_H_
284