1 /* ---------------------------------------------------------------------------- 2 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved. 3 * Description: RISCV Dynamic Load HeadFile 4 * Author: Huawei LiteOS Team 5 * Create: 2022-12-20 6 * Redistribution and use in source and binary forms, with or without modification, 7 * are permitted provided that the following conditions are met: 8 * 1. Redistributions of source code must retain the above copyright notice, this list of 9 * conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 * of conditions and the following disclaimer in the documentation and/or other materials 12 * provided with the distribution. 13 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 14 * to endorse or promote products derived from this software without specific prior written 15 * permission. 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * --------------------------------------------------------------------------- */ 28 29 #ifndef _ARCH_DYNLOAD_H 30 #define _ARCH_DYNLOAD_H 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif /* __cplusplus */ 35 36 #define DYNLOAD_ALIGN_SIZE 64 37 #define UINTMAX UINT32_MAX 38 39 /* Symbol table */ 40 typedef struct { 41 UINT32 stName; /* Symbol table name (string tbl index) */ 42 UINT32 stValue; /* Symbol table value */ 43 UINT32 stSize; /* Symbol table size */ 44 UINT8 stInfo; /* Symbol table type and binding */ 45 UINT8 stOther; /* Symbol table visibility */ 46 UINT16 stShndx; /* Section table index */ 47 } LDElf32Sym; 48 49 #define LD_ELF_SYM LDElf32Sym 50 51 /* Section header */ 52 typedef struct { 53 UINT32 shName; /* Section name (string tbl index) */ 54 UINT32 shType; /* Section type */ 55 UINT32 shFlags; /* Section flags */ 56 UINT32 shAddr; /* Section virtual addr at execution */ 57 UINT32 shOffset; /* Section file offset */ 58 UINT32 shSize; /* Section size in bytes */ 59 UINT32 shLink; /* Link to another section */ 60 UINT32 shInfo; /* Additional section information */ 61 UINT32 shAddrAlign; /* Section alignment */ 62 UINT32 shEntSize; /* Entry size if section holds table */ 63 } LDElf32Shdr; 64 65 #define LD_ELF_SHDR LDElf32Shdr 66 67 /* Program Header */ 68 typedef struct { 69 UINT32 type; /* Segment type */ 70 UINT32 offset; /* Segment file offset */ 71 UINT32 vAddr; /* Segment virtual address */ 72 UINT32 phyAddr; /* Segment physical address */ 73 UINT32 fileSize; /* Segment size in file */ 74 UINT32 memSize; /* Segment size in memory */ 75 UINT32 flags; /* Segment flags */ 76 UINT32 align; /* Segment alignment */ 77 } LDElf32Phdr; 78 79 #define LD_ELF_PHDR LDElf32Phdr 80 81 /* Elf header */ 82 #define LD_EI_NIDENT 16 83 typedef struct { 84 UINT8 elfIdent[LD_EI_NIDENT]; /* Magic number and other info */ 85 UINT16 elfType; /* Object file type */ 86 UINT16 elfMachine; /* Architecture */ 87 UINT32 elfVersion; /* Object file version */ 88 UINT32 elfEntry; /* Entry point virtual address */ 89 UINT32 elfPhoff; /* Program header table file offset */ 90 UINT32 elfShoff; /* Section header table file offset */ 91 UINT32 elfFlags; /* Processor-specific flags */ 92 UINT16 elfHeadSize; /* ELF header size in bytes */ 93 UINT16 elfPhSize; /* Program header table entry size */ 94 UINT16 elfPhNum; /* Program header table entry count */ 95 UINT16 elfShEntSize; /* Section header table entry size */ 96 UINT16 elfShNum; /* Section header table entry count */ 97 UINT16 elfShStrIndex; /* Section header string table index */ 98 } LDElf32Ehdr; 99 100 #define LD_ELF_EHDR LDElf32Ehdr 101 102 /* EI_CLASS */ 103 #define LD_ELF_CLASS32 1 104 #define LD_ELF_CLASS LD_ELF_CLASS32 105 106 /* e_machine */ 107 #define LD_EM_RISCV 243 /* RISC_V */ 108 #define LD_EM_TYPE LD_EM_RISCV 109 110 /* Dynamic */ 111 typedef struct { 112 UINT32 dynTag; /* Dynamic entry type */ 113 union { 114 UINT32 val; /* Integer value */ 115 UINT32 ptr; /* Address value */ 116 } dyn; 117 } LDElf32Dyn; 118 119 #define LD_ELF_DYN LDElf32Dyn 120 121 /* Relocation */ 122 typedef struct { 123 UINT32 offset; /* Address */ 124 UINT32 info; /* Relocation type and symbol index */ 125 } LDElf32Rel; 126 127 typedef struct { 128 UINT32 offset; /* Address */ 129 UINT32 info; /* Relocation type and symbol index */ 130 INT32 addend; /* Addend */ 131 } LDElf32Rela; 132 133 #define LD_ELF_REL LDElf32Rel 134 #define LD_ELF_RELA LDElf32Rela 135 136 #define LD_ELF_R_SYM(info) ((info) >> 8) 137 #define LD_ELF_R_TYPE(info) ((info) & 0xFFU) 138 #define LD_ELF_R_INFO(sym, type) (((sym) << 8) + (UINT8)(type)) 139 140 /* Dynamic linker uses the following 12 relocation types */ 141 #define OS_R_RISCV_NONE 0 142 #define OS_R_RISCV_32 1 143 #define OS_R_RISCV_64 2 144 #define OS_R_RISCV_RELATIVE 3 145 #define OS_R_RISCV_COPY 4 146 #define OS_R_RISCV_JUMP_SLOT 5 147 #define OS_R_RISCV_TLS_DTPMOD32 6 148 #define OS_R_RISCV_TLS_DTPMOD64 7 149 #define OS_R_RISCV_TLS_DTPREL32 8 150 #define OS_R_RISCV_TLS_DTPREL64 9 151 #define OS_R_RISCV_TLS_TPREL32 10 152 #define OS_R_RISCV_TLS_TPREL64 11 153 154 /* Dynamic linker doesn't use the following relocation types */ 155 #define OS_R_RISCV_BRANCH 16 156 #define OS_R_RISCV_JAL 17 157 #define OS_R_RISCV_CALL 18 158 #define OS_R_RISCV_CALL_PLT 19 159 #define OS_R_RISCV_GOT_HI20 20 160 #define OS_R_RISCV_TLS_GOT_HI20 21 161 #define OS_R_RISCV_TLS_GD_HI20 22 162 #define OS_R_RISCV_PCREL_HI20 23 163 #define OS_R_RISCV_PCREL_LO12_I 24 164 #define OS_R_RISCV_PCREL_LO12_S 25 165 #define OS_R_RISCV_HI20 26 166 #define OS_R_RISCV_LO12_I 27 167 #define OS_R_RISCV_LO12_S 28 168 #define OS_R_RISCV_TPREL_HI20 29 169 #define OS_R_RISCV_TPREL_LO12_I 30 170 #define OS_R_RISCV_TPREL_LO12_S 31 171 #define OS_R_RISCV_TPREL_ADD 32 172 #define OS_R_RISCV_ADD8 33 173 #define OS_R_RISCV_ADD16 34 174 #define OS_R_RISCV_ADD32 35 175 #define OS_R_RISCV_ADD64 36 176 #define OS_R_RISCV_SUB8 37 177 #define OS_R_RISCV_SUB16 38 178 #define OS_R_RISCV_SUB32 39 179 #define OS_R_RISCV_SUB64 40 180 #define OS_R_RISCV_GNU_VTINHERIT 41 181 #define OS_R_RISCV_GNU_VTENTRY 42 182 #define OS_R_RISCV_ALIGN 43 183 #define OS_R_RISCV_RVC_BRANCH 44 184 #define OS_R_RISCV_RVC_JUMP 45 185 #define OS_R_RISCV_RVC_LUI 46 186 #define OS_R_RISCV_RELAX 51 187 #define OS_R_RISCV_GP_HI120 59 188 #define OS_R_RISCV_GP_LO12_I 60 189 #define OS_R_RISCV_GP_LO12_S 61 190 191 typedef struct { 192 UINT32 relocType; 193 UINT32 shType; /* REL section or RELA section. */ 194 UINTPTR position; /* the address of the place being relocated. */ 195 UINTPTR symAdd; /* the address of the symbol. */ 196 ssize_t addend; /* the addend for the relocation. */ 197 UINTPTR baseSegment; /* the addressing origin of the output segment defining the symbol S. */ 198 UINTPTR gotAddr; /* the address of the Global Offset Table. */ 199 /* 200 * T is 1 if the target symbol S has type STT_FUNC and 201 * the symbol addresses a Thumb instruction; it is 0 otherwise. 202 */ 203 UINT8 thumbFunc; 204 #define RESERVE_NUM 7 205 UINT8 reserved[RESERVE_NUM]; 206 } LDRelocParam; 207 208 typedef struct { 209 UINTPTR relTable; /* address of relocation table. */ 210 UINTPTR relTableSize; /* total size of relocation table. */ 211 UINTPTR relEntrySize; /* size of every relocation entry. */ 212 } RelocationInfo; 213 214 extern UINT32 ELF_RiscvRel32Reloc(const LDRelocParam *relocParam); 215 extern UINT32 ELF_RiscvJumpSlotReloc(const LDRelocParam *relocParam); 216 extern UINT32 ELF_RiscvRelativeReloc(const LDRelocParam *relocParam); 217 extern UINT32 ELF_RiscvJalReloc(const LDRelocParam *relocParam); 218 extern UINT32 ELF_RiscvBranchReloc(const LDRelocParam *relocParam); 219 extern UINT32 ELF_RiscvCallReloc(const LDRelocParam *relocParam); 220 extern UINT32 ELF_RiscvHigh20Reloc(const LDRelocParam *relocParam); 221 extern UINT32 ELF_RiscvLow12IReloc(const LDRelocParam *relocParam); 222 extern UINT32 ELF_RiscvLow12SReloc(const LDRelocParam *relocParam); 223 extern UINT32 ELF_RiscvAddReloc(const LDRelocParam *relocParam, UINT32 type); 224 extern UINT32 ELF_RiscvSubReloc(const LDRelocParam *relocParam, UINT32 type); 225 extern UINT32 ArchSegRelocImp(const LD_ELF_RELA *rela, const LDRelocParam *relocParam); 226 extern UINT32 ArchObjRelocImp(const LD_ELF_RELA *relocCmd, const LDRelocParam *relocParam); 227 extern UINT32 ArchSegRelocTblCheck(const RelocationInfo *relocInfo); 228 229 #ifdef __cplusplus 230 } 231 #endif /* __cplusplus */ 232 233 #endif /* _ARCH_DYNLOAD_H */ 234