xref: /optee_os/ldelf/ta_elf.h (revision 4af447d4084e293800d4e463d65003c016b91f29)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2019, Linaro Limited
4  */
5 
6 #ifndef TA_ELF_H
7 #define TA_ELF_H
8 
9 #include <ldelf.h>
10 #include <stdarg.h>
11 #include <sys/queue.h>
12 #include <tee_api_types.h>
13 #include <types_ext.h>
14 
15 struct segment {
16 	size_t offset;
17 	size_t vaddr;
18 	size_t filesz;
19 	size_t memsz;
20 	size_t flags;
21 	size_t align;
22 	bool remapped_writeable;
23 	TAILQ_ENTRY(segment) link;
24 };
25 
26 TAILQ_HEAD(segment_head, segment);
27 
28 struct ta_elf {
29 	bool is_main;
30 	bool is_32bit;	/* Initialized from Elf32_Ehdr/Elf64_Ehdr */
31 	bool is_legacy;
32 
33 	vaddr_t load_addr;
34 	vaddr_t max_addr;
35 	vaddr_t max_offs;
36 
37 	vaddr_t ehdr_addr;
38 
39 	/* Initialized from Elf32_Ehdr/Elf64_Ehdr */
40 	vaddr_t e_entry;
41 	vaddr_t e_phoff;
42 	vaddr_t e_shoff;
43 	unsigned int e_phnum;
44 	unsigned int e_shnum;
45 	unsigned int e_phentsize;
46 	unsigned int e_shentsize;
47 
48 	void *phdr;
49 	void *shdr;
50 	/*
51 	 * dynsymtab and dynstr are used for external symbols, they may hold
52 	 * other symbols too.
53 	 */
54 	void *dynsymtab;
55 	size_t num_dynsyms;
56 	const char *dynstr;
57 	size_t dynstr_size;
58 
59 	/* DT_HASH hash table for faster resolution of external symbols */
60 	void *hashtab;
61 
62 	/* DT_SONAME */
63 	char *soname;
64 
65 	struct segment_head segs;
66 
67 	vaddr_t exidx_start;
68 	size_t exidx_size;
69 
70 	/* Thread Local Storage */
71 
72 	size_t tls_mod_id;
73 	/* PT_TLS segment */
74 	vaddr_t tls_start;
75 	size_t tls_filesz; /* Covers the .tdata section */
76 	size_t tls_memsz; /* Covers the .tdata and .tbss sections */
77 #ifdef ARM64
78 	/* Offset of the copy of the TLS block in the TLS area of the TCB */
79 	size_t tls_tcb_offs;
80 #endif
81 
82 	uint32_t handle;
83 
84 	struct ta_head *head;
85 
86 	TEE_UUID uuid;
87 	TAILQ_ENTRY(ta_elf) link;
88 };
89 
90 TAILQ_HEAD(ta_elf_queue, ta_elf);
91 
92 typedef void (*print_func_t)(void *pctx, const char *fmt, va_list ap)
93 	__printf(2, 0);
94 
95 extern struct ta_elf_queue main_elf_queue;
96 struct ta_elf *ta_elf_find_elf(const TEE_UUID *uuid);
97 
98 void ta_elf_load_main(const TEE_UUID *uuid, uint32_t *is_32bit, uint64_t *sp,
99 		      uint32_t *ta_flags);
100 void ta_elf_finalize_load_main(uint64_t *entry);
101 void ta_elf_load_dependency(struct ta_elf *elf, bool is_32bit);
102 void ta_elf_relocate(struct ta_elf *elf);
103 void ta_elf_finalize_mappings(struct ta_elf *elf);
104 
105 void ta_elf_print_mappings(void *pctx, print_func_t print_func,
106 			   struct ta_elf_queue *elf_queue, size_t num_maps,
107 			   struct dump_map *maps, vaddr_t mpool_base);
108 
109 #ifdef CFG_UNWIND
110 void ta_elf_stack_trace_a32(uint32_t regs[16]);
111 void ta_elf_stack_trace_a64(uint64_t fp, uint64_t sp, uint64_t pc);
112 #else
113 static inline void ta_elf_stack_trace_a32(uint32_t regs[16] __unused) { }
114 static inline void ta_elf_stack_trace_a64(uint64_t fp __unused,
115 					  uint64_t sp __unused,
116 					  uint64_t pc __unused) { }
117 #endif /*CFG_UNWIND*/
118 
119 TEE_Result ta_elf_resolve_sym(const char *name, vaddr_t *val,
120 			      struct ta_elf **found_elf, struct ta_elf *elf);
121 TEE_Result ta_elf_add_library(const TEE_UUID *uuid);
122 TEE_Result ta_elf_set_init_fini_info_compat(bool is_32bit);
123 TEE_Result ta_elf_set_elf_phdr_info(bool is_32bit);
124 
125 #endif /*TA_ELF_H*/
126