1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2019, Linaro Limited 4 */ 5 6 #include <assert.h> 7 #include <ldelf.h> 8 #include <malloc.h> 9 #include <sys/queue.h> 10 #include <tee_api_types.h> 11 #include <trace.h> 12 #include <types_ext.h> 13 14 #include "ta_elf.h" 15 #include "sys.h" 16 17 static size_t mpool_size = 2 * SMALL_PAGE_SIZE; 18 static vaddr_t mpool_base; 19 20 static void __noreturn __maybe_unused dump_ta_state(struct dump_entry_arg *arg) 21 { 22 struct ta_elf *elf = TAILQ_FIRST(&main_elf_queue); 23 24 assert(elf && elf->is_main); 25 EMSG_RAW("Status of TA %pUl", (void *)&elf->uuid); 26 EMSG_RAW(" arch: %s", elf->is_32bit ? "arm" : "aarch64"); 27 28 29 ta_elf_print_mappings(&main_elf_queue, arg->num_maps, arg->maps, 30 mpool_base); 31 32 if (arg->is_arm32) 33 ta_elf_stack_trace_a32(arg->arm32.regs); 34 else 35 ta_elf_stack_trace_a64(arg->arm64.fp, arg->arm64.sp, 36 arg->arm64.pc); 37 38 sys_return_cleanup(); 39 } 40 41 /* 42 * ldelf()- Loads ELF into memory 43 * @arg: Argument passing to/from TEE Core 44 * 45 * Only called from assembly 46 */ 47 void __noreturn ldelf(struct ldelf_arg *arg); 48 void ldelf(struct ldelf_arg *arg) 49 { 50 TEE_Result res = TEE_SUCCESS; 51 struct ta_elf *elf = NULL; 52 53 DMSG("Loading TA %pUl", (void *)&arg->uuid); 54 res = sys_map_zi(mpool_size, 0, &mpool_base, 0, 0); 55 if (res) { 56 EMSG("sys_map_zi(%zu): result %"PRIx32, mpool_size, res); 57 panic(); 58 } 59 malloc_add_pool((void *)mpool_base, mpool_size); 60 61 /* Load the main binary and get a list of dependencies, if any. */ 62 ta_elf_load_main(&arg->uuid, &arg->is_32bit, &arg->entry_func, 63 &arg->stack_ptr, &arg->flags); 64 65 /* 66 * Load binaries, ta_elf_load() may add external libraries to the 67 * list, so the loop will end when all the dependencies are 68 * satisfied. 69 */ 70 TAILQ_FOREACH(elf, &main_elf_queue, link) 71 ta_elf_load_dependency(elf, arg->is_32bit); 72 73 TAILQ_FOREACH(elf, &main_elf_queue, link) { 74 ta_elf_relocate(elf); 75 ta_elf_finalize_mappings(elf); 76 } 77 78 TAILQ_FOREACH(elf, &main_elf_queue, link) 79 DMSG("ELF (%pUl) at %#"PRIxVA, 80 (void *)&elf->uuid, elf->load_addr); 81 82 #if TRACE_LEVEL >= TRACE_ERROR 83 arg->dump_entry = (vaddr_t)(void *)dump_ta_state; 84 #else 85 arg->dump_entry = 0; 86 #endif 87 88 sys_return_cleanup(); 89 } 90