• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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