xref: /optee_os/ldelf/main.c (revision 0242833aad7b016d788bfc9ab49140e42ba54182)
17509ff7cSJens Wiklander // SPDX-License-Identifier: BSD-2-Clause
27509ff7cSJens Wiklander /*
37509ff7cSJens Wiklander  * Copyright (c) 2019, Linaro Limited
47509ff7cSJens Wiklander  */
57509ff7cSJens Wiklander 
665137432SJens Wiklander #include <assert.h>
77509ff7cSJens Wiklander #include <ldelf.h>
87509ff7cSJens Wiklander #include <malloc.h>
97509ff7cSJens Wiklander #include <sys/queue.h>
107509ff7cSJens Wiklander #include <tee_api_types.h>
117509ff7cSJens Wiklander #include <trace.h>
127509ff7cSJens Wiklander #include <types_ext.h>
137509ff7cSJens Wiklander 
147509ff7cSJens Wiklander #include "ta_elf.h"
157509ff7cSJens Wiklander #include "sys.h"
167509ff7cSJens Wiklander 
177509ff7cSJens Wiklander static size_t mpool_size = 2 * SMALL_PAGE_SIZE;
187509ff7cSJens Wiklander static vaddr_t mpool_base;
197509ff7cSJens Wiklander 
2065137432SJens Wiklander static void __noreturn __maybe_unused dump_ta_state(struct dump_entry_arg *arg)
2165137432SJens Wiklander {
2265137432SJens Wiklander 	struct ta_elf *elf = TAILQ_FIRST(&main_elf_queue);
2365137432SJens Wiklander 
2465137432SJens Wiklander 	assert(elf && elf->is_main);
2565137432SJens Wiklander 	EMSG_RAW("Status of TA %pUl", (void *)&elf->uuid);
2665137432SJens Wiklander 	EMSG_RAW(" arch: %s", elf->is_32bit ? "arm" : "aarch64");
2765137432SJens Wiklander 
2865137432SJens Wiklander 
29*0242833aSJens Wiklander 	ta_elf_print_mappings(&main_elf_queue, arg->num_maps, arg->maps,
30*0242833aSJens Wiklander 			      mpool_base);
31*0242833aSJens Wiklander 
32*0242833aSJens Wiklander 	if (arg->is_arm32)
33*0242833aSJens Wiklander 		ta_elf_stack_trace_a32(arg->arm32.regs);
34*0242833aSJens Wiklander 	else
35*0242833aSJens Wiklander 		ta_elf_stack_trace_a64(arg->arm64.fp, arg->arm64.sp,
36*0242833aSJens Wiklander 				       arg->arm64.pc);
37*0242833aSJens Wiklander 
3865137432SJens Wiklander 	sys_return_cleanup();
3965137432SJens Wiklander }
4065137432SJens Wiklander 
417509ff7cSJens Wiklander /*
427509ff7cSJens Wiklander  * ldelf()- Loads ELF into memory
437509ff7cSJens Wiklander  * @arg:	Argument passing to/from TEE Core
447509ff7cSJens Wiklander  *
457509ff7cSJens Wiklander  * Only called from assembly
467509ff7cSJens Wiklander  */
477509ff7cSJens Wiklander void __noreturn ldelf(struct ldelf_arg *arg);
487509ff7cSJens Wiklander void ldelf(struct ldelf_arg *arg)
497509ff7cSJens Wiklander {
507509ff7cSJens Wiklander 	TEE_Result res = TEE_SUCCESS;
517509ff7cSJens Wiklander 	struct ta_elf *elf = NULL;
527509ff7cSJens Wiklander 
537509ff7cSJens Wiklander 	DMSG("Loading TA %pUl", (void *)&arg->uuid);
547509ff7cSJens Wiklander 	res = sys_map_zi(mpool_size, 0, &mpool_base, 0, 0);
557509ff7cSJens Wiklander 	if (res) {
567509ff7cSJens Wiklander 		EMSG("sys_map_zi(%zu): result %"PRIx32, mpool_size, res);
577509ff7cSJens Wiklander 		panic();
587509ff7cSJens Wiklander 	}
597509ff7cSJens Wiklander 	malloc_add_pool((void *)mpool_base, mpool_size);
607509ff7cSJens Wiklander 
617509ff7cSJens Wiklander 	/* Load the main binary and get a list of dependencies, if any. */
627509ff7cSJens Wiklander 	ta_elf_load_main(&arg->uuid, &arg->is_32bit, &arg->entry_func,
637509ff7cSJens Wiklander 			 &arg->stack_ptr, &arg->flags);
647509ff7cSJens Wiklander 
657509ff7cSJens Wiklander 	/*
667509ff7cSJens Wiklander 	 * Load binaries, ta_elf_load() may add external libraries to the
677509ff7cSJens Wiklander 	 * list, so the loop will end when all the dependencies are
687509ff7cSJens Wiklander 	 * satisfied.
697509ff7cSJens Wiklander 	 */
707509ff7cSJens Wiklander 	TAILQ_FOREACH(elf, &main_elf_queue, link)
717509ff7cSJens Wiklander 		ta_elf_load_dependency(elf, arg->is_32bit);
727509ff7cSJens Wiklander 
737509ff7cSJens Wiklander 	TAILQ_FOREACH(elf, &main_elf_queue, link) {
747509ff7cSJens Wiklander 		ta_elf_relocate(elf);
757509ff7cSJens Wiklander 		ta_elf_finalize_mappings(elf);
767509ff7cSJens Wiklander 	}
777509ff7cSJens Wiklander 
787509ff7cSJens Wiklander 	TAILQ_FOREACH(elf, &main_elf_queue, link)
797509ff7cSJens Wiklander 		DMSG("ELF (%pUl) at %#"PRIxVA,
807509ff7cSJens Wiklander 		     (void *)&elf->uuid, elf->load_addr);
817509ff7cSJens Wiklander 
8265137432SJens Wiklander #if TRACE_LEVEL >= TRACE_ERROR
8365137432SJens Wiklander 	arg->dump_entry = (vaddr_t)(void *)dump_ta_state;
8465137432SJens Wiklander #else
8565137432SJens Wiklander 	arg->dump_entry = 0;
8665137432SJens Wiklander #endif
8765137432SJens Wiklander 
887509ff7cSJens Wiklander 	sys_return_cleanup();
897509ff7cSJens Wiklander }
90