Line data Source code
1 1 : /**
2 : * @file
3 : * @brief RISCV-Specific constants for ELF binaries.
4 : *
5 : * References can be found here:
6 : * https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc
7 : */
8 : /*
9 : * Copyright (c) 2024 CISPA Helmholtz Center for Information Security gGmbH
10 : *
11 : * SPDX-License-Identifier: Apache-2.0
12 : */
13 : #ifndef ZEPHYR_ARCH_RISCV_ELF_H
14 : #define ZEPHYR_ARCH_RISCV_ELF_H
15 :
16 : #include <stdint.h>
17 : #include <zephyr/sys/util_macro.h>
18 :
19 : #ifdef __cplusplus
20 : extern "C" {
21 : #endif
22 :
23 : /**
24 : * Relocation names for RISCV-specific relocations
25 : * @cond ignore
26 : */
27 :
28 : #define R_RISCV_NONE 0
29 : #define R_RISCV_32 1
30 : #define R_RISCV_64 2
31 : #define R_RISCV_RELATIVE 3
32 : #define R_RISCV_COPY 4
33 : #define R_RISCV_JUMP_SLOT 5
34 : #define R_RISCV_TLS_DTPMOD32 6
35 : #define R_RISCV_TLS_DTPMOD64 7
36 : #define R_RISCV_TLS_DTPREL32 8
37 : #define R_RISCV_TLS_DTPREL64 9
38 : #define R_RISCV_TLS_TPREL32 10
39 : #define R_RISCV_TLS_TPREL64 11
40 : #define R_RISCV_TLSDESC 12
41 : /* 13-15 reserved */
42 : #define R_RISCV_BRANCH 16
43 : #define R_RISCV_JAL 17
44 : #define R_RISCV_CALL 18
45 : #define R_RISCV_CALL_PLT 19
46 : #define R_RISCV_GOT_HI20 20
47 : #define R_RISCV_TLS_GOT_HI20 21
48 : #define R_RISCV_TLS_GD_HI20 22
49 : #define R_RISCV_PCREL_HI20 23
50 : #define R_RISCV_PCREL_LO12_I 24
51 : #define R_RISCV_PCREL_LO12_S 25
52 : #define R_RISCV_HI20 26
53 : #define R_RISCV_LO12_I 27
54 : #define R_RISCV_LO12_S 28
55 : #define R_RISCV_TPREL_HI20 29
56 : #define R_RISCV_TPREL_LO12_I 30
57 : #define R_RISCV_TPREL_LO12_S 31
58 : #define R_RISCV_TPREL_ADD 32
59 : #define R_RISCV_ADD8 33
60 : #define R_RISCV_ADD16 34
61 : #define R_RISCV_ADD32 35
62 : #define R_RISCV_ADD64 36
63 : #define R_RISCV_SUB8 37
64 : #define R_RISCV_SUB16 38
65 : #define R_RISCV_SUB32 39
66 : #define R_RISCV_SUB64 40
67 : #define R_RISCV_GOT32_PCREL 41
68 : /* 42 reserved */
69 : #define R_RISCV_ALIGN 43
70 : /* next two refer to compressed instructions */
71 : #define R_RISCV_RVC_BRANCH 44
72 : #define R_RISCV_RVC_JUMP 45
73 : /* 46-50 reserved */
74 : #define R_RISCV_RELAX 51
75 : #define R_RISCV_SUB6 52
76 : #define R_RISCV_SET6 53
77 : #define R_RISCV_SET8 54
78 : #define R_RISCV_SET16 55
79 : #define R_RISCV_SET32 56
80 : #define R_RISCV_32_PCREL 57
81 : #define R_RISCV_IRELATIVE 58
82 : #define R_RISCV_PLT32 59
83 : #define R_RISCV_SET_ULEB128 60
84 : #define R_RISCV_SUB_ULEB128 61
85 : #define R_RISCV_TLSDESC_HI20 62
86 : #define R_RISCV_TLSDESC_LOAD_LO12 63
87 : #define R_RISCV_TLSDESC_ADD_LO12 64
88 : #define R_RISCV_TLSDESC_CALL 65
89 : /* 66-190 reserved */
90 : #define R_RISCV_VENDOR 191
91 : /* 192-255 reserved */
92 : /** @endcond */
93 :
94 : /**
95 : * "wordclass" from RISC-V specification
96 : * @cond ignore
97 : */
98 : #if defined(CONFIG_64BIT)
99 : typedef uint64_t r_riscv_wordclass_t;
100 : #else
101 : typedef uint32_t r_riscv_wordclass_t;
102 : #endif
103 : /** @endcond */
104 :
105 : /** @brief Extract bit from immediate
106 : *
107 : * @param imm8 immediate value (usually upper 20 or lower 12 bit)
108 : * @param bit which bit to extract
109 : */
110 1 : #define R_RISCV_IMM8_GET_BIT(imm8, bit) (((imm8) & BIT(bit)) >> (bit))
111 :
112 : /** @brief Generate mask for immediate in B-type RISC-V instruction
113 : *
114 : * @param imm8 immediate value, lower 12 bits used;
115 : * due to alignment requirements, imm8[0] is implicitly 0
116 : *
117 : */
118 1 : #define R_RISCV_BTYPE_IMM8_MASK(imm8) \
119 : ((R_RISCV_IMM8_GET_BIT(imm8, 12) << 31) | (R_RISCV_IMM8_GET_BIT(imm8, 10) << 30) | \
120 : (R_RISCV_IMM8_GET_BIT(imm8, 9) << 29) | (R_RISCV_IMM8_GET_BIT(imm8, 8) << 28) | \
121 : (R_RISCV_IMM8_GET_BIT(imm8, 7) << 27) | (R_RISCV_IMM8_GET_BIT(imm8, 6) << 26) | \
122 : (R_RISCV_IMM8_GET_BIT(imm8, 5) << 25) | (R_RISCV_IMM8_GET_BIT(imm8, 4) << 11) | \
123 : (R_RISCV_IMM8_GET_BIT(imm8, 3) << 10) | (R_RISCV_IMM8_GET_BIT(imm8, 2) << 9) | \
124 : (R_RISCV_IMM8_GET_BIT(imm8, 1) << 8) | (R_RISCV_IMM8_GET_BIT(imm8, 11) << 7))
125 :
126 : /** @brief Generate mask for immediate in J-type RISC-V instruction
127 : *
128 : * @param imm8 immediate value, lower 21 bits used;
129 : * due to alignment requirements, imm8[0] is implicitly 0
130 : *
131 : */
132 1 : #define R_RISCV_JTYPE_IMM8_MASK(imm8) \
133 : ((R_RISCV_IMM8_GET_BIT(imm8, 20) << 31) | (R_RISCV_IMM8_GET_BIT(imm8, 10) << 30) | \
134 : (R_RISCV_IMM8_GET_BIT(imm8, 9) << 29) | (R_RISCV_IMM8_GET_BIT(imm8, 8) << 28) | \
135 : (R_RISCV_IMM8_GET_BIT(imm8, 7) << 27) | (R_RISCV_IMM8_GET_BIT(imm8, 6) << 26) | \
136 : (R_RISCV_IMM8_GET_BIT(imm8, 5) << 25) | (R_RISCV_IMM8_GET_BIT(imm8, 4) << 24) | \
137 : (R_RISCV_IMM8_GET_BIT(imm8, 3) << 23) | (R_RISCV_IMM8_GET_BIT(imm8, 2) << 22) | \
138 : (R_RISCV_IMM8_GET_BIT(imm8, 1) << 21) | (R_RISCV_IMM8_GET_BIT(imm8, 11) << 20) | \
139 : (R_RISCV_IMM8_GET_BIT(imm8, 19) << 19) | (R_RISCV_IMM8_GET_BIT(imm8, 18) << 18) | \
140 : (R_RISCV_IMM8_GET_BIT(imm8, 17) << 17) | (R_RISCV_IMM8_GET_BIT(imm8, 16) << 16) | \
141 : (R_RISCV_IMM8_GET_BIT(imm8, 15) << 15) | (R_RISCV_IMM8_GET_BIT(imm8, 14) << 14) | \
142 : (R_RISCV_IMM8_GET_BIT(imm8, 13) << 13) | (R_RISCV_IMM8_GET_BIT(imm8, 12) << 12))
143 :
144 : /** @brief Generate mask for immediate in S-type RISC-V instruction
145 : *
146 : * @param imm8 immediate value, lower 12 bits used
147 : *
148 : */
149 1 : #define R_RISCV_STYPE_IMM8_MASK(imm8) \
150 : ((R_RISCV_IMM8_GET_BIT(imm8, 11) << 31) | (R_RISCV_IMM8_GET_BIT(imm8, 10) << 30) | \
151 : (R_RISCV_IMM8_GET_BIT(imm8, 9) << 29) | (R_RISCV_IMM8_GET_BIT(imm8, 8) << 28) | \
152 : (R_RISCV_IMM8_GET_BIT(imm8, 7) << 27) | (R_RISCV_IMM8_GET_BIT(imm8, 6) << 26) | \
153 : (R_RISCV_IMM8_GET_BIT(imm8, 5) << 25) | (R_RISCV_IMM8_GET_BIT(imm8, 4) << 11) | \
154 : (R_RISCV_IMM8_GET_BIT(imm8, 3) << 10) | (R_RISCV_IMM8_GET_BIT(imm8, 2) << 9) | \
155 : (R_RISCV_IMM8_GET_BIT(imm8, 1) << 8) | (R_RISCV_IMM8_GET_BIT(imm8, 0) << 7))
156 :
157 : /** @brief Generate mask for immediate in compressed J-type RISC-V instruction
158 : *
159 : * @param imm8 immediate value, lower 12 bits used;
160 : * due to alignment requirements, imm8[0] is implicitly 0
161 : *
162 : */
163 1 : #define R_RISCV_CJTYPE_IMM8_MASK(imm8) \
164 : ((R_RISCV_IMM8_GET_BIT(imm8, 11) << 12) | (R_RISCV_IMM8_GET_BIT(imm8, 4) << 11) | \
165 : (R_RISCV_IMM8_GET_BIT(imm8, 9) << 10) | (R_RISCV_IMM8_GET_BIT(imm8, 8) << 9) | \
166 : (R_RISCV_IMM8_GET_BIT(imm8, 10) << 8) | (R_RISCV_IMM8_GET_BIT(imm8, 6) << 7) | \
167 : (R_RISCV_IMM8_GET_BIT(imm8, 7) << 6) | (R_RISCV_IMM8_GET_BIT(imm8, 3) << 5) | \
168 : (R_RISCV_IMM8_GET_BIT(imm8, 2) << 4) | (R_RISCV_IMM8_GET_BIT(imm8, 1) << 3) | \
169 : (R_RISCV_IMM8_GET_BIT(imm8, 5) << 2))
170 :
171 : /** @brief Generate mask for immediate in compressed B-type RISC-V instruction
172 : *
173 : * @param imm8 immediate value, lower 9 bits used;
174 : * due to alignment requirements, imm8[0] is implicitly 0
175 : *
176 : */
177 1 : #define R_RISCV_CBTYPE_IMM8_MASK(imm8) \
178 : ((R_RISCV_IMM8_GET_BIT(imm8, 8) << 12) | (R_RISCV_IMM8_GET_BIT(imm8, 4) << 11) | \
179 : (R_RISCV_IMM8_GET_BIT(imm8, 3) << 10) | (R_RISCV_IMM8_GET_BIT(imm8, 7) << 6) | \
180 : (R_RISCV_IMM8_GET_BIT(imm8, 6) << 5) | (R_RISCV_IMM8_GET_BIT(imm8, 2) << 4) | \
181 : (R_RISCV_IMM8_GET_BIT(imm8, 1) << 3) | (R_RISCV_IMM8_GET_BIT(imm8, 5) << 2))
182 :
183 : /** @brief Clear immediate bits in B-type instruction.
184 : *
185 : * @param operand Address of RISC-V instruction, B-type
186 : *
187 : */
188 1 : #define R_RISCV_CLEAR_BTYPE_IMM8(operand) ((operand) & ~R_RISCV_BTYPE_IMM8_MASK((uint32_t) -1))
189 :
190 : /** @brief Overwrite immediate in B-type instruction
191 : *
192 : * @param operand Address of RISC-V instruction, B-type
193 : * @param imm8 New immediate
194 : *
195 : */
196 1 : #define R_RISCV_SET_BTYPE_IMM8(operand, imm8) \
197 : ((R_RISCV_CLEAR_BTYPE_IMM8(operand)) | R_RISCV_BTYPE_IMM8_MASK(imm8))
198 :
199 : /** @brief Clear immediate bits in J-type instruction.
200 : *
201 : * @param operand Address of RISC-V instruction, J-type
202 : *
203 : */
204 1 : #define R_RISCV_CLEAR_JTYPE_IMM8(operand) ((operand) & ~R_RISCV_JTYPE_IMM8_MASK((uint32_t) -1))
205 :
206 : /** @brief Overwrite immediate in J-type instruction
207 : *
208 : * @param operand Address of RISC-V instruction, J-type
209 : * @param imm8 New immediate
210 : *
211 : */
212 1 : #define R_RISCV_SET_JTYPE_IMM8(operand, imm8) \
213 : ((R_RISCV_CLEAR_JTYPE_IMM8(operand)) | R_RISCV_JTYPE_IMM8_MASK(imm8))
214 :
215 : /** @brief Clear immediate bits in S-type instruction.
216 : *
217 : * @param operand Address of RISC-V instruction, S-type
218 : *
219 : */
220 1 : #define R_RISCV_CLEAR_STYPE_IMM8(operand) ((operand) & ~R_RISCV_STYPE_IMM8_MASK((uint32_t) -1))
221 :
222 : /** @brief Overwrite immediate in S-type instruction
223 : *
224 : * @param operand Address of RISC-V instruction, S-type
225 : * @param imm8 New immediate
226 : *
227 : */
228 1 : #define R_RISCV_SET_STYPE_IMM8(operand, imm8) \
229 : ((R_RISCV_CLEAR_STYPE_IMM8(operand)) | R_RISCV_STYPE_IMM8_MASK(imm8))
230 :
231 : /** @brief Clear immediate bits in compressed J-type instruction.
232 : *
233 : * @param operand Address of RISC-V instruction, compressed-J-type
234 : *
235 : */
236 1 : #define R_RISCV_CLEAR_CJTYPE_IMM8(operand) ((operand) & ~R_RISCV_CJTYPE_IMM8_MASK((uint32_t) -1))
237 :
238 : /** @brief Overwrite immediate in compressed J-type instruction
239 : *
240 : * @param operand Address of RISC-V instruction, compressed-J-type
241 : * @param imm8 New immediate
242 : *
243 : */
244 1 : #define R_RISCV_SET_CJTYPE_IMM8(operand, imm8) \
245 : ((R_RISCV_CLEAR_CJTYPE_IMM8(operand)) | R_RISCV_CJTYPE_IMM8_MASK(imm8))
246 :
247 : /** @brief Clear immediate bits in compressed B-type instruction.
248 : *
249 : * @param operand Address of RISC-V instruction, compressed-B-type
250 : *
251 : */
252 1 : #define R_RISCV_CLEAR_CBTYPE_IMM8(operand) ((operand) & ~R_RISCV_CBTYPE_IMM8_MASK((uint32_t) -1))
253 :
254 : /** @brief Overwrite immediate in compressed B-type instruction
255 : *
256 : * @param operand Address of RISC-V instruction, compressed-B-type
257 : * @param imm8 New immediate
258 : *
259 : */
260 1 : #define R_RISCV_SET_CBTYPE_IMM8(operand, imm8) \
261 : ((R_RISCV_CLEAR_CBTYPE_IMM8(operand)) | R_RISCV_CBTYPE_IMM8_MASK(imm8))
262 :
263 : /** @brief Clear immediate bits in U-type instruction.
264 : *
265 : * @param operand Address of RISC-V instruction, U-type
266 : *
267 : */
268 1 : #define R_RISCV_CLEAR_UTYPE_IMM8(operand) ((operand) & ~(0xFFFFF000))
269 :
270 : /** @brief Overwrite immediate in U-type instruction
271 : *
272 : * @param operand Address of RISC-V instruction, U-type
273 : * @param imm8 New immediate
274 : *
275 : */
276 1 : #define R_RISCV_SET_UTYPE_IMM8(operand, imm8) \
277 : ((R_RISCV_CLEAR_UTYPE_IMM8(operand)) | ((imm8) & 0xFFFFF000))
278 :
279 : /** @brief Clear immediate bits in I-type instruction.
280 : *
281 : * @param operand Address of RISC-V instruction, I-type
282 : *
283 : */
284 1 : #define R_RISCV_CLEAR_ITYPE_IMM8(operand) ((operand) & ~(0xFFF00000))
285 :
286 : /** @brief Overwrite immediate in I-type instruction
287 : *
288 : * @param operand Address of RISC-V instruction, I-type
289 : * @param imm8 New immediate
290 : *
291 : */
292 1 : #define R_RISCV_SET_ITYPE_IMM8(operand, imm8) ((R_RISCV_CLEAR_ITYPE_IMM8(operand)) | ((imm8) << 20))
293 :
294 : #ifdef __cplusplus
295 : }
296 : #endif
297 :
298 : #endif /* ZEPHYR_ARCH_RISCV_ELF_H */
|