Skip to content

Commit

Permalink
core: arm64: support relocation type R_AARCH64_ABS64 (257)
Browse files Browse the repository at this point in the history
If a 64-bit TA contains relocations of type R_AARCH64_ABS64, OP-TEE
refuses to load it and logs the following error:

  ERROR:   TEE-CORE: Unknown relocation type 257

This relocation type does not seem to happen in our test applications,
but someone has experienced the issue after linking a TA against a
third-party static library [1]. I could reproduce the issue by
compiling the hello_world TA with -fPIC instead of -fpie. This simple
change generates *one* R_AARCH64_ABS64 in the TA ELF file.

This commit adds the necessary code to support R_AARCH64_ABS64.

[1] OP-TEE#1399

Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (qemu_v8)
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
  • Loading branch information
jforissier committed Mar 22, 2017
1 parent 6a214ba commit ef53fb0
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
1 change: 1 addition & 0 deletions core/arch/arm/kernel/elf_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,7 @@ typedef struct {
#define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */
#define R_386_IRELATIVE 42 /* PLT entry resolved indirectly at runtime */

#define R_AARCH64_ABS64 257
#define R_AARCH64_RELATIVE 1027

#define R_ARM_NONE 0 /* No relocation. */
Expand Down
33 changes: 33 additions & 0 deletions core/arch/arm/kernel/elf_load.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,16 +499,41 @@ static TEE_Result e32_process_rel(struct elf_load_state *state, size_t rel_sidx,
static TEE_Result e64_process_rel(struct elf_load_state *state,
size_t rel_sidx, vaddr_t vabase)
{
Elf64_Ehdr *ehdr = state->ehdr;
Elf64_Shdr *shdr = state->shdr;
Elf64_Rela *rela;
Elf64_Rela *rela_end;
size_t sym_tab_idx;
Elf64_Sym *sym_tab = NULL;
size_t num_syms = 0;

if (shdr[rel_sidx].sh_type != SHT_RELA)
return TEE_ERROR_NOT_IMPLEMENTED;

if (shdr[rel_sidx].sh_entsize != sizeof(Elf64_Rela))
return TEE_ERROR_BAD_FORMAT;

sym_tab_idx = shdr[rel_sidx].sh_link;
if (sym_tab_idx) {
if (sym_tab_idx >= ehdr->e_shnum)
return TEE_ERROR_BAD_FORMAT;

if (shdr[sym_tab_idx].sh_entsize != sizeof(Elf64_Sym))
return TEE_ERROR_BAD_FORMAT;

/* Check the address is inside TA memory */
if (shdr[sym_tab_idx].sh_addr > state->vasize ||
(shdr[sym_tab_idx].sh_addr +
shdr[sym_tab_idx].sh_size) > state->vasize)
return TEE_ERROR_BAD_FORMAT;

sym_tab = (Elf64_Sym *)(vabase + shdr[sym_tab_idx].sh_addr);
if (!ALIGNMENT_IS_OK(sym_tab, Elf64_Sym))
return TEE_ERROR_BAD_FORMAT;

num_syms = shdr[sym_tab_idx].sh_size / sizeof(Elf64_Sym);
}

/* Check the address is inside TA memory */
if (shdr[rel_sidx].sh_addr >= state->vasize)
return TEE_ERROR_BAD_FORMAT;
Expand All @@ -522,6 +547,7 @@ static TEE_Result e64_process_rel(struct elf_load_state *state,
rela_end = rela + shdr[rel_sidx].sh_size / sizeof(Elf64_Rela);
for (; rela < rela_end; rela++) {
Elf64_Addr *where;
size_t sym_idx;

/* Check the address is inside TA memory */
if (rela->r_offset >= state->vasize)
Expand All @@ -532,6 +558,13 @@ static TEE_Result e64_process_rel(struct elf_load_state *state,
return TEE_ERROR_BAD_FORMAT;

switch (ELF64_R_TYPE(rela->r_info)) {
case R_AARCH64_ABS64:
sym_idx = ELF64_R_SYM(rela->r_info);
if (sym_idx > num_syms)
return TEE_ERROR_BAD_FORMAT;
*where = rela->r_addend + sym_tab[sym_idx].st_value +
vabase;
break;
case R_AARCH64_RELATIVE:
*where = rela->r_addend + vabase;
break;
Expand Down

0 comments on commit ef53fb0

Please sign in to comment.