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 bool bti_enabled;
33
34 vaddr_t load_addr;
35 vaddr_t max_addr;
36 vaddr_t max_offs;
37
38 vaddr_t ehdr_addr;
39
40 /* Initialized from Elf32_Ehdr/Elf64_Ehdr */
41 vaddr_t e_entry;
42 vaddr_t e_phoff;
43 vaddr_t e_shoff;
44 unsigned int e_phnum;
45 unsigned int e_shnum;
46 unsigned int e_phentsize;
47 unsigned int e_shentsize;
48
49 void *phdr;
50 void *shdr;
51 /*
52 * dynsymtab and dynstr are used for external symbols, they may hold
53 * other symbols too.
54 */
55 void *dynsymtab;
56 size_t num_dynsyms;
57 const char *dynstr;
58 size_t dynstr_size;
59
60 /* DT_HASH hash table for faster resolution of external symbols */
61 void *hashtab;
62
63 /* DT_SONAME */
64 char *soname;
65
66 struct segment_head segs;
67
68 vaddr_t exidx_start;
69 size_t exidx_size;
70
71 /* Thread Local Storage */
72
73 size_t tls_mod_id;
74 /* PT_TLS segment */
75 vaddr_t tls_start;
76 size_t tls_filesz; /* Covers the .tdata section */
77 size_t tls_memsz; /* Covers the .tdata and .tbss sections */
78 #ifdef ARM64
79 /* Offset of the copy of the TLS block in the TLS area of the TCB */
80 size_t tls_tcb_offs;
81 #endif
82
83 /* PT_GNU_PROPERTY segment */
84 vaddr_t prop_start;
85 size_t prop_align;
86 size_t prop_memsz;
87
88 uint32_t handle;
89
90 struct ta_head *head;
91
92 TEE_UUID uuid;
93 TAILQ_ENTRY(ta_elf) link;
94 };
95
96 TAILQ_HEAD(ta_elf_queue, ta_elf);
97
98 typedef void (*print_func_t)(void *pctx, const char *fmt, va_list ap)
99 __printf(2, 0);
100
101 extern struct ta_elf_queue main_elf_queue;
102 struct ta_elf *ta_elf_find_elf(const TEE_UUID *uuid);
103
104 void ta_elf_load_main(const TEE_UUID *uuid, uint32_t *is_32bit, uint64_t *sp,
105 uint32_t *ta_flags);
106 void ta_elf_finalize_load_main(uint64_t *entry);
107 void ta_elf_load_dependency(struct ta_elf *elf, bool is_32bit);
108 void ta_elf_relocate(struct ta_elf *elf);
109 void ta_elf_finalize_mappings(struct ta_elf *elf);
110
111 void ta_elf_print_mappings(void *pctx, print_func_t print_func,
112 struct ta_elf_queue *elf_queue, size_t num_maps,
113 struct dump_map *maps, vaddr_t mpool_base);
114
115 #ifdef CFG_UNWIND
116 void ta_elf_stack_trace_a32(uint32_t regs[16]);
117 void ta_elf_stack_trace_a64(uint64_t fp, uint64_t sp, uint64_t pc);
118 #else
ta_elf_stack_trace_a32(uint32_t regs[16]__unused)119 static inline void ta_elf_stack_trace_a32(uint32_t regs[16] __unused) { }
ta_elf_stack_trace_a64(uint64_t fp __unused,uint64_t sp __unused,uint64_t pc __unused)120 static inline void ta_elf_stack_trace_a64(uint64_t fp __unused,
121 uint64_t sp __unused,
122 uint64_t pc __unused) { }
123 #endif /*CFG_UNWIND*/
124
125 TEE_Result ta_elf_resolve_sym(const char *name, vaddr_t *val,
126 struct ta_elf **found_elf, struct ta_elf *elf);
127 TEE_Result ta_elf_add_library(const TEE_UUID *uuid);
128 TEE_Result ta_elf_set_init_fini_info_compat(bool is_32bit);
129 TEE_Result ta_elf_set_elf_phdr_info(bool is_32bit);
130
131 #endif /*TA_ELF_H*/
132