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 /* DT_GNU_HASH table as an alternative to DT_HASH */ 63 void *gnu_hashtab; 64 size_t gnu_hashtab_size; 65 66 /* DT_SONAME */ 67 char *soname; 68 69 struct segment_head segs; 70 71 vaddr_t exidx_start; 72 size_t exidx_size; 73 74 /* Thread Local Storage */ 75 76 size_t tls_mod_id; 77 /* PT_TLS segment */ 78 vaddr_t tls_start; 79 size_t tls_filesz; /* Covers the .tdata section */ 80 size_t tls_memsz; /* Covers the .tdata and .tbss sections */ 81 #ifdef ARM64 82 /* Offset of the copy of the TLS block in the TLS area of the TCB */ 83 size_t tls_tcb_offs; 84 #endif 85 86 /* PT_GNU_PROPERTY segment */ 87 vaddr_t prop_start; 88 size_t prop_align; 89 size_t prop_memsz; 90 91 uint32_t handle; 92 93 struct ta_head *head; 94 95 TEE_UUID uuid; 96 TAILQ_ENTRY(ta_elf) link; 97 }; 98 99 TAILQ_HEAD(ta_elf_queue, ta_elf); 100 101 /* Format of the DT_GNU_HASH entry in the ELF dynamic section */ 102 struct gnu_hashtab { 103 uint32_t nbuckets; 104 uint32_t symoffset; 105 uint32_t bloom_size; 106 uint32_t bloom_shift; 107 /* 108 * Followed by: 109 * 110 * uint{32,64}_t bloom[bloom_size]; 111 * uint32_t buckets[nbuckets]; 112 * uint32_t chain[]; 113 */ 114 }; 115 116 typedef void (*print_func_t)(void *pctx, const char *fmt, va_list ap) 117 __printf(2, 0); 118 119 extern struct ta_elf_queue main_elf_queue; 120 struct ta_elf *ta_elf_find_elf(const TEE_UUID *uuid); 121 122 void ta_elf_load_main(const TEE_UUID *uuid, uint32_t *is_32bit, uint64_t *sp, 123 uint32_t *ta_flags); 124 void ta_elf_finalize_load_main(uint64_t *entry); 125 void ta_elf_load_dependency(struct ta_elf *elf, bool is_32bit); 126 void ta_elf_relocate(struct ta_elf *elf); 127 void ta_elf_finalize_mappings(struct ta_elf *elf); 128 129 void ta_elf_print_mappings(void *pctx, print_func_t print_func, 130 struct ta_elf_queue *elf_queue, size_t num_maps, 131 struct dump_map *maps, vaddr_t mpool_base); 132 133 #ifdef CFG_UNWIND 134 void ta_elf_stack_trace_a32(uint32_t regs[16]); 135 void ta_elf_stack_trace_a64(uint64_t fp, uint64_t sp, uint64_t pc); 136 #else 137 static inline void ta_elf_stack_trace_a32(uint32_t regs[16] __unused) { } 138 static inline void ta_elf_stack_trace_a64(uint64_t fp __unused, 139 uint64_t sp __unused, 140 uint64_t pc __unused) { } 141 #endif /*CFG_UNWIND*/ 142 143 TEE_Result ta_elf_resolve_sym(const char *name, vaddr_t *val, 144 struct ta_elf **found_elf, struct ta_elf *elf); 145 TEE_Result ta_elf_add_library(const TEE_UUID *uuid); 146 TEE_Result ta_elf_set_init_fini_info_compat(bool is_32bit); 147 TEE_Result ta_elf_set_elf_phdr_info(bool is_32bit); 148 149 #endif /*TA_ELF_H*/ 150