xref: /optee_os/ldelf/main.c (revision 3dd0e94e9ea7b3baf41bfa7f7182765ec63e02f1)
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