@@ -115,7 +115,7 @@ enum cheri_branch_ops
115
115
static inline struct cheri_frame *
116
116
getCHERIFrame (mcontext_t * context )
117
117
{
118
- #ifdef __CHERI_SANDBOX__
118
+ #ifdef __CHERI_PURE_CAPABILITY__
119
119
return & context -> mc_cheriframe ;
120
120
#else
121
121
assert_eq (context -> mc_cp2state_len , sizeof (struct cheri_frame ));
@@ -239,6 +239,18 @@ isInDelaySlot(mcontext_t *context)
239
239
return getImm (context -> cause , 31 , 1 );
240
240
}
241
241
242
+ static inline void
243
+ setPc (mcontext_t * context , register_t pc )
244
+ {
245
+ #ifdef __CHERI_PURE_CAPABILITY__
246
+ struct cheri_frame * frame = getCHERIFrame (context );
247
+
248
+ frame -> cf_pcc = __builtin_cheri_offset_set (frame -> cf_pcc , pc );
249
+ #else
250
+ context -> mc_pc = pc ;
251
+ #endif
252
+ }
253
+
242
254
/**
243
255
* If we are in a branch delay slot, work out what the next instruction will
244
256
* be. This is either the branch target or the instruction immediately
@@ -279,42 +291,42 @@ emulateBranch(mcontext_t *context, register_t pc)
279
291
"In delay slot for not-taken likely branch!" );
280
292
case MIPS_BRANCH_BLTZ :
281
293
case MIPS_BRANCH_BLTZAL :
282
- context -> mc_pc = ( (regVal < 0 ) ? branchPc : normalPc );
294
+ setPc ( context , (regVal < 0 ) ? branchPc : normalPc );
283
295
return true;
284
296
case MIPS_BRANCH_BGEZL :
285
297
case MIPS_BRANCH_BGEZ :
286
298
assert ((regVal < 0 ) &&
287
299
"In delay slot for not-taken likely branch!" );
288
300
case MIPS_BRANCH_BGEZAL :
289
301
case MIPS_BRANCH_BGEZALL :
290
- context -> mc_pc = ( (regVal >= 0 ) ? branchPc : normalPc );
302
+ setPc ( context , (regVal >= 0 ) ? branchPc : normalPc );
291
303
return true;
292
304
}
293
305
break ;
294
306
}
295
307
case MIPS_BRANCH_J :
296
308
case MIPS_BRANCH_JAL :
297
- context -> mc_pc = (getImm (instr , 25 , 0 )<<2 ) & ((pc >> 28 ) << 28 );
309
+ setPc ( context , (getImm (instr , 25 , 0 )<<2 ) & ((pc >> 28 ) << 28 ) );
298
310
return true;
299
311
case MIPS_BRANCH_JR :
300
312
case MIPS_BRANCH_JALR :
301
- context -> mc_pc = getReg (context , instr , 25 );
313
+ setPc ( context , getReg (context , instr , 25 ) );
302
314
return true;
303
315
case MIPS_BRANCH_BEQL :
304
316
case MIPS_BRANCH_BEQ :
305
- context -> mc_pc = ( (regVal == regVal2 ) ? branchPc : normalPc );
317
+ setPc ( context , (regVal == regVal2 ) ? branchPc : normalPc );
306
318
return true;
307
319
case MIPS_BRANCH_BNEL :
308
320
case MIPS_BRANCH_BNE :
309
- context -> mc_pc = ( (regVal != regVal2 ) ? branchPc : normalPc );
321
+ setPc ( context , (regVal != regVal2 ) ? branchPc : normalPc );
310
322
return true;
311
323
case MIPS_BRANCH_BLEZL :
312
324
case MIPS_BRANCH_BLEZ :
313
- context -> mc_pc = ( (regVal <= 0 ) ? branchPc : normalPc );
325
+ setPc ( context , (regVal <= 0 ) ? branchPc : normalPc );
314
326
return true;
315
327
case MIPS_BRANCH_BGTZL :
316
328
case MIPS_BRANCH_BGTZ :
317
- context -> mc_pc = ( (regVal > 0 ) ? branchPc : normalPc );
329
+ setPc ( context , (regVal > 0 ) ? branchPc : normalPc );
318
330
return true;
319
331
case MIPS_BRANCH_CHERI :
320
332
{
@@ -324,28 +336,26 @@ emulateBranch(mcontext_t *context, register_t pc)
324
336
{
325
337
void * __capability cap = getCapReg (context , instr , 20 );
326
338
bool tag = __builtin_cheri_tag_get (cap );
327
- context -> mc_pc = ( !tag ? branchPc : normalPc );
339
+ setPc ( context , !tag ? branchPc : normalPc );
328
340
return true;
329
341
}
330
342
case CHERI_BRANCH_CBTS :
331
343
{
332
344
void * __capability cap = getCapReg (context , instr , 20 );
333
345
bool tag = __builtin_cheri_tag_get (cap );
334
- context -> mc_pc = ( tag ? branchPc : normalPc );
346
+ setPc ( context , tag ? branchPc : normalPc );
335
347
return true;
336
348
}
337
349
case CHERI_BRANCH_CJR :
338
350
case CHERI_BRANCH_CJALR :
339
351
{
340
- context -> mc_pc = getReg (context , instr , 10 );
341
352
// FIXME: This is very ugly, but to fix it we need to
342
353
// define a new structure to replace cheri_frame.
343
354
struct cheri_frame * frame = getCHERIFrame (context );
344
- // Note: The /cap_size is safe here because if this is not
345
- // aligned then the load will fail anyway...
346
- int regno = offsetof(struct cheri_frame , cf_pcc ) / cap_size ;
347
- (((void * __capability * )frame )[regno ]) =
348
- getCapReg (context , instr , 15 );
355
+ frame -> cf_pcc = getCapReg (context , instr , 15 );
356
+ #ifndef __CHERI_PURE_CAPABILITY__
357
+ context -> mc_pc = __builtin_cheri_offset_get (frame -> cf_pcc );
358
+ #endif
349
359
return true;
350
360
}
351
361
}
@@ -363,8 +373,12 @@ capsighandler(int signo, siginfo_t *info __unused, ucontext_t *uap)
363
373
{
364
374
mcontext_t * context = & uap -> uc_mcontext ;
365
375
bool isDelaySlot = isInDelaySlot (context );
366
- register_t pc = context -> mc_pc ;
367
376
struct cheri_frame * frame = getCHERIFrame (context );
377
+ #ifdef __CHERI_PURE_CAPABILITY__
378
+ register_t pc = __builtin_cheri_offset_get (frame -> cf_pcc );
379
+ #else
380
+ register_t pc = context -> mc_pc ;
381
+ #endif
368
382
void * __capability reg = getCapRegAtIndex (context , frame -> cf_capcause & 0xff );
369
383
assert_eq (signo , SIGPROT );
370
384
assert (test_fault_handler );
@@ -386,7 +400,7 @@ capsighandler(int signo, siginfo_t *info __unused, ucontext_t *uap)
386
400
}
387
401
else
388
402
{
389
- context -> mc_pc += 4 ;
403
+ setPc ( context , pc + 4 ) ;
390
404
}
391
405
}
392
406
0 commit comments