1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2019, Linaro Limited
4 */
5
6 #include <assert.h>
7 #include <compiler.h>
8 #include <confine_array_index.h>
9 #include <elf32.h>
10 #include <elf64.h>
11 #include <elf_common.h>
12 #include <string.h>
13 #include <tee_api_types.h>
14 #include <util.h>
15
16 #include "sys.h"
17 #include "ta_elf.h"
18
elf_hash(const char * name)19 static uint32_t elf_hash(const char *name)
20 {
21 const unsigned char *p = (const unsigned char *)name;
22 uint32_t h = 0;
23 uint32_t g = 0;
24
25 while (*p) {
26 h = (h << 4) + *p++;
27 g = h & 0xf0000000;
28 if (g)
29 h ^= g >> 24;
30 h &= ~g;
31 }
32 return h;
33 }
34
__resolve_sym(struct ta_elf * elf,unsigned int st_bind,unsigned int st_type,size_t st_shndx,size_t st_name,size_t st_value,const char * name,vaddr_t * val,bool weak_ok)35 static bool __resolve_sym(struct ta_elf *elf, unsigned int st_bind,
36 unsigned int st_type, size_t st_shndx,
37 size_t st_name, size_t st_value, const char *name,
38 vaddr_t *val, bool weak_ok)
39 {
40 bool bind_ok = false;
41
42 if (!st_name)
43 return false;
44 if (st_name > elf->dynstr_size)
45 err(TEE_ERROR_BAD_FORMAT, "Symbol name out of range");
46 if (strcmp(name, elf->dynstr + st_name))
47 return false;
48 if (st_bind == STB_GLOBAL || (weak_ok && st_bind == STB_WEAK))
49 bind_ok = true;
50 if (!bind_ok)
51 return false;
52 if (st_bind == STB_WEAK && st_shndx == SHN_UNDEF) {
53 if (val)
54 *val = 0;
55 return true;
56 }
57 if (st_shndx == SHN_UNDEF || st_shndx == SHN_XINDEX)
58 return false;
59
60 switch (st_type) {
61 case STT_NOTYPE:
62 case STT_OBJECT:
63 case STT_FUNC:
64 if (st_value > (elf->max_addr - elf->load_addr))
65 err(TEE_ERROR_BAD_FORMAT,
66 "Symbol location out of range");
67 if (val)
68 *val = st_value + elf->load_addr;
69 break;
70 case STT_TLS:
71 if (val)
72 *val = st_value;
73 break;
74 default:
75 err(TEE_ERROR_NOT_SUPPORTED, "Symbol type not supported");
76 }
77
78 return true;
79 }
80
resolve_sym_helper(uint32_t hash,const char * name,vaddr_t * val,struct ta_elf * elf,bool weak_ok)81 static TEE_Result resolve_sym_helper(uint32_t hash, const char *name,
82 vaddr_t *val, struct ta_elf *elf,
83 bool weak_ok)
84 {
85 /*
86 * Using uint32_t here for convenience because both Elf64_Word
87 * and Elf32_Word are 32-bit types
88 */
89 uint32_t *hashtab = elf->hashtab;
90 uint32_t nbuckets = hashtab[0];
91 uint32_t nchains = hashtab[1];
92 uint32_t *bucket = &hashtab[2];
93 uint32_t *chain = &bucket[nbuckets];
94 size_t n = 0;
95
96 if (elf->is_32bit) {
97 Elf32_Sym *sym = elf->dynsymtab;
98
99 for (n = bucket[hash % nbuckets]; n; n = chain[n]) {
100 if (n >= nchains || n >= elf->num_dynsyms)
101 err(TEE_ERROR_BAD_FORMAT,
102 "Index out of range");
103 /*
104 * We're loading values from sym[] which later
105 * will be used to load something.
106 * => Spectre V1 pattern, need to cap the index
107 * against speculation.
108 */
109 n = confine_array_index(n, elf->num_dynsyms);
110 if (__resolve_sym(elf,
111 ELF32_ST_BIND(sym[n].st_info),
112 ELF32_ST_TYPE(sym[n].st_info),
113 sym[n].st_shndx,
114 sym[n].st_name,
115 sym[n].st_value, name, val, weak_ok))
116 return TEE_SUCCESS;
117 }
118 } else {
119 Elf64_Sym *sym = elf->dynsymtab;
120
121 for (n = bucket[hash % nbuckets]; n; n = chain[n]) {
122 if (n >= nchains || n >= elf->num_dynsyms)
123 err(TEE_ERROR_BAD_FORMAT,
124 "Index out of range");
125 /*
126 * We're loading values from sym[] which later
127 * will be used to load something.
128 * => Spectre V1 pattern, need to cap the index
129 * against speculation.
130 */
131 n = confine_array_index(n, elf->num_dynsyms);
132 if (__resolve_sym(elf,
133 ELF64_ST_BIND(sym[n].st_info),
134 ELF64_ST_TYPE(sym[n].st_info),
135 sym[n].st_shndx,
136 sym[n].st_name,
137 sym[n].st_value, name, val, weak_ok))
138 return TEE_SUCCESS;
139 }
140 }
141
142 return TEE_ERROR_ITEM_NOT_FOUND;
143 }
144
145 /*
146 * Look for named symbol in @elf, or all modules if @elf == NULL. Global symbols
147 * are searched first, then weak ones. Last option, when at least one weak but
148 * undefined symbol exists, resolve to zero. Otherwise return
149 * TEE_ERROR_ITEM_NOT_FOUND.
150 * @val (if != 0) receives the symbol value
151 * @found_elf (if != 0) receives the module where the symbol is found
152 */
ta_elf_resolve_sym(const char * name,vaddr_t * val,struct ta_elf ** found_elf,struct ta_elf * elf)153 TEE_Result ta_elf_resolve_sym(const char *name, vaddr_t *val,
154 struct ta_elf **found_elf,
155 struct ta_elf *elf)
156 {
157 uint32_t hash = elf_hash(name);
158
159 if (elf) {
160 /* Search global symbols */
161 if (!resolve_sym_helper(hash, name, val, elf,
162 false /* !weak_ok */))
163 goto success;
164 /* Search weak symbols */
165 if (!resolve_sym_helper(hash, name, val, elf,
166 true /* weak_ok */))
167 goto success;
168 }
169
170 TAILQ_FOREACH(elf, &main_elf_queue, link) {
171 if (!resolve_sym_helper(hash, name, val, elf,
172 false /* !weak_ok */))
173 goto success;
174 if (!resolve_sym_helper(hash, name, val, elf,
175 true /* weak_ok */))
176 goto success;
177 }
178
179 return TEE_ERROR_ITEM_NOT_FOUND;
180
181 success:
182 if (found_elf)
183 *found_elf = elf;
184 return TEE_SUCCESS;
185 }
186
e32_get_sym_name(const Elf32_Sym * sym_tab,size_t num_syms,const char * str_tab,size_t str_tab_size,Elf32_Rel * rel,const char ** name)187 static void e32_get_sym_name(const Elf32_Sym *sym_tab, size_t num_syms,
188 const char *str_tab, size_t str_tab_size,
189 Elf32_Rel *rel, const char **name)
190 {
191 size_t sym_idx = 0;
192 size_t name_idx = 0;
193
194 sym_idx = ELF32_R_SYM(rel->r_info);
195 if (sym_idx >= num_syms)
196 err(TEE_ERROR_BAD_FORMAT, "Symbol index out of range");
197 sym_idx = confine_array_index(sym_idx, num_syms);
198
199 name_idx = sym_tab[sym_idx].st_name;
200 if (name_idx >= str_tab_size)
201 err(TEE_ERROR_BAD_FORMAT, "Name index out of range");
202 *name = str_tab + name_idx;
203 }
204
resolve_sym(const char * name,vaddr_t * val,struct ta_elf ** mod)205 static void resolve_sym(const char *name, vaddr_t *val, struct ta_elf **mod)
206 {
207 TEE_Result res = ta_elf_resolve_sym(name, val, mod, NULL);
208
209 if (res)
210 err(res, "Symbol %s not found", name);
211 }
212
e32_process_dyn_rel(const Elf32_Sym * sym_tab,size_t num_syms,const char * str_tab,size_t str_tab_size,Elf32_Rel * rel,Elf32_Addr * where)213 static void e32_process_dyn_rel(const Elf32_Sym *sym_tab, size_t num_syms,
214 const char *str_tab, size_t str_tab_size,
215 Elf32_Rel *rel, Elf32_Addr *where)
216 {
217 const char *name = NULL;
218 vaddr_t val = 0;
219
220 e32_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rel, &name);
221 resolve_sym(name, &val, NULL);
222 *where = val;
223 }
224
e32_tls_get_module(const Elf32_Sym * sym_tab,size_t num_syms,const char * str_tab,size_t str_tab_size,Elf32_Rel * rel,struct ta_elf ** mod)225 static void e32_tls_get_module(const Elf32_Sym *sym_tab, size_t num_syms,
226 const char *str_tab, size_t str_tab_size,
227 Elf32_Rel *rel, struct ta_elf **mod)
228 {
229 const char *name = NULL;
230 size_t sym_idx = 0;
231
232 sym_idx = ELF32_R_SYM(rel->r_info);
233 if (sym_idx >= num_syms)
234 err(TEE_ERROR_BAD_FORMAT, "Symbol index out of range");
235 sym_idx = confine_array_index(sym_idx, num_syms);
236 if (!sym_idx || sym_tab[sym_idx].st_shndx != SHN_UNDEF) {
237 /* No symbol, or symbol is defined in current module */
238 return;
239 }
240
241 e32_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rel, &name);
242 resolve_sym(name, NULL, mod);
243 }
244
e32_tls_resolve(const Elf32_Sym * sym_tab,size_t num_syms,const char * str_tab,size_t str_tab_size,Elf32_Rel * rel,vaddr_t * val)245 static void e32_tls_resolve(const Elf32_Sym *sym_tab, size_t num_syms,
246 const char *str_tab, size_t str_tab_size,
247 Elf32_Rel *rel, vaddr_t *val)
248 {
249 const char *name = NULL;
250
251 e32_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rel, &name);
252 resolve_sym(name, val, NULL);
253 }
254
e32_relocate(struct ta_elf * elf,unsigned int rel_sidx)255 static void e32_relocate(struct ta_elf *elf, unsigned int rel_sidx)
256 {
257 Elf32_Shdr *shdr = elf->shdr;
258 Elf32_Rel *rel = NULL;
259 Elf32_Rel *rel_end = NULL;
260 size_t sym_tab_idx = 0;
261 Elf32_Sym *sym_tab = NULL;
262 size_t num_syms = 0;
263 size_t sh_end = 0;
264 const char *str_tab = NULL;
265 size_t str_tab_size = 0;
266
267 assert(shdr[rel_sidx].sh_type == SHT_REL);
268
269 assert(shdr[rel_sidx].sh_entsize == sizeof(Elf32_Rel));
270
271 sym_tab_idx = shdr[rel_sidx].sh_link;
272 if (sym_tab_idx) {
273 size_t str_tab_idx = 0;
274
275 if (sym_tab_idx >= elf->e_shnum)
276 err(TEE_ERROR_BAD_FORMAT, "SYMTAB index out of range");
277 sym_tab_idx = confine_array_index(sym_tab_idx, elf->e_shnum);
278
279 assert(shdr[sym_tab_idx].sh_entsize == sizeof(Elf32_Sym));
280
281 /* Check the address is inside ELF memory */
282 if (ADD_OVERFLOW(shdr[sym_tab_idx].sh_addr,
283 shdr[sym_tab_idx].sh_size, &sh_end))
284 err(TEE_ERROR_BAD_FORMAT, "Overflow");
285 if (sh_end >= (elf->max_addr - elf->load_addr))
286 err(TEE_ERROR_BAD_FORMAT, "SYMTAB out of range");
287
288 sym_tab = (Elf32_Sym *)(elf->load_addr +
289 shdr[sym_tab_idx].sh_addr);
290
291 num_syms = shdr[sym_tab_idx].sh_size / sizeof(Elf32_Sym);
292
293 str_tab_idx = shdr[sym_tab_idx].sh_link;
294 if (str_tab_idx) {
295 if (str_tab_idx >= elf->e_shnum)
296 err(TEE_ERROR_BAD_FORMAT,
297 "STRTAB index out of range");
298 str_tab_idx = confine_array_index(str_tab_idx,
299 elf->e_shnum);
300
301 /* Check the address is inside ELF memory */
302 if (ADD_OVERFLOW(shdr[str_tab_idx].sh_addr,
303 shdr[str_tab_idx].sh_size, &sh_end))
304 err(TEE_ERROR_BAD_FORMAT, "Overflow");
305 if (sh_end >= (elf->max_addr - elf->load_addr))
306 err(TEE_ERROR_BAD_FORMAT,
307 "STRTAB out of range");
308
309 str_tab = (const char *)(elf->load_addr +
310 shdr[str_tab_idx].sh_addr);
311 str_tab_size = shdr[str_tab_idx].sh_size;
312 }
313 }
314
315 /* Check the address is inside TA memory */
316 if (ADD_OVERFLOW(shdr[rel_sidx].sh_addr,
317 shdr[rel_sidx].sh_size, &sh_end))
318 err(TEE_ERROR_BAD_FORMAT, "Overflow");
319 if (sh_end >= (elf->max_addr - elf->load_addr))
320 err(TEE_ERROR_BAD_FORMAT, ".rel.*/REL out of range");
321 rel = (Elf32_Rel *)(elf->load_addr + shdr[rel_sidx].sh_addr);
322
323 rel_end = rel + shdr[rel_sidx].sh_size / sizeof(Elf32_Rel);
324 for (; rel < rel_end; rel++) {
325 struct ta_elf *mod = NULL;
326 Elf32_Addr *where = NULL;
327 size_t sym_idx = 0;
328 vaddr_t val = 0;
329
330 /* Check the address is inside TA memory */
331 if (rel->r_offset >= (elf->max_addr - elf->load_addr))
332 err(TEE_ERROR_BAD_FORMAT,
333 "Relocation offset out of range");
334 where = (Elf32_Addr *)(elf->load_addr + rel->r_offset);
335
336 switch (ELF32_R_TYPE(rel->r_info)) {
337 case R_ARM_NONE:
338 /*
339 * One would expect linker prevents such useless entry
340 * in the relocation table. We still handle this type
341 * here in case such entries exist.
342 */
343 break;
344 case R_ARM_ABS32:
345 sym_idx = ELF32_R_SYM(rel->r_info);
346 if (sym_idx >= num_syms)
347 err(TEE_ERROR_BAD_FORMAT,
348 "Symbol index out of range");
349 if (sym_tab[sym_idx].st_shndx == SHN_UNDEF) {
350 /* Symbol is external */
351 e32_process_dyn_rel(sym_tab, num_syms, str_tab,
352 str_tab_size, rel, where);
353 } else {
354 *where += elf->load_addr +
355 sym_tab[sym_idx].st_value;
356 }
357 break;
358 case R_ARM_REL32:
359 sym_idx = ELF32_R_SYM(rel->r_info);
360 if (sym_idx >= num_syms)
361 err(TEE_ERROR_BAD_FORMAT,
362 "Symbol index out of range");
363 *where += sym_tab[sym_idx].st_value - rel->r_offset;
364 break;
365 case R_ARM_RELATIVE:
366 *where += elf->load_addr;
367 break;
368 case R_ARM_GLOB_DAT:
369 case R_ARM_JUMP_SLOT:
370 if (!sym_tab)
371 err(TEE_ERROR_BAD_FORMAT,
372 "Missing symbol table");
373 e32_process_dyn_rel(sym_tab, num_syms, str_tab,
374 str_tab_size, rel, where);
375 break;
376 case R_ARM_TLS_DTPMOD32:
377 if (!sym_tab)
378 err(TEE_ERROR_BAD_FORMAT,
379 "Missing symbol table");
380 mod = elf;
381 e32_tls_get_module(sym_tab, num_syms, str_tab,
382 str_tab_size, rel, &mod);
383 *where = mod->tls_mod_id;
384 break;
385 case R_ARM_TLS_DTPOFF32:
386 if (!sym_tab)
387 err(TEE_ERROR_BAD_FORMAT,
388 "Missing symbol table");
389 e32_tls_resolve(sym_tab, num_syms, str_tab,
390 str_tab_size, rel, &val);
391 *where = val;
392 break;
393 default:
394 err(TEE_ERROR_BAD_FORMAT, "Unknown relocation type %d",
395 ELF32_R_TYPE(rel->r_info));
396 }
397 }
398 }
399
400 #ifdef ARM64
e64_get_sym_name(const Elf64_Sym * sym_tab,size_t num_syms,const char * str_tab,size_t str_tab_size,Elf64_Rela * rela,const char ** name)401 static void e64_get_sym_name(const Elf64_Sym *sym_tab, size_t num_syms,
402 const char *str_tab, size_t str_tab_size,
403 Elf64_Rela *rela, const char **name)
404 {
405 size_t sym_idx = 0;
406 size_t name_idx = 0;
407
408 sym_idx = ELF64_R_SYM(rela->r_info);
409 if (sym_idx >= num_syms)
410 err(TEE_ERROR_BAD_FORMAT, "Symbol index out of range");
411 sym_idx = confine_array_index(sym_idx, num_syms);
412
413 name_idx = sym_tab[sym_idx].st_name;
414 if (name_idx >= str_tab_size)
415 err(TEE_ERROR_BAD_FORMAT, "Name index out of range");
416 *name = str_tab + name_idx;
417 }
418
e64_process_dyn_rela(const Elf64_Sym * sym_tab,size_t num_syms,const char * str_tab,size_t str_tab_size,Elf64_Rela * rela,Elf64_Addr * where)419 static void e64_process_dyn_rela(const Elf64_Sym *sym_tab, size_t num_syms,
420 const char *str_tab, size_t str_tab_size,
421 Elf64_Rela *rela, Elf64_Addr *where)
422 {
423 const char *name = NULL;
424 uintptr_t val = 0;
425
426 e64_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rela, &name);
427 resolve_sym(name, &val, NULL);
428 *where = val;
429 }
430
e64_process_tls_tprel_rela(const Elf64_Sym * sym_tab,size_t num_syms,const char * str_tab,size_t str_tab_size,Elf64_Rela * rela,Elf64_Addr * where,struct ta_elf * elf)431 static void e64_process_tls_tprel_rela(const Elf64_Sym *sym_tab,
432 size_t num_syms, const char *str_tab,
433 size_t str_tab_size, Elf64_Rela *rela,
434 Elf64_Addr *where, struct ta_elf *elf)
435 {
436 struct ta_elf *mod = NULL;
437 const char *name = NULL;
438 size_t sym_idx = 0;
439 vaddr_t symval = 0;
440
441 sym_idx = ELF64_R_SYM(rela->r_info);
442 if (sym_idx) {
443 e64_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rela,
444 &name);
445 resolve_sym(name, &symval, &mod);
446 } else {
447 mod = elf;
448 }
449 *where = symval + mod->tls_tcb_offs + rela->r_addend;
450 }
451
452 struct tlsdesc {
453 long (*resolver)(struct tlsdesc *td);
454 long value;
455 };
456
457 /* Helper function written in assembly due to the calling convention */
458 long tlsdesc_resolve(struct tlsdesc *td);
459
e64_process_tlsdesc_rela(const Elf64_Sym * sym_tab,size_t num_syms,const char * str_tab,size_t str_tab_size,Elf64_Rela * rela,Elf64_Addr * where,struct ta_elf * elf)460 static void e64_process_tlsdesc_rela(const Elf64_Sym *sym_tab, size_t num_syms,
461 const char *str_tab, size_t str_tab_size,
462 Elf64_Rela *rela, Elf64_Addr *where,
463 struct ta_elf *elf)
464 {
465 /*
466 * @where points to a pair of 64-bit words in the GOT or PLT which is
467 * mapped to a struct tlsdesc:
468 *
469 * - resolver() must return the offset of the thread-local variable
470 * relative to TPIDR_EL0.
471 * - value is implementation-dependent. The TLS_TPREL handling code is
472 * re-used to get the desired offset so that tlsdesc_resolve() just
473 * needs to return this value.
474 *
475 * Both the TA and ldelf are AArch64 so it is OK to point to a function
476 * in ldelf.
477 */
478 *where = (Elf64_Addr)tlsdesc_resolve;
479 e64_process_tls_tprel_rela(sym_tab, num_syms, str_tab, str_tab_size,
480 rela, where + 1, elf);
481 }
482
e64_relocate(struct ta_elf * elf,unsigned int rel_sidx)483 static void e64_relocate(struct ta_elf *elf, unsigned int rel_sidx)
484 {
485 Elf64_Shdr *shdr = elf->shdr;
486 Elf64_Rela *rela = NULL;
487 Elf64_Rela *rela_end = NULL;
488 size_t sym_tab_idx = 0;
489 Elf64_Sym *sym_tab = NULL;
490 size_t num_syms = 0;
491 size_t sh_end = 0;
492 const char *str_tab = NULL;
493 size_t str_tab_size = 0;
494
495 assert(shdr[rel_sidx].sh_type == SHT_RELA);
496
497 assert(shdr[rel_sidx].sh_entsize == sizeof(Elf64_Rela));
498
499 sym_tab_idx = shdr[rel_sidx].sh_link;
500 if (sym_tab_idx) {
501 size_t str_tab_idx = 0;
502
503 if (sym_tab_idx >= elf->e_shnum)
504 err(TEE_ERROR_BAD_FORMAT, "SYMTAB index out of range");
505 sym_tab_idx = confine_array_index(sym_tab_idx, elf->e_shnum);
506
507 assert(shdr[sym_tab_idx].sh_entsize == sizeof(Elf64_Sym));
508
509 /* Check the address is inside TA memory */
510 if (ADD_OVERFLOW(shdr[sym_tab_idx].sh_addr,
511 shdr[sym_tab_idx].sh_size, &sh_end))
512 err(TEE_ERROR_BAD_FORMAT, "Overflow");
513 if (sh_end >= (elf->max_addr - elf->load_addr))
514 err(TEE_ERROR_BAD_FORMAT, "SYMTAB out of range");
515
516 sym_tab = (Elf64_Sym *)(elf->load_addr +
517 shdr[sym_tab_idx].sh_addr);
518
519 num_syms = shdr[sym_tab_idx].sh_size / sizeof(Elf64_Sym);
520
521 str_tab_idx = shdr[sym_tab_idx].sh_link;
522 if (str_tab_idx) {
523 if (str_tab_idx >= elf->e_shnum)
524 err(TEE_ERROR_BAD_FORMAT,
525 "STRTAB index out of range");
526 str_tab_idx = confine_array_index(str_tab_idx,
527 elf->e_shnum);
528
529 /* Check the address is inside ELF memory */
530 if (ADD_OVERFLOW(shdr[str_tab_idx].sh_addr,
531 shdr[str_tab_idx].sh_size, &sh_end))
532 err(TEE_ERROR_BAD_FORMAT, "Overflow");
533 if (sh_end >= (elf->max_addr - elf->load_addr))
534 err(TEE_ERROR_BAD_FORMAT,
535 "STRTAB out of range");
536
537 str_tab = (const char *)(elf->load_addr +
538 shdr[str_tab_idx].sh_addr);
539 str_tab_size = shdr[str_tab_idx].sh_size;
540 }
541 }
542
543 /* Check the address is inside TA memory */
544 if (ADD_OVERFLOW(shdr[rel_sidx].sh_addr,
545 shdr[rel_sidx].sh_size, &sh_end))
546 err(TEE_ERROR_BAD_FORMAT, "Overflow");
547 if (sh_end >= (elf->max_addr - elf->load_addr))
548 err(TEE_ERROR_BAD_FORMAT, ".rel.*/REL out of range");
549 rela = (Elf64_Rela *)(elf->load_addr + shdr[rel_sidx].sh_addr);
550
551 rela_end = rela + shdr[rel_sidx].sh_size / sizeof(Elf64_Rela);
552 for (; rela < rela_end; rela++) {
553 Elf64_Addr *where = NULL;
554 size_t sym_idx = 0;
555
556 /* Check the address is inside TA memory */
557 if (rela->r_offset >= (elf->max_addr - elf->load_addr))
558 err(TEE_ERROR_BAD_FORMAT,
559 "Relocation offset out of range");
560
561 where = (Elf64_Addr *)(elf->load_addr + rela->r_offset);
562
563 switch (ELF64_R_TYPE(rela->r_info)) {
564 case R_AARCH64_NONE:
565 /*
566 * One would expect linker prevents such useless entry
567 * in the relocation table. We still handle this type
568 * here in case such entries exist.
569 */
570 break;
571 case R_AARCH64_ABS64:
572 sym_idx = ELF64_R_SYM(rela->r_info);
573 if (sym_idx >= num_syms)
574 err(TEE_ERROR_BAD_FORMAT,
575 "Symbol index out of range");
576 sym_idx = confine_array_index(sym_idx, num_syms);
577 if (sym_tab[sym_idx].st_shndx == SHN_UNDEF) {
578 /* Symbol is external */
579 e64_process_dyn_rela(sym_tab, num_syms, str_tab,
580 str_tab_size, rela, where);
581 } else {
582 *where = rela->r_addend + elf->load_addr +
583 sym_tab[sym_idx].st_value;
584 }
585 break;
586 case R_AARCH64_RELATIVE:
587 *where = rela->r_addend + elf->load_addr;
588 break;
589 case R_AARCH64_GLOB_DAT:
590 case R_AARCH64_JUMP_SLOT:
591 e64_process_dyn_rela(sym_tab, num_syms, str_tab,
592 str_tab_size, rela, where);
593 break;
594 case R_AARCH64_TLS_TPREL:
595 e64_process_tls_tprel_rela(sym_tab, num_syms, str_tab,
596 str_tab_size, rela, where,
597 elf);
598 break;
599 case R_AARCH64_TLSDESC:
600 e64_process_tlsdesc_rela(sym_tab, num_syms, str_tab,
601 str_tab_size, rela, where,
602 elf);
603 break;
604 default:
605 err(TEE_ERROR_BAD_FORMAT, "Unknown relocation type %zd",
606 ELF64_R_TYPE(rela->r_info));
607 }
608 }
609 }
610 #else /*ARM64*/
e64_relocate(struct ta_elf * elf __unused,unsigned int rel_sidx __unused)611 static void __noreturn e64_relocate(struct ta_elf *elf __unused,
612 unsigned int rel_sidx __unused)
613 {
614 err(TEE_ERROR_NOT_SUPPORTED, "arm64 not supported");
615 }
616 #endif /*ARM64*/
617
ta_elf_relocate(struct ta_elf * elf)618 void ta_elf_relocate(struct ta_elf *elf)
619 {
620 size_t n = 0;
621
622 if (elf->is_32bit) {
623 Elf32_Shdr *shdr = elf->shdr;
624
625 for (n = 0; n < elf->e_shnum; n++)
626 if (shdr[n].sh_type == SHT_REL)
627 e32_relocate(elf, n);
628 } else {
629 Elf64_Shdr *shdr = elf->shdr;
630
631 for (n = 0; n < elf->e_shnum; n++)
632 if (shdr[n].sh_type == SHT_RELA)
633 e64_relocate(elf, n);
634
635 }
636 }
637