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