Skip to content

Commit 2c16b2c

Browse files
committed
Fix undefined behavior caused by mismatched parameter types
When using 'make ENABLE_UBSAN=1 check CC=clang', the following error is observed: src/emulate.c:1110:13: runtime error: call to function do_fuse1 through pointer to incorrect function type 'bool (*)(struct riscv_internal *, const struct rv_insn *, unsigned long, unsigned int)' /home/eleanor/code/rv32emu/src/emulate.c:415: note: do_fuse1 defined here SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/emulate.c:1110:13 After fixing the first error with 'do_fuse1', similar errors were observed for other functions like 'do_fuse2', 'do_fuse3', 'do_fuse4', and 'do_jal'. The root cause was type mismatches in parameter declarations, where 'rv_insn_t *' was used instead of the expected 'const rv_insn_t *'. Since 'do_jal' was generated by the 'RVOP' macro in 'rv32emu_template.c', the macro was also corrected. These changes resolve the UBSAN errors and align all function pointers and implementations.
1 parent 25b9ac0 commit 2c16b2c

File tree

1 file changed

+45
-33
lines changed

1 file changed

+45
-33
lines changed

src/emulate.c

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -374,42 +374,45 @@ static uint32_t peripheral_update_ctr = 64;
374374
#endif
375375

376376
/* Interpreter-based execution path */
377-
#define RVOP(inst, code, asm) \
378-
static bool do_##inst(riscv_t *rv, rv_insn_t *ir, uint64_t cycle, \
379-
uint32_t PC) \
380-
{ \
381-
IIF(RV32_HAS(SYSTEM))(ctr++;, ) cycle++; \
382-
code; \
383-
IIF(RV32_HAS(SYSTEM)) \
384-
( \
385-
if (need_handle_signal) { \
386-
need_handle_signal = false; \
387-
return true; \
388-
}, ) nextop : PC += __rv_insn_##inst##_len; \
389-
IIF(RV32_HAS(SYSTEM)) \
390-
(IIF(RV32_HAS(JIT))( \
391-
, if (unlikely(need_clear_block_map)) { \
392-
block_map_clear(rv); \
393-
need_clear_block_map = false; \
394-
rv->csr_cycle = cycle; \
395-
rv->PC = PC; \
396-
return false; \
397-
}), ); \
398-
if (unlikely(RVOP_NO_NEXT(ir))) \
399-
goto end_op; \
400-
const rv_insn_t *next = ir->next; \
401-
MUST_TAIL return next->impl(rv, next, cycle, PC); \
402-
end_op: \
403-
rv->csr_cycle = cycle; \
404-
rv->PC = PC; \
405-
return true; \
377+
#define RVOP(inst, code, asm) \
378+
static bool do_##inst(riscv_t *rv, const rv_insn_t *ir, uint64_t cycle, \
379+
uint32_t PC) \
380+
{ \
381+
IIF(RV32_HAS(SYSTEM))(ctr++;, ) cycle++; \
382+
code; \
383+
IIF(RV32_HAS(SYSTEM)) \
384+
( \
385+
if (need_handle_signal) { \
386+
need_handle_signal = false; \
387+
return true; \
388+
}, ) nextop : PC += __rv_insn_##inst##_len; \
389+
IIF(RV32_HAS(SYSTEM)) \
390+
(IIF(RV32_HAS(JIT))( \
391+
, if (unlikely(need_clear_block_map)) { \
392+
block_map_clear(rv); \
393+
need_clear_block_map = false; \
394+
rv->csr_cycle = cycle; \
395+
rv->PC = PC; \
396+
return false; \
397+
}), ); \
398+
if (unlikely(RVOP_NO_NEXT(ir))) \
399+
goto end_op; \
400+
const rv_insn_t *next = ir->next; \
401+
MUST_TAIL return next->impl(rv, next, cycle, PC); \
402+
end_op: \
403+
rv->csr_cycle = cycle; \
404+
rv->PC = PC; \
405+
return true; \
406406
}
407407

408408
#include "rv32_template.c"
409409
#undef RVOP
410410

411411
/* multiple LUI */
412-
static bool do_fuse1(riscv_t *rv, rv_insn_t *ir, uint64_t cycle, uint32_t PC)
412+
static bool do_fuse1(riscv_t *rv,
413+
const rv_insn_t *ir,
414+
uint64_t cycle,
415+
uint32_t PC)
413416
{
414417
cycle += ir->imm2;
415418
opcode_fuse_t *fuse = ir->fuse;
@@ -426,7 +429,10 @@ static bool do_fuse1(riscv_t *rv, rv_insn_t *ir, uint64_t cycle, uint32_t PC)
426429
}
427430

428431
/* LUI + ADD */
429-
static bool do_fuse2(riscv_t *rv, rv_insn_t *ir, uint64_t cycle, uint32_t PC)
432+
static bool do_fuse2(riscv_t *rv,
433+
const rv_insn_t *ir,
434+
uint64_t cycle,
435+
uint32_t PC)
430436
{
431437
cycle += 2;
432438
rv->X[ir->rd] = ir->imm;
@@ -442,7 +448,10 @@ static bool do_fuse2(riscv_t *rv, rv_insn_t *ir, uint64_t cycle, uint32_t PC)
442448
}
443449

444450
/* multiple SW */
445-
static bool do_fuse3(riscv_t *rv, rv_insn_t *ir, uint64_t cycle, uint32_t PC)
451+
static bool do_fuse3(riscv_t *rv,
452+
const rv_insn_t *ir,
453+
uint64_t cycle,
454+
uint32_t PC)
446455
{
447456
cycle += ir->imm2;
448457
opcode_fuse_t *fuse = ir->fuse;
@@ -466,7 +475,10 @@ static bool do_fuse3(riscv_t *rv, rv_insn_t *ir, uint64_t cycle, uint32_t PC)
466475
}
467476

468477
/* multiple LW */
469-
static bool do_fuse4(riscv_t *rv, rv_insn_t *ir, uint64_t cycle, uint32_t PC)
478+
static bool do_fuse4(riscv_t *rv,
479+
const rv_insn_t *ir,
480+
uint64_t cycle,
481+
uint32_t PC)
470482
{
471483
cycle += ir->imm2;
472484
opcode_fuse_t *fuse = ir->fuse;

0 commit comments

Comments
 (0)