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 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 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 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 */ 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 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 bool *weak_undef) 191 { 192 size_t sym_idx = 0; 193 size_t name_idx = 0; 194 195 sym_idx = ELF32_R_SYM(rel->r_info); 196 if (sym_idx >= num_syms) 197 err(TEE_ERROR_BAD_FORMAT, "Symbol index out of range"); 198 sym_idx = confine_array_index(sym_idx, num_syms); 199 200 name_idx = sym_tab[sym_idx].st_name; 201 if (name_idx >= str_tab_size) 202 err(TEE_ERROR_BAD_FORMAT, "Name index out of range"); 203 *name = str_tab + name_idx; 204 205 if (!weak_undef) 206 return; 207 if (sym_tab[sym_idx].st_shndx == SHN_UNDEF && 208 ELF32_ST_BIND(sym_tab[sym_idx].st_info) == STB_WEAK) 209 *weak_undef = true; 210 else 211 *weak_undef = false; 212 } 213 214 static void resolve_sym(const char *name, vaddr_t *val, struct ta_elf **mod, 215 bool err_if_not_found) 216 { 217 TEE_Result res = ta_elf_resolve_sym(name, val, mod, NULL); 218 219 if (res) { 220 if (err_if_not_found) 221 err(res, "Symbol %s not found", name); 222 else 223 *val = 0; 224 } 225 } 226 227 static void e32_process_dyn_rel(const Elf32_Sym *sym_tab, size_t num_syms, 228 const char *str_tab, size_t str_tab_size, 229 Elf32_Rel *rel, Elf32_Addr *where) 230 { 231 const char *name = NULL; 232 vaddr_t val = 0; 233 bool weak_undef = false; 234 235 e32_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rel, &name, 236 &weak_undef); 237 resolve_sym(name, &val, NULL, !weak_undef); 238 *where = val; 239 } 240 241 static void e32_tls_get_module(const Elf32_Sym *sym_tab, size_t num_syms, 242 const char *str_tab, size_t str_tab_size, 243 Elf32_Rel *rel, struct ta_elf **mod) 244 { 245 const char *name = NULL; 246 size_t sym_idx = 0; 247 248 sym_idx = ELF32_R_SYM(rel->r_info); 249 if (sym_idx >= num_syms) 250 err(TEE_ERROR_BAD_FORMAT, "Symbol index out of range"); 251 sym_idx = confine_array_index(sym_idx, num_syms); 252 if (!sym_idx || sym_tab[sym_idx].st_shndx != SHN_UNDEF) { 253 /* No symbol, or symbol is defined in current module */ 254 return; 255 } 256 257 e32_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rel, &name, 258 NULL); 259 resolve_sym(name, NULL, mod, false); 260 } 261 262 static void e32_tls_resolve(const Elf32_Sym *sym_tab, size_t num_syms, 263 const char *str_tab, size_t str_tab_size, 264 Elf32_Rel *rel, vaddr_t *val) 265 { 266 const char *name = NULL; 267 268 e32_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rel, &name, 269 NULL); 270 resolve_sym(name, val, NULL, false); 271 } 272 273 static void e32_relocate(struct ta_elf *elf, unsigned int rel_sidx) 274 { 275 Elf32_Shdr *shdr = elf->shdr; 276 Elf32_Rel *rel = NULL; 277 Elf32_Rel *rel_end = NULL; 278 size_t sym_tab_idx = 0; 279 Elf32_Sym *sym_tab = NULL; 280 size_t num_syms = 0; 281 size_t sh_end = 0; 282 const char *str_tab = NULL; 283 size_t str_tab_size = 0; 284 285 assert(shdr[rel_sidx].sh_type == SHT_REL); 286 287 assert(shdr[rel_sidx].sh_entsize == sizeof(Elf32_Rel)); 288 289 sym_tab_idx = shdr[rel_sidx].sh_link; 290 if (sym_tab_idx) { 291 size_t str_tab_idx = 0; 292 293 if (sym_tab_idx >= elf->e_shnum) 294 err(TEE_ERROR_BAD_FORMAT, "SYMTAB index out of range"); 295 sym_tab_idx = confine_array_index(sym_tab_idx, elf->e_shnum); 296 297 assert(shdr[sym_tab_idx].sh_entsize == sizeof(Elf32_Sym)); 298 299 /* Check the address is inside ELF memory */ 300 if (ADD_OVERFLOW(shdr[sym_tab_idx].sh_addr, 301 shdr[sym_tab_idx].sh_size, &sh_end)) 302 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 303 if (sh_end >= (elf->max_addr - elf->load_addr)) 304 err(TEE_ERROR_BAD_FORMAT, "SYMTAB out of range"); 305 306 sym_tab = (Elf32_Sym *)(elf->load_addr + 307 shdr[sym_tab_idx].sh_addr); 308 309 num_syms = shdr[sym_tab_idx].sh_size / sizeof(Elf32_Sym); 310 311 str_tab_idx = shdr[sym_tab_idx].sh_link; 312 if (str_tab_idx) { 313 if (str_tab_idx >= elf->e_shnum) 314 err(TEE_ERROR_BAD_FORMAT, 315 "STRTAB index out of range"); 316 str_tab_idx = confine_array_index(str_tab_idx, 317 elf->e_shnum); 318 319 /* Check the address is inside ELF memory */ 320 if (ADD_OVERFLOW(shdr[str_tab_idx].sh_addr, 321 shdr[str_tab_idx].sh_size, &sh_end)) 322 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 323 if (sh_end >= (elf->max_addr - elf->load_addr)) 324 err(TEE_ERROR_BAD_FORMAT, 325 "STRTAB out of range"); 326 327 str_tab = (const char *)(elf->load_addr + 328 shdr[str_tab_idx].sh_addr); 329 str_tab_size = shdr[str_tab_idx].sh_size; 330 } 331 } 332 333 /* Check the address is inside TA memory */ 334 if (ADD_OVERFLOW(shdr[rel_sidx].sh_addr, 335 shdr[rel_sidx].sh_size, &sh_end)) 336 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 337 if (sh_end >= (elf->max_addr - elf->load_addr)) 338 err(TEE_ERROR_BAD_FORMAT, ".rel.*/REL out of range"); 339 rel = (Elf32_Rel *)(elf->load_addr + shdr[rel_sidx].sh_addr); 340 341 rel_end = rel + shdr[rel_sidx].sh_size / sizeof(Elf32_Rel); 342 for (; rel < rel_end; rel++) { 343 struct ta_elf *mod = NULL; 344 Elf32_Addr *where = NULL; 345 size_t sym_idx = 0; 346 vaddr_t val = 0; 347 348 /* Check the address is inside TA memory */ 349 if (rel->r_offset >= (elf->max_addr - elf->load_addr)) 350 err(TEE_ERROR_BAD_FORMAT, 351 "Relocation offset out of range"); 352 where = (Elf32_Addr *)(elf->load_addr + rel->r_offset); 353 354 switch (ELF32_R_TYPE(rel->r_info)) { 355 case R_ARM_NONE: 356 /* 357 * One would expect linker prevents such useless entry 358 * in the relocation table. We still handle this type 359 * here in case such entries exist. 360 */ 361 break; 362 case R_ARM_ABS32: 363 sym_idx = ELF32_R_SYM(rel->r_info); 364 if (sym_idx >= num_syms) 365 err(TEE_ERROR_BAD_FORMAT, 366 "Symbol index out of range"); 367 if (sym_tab[sym_idx].st_shndx == SHN_UNDEF) { 368 /* Symbol is external */ 369 e32_process_dyn_rel(sym_tab, num_syms, str_tab, 370 str_tab_size, rel, where); 371 } else { 372 *where += elf->load_addr + 373 sym_tab[sym_idx].st_value; 374 } 375 break; 376 case R_ARM_REL32: 377 sym_idx = ELF32_R_SYM(rel->r_info); 378 if (sym_idx >= num_syms) 379 err(TEE_ERROR_BAD_FORMAT, 380 "Symbol index out of range"); 381 *where += sym_tab[sym_idx].st_value - rel->r_offset; 382 break; 383 case R_ARM_RELATIVE: 384 *where += elf->load_addr; 385 break; 386 case R_ARM_GLOB_DAT: 387 case R_ARM_JUMP_SLOT: 388 if (!sym_tab) 389 err(TEE_ERROR_BAD_FORMAT, 390 "Missing symbol table"); 391 e32_process_dyn_rel(sym_tab, num_syms, str_tab, 392 str_tab_size, rel, where); 393 break; 394 case R_ARM_TLS_DTPMOD32: 395 if (!sym_tab) 396 err(TEE_ERROR_BAD_FORMAT, 397 "Missing symbol table"); 398 mod = elf; 399 e32_tls_get_module(sym_tab, num_syms, str_tab, 400 str_tab_size, rel, &mod); 401 *where = mod->tls_mod_id; 402 break; 403 case R_ARM_TLS_DTPOFF32: 404 if (!sym_tab) 405 err(TEE_ERROR_BAD_FORMAT, 406 "Missing symbol table"); 407 e32_tls_resolve(sym_tab, num_syms, str_tab, 408 str_tab_size, rel, &val); 409 *where = val; 410 break; 411 default: 412 err(TEE_ERROR_BAD_FORMAT, "Unknown relocation type %d", 413 ELF32_R_TYPE(rel->r_info)); 414 } 415 } 416 } 417 418 #ifdef ARM64 419 static void e64_get_sym_name(const Elf64_Sym *sym_tab, size_t num_syms, 420 const char *str_tab, size_t str_tab_size, 421 Elf64_Rela *rela, const char **name, 422 bool *weak_undef) 423 { 424 size_t sym_idx = 0; 425 size_t name_idx = 0; 426 427 sym_idx = ELF64_R_SYM(rela->r_info); 428 if (sym_idx >= num_syms) 429 err(TEE_ERROR_BAD_FORMAT, "Symbol index out of range"); 430 sym_idx = confine_array_index(sym_idx, num_syms); 431 432 name_idx = sym_tab[sym_idx].st_name; 433 if (name_idx >= str_tab_size) 434 err(TEE_ERROR_BAD_FORMAT, "Name index out of range"); 435 *name = str_tab + name_idx; 436 437 if (sym_tab[sym_idx].st_shndx == SHN_UNDEF && 438 ELF64_ST_BIND(sym_tab[sym_idx].st_info) == STB_WEAK) 439 *weak_undef = true; 440 else 441 *weak_undef = false; 442 } 443 444 static void e64_process_dyn_rela(const Elf64_Sym *sym_tab, size_t num_syms, 445 const char *str_tab, size_t str_tab_size, 446 Elf64_Rela *rela, Elf64_Addr *where) 447 { 448 const char *name = NULL; 449 uintptr_t val = 0; 450 bool weak_undef = false; 451 452 e64_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rela, &name, 453 &weak_undef); 454 resolve_sym(name, &val, NULL, !weak_undef); 455 *where = val; 456 } 457 458 static void e64_process_tls_tprel_rela(const Elf64_Sym *sym_tab, 459 size_t num_syms, const char *str_tab, 460 size_t str_tab_size, Elf64_Rela *rela, 461 Elf64_Addr *where, struct ta_elf *elf) 462 { 463 struct ta_elf *mod = NULL; 464 bool weak_undef = false; 465 const char *name = NULL; 466 size_t sym_idx = 0; 467 vaddr_t symval = 0; 468 469 sym_idx = ELF64_R_SYM(rela->r_info); 470 if (sym_idx) { 471 e64_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rela, 472 &name, &weak_undef); 473 resolve_sym(name, &symval, &mod, !weak_undef); 474 } else { 475 mod = elf; 476 } 477 *where = symval + mod->tls_tcb_offs + rela->r_addend; 478 } 479 480 struct tlsdesc { 481 long (*resolver)(struct tlsdesc *td); 482 long value; 483 }; 484 485 /* Helper function written in assembly due to the calling convention */ 486 long tlsdesc_resolve(struct tlsdesc *td); 487 488 static void e64_process_tlsdesc_rela(const Elf64_Sym *sym_tab, size_t num_syms, 489 const char *str_tab, size_t str_tab_size, 490 Elf64_Rela *rela, Elf64_Addr *where, 491 struct ta_elf *elf) 492 { 493 /* 494 * @where points to a pair of 64-bit words in the GOT or PLT which is 495 * mapped to a struct tlsdesc: 496 * 497 * - resolver() must return the offset of the thread-local variable 498 * relative to TPIDR_EL0. 499 * - value is implementation-dependent. The TLS_TPREL handling code is 500 * re-used to get the desired offset so that tlsdesc_resolve() just 501 * needs to return this value. 502 * 503 * Both the TA and ldelf are AArch64 so it is OK to point to a function 504 * in ldelf. 505 */ 506 *where = (Elf64_Addr)tlsdesc_resolve; 507 e64_process_tls_tprel_rela(sym_tab, num_syms, str_tab, str_tab_size, 508 rela, where + 1, elf); 509 } 510 511 static void e64_relocate(struct ta_elf *elf, unsigned int rel_sidx) 512 { 513 Elf64_Shdr *shdr = elf->shdr; 514 Elf64_Rela *rela = NULL; 515 Elf64_Rela *rela_end = NULL; 516 size_t sym_tab_idx = 0; 517 Elf64_Sym *sym_tab = NULL; 518 size_t num_syms = 0; 519 size_t sh_end = 0; 520 const char *str_tab = NULL; 521 size_t str_tab_size = 0; 522 523 assert(shdr[rel_sidx].sh_type == SHT_RELA); 524 525 assert(shdr[rel_sidx].sh_entsize == sizeof(Elf64_Rela)); 526 527 sym_tab_idx = shdr[rel_sidx].sh_link; 528 if (sym_tab_idx) { 529 size_t str_tab_idx = 0; 530 531 if (sym_tab_idx >= elf->e_shnum) 532 err(TEE_ERROR_BAD_FORMAT, "SYMTAB index out of range"); 533 sym_tab_idx = confine_array_index(sym_tab_idx, elf->e_shnum); 534 535 assert(shdr[sym_tab_idx].sh_entsize == sizeof(Elf64_Sym)); 536 537 /* Check the address is inside TA memory */ 538 if (ADD_OVERFLOW(shdr[sym_tab_idx].sh_addr, 539 shdr[sym_tab_idx].sh_size, &sh_end)) 540 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 541 if (sh_end >= (elf->max_addr - elf->load_addr)) 542 err(TEE_ERROR_BAD_FORMAT, "SYMTAB out of range"); 543 544 sym_tab = (Elf64_Sym *)(elf->load_addr + 545 shdr[sym_tab_idx].sh_addr); 546 547 num_syms = shdr[sym_tab_idx].sh_size / sizeof(Elf64_Sym); 548 549 str_tab_idx = shdr[sym_tab_idx].sh_link; 550 if (str_tab_idx) { 551 if (str_tab_idx >= elf->e_shnum) 552 err(TEE_ERROR_BAD_FORMAT, 553 "STRTAB index out of range"); 554 str_tab_idx = confine_array_index(str_tab_idx, 555 elf->e_shnum); 556 557 /* Check the address is inside ELF memory */ 558 if (ADD_OVERFLOW(shdr[str_tab_idx].sh_addr, 559 shdr[str_tab_idx].sh_size, &sh_end)) 560 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 561 if (sh_end >= (elf->max_addr - elf->load_addr)) 562 err(TEE_ERROR_BAD_FORMAT, 563 "STRTAB out of range"); 564 565 str_tab = (const char *)(elf->load_addr + 566 shdr[str_tab_idx].sh_addr); 567 str_tab_size = shdr[str_tab_idx].sh_size; 568 } 569 } 570 571 /* Check the address is inside TA memory */ 572 if (ADD_OVERFLOW(shdr[rel_sidx].sh_addr, 573 shdr[rel_sidx].sh_size, &sh_end)) 574 err(TEE_ERROR_BAD_FORMAT, "Overflow"); 575 if (sh_end >= (elf->max_addr - elf->load_addr)) 576 err(TEE_ERROR_BAD_FORMAT, ".rel.*/REL out of range"); 577 rela = (Elf64_Rela *)(elf->load_addr + shdr[rel_sidx].sh_addr); 578 579 rela_end = rela + shdr[rel_sidx].sh_size / sizeof(Elf64_Rela); 580 for (; rela < rela_end; rela++) { 581 Elf64_Addr *where = NULL; 582 size_t sym_idx = 0; 583 584 /* Check the address is inside TA memory */ 585 if (rela->r_offset >= (elf->max_addr - elf->load_addr)) 586 err(TEE_ERROR_BAD_FORMAT, 587 "Relocation offset out of range"); 588 589 where = (Elf64_Addr *)(elf->load_addr + rela->r_offset); 590 591 switch (ELF64_R_TYPE(rela->r_info)) { 592 case R_AARCH64_NONE: 593 /* 594 * One would expect linker prevents such useless entry 595 * in the relocation table. We still handle this type 596 * here in case such entries exist. 597 */ 598 break; 599 case R_AARCH64_ABS64: 600 sym_idx = ELF64_R_SYM(rela->r_info); 601 if (sym_idx >= num_syms) 602 err(TEE_ERROR_BAD_FORMAT, 603 "Symbol index out of range"); 604 sym_idx = confine_array_index(sym_idx, num_syms); 605 if (sym_tab[sym_idx].st_shndx == SHN_UNDEF) { 606 /* Symbol is external */ 607 e64_process_dyn_rela(sym_tab, num_syms, str_tab, 608 str_tab_size, rela, where); 609 } else { 610 *where = rela->r_addend + elf->load_addr + 611 sym_tab[sym_idx].st_value; 612 } 613 break; 614 case R_AARCH64_RELATIVE: 615 *where = rela->r_addend + elf->load_addr; 616 break; 617 case R_AARCH64_GLOB_DAT: 618 case R_AARCH64_JUMP_SLOT: 619 e64_process_dyn_rela(sym_tab, num_syms, str_tab, 620 str_tab_size, rela, where); 621 break; 622 case R_AARCH64_TLS_TPREL: 623 e64_process_tls_tprel_rela(sym_tab, num_syms, str_tab, 624 str_tab_size, rela, where, 625 elf); 626 break; 627 case R_AARCH64_TLSDESC: 628 e64_process_tlsdesc_rela(sym_tab, num_syms, str_tab, 629 str_tab_size, rela, where, 630 elf); 631 break; 632 default: 633 err(TEE_ERROR_BAD_FORMAT, "Unknown relocation type %zd", 634 ELF64_R_TYPE(rela->r_info)); 635 } 636 } 637 } 638 #else /*ARM64*/ 639 static void __noreturn e64_relocate(struct ta_elf *elf __unused, 640 unsigned int rel_sidx __unused) 641 { 642 err(TEE_ERROR_NOT_SUPPORTED, "arm64 not supported"); 643 } 644 #endif /*ARM64*/ 645 646 void ta_elf_relocate(struct ta_elf *elf) 647 { 648 size_t n = 0; 649 650 if (elf->is_32bit) { 651 Elf32_Shdr *shdr = elf->shdr; 652 653 for (n = 0; n < elf->e_shnum; n++) 654 if (shdr[n].sh_type == SHT_REL) 655 e32_relocate(elf, n); 656 } else { 657 Elf64_Shdr *shdr = elf->shdr; 658 659 for (n = 0; n < elf->e_shnum; n++) 660 if (shdr[n].sh_type == SHT_RELA) 661 e64_relocate(elf, n); 662 663 } 664 } 665