xref: /optee_os/ldelf/ta_elf.h (revision ba2a6adb764f1310ad3c3091d89de84274f86b02)
17509ff7cSJens Wiklander /* SPDX-License-Identifier: BSD-2-Clause */
27509ff7cSJens Wiklander /*
37509ff7cSJens Wiklander  * Copyright (c) 2019, Linaro Limited
4af78e1b1SImre Kis  * Copyright (c) 2022-2023, Arm Limited
57509ff7cSJens Wiklander  */
67509ff7cSJens Wiklander 
77509ff7cSJens Wiklander #ifndef TA_ELF_H
87509ff7cSJens Wiklander #define TA_ELF_H
97509ff7cSJens Wiklander 
1065137432SJens Wiklander #include <ldelf.h>
11ebef121cSJerome Forissier #include <stdarg.h>
127509ff7cSJens Wiklander #include <sys/queue.h>
137509ff7cSJens Wiklander #include <tee_api_types.h>
147509ff7cSJens Wiklander #include <types_ext.h>
157509ff7cSJens Wiklander 
167509ff7cSJens Wiklander struct segment {
177509ff7cSJens Wiklander 	size_t offset;
187509ff7cSJens Wiklander 	size_t vaddr;
197509ff7cSJens Wiklander 	size_t filesz;
207509ff7cSJens Wiklander 	size_t memsz;
217509ff7cSJens Wiklander 	size_t flags;
227509ff7cSJens Wiklander 	size_t align;
237509ff7cSJens Wiklander 	bool remapped_writeable;
247509ff7cSJens Wiklander 	TAILQ_ENTRY(segment) link;
257509ff7cSJens Wiklander };
267509ff7cSJens Wiklander 
277509ff7cSJens Wiklander TAILQ_HEAD(segment_head, segment);
287509ff7cSJens Wiklander 
297509ff7cSJens Wiklander struct ta_elf {
307509ff7cSJens Wiklander 	bool is_main;
317509ff7cSJens Wiklander 	bool is_32bit;	/* Initialized from Elf32_Ehdr/Elf64_Ehdr */
327509ff7cSJens Wiklander 	bool is_legacy;
33e84a7da4SRuchika Gupta 	bool bti_enabled;
347509ff7cSJens Wiklander 
357509ff7cSJens Wiklander 	vaddr_t load_addr;
367509ff7cSJens Wiklander 	vaddr_t max_addr;
377509ff7cSJens Wiklander 	vaddr_t max_offs;
387509ff7cSJens Wiklander 
397509ff7cSJens Wiklander 	vaddr_t ehdr_addr;
407509ff7cSJens Wiklander 
417509ff7cSJens Wiklander 	/* Initialized from Elf32_Ehdr/Elf64_Ehdr */
427509ff7cSJens Wiklander 	vaddr_t e_entry;
437509ff7cSJens Wiklander 	vaddr_t e_phoff;
447509ff7cSJens Wiklander 	vaddr_t e_shoff;
457509ff7cSJens Wiklander 	unsigned int e_phnum;
467509ff7cSJens Wiklander 	unsigned int e_shnum;
477509ff7cSJens Wiklander 	unsigned int e_phentsize;
487509ff7cSJens Wiklander 	unsigned int e_shentsize;
497509ff7cSJens Wiklander 
507509ff7cSJens Wiklander 	void *phdr;
517509ff7cSJens Wiklander 	void *shdr;
527509ff7cSJens Wiklander 	/*
537509ff7cSJens Wiklander 	 * dynsymtab and dynstr are used for external symbols, they may hold
547509ff7cSJens Wiklander 	 * other symbols too.
557509ff7cSJens Wiklander 	 */
567509ff7cSJens Wiklander 	void *dynsymtab;
577509ff7cSJens Wiklander 	size_t num_dynsyms;
587509ff7cSJens Wiklander 	const char *dynstr;
597509ff7cSJens Wiklander 	size_t dynstr_size;
607509ff7cSJens Wiklander 
619f392760SJerome Forissier 	/* DT_HASH hash table for faster resolution of external symbols */
629f392760SJerome Forissier 	void *hashtab;
63bdf82531SJerome Forissier 	/* DT_GNU_HASH table as an alternative to DT_HASH */
64bdf82531SJerome Forissier 	void *gnu_hashtab;
65bdf82531SJerome Forissier 	size_t gnu_hashtab_size;
669f392760SJerome Forissier 
679d224046SJerome Forissier 	/* DT_SONAME */
689d224046SJerome Forissier 	char *soname;
699d224046SJerome Forissier 
707509ff7cSJens Wiklander 	struct segment_head segs;
717509ff7cSJens Wiklander 
720242833aSJens Wiklander 	vaddr_t exidx_start;
730242833aSJens Wiklander 	size_t exidx_size;
740242833aSJens Wiklander 
75c88ba125SJerome Forissier 	/* Thread Local Storage */
76fe684948SJerome Forissier 
77c88ba125SJerome Forissier 	size_t tls_mod_id;
78fe684948SJerome Forissier 	/* PT_TLS segment */
79fe684948SJerome Forissier 	vaddr_t tls_start;
80fe684948SJerome Forissier 	size_t tls_filesz; /* Covers the .tdata section */
81fe684948SJerome Forissier 	size_t tls_memsz; /* Covers the .tdata and .tbss sections */
82fe684948SJerome Forissier #ifdef ARM64
83fe684948SJerome Forissier 	/* Offset of the copy of the TLS block in the TLS area of the TCB */
84fe684948SJerome Forissier 	size_t tls_tcb_offs;
85fe684948SJerome Forissier #endif
86c88ba125SJerome Forissier 
87e84a7da4SRuchika Gupta 	/* PT_GNU_PROPERTY segment */
88e84a7da4SRuchika Gupta 	vaddr_t prop_start;
89e84a7da4SRuchika Gupta 	size_t prop_align;
90e84a7da4SRuchika Gupta 	size_t prop_memsz;
91e84a7da4SRuchika Gupta 
927509ff7cSJens Wiklander 	uint32_t handle;
937509ff7cSJens Wiklander 
94c35dfd95SJens Wiklander 	struct ta_head *head;
95c35dfd95SJens Wiklander 
967509ff7cSJens Wiklander 	TEE_UUID uuid;
977509ff7cSJens Wiklander 	TAILQ_ENTRY(ta_elf) link;
987509ff7cSJens Wiklander };
997509ff7cSJens Wiklander 
1007509ff7cSJens Wiklander TAILQ_HEAD(ta_elf_queue, ta_elf);
1017509ff7cSJens Wiklander 
102bdf82531SJerome Forissier /* Format of the DT_GNU_HASH entry in the ELF dynamic section */
103bdf82531SJerome Forissier struct gnu_hashtab {
104bdf82531SJerome Forissier 	uint32_t nbuckets;
105bdf82531SJerome Forissier 	uint32_t symoffset;
106bdf82531SJerome Forissier 	uint32_t bloom_size;
107bdf82531SJerome Forissier 	uint32_t bloom_shift;
108bdf82531SJerome Forissier 	/*
109bdf82531SJerome Forissier 	 * Followed by:
110bdf82531SJerome Forissier 	 *
111bdf82531SJerome Forissier 	 * uint{32,64}_t bloom[bloom_size];
112bdf82531SJerome Forissier 	 * uint32_t buckets[nbuckets];
113bdf82531SJerome Forissier 	 * uint32_t chain[];
114bdf82531SJerome Forissier 	 */
115bdf82531SJerome Forissier };
116bdf82531SJerome Forissier 
117c86f218cSJens Wiklander typedef void (*print_func_t)(void *pctx, const char *fmt, va_list ap)
118c86f218cSJens Wiklander 	__printf(2, 0);
119c86f218cSJens Wiklander 
1207509ff7cSJens Wiklander extern struct ta_elf_queue main_elf_queue;
121ebef121cSJerome Forissier struct ta_elf *ta_elf_find_elf(const TEE_UUID *uuid);
1227509ff7cSJens Wiklander 
123c35dfd95SJens Wiklander void ta_elf_load_main(const TEE_UUID *uuid, uint32_t *is_32bit, uint64_t *sp,
124c35dfd95SJens Wiklander 		      uint32_t *ta_flags);
125af78e1b1SImre Kis void ta_elf_finalize_load_main(uint64_t *entry, uint64_t *load_addr);
1267509ff7cSJens Wiklander void ta_elf_load_dependency(struct ta_elf *elf, bool is_32bit);
1277509ff7cSJens Wiklander void ta_elf_relocate(struct ta_elf *elf);
1287509ff7cSJens Wiklander void ta_elf_finalize_mappings(struct ta_elf *elf);
1297509ff7cSJens Wiklander 
130c86f218cSJens Wiklander void ta_elf_print_mappings(void *pctx, print_func_t print_func,
131c86f218cSJens Wiklander 			   struct ta_elf_queue *elf_queue, size_t num_maps,
13265137432SJens Wiklander 			   struct dump_map *maps, vaddr_t mpool_base);
133c86f218cSJens Wiklander 
1340242833aSJens Wiklander #ifdef CFG_UNWIND
1350242833aSJens Wiklander void ta_elf_stack_trace_a32(uint32_t regs[16]);
1360242833aSJens Wiklander void ta_elf_stack_trace_a64(uint64_t fp, uint64_t sp, uint64_t pc);
137*ba2a6adbSAlvin Chang void ta_elf_stack_trace_riscv(uint64_t fp, uint64_t pc);
1380242833aSJens Wiklander #else
ta_elf_stack_trace_a32(uint32_t regs[16]__unused)1390242833aSJens Wiklander 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)1400242833aSJens Wiklander static inline void ta_elf_stack_trace_a64(uint64_t fp __unused,
1410242833aSJens Wiklander 					  uint64_t sp __unused,
1420242833aSJens Wiklander 					  uint64_t pc __unused) { }
ta_elf_stack_trace_riscv(uint64_t fp __unused,uint64_t pc __unused)143*ba2a6adbSAlvin Chang static inline void ta_elf_stack_trace_riscv(uint64_t fp __unused,
144*ba2a6adbSAlvin Chang 					    uint64_t pc __unused) { }
1450242833aSJens Wiklander #endif /*CFG_UNWIND*/
146c86f218cSJens Wiklander 
147ebef121cSJerome Forissier TEE_Result ta_elf_resolve_sym(const char *name, vaddr_t *val,
148c88ba125SJerome Forissier 			      struct ta_elf **found_elf, struct ta_elf *elf);
149ebef121cSJerome Forissier TEE_Result ta_elf_add_library(const TEE_UUID *uuid);
15001b02a16SJerome Forissier TEE_Result ta_elf_set_init_fini_info_compat(bool is_32bit);
1519d224046SJerome Forissier TEE_Result ta_elf_set_elf_phdr_info(bool is_32bit);
152c86f218cSJens Wiklander 
1537509ff7cSJens Wiklander #endif /*TA_ELF_H*/
154