aboutsummaryrefslogtreecommitdiff
path: root/ldelf/ta_elf_rel.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldelf/ta_elf_rel.c')
-rw-r--r--ldelf/ta_elf_rel.c36
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));