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