17509ff7cSJens Wiklander // SPDX-License-Identifier: BSD-2-Clause 27509ff7cSJens Wiklander /* 37509ff7cSJens Wiklander * Copyright (c) 2019, Linaro Limited 47509ff7cSJens Wiklander */ 57509ff7cSJens Wiklander 67509ff7cSJens Wiklander #include <assert.h> 77509ff7cSJens Wiklander #include <elf32.h> 87509ff7cSJens Wiklander #include <elf64.h> 97509ff7cSJens Wiklander #include <elf_common.h> 107509ff7cSJens Wiklander #include <string.h> 117509ff7cSJens Wiklander #include <tee_api_types.h> 127509ff7cSJens Wiklander #include <util.h> 137509ff7cSJens Wiklander 147509ff7cSJens Wiklander #include "sys.h" 157509ff7cSJens Wiklander #include "ta_elf.h" 167509ff7cSJens Wiklander 179f392760SJerome Forissier static uint32_t elf_hash(const char *name) 189f392760SJerome Forissier { 199f392760SJerome Forissier const unsigned char *p = (const unsigned char *)name; 209f392760SJerome Forissier uint32_t h = 0; 219f392760SJerome Forissier uint32_t g = 0; 229f392760SJerome Forissier 239f392760SJerome Forissier while (*p) { 249f392760SJerome Forissier h = (h << 4) + *p++; 259f392760SJerome Forissier g = h & 0xf0000000; 269f392760SJerome Forissier if (g) 279f392760SJerome Forissier h ^= g >> 24; 289f392760SJerome Forissier h &= ~g; 299f392760SJerome Forissier } 309f392760SJerome Forissier return h; 319f392760SJerome Forissier } 329f392760SJerome Forissier 337509ff7cSJens Wiklander static bool __resolve_sym(struct ta_elf *elf, unsigned int bind, 347509ff7cSJens Wiklander size_t st_shndx, size_t st_name, size_t st_value, 357509ff7cSJens Wiklander const char *name, vaddr_t *val) 367509ff7cSJens Wiklander { 377509ff7cSJens Wiklander if (bind != STB_GLOBAL) 387509ff7cSJens Wiklander return false; 397509ff7cSJens Wiklander if (st_shndx == SHN_UNDEF || st_shndx == SHN_XINDEX) 407509ff7cSJens Wiklander return false; 417509ff7cSJens Wiklander if (!st_name) 427509ff7cSJens Wiklander return false; 437509ff7cSJens Wiklander if (st_name > elf->dynstr_size) 447509ff7cSJens Wiklander err(TEE_ERROR_BAD_FORMAT, "Symbol out of range"); 457509ff7cSJens Wiklander 467509ff7cSJens Wiklander if (strcmp(name, elf->dynstr + st_name)) 477509ff7cSJens Wiklander return false; 487509ff7cSJens Wiklander 497509ff7cSJens Wiklander *val = st_value + elf->load_addr; 507509ff7cSJens Wiklander return true; 517509ff7cSJens Wiklander } 527509ff7cSJens Wiklander 53*ebef121cSJerome Forissier static TEE_Result resolve_sym_helper(uint32_t hash, const char *name, 54*ebef121cSJerome Forissier vaddr_t *val, struct ta_elf *elf) 557509ff7cSJens Wiklander { 569f392760SJerome Forissier /* 579f392760SJerome Forissier * Using uint32_t here for convenience because both Elf64_Word 589f392760SJerome Forissier * and Elf32_Word are 32-bit types 599f392760SJerome Forissier */ 609f392760SJerome Forissier uint32_t *hashtab = elf->hashtab; 619f392760SJerome Forissier uint32_t nbuckets = hashtab[0]; 629f392760SJerome Forissier uint32_t nchains = hashtab[1]; 639f392760SJerome Forissier uint32_t *bucket = &hashtab[2]; 649f392760SJerome Forissier uint32_t *chain = &bucket[nbuckets]; 65*ebef121cSJerome Forissier size_t n = 0; 669f392760SJerome Forissier 677509ff7cSJens Wiklander if (elf->is_32bit) { 687509ff7cSJens Wiklander Elf32_Sym *sym = elf->dynsymtab; 697509ff7cSJens Wiklander 709f392760SJerome Forissier for (n = bucket[hash % nbuckets]; n; n = chain[n]) { 719f392760SJerome Forissier assert(n < nchains); 727509ff7cSJens Wiklander if (__resolve_sym(elf, 737509ff7cSJens Wiklander ELF32_ST_BIND(sym[n].st_info), 747509ff7cSJens Wiklander sym[n].st_shndx, 757509ff7cSJens Wiklander sym[n].st_name, 767509ff7cSJens Wiklander sym[n].st_value, name, val)) 77c86f218cSJens Wiklander return TEE_SUCCESS; 787509ff7cSJens Wiklander } 797509ff7cSJens Wiklander } else { 807509ff7cSJens Wiklander Elf64_Sym *sym = elf->dynsymtab; 817509ff7cSJens Wiklander 829f392760SJerome Forissier for (n = bucket[hash % nbuckets]; n; n = chain[n]) { 839f392760SJerome Forissier assert(n < nchains); 847509ff7cSJens Wiklander if (__resolve_sym(elf, 857509ff7cSJens Wiklander ELF64_ST_BIND(sym[n].st_info), 867509ff7cSJens Wiklander sym[n].st_shndx, 877509ff7cSJens Wiklander sym[n].st_name, 887509ff7cSJens Wiklander sym[n].st_value, name, val)) 89c86f218cSJens Wiklander return TEE_SUCCESS; 907509ff7cSJens Wiklander } 917509ff7cSJens Wiklander } 92*ebef121cSJerome Forissier 93*ebef121cSJerome Forissier return TEE_ERROR_ITEM_NOT_FOUND; 947509ff7cSJens Wiklander } 95c86f218cSJens Wiklander 96*ebef121cSJerome Forissier TEE_Result ta_elf_resolve_sym(const char *name, vaddr_t *val, 97*ebef121cSJerome Forissier struct ta_elf *elf) 98*ebef121cSJerome Forissier { 99*ebef121cSJerome Forissier uint32_t hash = elf_hash(name); 100*ebef121cSJerome Forissier 101*ebef121cSJerome Forissier if (elf) 102*ebef121cSJerome Forissier return resolve_sym_helper(hash, name, val, elf); 103*ebef121cSJerome Forissier 104*ebef121cSJerome Forissier TAILQ_FOREACH(elf, &main_elf_queue, link) 105*ebef121cSJerome Forissier if (!resolve_sym_helper(hash, name, val, elf)) 106*ebef121cSJerome Forissier return TEE_SUCCESS; 107*ebef121cSJerome Forissier 108c86f218cSJens Wiklander return TEE_ERROR_ITEM_NOT_FOUND; 109c86f218cSJens Wiklander } 110c86f218cSJens Wiklander 111c86f218cSJens Wiklander static void resolve_sym(const char *name, vaddr_t *val) 112c86f218cSJens Wiklander { 113*ebef121cSJerome Forissier TEE_Result res = ta_elf_resolve_sym(name, val, NULL); 114c86f218cSJens Wiklander 115c86f218cSJens Wiklander if (res) 116c86f218cSJens Wiklander err(res, "Symbol %s not found", name); 1177509ff7cSJens Wiklander } 1187509ff7cSJens Wiklander 1197509ff7cSJens Wiklander static void e32_process_dyn_rel(const Elf32_Sym *sym_tab, size_t num_syms, 1207509ff7cSJens Wiklander const char *str_tab, size_t str_tab_size, 1217509ff7cSJens Wiklander Elf32_Rel *rel, Elf32_Addr *where) 1227509ff7cSJens Wiklander { 1237509ff7cSJens Wiklander size_t sym_idx = 0; 1247509ff7cSJens Wiklander const char *name = NULL; 1257509ff7cSJens Wiklander vaddr_t val = 0; 1267509ff7cSJens Wiklander size_t name_idx = 0; 1277509ff7cSJens Wiklander 1287509ff7cSJens Wiklander sym_idx = ELF32_R_SYM(rel->r_info); 1297509ff7cSJens Wiklander assert(sym_idx < num_syms); 1307509ff7cSJens Wiklander 1317509ff7cSJens Wiklander name_idx = sym_tab[sym_idx].st_name; 1327509ff7cSJens Wiklander assert(name_idx < str_tab_size); 1337509ff7cSJens Wiklander name = str_tab + name_idx; 1347509ff7cSJens Wiklander 1357509ff7cSJens Wiklander resolve_sym(name, &val); 1367509ff7cSJens Wiklander *where = val; 1377509ff7cSJens Wiklander } 1387509ff7cSJens Wiklander 1397509ff7cSJens Wiklander static void e32_relocate(struct ta_elf *elf, unsigned int rel_sidx) 1407509ff7cSJens Wiklander { 1417509ff7cSJens Wiklander Elf32_Shdr *shdr = elf->shdr; 1427509ff7cSJens Wiklander Elf32_Rel *rel = NULL; 1437509ff7cSJens Wiklander Elf32_Rel *rel_end = NULL; 1447509ff7cSJens Wiklander size_t sym_tab_idx = 0; 1457509ff7cSJens Wiklander Elf32_Sym *sym_tab = NULL; 1467509ff7cSJens Wiklander size_t num_syms = 0; 1477509ff7cSJens Wiklander size_t sh_end = 0; 1487509ff7cSJens Wiklander const char *str_tab = NULL; 1497509ff7cSJens Wiklander size_t str_tab_size = 0; 1507509ff7cSJens Wiklander 1517509ff7cSJens Wiklander assert(shdr[rel_sidx].sh_type == SHT_REL); 1527509ff7cSJens Wiklander 1537509ff7cSJens Wiklander assert(shdr[rel_sidx].sh_entsize == sizeof(Elf32_Rel)); 1547509ff7cSJens Wiklander 1557509ff7cSJens Wiklander sym_tab_idx = shdr[rel_sidx].sh_link; 1567509ff7cSJens Wiklander if (sym_tab_idx) { 1577509ff7cSJens Wiklander size_t str_tab_idx = 0; 1587509ff7cSJens Wiklander 1597509ff7cSJens Wiklander assert(sym_tab_idx < elf->e_shnum); 1607509ff7cSJens Wiklander 1617509ff7cSJens Wiklander assert(shdr[sym_tab_idx].sh_entsize == sizeof(Elf32_Sym)); 1627509ff7cSJens Wiklander 1637509ff7cSJens Wiklander /* Check the address is inside ELF memory */ 1647509ff7cSJens Wiklander if (ADD_OVERFLOW(shdr[sym_tab_idx].sh_addr, 1657509ff7cSJens Wiklander shdr[sym_tab_idx].sh_size, &sh_end)) 1667509ff7cSJens Wiklander err(TEE_ERROR_SECURITY, "Overflow"); 1677509ff7cSJens Wiklander assert(sh_end < (elf->max_addr - elf->load_addr)); 1687509ff7cSJens Wiklander 1697509ff7cSJens Wiklander sym_tab = (Elf32_Sym *)(elf->load_addr + 1707509ff7cSJens Wiklander shdr[sym_tab_idx].sh_addr); 1717509ff7cSJens Wiklander 1727509ff7cSJens Wiklander num_syms = shdr[sym_tab_idx].sh_size / sizeof(Elf32_Sym); 1737509ff7cSJens Wiklander 1747509ff7cSJens Wiklander str_tab_idx = shdr[sym_tab_idx].sh_link; 1757509ff7cSJens Wiklander if (str_tab_idx) { 1767509ff7cSJens Wiklander /* Check the address is inside ELF memory */ 1777509ff7cSJens Wiklander if (ADD_OVERFLOW(shdr[str_tab_idx].sh_addr, 1787509ff7cSJens Wiklander shdr[str_tab_idx].sh_size, &sh_end)) 1797509ff7cSJens Wiklander err(TEE_ERROR_SECURITY, "Overflow"); 1807509ff7cSJens Wiklander assert(sh_end < (elf->max_addr - elf->load_addr)); 1817509ff7cSJens Wiklander 1827509ff7cSJens Wiklander str_tab = (const char *)(elf->load_addr + 1837509ff7cSJens Wiklander shdr[str_tab_idx].sh_addr); 1847509ff7cSJens Wiklander str_tab_size = shdr[str_tab_idx].sh_size; 1857509ff7cSJens Wiklander } 1867509ff7cSJens Wiklander } 1877509ff7cSJens Wiklander 1887509ff7cSJens Wiklander /* Check the address is inside TA memory */ 1897509ff7cSJens Wiklander assert(shdr[rel_sidx].sh_addr < (elf->max_addr - elf->load_addr)); 1907509ff7cSJens Wiklander rel = (Elf32_Rel *)(elf->load_addr + shdr[rel_sidx].sh_addr); 1917509ff7cSJens Wiklander 1927509ff7cSJens Wiklander /* Check the address is inside TA memory */ 1937509ff7cSJens Wiklander if (ADD_OVERFLOW(shdr[rel_sidx].sh_addr, shdr[rel_sidx].sh_size, 1947509ff7cSJens Wiklander &sh_end)) 1957509ff7cSJens Wiklander err(TEE_ERROR_SECURITY, "Overflow"); 1967509ff7cSJens Wiklander assert(sh_end < (elf->max_addr - elf->load_addr)); 1977509ff7cSJens Wiklander rel_end = rel + shdr[rel_sidx].sh_size / sizeof(Elf32_Rel); 1987509ff7cSJens Wiklander for (; rel < rel_end; rel++) { 1997509ff7cSJens Wiklander Elf32_Addr *where = NULL; 2007509ff7cSJens Wiklander size_t sym_idx = 0; 2017509ff7cSJens Wiklander 2027509ff7cSJens Wiklander /* Check the address is inside TA memory */ 2037509ff7cSJens Wiklander assert(rel->r_offset < (elf->max_addr - elf->load_addr)); 2047509ff7cSJens Wiklander where = (Elf32_Addr *)(elf->load_addr + rel->r_offset); 2057509ff7cSJens Wiklander 2067509ff7cSJens Wiklander switch (ELF32_R_TYPE(rel->r_info)) { 2077509ff7cSJens Wiklander case R_ARM_ABS32: 2087509ff7cSJens Wiklander sym_idx = ELF32_R_SYM(rel->r_info); 2097509ff7cSJens Wiklander assert(sym_idx < num_syms); 2107509ff7cSJens Wiklander if (sym_tab[sym_idx].st_shndx == SHN_UNDEF) { 2117509ff7cSJens Wiklander /* Symbol is external */ 2127509ff7cSJens Wiklander e32_process_dyn_rel(sym_tab, num_syms, str_tab, 2137509ff7cSJens Wiklander str_tab_size, rel, where); 2147509ff7cSJens Wiklander } else { 2157509ff7cSJens Wiklander *where += elf->load_addr + 2167509ff7cSJens Wiklander sym_tab[sym_idx].st_value; 2177509ff7cSJens Wiklander } 2187509ff7cSJens Wiklander break; 2197509ff7cSJens Wiklander case R_ARM_REL32: 2207509ff7cSJens Wiklander sym_idx = ELF32_R_SYM(rel->r_info); 2217509ff7cSJens Wiklander assert(sym_idx < num_syms); 2227509ff7cSJens Wiklander *where += sym_tab[sym_idx].st_value - rel->r_offset; 2237509ff7cSJens Wiklander break; 2247509ff7cSJens Wiklander case R_ARM_RELATIVE: 2257509ff7cSJens Wiklander *where += elf->load_addr; 2267509ff7cSJens Wiklander break; 2277509ff7cSJens Wiklander case R_ARM_GLOB_DAT: 2287509ff7cSJens Wiklander case R_ARM_JUMP_SLOT: 2297509ff7cSJens Wiklander e32_process_dyn_rel(sym_tab, num_syms, str_tab, 2307509ff7cSJens Wiklander str_tab_size, rel, where); 2317509ff7cSJens Wiklander break; 2327509ff7cSJens Wiklander default: 2337509ff7cSJens Wiklander err(TEE_ERROR_BAD_FORMAT, "Unknown relocation type %d", 2347509ff7cSJens Wiklander ELF32_R_TYPE(rel->r_info)); 2357509ff7cSJens Wiklander } 2367509ff7cSJens Wiklander } 2377509ff7cSJens Wiklander } 2387509ff7cSJens Wiklander 2397509ff7cSJens Wiklander #ifdef ARM64 2407509ff7cSJens Wiklander static void e64_process_dyn_rela(const Elf64_Sym *sym_tab, size_t num_syms, 2417509ff7cSJens Wiklander const char *str_tab, size_t str_tab_size, 2427509ff7cSJens Wiklander Elf64_Rela *rela, Elf64_Addr *where) 2437509ff7cSJens Wiklander { 2447509ff7cSJens Wiklander size_t sym_idx = 0; 2457509ff7cSJens Wiklander const char *name = NULL; 2467509ff7cSJens Wiklander uintptr_t val = 0; 2477509ff7cSJens Wiklander size_t name_idx = 0; 2487509ff7cSJens Wiklander 2497509ff7cSJens Wiklander sym_idx = ELF64_R_SYM(rela->r_info); 2507509ff7cSJens Wiklander assert(sym_idx < num_syms); 2517509ff7cSJens Wiklander 2527509ff7cSJens Wiklander name_idx = sym_tab[sym_idx].st_name; 2537509ff7cSJens Wiklander assert(name_idx < str_tab_size); 2547509ff7cSJens Wiklander name = str_tab + name_idx; 2557509ff7cSJens Wiklander 2567509ff7cSJens Wiklander resolve_sym(name, &val); 2577509ff7cSJens Wiklander *where = val; 2587509ff7cSJens Wiklander } 2597509ff7cSJens Wiklander 2607509ff7cSJens Wiklander static void e64_relocate(struct ta_elf *elf, unsigned int rel_sidx) 2617509ff7cSJens Wiklander { 2627509ff7cSJens Wiklander Elf64_Shdr *shdr = elf->shdr; 2637509ff7cSJens Wiklander Elf64_Rela *rela = NULL; 2647509ff7cSJens Wiklander Elf64_Rela *rela_end = NULL; 2657509ff7cSJens Wiklander size_t sym_tab_idx = 0; 2667509ff7cSJens Wiklander Elf64_Sym *sym_tab = NULL; 2677509ff7cSJens Wiklander size_t num_syms = 0; 2687509ff7cSJens Wiklander size_t sh_end = 0; 2697509ff7cSJens Wiklander const char *str_tab = NULL; 2707509ff7cSJens Wiklander size_t str_tab_size = 0; 2717509ff7cSJens Wiklander 2727509ff7cSJens Wiklander assert(shdr[rel_sidx].sh_type == SHT_RELA); 2737509ff7cSJens Wiklander 2747509ff7cSJens Wiklander assert(shdr[rel_sidx].sh_entsize == sizeof(Elf64_Rela)); 2757509ff7cSJens Wiklander 2767509ff7cSJens Wiklander sym_tab_idx = shdr[rel_sidx].sh_link; 2777509ff7cSJens Wiklander if (sym_tab_idx) { 2787509ff7cSJens Wiklander size_t str_tab_idx = 0; 2797509ff7cSJens Wiklander 2807509ff7cSJens Wiklander assert(sym_tab_idx < elf->e_shnum); 2817509ff7cSJens Wiklander 2827509ff7cSJens Wiklander assert(shdr[sym_tab_idx].sh_entsize == sizeof(Elf64_Sym)); 2837509ff7cSJens Wiklander 2847509ff7cSJens Wiklander /* Check the address is inside TA memory */ 2857509ff7cSJens Wiklander if (ADD_OVERFLOW(shdr[sym_tab_idx].sh_addr, 2867509ff7cSJens Wiklander shdr[sym_tab_idx].sh_size, &sh_end)) 2877509ff7cSJens Wiklander err(TEE_ERROR_SECURITY, "Overflow"); 2887509ff7cSJens Wiklander assert(sh_end < (elf->max_addr - elf->load_addr)); 2897509ff7cSJens Wiklander 2907509ff7cSJens Wiklander sym_tab = (Elf64_Sym *)(elf->load_addr + 2917509ff7cSJens Wiklander shdr[sym_tab_idx].sh_addr); 2927509ff7cSJens Wiklander 2937509ff7cSJens Wiklander num_syms = shdr[sym_tab_idx].sh_size / sizeof(Elf64_Sym); 2947509ff7cSJens Wiklander 2957509ff7cSJens Wiklander str_tab_idx = shdr[sym_tab_idx].sh_link; 2967509ff7cSJens Wiklander if (str_tab_idx) { 2977509ff7cSJens Wiklander /* Check the address is inside ELF memory */ 2987509ff7cSJens Wiklander if (ADD_OVERFLOW(shdr[str_tab_idx].sh_addr, 2997509ff7cSJens Wiklander shdr[str_tab_idx].sh_size, &sh_end)) 3007509ff7cSJens Wiklander err(TEE_ERROR_SECURITY, "Overflow"); 3017509ff7cSJens Wiklander assert(sh_end < (elf->max_addr - elf->load_addr)); 3027509ff7cSJens Wiklander 3037509ff7cSJens Wiklander str_tab = (const char *)(elf->load_addr + 3047509ff7cSJens Wiklander shdr[str_tab_idx].sh_addr); 3057509ff7cSJens Wiklander str_tab_size = shdr[str_tab_idx].sh_size; 3067509ff7cSJens Wiklander } 3077509ff7cSJens Wiklander } 3087509ff7cSJens Wiklander 3097509ff7cSJens Wiklander /* Check the address is inside TA memory */ 3107509ff7cSJens Wiklander assert(shdr[rel_sidx].sh_addr < (elf->max_addr - elf->load_addr)); 3117509ff7cSJens Wiklander rela = (Elf64_Rela *)(elf->load_addr + shdr[rel_sidx].sh_addr); 3127509ff7cSJens Wiklander 3137509ff7cSJens Wiklander /* Check the address is inside TA memory */ 3147509ff7cSJens Wiklander if (ADD_OVERFLOW(shdr[rel_sidx].sh_addr, shdr[rel_sidx].sh_size, 3157509ff7cSJens Wiklander &sh_end)) 3167509ff7cSJens Wiklander err(TEE_ERROR_SECURITY, "Overflow"); 3177509ff7cSJens Wiklander assert(sh_end < (elf->max_addr - elf->load_addr)); 3187509ff7cSJens Wiklander rela_end = rela + shdr[rel_sidx].sh_size / sizeof(Elf64_Rela); 3197509ff7cSJens Wiklander for (; rela < rela_end; rela++) { 3207509ff7cSJens Wiklander Elf64_Addr *where = NULL; 3217509ff7cSJens Wiklander size_t sym_idx = 0; 3227509ff7cSJens Wiklander 3237509ff7cSJens Wiklander /* Check the address is inside TA memory */ 3247509ff7cSJens Wiklander assert(rela->r_offset < (elf->max_addr - elf->load_addr)); 3257509ff7cSJens Wiklander 3267509ff7cSJens Wiklander where = (Elf64_Addr *)(elf->load_addr + rela->r_offset); 3277509ff7cSJens Wiklander 3287509ff7cSJens Wiklander switch (ELF64_R_TYPE(rela->r_info)) { 3297509ff7cSJens Wiklander case R_AARCH64_ABS64: 3307509ff7cSJens Wiklander sym_idx = ELF64_R_SYM(rela->r_info); 3317509ff7cSJens Wiklander assert(sym_idx < num_syms); 3327509ff7cSJens Wiklander if (sym_tab[sym_idx].st_shndx == SHN_UNDEF) { 3337509ff7cSJens Wiklander /* Symbol is external */ 3347509ff7cSJens Wiklander e64_process_dyn_rela(sym_tab, num_syms, str_tab, 3357509ff7cSJens Wiklander str_tab_size, rela, where); 3367509ff7cSJens Wiklander } else { 3377509ff7cSJens Wiklander *where = rela->r_addend + elf->load_addr + 3387509ff7cSJens Wiklander sym_tab[sym_idx].st_value; 3397509ff7cSJens Wiklander } 3407509ff7cSJens Wiklander break; 3417509ff7cSJens Wiklander case R_AARCH64_RELATIVE: 3427509ff7cSJens Wiklander *where = rela->r_addend + elf->load_addr; 3437509ff7cSJens Wiklander break; 3447509ff7cSJens Wiklander case R_AARCH64_GLOB_DAT: 3457509ff7cSJens Wiklander case R_AARCH64_JUMP_SLOT: 3467509ff7cSJens Wiklander e64_process_dyn_rela(sym_tab, num_syms, str_tab, 3477509ff7cSJens Wiklander str_tab_size, rela, where); 3487509ff7cSJens Wiklander break; 3497509ff7cSJens Wiklander default: 3507509ff7cSJens Wiklander err(TEE_ERROR_BAD_FORMAT, "Unknown relocation type %zd", 3517509ff7cSJens Wiklander ELF64_R_TYPE(rela->r_info)); 3527509ff7cSJens Wiklander } 3537509ff7cSJens Wiklander } 3547509ff7cSJens Wiklander } 3557509ff7cSJens Wiklander #else /*ARM64*/ 3567509ff7cSJens Wiklander static void e64_relocate(struct ta_elf *elf __unused, 3577509ff7cSJens Wiklander unsigned int rel_sidx __unused) 3587509ff7cSJens Wiklander { 3597509ff7cSJens Wiklander err(TEE_ERROR_NOT_SUPPORTED, "arm64 not supported"); 3607509ff7cSJens Wiklander } 3617509ff7cSJens Wiklander #endif /*ARM64*/ 3627509ff7cSJens Wiklander 3637509ff7cSJens Wiklander void ta_elf_relocate(struct ta_elf *elf) 3647509ff7cSJens Wiklander { 3657509ff7cSJens Wiklander size_t n = 0; 3667509ff7cSJens Wiklander 3677509ff7cSJens Wiklander if (elf->is_32bit) { 3687509ff7cSJens Wiklander Elf32_Shdr *shdr = elf->shdr; 3697509ff7cSJens Wiklander 3707509ff7cSJens Wiklander for (n = 0; n < elf->e_shnum; n++) 3717509ff7cSJens Wiklander if (shdr[n].sh_type == SHT_REL) 3727509ff7cSJens Wiklander e32_relocate(elf, n); 3737509ff7cSJens Wiklander } else { 3747509ff7cSJens Wiklander Elf64_Shdr *shdr = elf->shdr; 3757509ff7cSJens Wiklander 3767509ff7cSJens Wiklander for (n = 0; n < elf->e_shnum; n++) 3777509ff7cSJens Wiklander if (shdr[n].sh_type == SHT_RELA) 3787509ff7cSJens Wiklander e64_relocate(elf, n); 3797509ff7cSJens Wiklander 3807509ff7cSJens Wiklander } 3817509ff7cSJens Wiklander } 382