@@ -162,6 +162,11 @@ static uint32_t extractBits(uint32_t Num, unsigned Low, unsigned Size) {
162
162
return (Num & (((1ULL << (Size + 1 )) - 1 ) << Low)) >> Low;
163
163
}
164
164
165
+ static inline bool isInRangeForImmS32 (int64_t Value) {
166
+ return (Value >= std::numeric_limits<int32_t >::min () &&
167
+ Value <= std::numeric_limits<int32_t >::max ());
168
+ }
169
+
165
170
class ELFJITLinker_riscv : public JITLinker <ELFJITLinker_riscv> {
166
171
friend class JITLinker <ELFJITLinker_riscv>;
167
172
@@ -191,12 +196,17 @@ class ELFJITLinker_riscv : public JITLinker<ELFJITLinker_riscv> {
191
196
}
192
197
case R_RISCV_HI20: {
193
198
int64_t Value = (E.getTarget ().getAddress () + E.getAddend ()).getValue ();
194
- int32_t Hi = (Value + 0x800 ) & 0xFFFFF000 ;
199
+ int64_t Hi = Value + 0x800 ;
200
+ if (LLVM_UNLIKELY (!isInRangeForImmS32 (Hi)))
201
+ return makeTargetOutOfRangeError (G, B, E);
195
202
uint32_t RawInstr = *(little32_t *)FixupPtr;
196
- *(little32_t *)FixupPtr = (RawInstr & 0xFFF ) | static_cast <uint32_t >(Hi);
203
+ *(little32_t *)FixupPtr =
204
+ (RawInstr & 0xFFF ) | (static_cast <uint32_t >(Hi & 0xFFFFF000 ));
197
205
break ;
198
206
}
199
207
case R_RISCV_LO12_I: {
208
+ // FIXME: We assume that R_RISCV_HI20 is present in object code and pairs
209
+ // with current relocation R_RISCV_LO12_I. So here may need a check.
200
210
int64_t Value = (E.getTarget ().getAddress () + E.getAddend ()).getValue ();
201
211
int32_t Lo = Value & 0xFFF ;
202
212
uint32_t RawInstr = *(little32_t *)FixupPtr;
@@ -206,23 +216,32 @@ class ELFJITLinker_riscv : public JITLinker<ELFJITLinker_riscv> {
206
216
}
207
217
case R_RISCV_CALL: {
208
218
int64_t Value = E.getTarget ().getAddress () + E.getAddend () - FixupAddress;
209
- int32_t Hi = (Value + 0x800 ) & 0xFFFFF000 ;
219
+ int64_t Hi = Value + 0x800 ;
220
+ if (LLVM_UNLIKELY (!isInRangeForImmS32 (Hi)))
221
+ return makeTargetOutOfRangeError (G, B, E);
210
222
int32_t Lo = Value & 0xFFF ;
211
223
uint32_t RawInstrAuipc = *(little32_t *)FixupPtr;
212
224
uint32_t RawInstrJalr = *(little32_t *)(FixupPtr + 4 );
213
- *(little32_t *)FixupPtr = RawInstrAuipc | static_cast <uint32_t >(Hi);
225
+ *(little32_t *)FixupPtr =
226
+ RawInstrAuipc | (static_cast <uint32_t >(Hi & 0xFFFFF000 ));
214
227
*(little32_t *)(FixupPtr + 4 ) =
215
228
RawInstrJalr | (static_cast <uint32_t >(Lo) << 20 );
216
229
break ;
217
230
}
218
231
case R_RISCV_PCREL_HI20: {
219
232
int64_t Value = E.getTarget ().getAddress () + E.getAddend () - FixupAddress;
220
- int32_t Hi = (Value + 0x800 ) & 0xFFFFF000 ;
233
+ int64_t Hi = Value + 0x800 ;
234
+ if (LLVM_UNLIKELY (!isInRangeForImmS32 (Hi)))
235
+ return makeTargetOutOfRangeError (G, B, E);
221
236
uint32_t RawInstr = *(little32_t *)FixupPtr;
222
- *(little32_t *)FixupPtr = (RawInstr & 0xFFF ) | static_cast <uint32_t >(Hi);
237
+ *(little32_t *)FixupPtr =
238
+ (RawInstr & 0xFFF ) | (static_cast <uint32_t >(Hi & 0xFFFFF000 ));
223
239
break ;
224
240
}
225
241
case R_RISCV_PCREL_LO12_I: {
242
+ // FIXME: We assume that R_RISCV_PCREL_HI20 is present in object code and
243
+ // pairs with current relocation R_RISCV_PCREL_LO12_I. So here may need a
244
+ // check.
226
245
auto RelHI20 = getRISCVPCRelHi20 (E);
227
246
if (!RelHI20)
228
247
return RelHI20.takeError ();
@@ -235,6 +254,9 @@ class ELFJITLinker_riscv : public JITLinker<ELFJITLinker_riscv> {
235
254
break ;
236
255
}
237
256
case R_RISCV_PCREL_LO12_S: {
257
+ // FIXME: We assume that R_RISCV_PCREL_HI20 is present in object code and
258
+ // pairs with current relocation R_RISCV_PCREL_LO12_S. So here may need a
259
+ // check.
238
260
auto RelHI20 = getRISCVPCRelHi20 (E);
239
261
int64_t Value = RelHI20->getTarget ().getAddress () +
240
262
RelHI20->getAddend () - E.getTarget ().getAddress ();
0 commit comments