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