1 /*
2  * Copyright (c) 2015, Google, Inc. All rights reserved
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 #pragma once
25 
26 #include <sys/types.h>
27 
28 /* 32-bit types */
29 typedef uint32_t Elf32_Addr;
30 typedef uint32_t Elf32_Off;
31 typedef uint16_t Elf32_Half;
32 typedef uint32_t Elf32_Word;
33 typedef int32_t Elf32_Sword;
34 
35 /* 64-bit types */
36 typedef uint64_t Elf64_Addr;
37 typedef uint64_t Elf64_Off;
38 typedef uint16_t Elf64_Half;
39 typedef uint32_t Elf64_Word;
40 typedef int32_t Elf64_Sword;
41 typedef uint64_t Elf64_Xword;
42 typedef int64_t Elf64_Sxword;
43 
44 /*
45  * ELF Headers
46  */
47 #define EI_NIDENT 16
48 
49 typedef struct {
50     unsigned char e_ident[EI_NIDENT];
51     Elf32_Half e_type;
52     Elf32_Half e_machine;
53     Elf32_Word e_version;
54     Elf32_Addr e_entry;
55     Elf32_Off e_phoff;
56     Elf32_Off e_shoff;
57     Elf32_Word e_flags;
58     Elf32_Half e_ehsize;
59     Elf32_Half e_phentsize;
60     Elf32_Half e_phnum;
61     Elf32_Half e_shentsize;
62     Elf32_Half e_shnum;
63     Elf32_Half e_shstrndx;
64 } Elf32_Ehdr;
65 
66 typedef struct {
67     unsigned char e_ident[EI_NIDENT];
68     Elf64_Half e_type;
69     Elf64_Half e_machine;
70     Elf64_Word e_version;
71     Elf64_Addr e_entry;
72     Elf64_Off e_phoff;
73     Elf64_Off e_shoff;
74     Elf64_Word e_flags;
75     Elf64_Half e_ehsize;
76     Elf64_Half e_phentsize;
77     Elf64_Half e_phnum;
78     Elf64_Half e_shentsize;
79     Elf64_Half e_shnum;
80     Elf64_Half e_shstrndx;
81 } Elf64_Ehdr;
82 
83 /* e_ident indexes */
84 #define EI_MAG0 0       /* File identification (0x7f) */
85 #define EI_MAG1 1       /* File identification ('E')  */
86 #define EI_MAG2 2       /* File identification ('L')  */
87 #define EI_MAG3 3       /* File identification ('F')  */
88 #define EI_CLASS 4      /* File class */
89 #define EI_DATA 5       /* Data encoding */
90 #define EI_VERSION 6    /* File version */
91 #define EI_OSABI 7      /* Operating system/ABI identification */
92 #define EI_ABIVERSION 8 /* ABI version */
93 #define EI_PAD 9        /* Start of padding bytes up to EI_NIDENT*/
94 #define EI_NIDENT 16    /* First non-ident header byte */
95 
96 /* e_ident[EI_MAG{0-3}] values */
97 #define ELFMAG0 0x7f
98 #define ELFMAG1 'E'
99 #define ELFMAG2 'L'
100 #define ELFMAG3 'F'
101 #define ELFMAG "\177ELF"
102 #define SELFMAG 4
103 
104 /* e_ident[EI_CLASS] */
105 #define ELFCLASSNONE 0 /* Invalid class */
106 #define ELFCLASS32 1   /* 32-bit */
107 #define ELFCLASS64 2   /* 64-bit */
108 
109 /* e_ident[EI_DATA] */
110 #define ELFDATANONE 0 /* Invalid data encoding */
111 #define ELFDATA2LSB 1 /* LSB */
112 #define ELFDATA2MSB 2 /* MSB */
113 
114 /* e_ident[EI_VERSION] */
115 #define EV_NONE 0    /* Invalid version */
116 #define EV_CURRENT 1 /* Current version */
117 
118 /* e_type */
119 #define ET_NONE 0        /* No file type */
120 #define ET_REL 1         /* Relocatable file */
121 #define ET_EXEC 2        /* Executable file */
122 #define ET_DYN 3         /* Shared object file */
123 #define ET_CORE 4        /* Core file */
124 #define ET_LOOS 0xfe00   /* OS specific range LO */
125 #define ET_HIOS 0xfeff   /* OS specific range HI */
126 #define ET_LOPROC 0xff00 /* Processor-specific range LO */
127 #define ET_HIPROC 0xffff /* Processor-specific range HI */
128 
129 /* e_machine */
130 #define EM_ARM 40 /* ARM */
131 
132 /*
133  * Program Header
134  */
135 typedef struct {
136     Elf32_Word p_type;
137     Elf32_Off p_offset;
138     Elf32_Addr p_vaddr;
139     Elf32_Addr p_paddr;
140     Elf32_Word p_filesz;
141     Elf32_Word p_memsz;
142     Elf32_Word p_flags;
143     Elf32_Word p_align;
144 } Elf32_Phdr;
145 
146 typedef struct {
147     Elf64_Word p_type;
148     Elf64_Word p_flags;
149     Elf64_Off p_offset;
150     Elf64_Addr p_vaddr;
151     Elf64_Addr p_paddr;
152     Elf64_Xword p_filesz;
153     Elf64_Xword p_memsz;
154     Elf64_Xword p_align;
155 } Elf64_Phdr;
156 
157 /* p_type */
158 #define PT_NULL 0            /* entry unused */
159 #define PT_LOAD 1            /* Loadable segment */
160 #define PT_DYNAMIC 2         /* Dynamic linking information */
161 #define PT_INTERP 3          /* Program interpreter */
162 #define PT_NOTE 4            /* Auxiliary information */
163 #define PT_SHLIB 5           /* Reserved, unspecified semantics */
164 #define PT_PHDR 6            /* Entry for header table itself */
165 #define PT_TLS 7             /* TLS initialisation */
166 #define PT_LOOS 0x60000000   /* OS-specific range LO */
167 #define PT_HIOS 0x6fffffff   /* OS-specific range HI */
168 #define PT_LOPROC 0x70000000 /* Processor-specific range LO */
169 #define PT_HIPROC 0x7fffffff /* Processor-specific range HI */
170 #define PT_GNU_PROPERTY (PT_LOOS + 0x474e553)
171 
172 /* p_flags */
173 #define PF_R 0x4               /* readable */
174 #define PF_W 0x2               /* writable */
175 #define PF_X 0x1               /* executable */
176 #define PF_MASKOS 0x0ff00000   /* OS specific values mask */
177 #define PF_MASKPROC 0xf0000000 /* Processor-specific values mask */
178 
179 /*
180  * Section Headers
181  */
182 typedef struct {
183     Elf32_Word sh_name;      /* section name (.shstrtab index) */
184     Elf32_Word sh_type;      /* section type */
185     Elf32_Word sh_flags;     /* section flags */
186     Elf32_Addr sh_addr;      /* virtual address */
187     Elf32_Off sh_offset;     /* file offset */
188     Elf32_Word sh_size;      /* section size */
189     Elf32_Word sh_link;      /* link to another */
190     Elf32_Word sh_info;      /* misc info */
191     Elf32_Word sh_addralign; /* memory alignment */
192     Elf32_Word sh_entsize;   /* table entry size */
193 } Elf32_Shdr;
194 
195 typedef struct {
196     Elf64_Word sh_name;       /* section name (.shstrtab index) */
197     Elf64_Word sh_type;       /* section type */
198     Elf64_Xword sh_flags;     /* section flags */
199     Elf64_Addr sh_addr;       /* virtual address */
200     Elf64_Off sh_offset;      /* file offset */
201     Elf64_Xword sh_size;      /* section size */
202     Elf64_Word sh_link;       /* link to another */
203     Elf64_Word sh_info;       /* misc info */
204     Elf64_Xword sh_addralign; /* memory alignment */
205     Elf64_Xword sh_entsize;   /* table entry size */
206 } Elf64_Shdr;
207 
208 /* sh_type */
209 #define SHT_NULL 0           /* entry unused */
210 #define SHT_PROGBITS 1       /* Program information */
211 #define SHT_SYMTAB 2         /* Symbol table */
212 #define SHT_STRTAB 3         /* String table */
213 #define SHT_RELA 4           /* Relocation information w/ addend */
214 #define SHT_HASH 5           /* Symbol hash table */
215 #define SHT_DYNAMIC 6        /* Dynamic linking information */
216 #define SHT_NOTE 7           /* Auxiliary information */
217 #define SHT_NOBITS 8         /* No space allocated in file image */
218 #define SHT_REL 9            /* Relocation information w/o addend */
219 #define SHT_SHLIB 10         /* Reserved, unspecified semantics */
220 #define SHT_DYNSYM 11        /* Symbol table for dynamic linker */
221 #define SHT_INIT_ARRAY 14    /* Initialization function pointers */
222 #define SHT_FINI_ARRAY 15    /* Termination function pointers */
223 #define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs */
224 #define SHT_GROUP 17         /* Section group */
225 #define SHT_SYMTAB_SHNDX 18  /* Section indexes (see SHN_XINDEX) */
226 
227 #define SHT_LOOS 0x60000000 /* OS specific range LO */
228 #define SHT_HIOS 0x6fffffff /* OS specific range HI */
229 
230 #define SHT_LOPROC 0x70000000 /* Processor-specific range LO */
231 #define SHT_HIPROC 0x7fffffff /* Processor-specific range HI */
232 
233 #define SHT_LOUSER 0x80000000 /* App-specific range LO */
234 #define SHT_HIUSER 0xffffffff /* App-specific range HI */
235 
236 /* sh_flags */
237 #define SHF_WRITE 0x00000001            /* Writable data */
238 #define SHF_ALLOC 0x00000002            /* Occupies memory */
239 #define SHF_EXECINSTR 0x00000004        /* Executable */
240 #define SHF_MERGE 0x00000010            /* Might be merged */
241 #define SHF_STRINGS 0x00000020          /* Contains nul terminated strings */
242 #define SHF_INFO_LINK 0x00000040        /* "sh_info" contains SHT index */
243 #define SHF_LINK_ORDER 0x00000080       /* Preserve order after combining */
244 #define SHF_OS_NONCONFORMING 0x00000100 /* OS specific handling required */
245 #define SHF_GROUP 0x00000200            /* Is member of a group */
246 #define SHF_TLS 0x00000400              /* Holds thread-local data */
247 #define SHF_MASKOS 0x0ff00000           /* OS specific values */
248 #define SHF_MASKPROC 0xf0000000         /* Processor-specific values */
249 
250 /*
251  * Note header
252  */
253 typedef struct {
254     Elf32_Word n_namesz;
255     Elf32_Word n_descsz;
256     Elf32_Word n_type;
257 } Elf32_Nhdr;
258 
259 typedef struct {
260     Elf64_Word n_namesz;
261     Elf64_Word n_descsz;
262     Elf64_Word n_type;
263 } Elf64_Nhdr;
264 
265 /* n_type values */
266 #define NT_GNU_PROPERTY_TYPE_0 5 /* .note.gnu.property */
267 
268 /*
269  * GNU Property (.note.gnu.property)
270  */
271 typedef struct {
272     Elf32_Word pr_type;
273     Elf32_Word pr_datasz;
274     Elf32_Word pr_data[];
275 } ELF_GnuProp;
276 
277 /* .note.gnu.property types */
278 #define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000
279 
280 /* Bits for GNU_PROPERTY_AARCH64_FEATURE_1_AND */
281 #define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1u << 0)
282 #define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1u << 1)
283