1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CHRE_PLATFORM_SHARED_LOADER_UTIL_H_
18 #define CHRE_PLATFORM_SHARED_LOADER_UTIL_H_
19 
20 // The below macros allow switching the ELF symbol type between 32/64-bit
21 // depending on what the chipset supports.
22 #ifndef ELFW
23 #ifndef __WORDSIZE
24 // Until we can get a hold of wordsize.h, we need to define it here.
25 // Only 32-bit architectures currently supported.
26 #ifndef __aarch64__
27 #define __WORDSIZE 32
28 #else
29 #error "Only 32-bit architectures currently supported"
30 #endif
31 #endif
32 // https://refspecs.linuxbase.org/elf/gabi4+/ch4.reloc.html
33 #define ELF32_R_SYM(info) ((info) >> 8)
34 #define ELF32_R_TYPE(info) ((unsigned char)(info))
35 #define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type))
36 #define __ELF_NATIVE_CLASS __WORDSIZE
37 #define ELFW(type) _ELFW(__ELF_NATIVE_CLASS, type)
38 #define _ELFW(bits, type) __ELFW(bits, type)
39 #define __ELFW(bits, type) ELF##bits##_##type
40 #endif
41 #define ELFW_R_TYPE(x) ELFW(R_TYPE)(x)
42 #define ELFW_R_SYM(x) ELFW(R_SYM)(x)
43 
44 struct ExportedData {
45   void *data;
46   const char *dataName;
47 };
48 
49 // The below is copied from bionic/libc/kernel/uapi/linux/elf.h
50 // to avoid pulling those deps into the build.
51 #if defined(__LP64__)
52 #define ElfW(type) Elf64_##type
53 #else
54 #define ElfW(type) Elf32_##type
55 #endif
56 
57 #define EM_ARM 40
58 #define EI_MAG0 0
59 #define EI_MAG1 1
60 #define EI_MAG2 2
61 #define EI_MAG3 3
62 #define EI_CLASS 4
63 #define EI_DATA 5
64 #define EI_VERSION 6
65 #define EI_OSABI 7
66 #define EI_PAD 8
67 #define ELFMAG0 0x7f
68 #define ELFMAG1 'E'
69 #define ELFMAG2 'L'
70 #define ELFMAG3 'F'
71 #define ELFMAG "\177ELF"
72 #define SELFMAG 4
73 #define ELFCLASSNONE 0
74 #define ELFCLASS32 1
75 #define ELFCLASS64 2
76 #define ELFCLASSNUM 3
77 #define ELFDATANONE 0
78 #define ELFDATA2LSB 1
79 #define ELFDATA2MSB 2
80 #define EV_NONE 0
81 #define EV_CURRENT 1
82 #define EV_NUM 2
83 #define ELFOSABI_NONE 0
84 #define ELFOSABI_LINUX 3
85 #define PT_NULL 0
86 #define PT_LOAD 1
87 #define PT_DYNAMIC 2
88 #define PT_INTERP 3
89 #define PT_NOTE 4
90 #define PT_SHLIB 5
91 #define PT_PHDR 6
92 #define PT_TLS 7
93 #define PT_LOOS 0x60000000
94 #define PT_HIOS 0x6fffffff
95 #define PT_LOPROC 0x70000000
96 #define PT_HIPROC 0x7fffffff
97 #define PT_GNU_EH_FRAME 0x6474e550
98 #define PT_GNU_STACK (PT_LOOS + 0x474e551)
99 #define PN_XNUM 0xffff
100 #define ET_NONE 0
101 #define ET_REL 1
102 #define ET_EXEC 2
103 #define ET_DYN 3
104 #define ET_CORE 4
105 #define ET_LOPROC 0xff00
106 #define ET_HIPROC 0xffff
107 #define DT_NULL 0
108 #define DT_NEEDED 1
109 #define DT_PLTRELSZ 2
110 #define DT_PLTGOT 3
111 #define DT_HASH 4
112 #define DT_STRTAB 5
113 #define DT_SYMTAB 6
114 #define DT_RELA 7
115 #define DT_RELASZ 8
116 #define DT_RELAENT 9
117 #define DT_STRSZ 10
118 #define DT_SYMENT 11
119 #define DT_INIT 12
120 #define DT_FINI 13
121 #define DT_SONAME 14
122 #define DT_RPATH 15
123 #define DT_SYMBOLIC 16
124 #define DT_REL 17
125 #define DT_RELSZ 18
126 #define DT_RELENT 19
127 #define DT_PLTREL 20
128 #define DT_DEBUG 21
129 #define DT_TEXTREL 22
130 #define DT_JMPREL 23
131 #define DT_ENCODING 32
132 
133 typedef __signed__ char __s8;
134 typedef unsigned char __u8;
135 typedef __signed__ short __s16;
136 typedef unsigned short __u16;
137 typedef __signed__ int __s32;
138 typedef unsigned int __u32;
139 typedef __signed__ long __s64;
140 typedef unsigned long __u64;
141 
142 typedef __u32 Elf32_Addr;
143 typedef __u16 Elf32_Half;
144 typedef __u32 Elf32_Off;
145 typedef __s32 Elf32_Sword;
146 typedef __u32 Elf32_Word;
147 
148 #define EI_NIDENT 16
149 typedef struct elf32_hdr {
150   unsigned char e_ident[EI_NIDENT];
151   Elf32_Half e_type;
152   Elf32_Half e_machine;
153   Elf32_Word e_version;
154   Elf32_Addr e_entry;
155   Elf32_Off e_phoff;
156   Elf32_Off e_shoff;
157   Elf32_Word e_flags;
158   Elf32_Half e_ehsize;
159   Elf32_Half e_phentsize;
160   Elf32_Half e_phnum;
161   Elf32_Half e_shentsize;
162   Elf32_Half e_shnum;
163   Elf32_Half e_shstrndx;
164 } Elf32_Ehdr;
165 
166 typedef struct dynamic {
167   Elf32_Sword d_tag;
168   union {
169     Elf32_Sword d_val;
170     Elf32_Addr d_ptr;
171   } d_un;
172 } Elf32_Dyn;
173 
174 typedef struct elf32_phdr {
175   Elf32_Word p_type;
176   Elf32_Off p_offset;
177   Elf32_Addr p_vaddr;
178   Elf32_Addr p_paddr;
179   Elf32_Word p_filesz;
180   Elf32_Word p_memsz;
181   Elf32_Word p_flags;
182   Elf32_Word p_align;
183 } Elf32_Phdr;
184 
185 typedef struct elf32_shdr {
186   Elf32_Word sh_name;
187   Elf32_Word sh_type;
188   Elf32_Word sh_flags;
189   Elf32_Addr sh_addr;
190   Elf32_Off sh_offset;
191   Elf32_Word sh_size;
192   Elf32_Word sh_link;
193   Elf32_Word sh_info;
194   Elf32_Word sh_addralign;
195   Elf32_Word sh_entsize;
196 } Elf32_Shdr;
197 
198 typedef struct elf32_rela {
199   Elf32_Addr r_offset;
200   Elf32_Word r_info;
201   Elf32_Sword r_addend;
202 } Elf32_Rela;
203 
204 typedef struct elf32_rel {
205   Elf32_Addr r_offset;
206   Elf32_Word r_info;
207 } Elf32_Rel;
208 
209 typedef struct elf32_sym {
210   Elf32_Word st_name;
211   Elf32_Addr st_value;
212   Elf32_Word st_size;
213   unsigned char st_info;
214   unsigned char st_other;
215   Elf32_Half st_shndx;
216 } Elf32_Sym;
217 
218 // The following defines are copied from bionic's elf_arm.h header
219 // at bionic/libc/kernel/uapi/linux/elf.h
220 // Only the relocation types currently supported are copied.
221 #define R_ARM_NONE 0
222 #define R_ARM_ABS32 2
223 #define R_ARM_COPY 20
224 #define R_ARM_GLOB_DAT 21
225 #define R_ARM_JUMP_SLOT 22
226 #define R_ARM_RELATIVE 23
227 
228 // The following (legal values for segment flags) are copied from
229 // bionic's elf.h
230 /* http://www.sco.com/developers/gabi/latest/ch5.pheader.html */
231 #define PF_X 0x1
232 #define PF_W 0x2
233 #define PF_R 0x4
234 #define PF_MASKOS 0x0ff00000
235 #define PF_MASKPROC 0xf0000000
236 
237 #endif  // CHRE_PLATFORM_SHARED_LOADER_UTIL_H_
238