17509ff7cSJens Wiklander /* SPDX-License-Identifier: BSD-2-Clause */ 27509ff7cSJens Wiklander /* 37509ff7cSJens Wiklander * Copyright (c) 2019, Linaro Limited 4*af78e1b1SImre 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); 125*af78e1b1SImre 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); 1370242833aSJens Wiklander #else 1380242833aSJens Wiklander static inline void ta_elf_stack_trace_a32(uint32_t regs[16] __unused) { } 1390242833aSJens Wiklander static inline void ta_elf_stack_trace_a64(uint64_t fp __unused, 1400242833aSJens Wiklander uint64_t sp __unused, 1410242833aSJens Wiklander uint64_t pc __unused) { } 1420242833aSJens Wiklander #endif /*CFG_UNWIND*/ 143c86f218cSJens Wiklander 144ebef121cSJerome Forissier TEE_Result ta_elf_resolve_sym(const char *name, vaddr_t *val, 145c88ba125SJerome Forissier struct ta_elf **found_elf, struct ta_elf *elf); 146ebef121cSJerome Forissier TEE_Result ta_elf_add_library(const TEE_UUID *uuid); 14701b02a16SJerome Forissier TEE_Result ta_elf_set_init_fini_info_compat(bool is_32bit); 1489d224046SJerome Forissier TEE_Result ta_elf_set_elf_phdr_info(bool is_32bit); 149c86f218cSJens Wiklander 1507509ff7cSJens Wiklander #endif /*TA_ELF_H*/ 151