diff options
Diffstat (limited to 'ldelf/ta_elf_rel.c')
-rw-r--r-- | ldelf/ta_elf_rel.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/ldelf/ta_elf_rel.c b/ldelf/ta_elf_rel.c index 0aa1b958..a757dda1 100644 --- a/ldelf/ta_elf_rel.c +++ b/ldelf/ta_elf_rel.c @@ -382,13 +382,11 @@ static void e32_relocate(struct ta_elf *elf, unsigned int rel_sidx) } #ifdef ARM64 -static void 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) +static void 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) { size_t sym_idx = 0; - const char *name = NULL; - uintptr_t val = 0; size_t name_idx = 0; sym_idx = ELF64_R_SYM(rela->r_info); @@ -399,12 +397,34 @@ static void e64_process_dyn_rela(const Elf64_Sym *sym_tab, size_t num_syms, name_idx = sym_tab[sym_idx].st_name; if (name_idx >= str_tab_size) err(TEE_ERROR_BAD_FORMAT, "Name index out of range"); - name = str_tab + name_idx; + *name = str_tab + name_idx; +} + +static void 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) +{ + const char *name = NULL; + uintptr_t val = 0; + e64_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rela, &name); resolve_sym(name, &val, NULL); *where = val; } +static void e64_process_tls_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 *mod = NULL; + const char *name = NULL; + vaddr_t symval = 0; + + e64_get_sym_name(sym_tab, num_syms, str_tab, str_tab_size, rela, &name); + ta_elf_resolve_sym(name, &symval, &mod, NULL, NULL); + *where = symval + mod->tls_tcb_offs + rela->r_addend; +} + static void e64_relocate(struct ta_elf *elf, unsigned int rel_sidx) { Elf64_Shdr *shdr = elf->shdr; @@ -509,6 +529,10 @@ static void e64_relocate(struct ta_elf *elf, unsigned int rel_sidx) e64_process_dyn_rela(sym_tab, num_syms, str_tab, str_tab_size, rela, where); break; + case R_AARCH64_TLS_TPREL: + e64_process_tls_rela(sym_tab, num_syms, str_tab, + str_tab_size, rela, where); + break; default: err(TEE_ERROR_BAD_FORMAT, "Unknown relocation type %zd", ELF64_R_TYPE(rela->r_info)); |