From 005252f3e2a64902079d92ac031e2a536919deb2 Mon Sep 17 00:00:00 2001 From: Dmitry Selyutin Date: Thu, 21 Sep 2023 23:19:15 +0300 Subject: [PATCH] caveat/ecall.c: refactor proxy ecall --- caveat/ecall.c | 70 +++++++++++++++++++++++++++++++------------------- caveat/ecall.h | 13 +++++++++- 2 files changed, 56 insertions(+), 27 deletions(-) diff --git a/caveat/ecall.c b/caveat/ecall.c index 2de27f0..327a51d 100644 --- a/caveat/ecall.c +++ b/caveat/ecall.c @@ -48,54 +48,66 @@ static Addr_t emulate_brk(Addr_t addr, struct pinfo_t* info) return newbrk; } - int proxy_ecall( struct core_t* cpu ) { - static long previous =0; + static long previous = 0; assert(insn(cpu->pc)->op_code == Op_ecall); - long rvnum = cpu->reg[17].l; - if (rvnum < 0 || rvnum >= rv_syscall_entries) { + long args[6]; + long guest = ecall_fetch(cpu, args); + if (guest < 0) { no_mapping: - fprintf(stderr, "RISC-V system call %ld has no mapping to host system\n", rvnum); + fprintf(stderr, "system call %ld has no mapping to host system\n", guest); fprintf(stderr, "Arguments(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", - cpu->reg[10].l, cpu->reg[11].l, cpu->reg[12].l, cpu->reg[13].l, cpu->reg[14].l, cpu->reg[15].l); + args[0], args[1], args[2], args[3], args[4], args[5]); abort(); } - struct ecall_entry const *entry = ecall_entry(rvnum); - long sysnum = entry->number; + struct ecall_entry const *entry = ecall_entry(guest); + long host = entry->number; char const *name = entry->name; + #ifdef DEBUG fprintf(stderr, "%10ld: %s[%ld:%ld](%lx, %lx, %lx, %lx, %lx, %lx)", cpu->counter.insn_executed-previous, - name, rvnum, sysnum, - cpu->reg[10].l, cpu->reg[11].l, cpu->reg[12].l, cpu->reg[13].l, cpu->reg[14].l, cpu->reg[15].l); + name, guest, host, + args[0], args[1], args[2], args[3], args[4], args[5]); previous = cpu->counter.insn_executed; #endif - switch (entry->number) { + switch (host) { case -1: goto no_mapping; case -2: - fprintf(stderr, "RISCV-V system call %s(#%ld) not supported on host system\n", name, sysnum); + fprintf(stderr, "system call %s(#%ld) not supported on host system\n", name, host); abort(); #if 0 case 12: /* sys_brk */ - cpu->reg[10].l = emulate_brk(cpu->reg[10].l, ¤t); + args[0] = emulate_brk(args[0], ¤t); break; #endif - case 60: /* sys_exit */ - case 231: /* sys_exit_group */\ +#if (defined(SYS_exit) || defined(SYS_exit_group)) +#ifdef SYS_exit + case SYS_exit: +#endif +#ifdef SYS_exit_group + case SYS_exit_group: +#endif return 1; +#endif /* (defined(SYS_exit) || defined(SYS_exit_group)) */ - case 13: /* sys_rt_sigaction */ +#ifdef SYS_rt_sigaction + case SYS_rt_sigaction: fprintf(stderr, "Trying to call rt_sigaction, always succeed without error.\n"); - cpu->reg[10].l = 0; // always succeed without error + args[0] = 0; // always succeed without error break; +#endif /* SYS_rt_sigaction */ - case 56: /* sys_clone */ +#ifdef SYS_clone + case SYS_clone: abort(); +#endif - case 96: /* gettimeofday */ +#ifdef SYS_gettimeofday + case SYS_gettimeofday: #define PRETEND_MIPS 1000 #ifdef PRETEND_MIPS { @@ -107,29 +119,35 @@ int proxy_ecall( struct core_t* cpu ) tv.tv_sec += tv.tv_usec / 1000000; // microseconds overflow tv.tv_usec %= 1000000; // fprintf(stderr, "gettimeofday(sec=%ld, usec=%4ld)\n", tv.tv_sec, tv.tv_usec); - memcpy(cpu->reg[10].p, &tv, sizeof tv); - cpu->reg[10].l = 0; + memcpy((void *)args[0], &tv, sizeof tv); + args[0] = 0; } break; #else goto default_case; #endif +#endif /* SYS_gettimeofday */ - case 3: /* sys_close */ - if (cpu->reg[10].l <= 2) { // Don't close stdin, stdout, stderr - cpu->reg[10].l = 0; +#ifdef SYS_close + case SYS_close: + if (args[0] <= 2) { // Don't close stdin, stdout, stderr + args[0] = 0; break; } goto default_case; +#endif default: default_case: - cpu->reg[10].l = syscall(sysnum, cpu->reg[10].l, cpu->reg[11].l, cpu->reg[12].l, cpu->reg[13].l, cpu->reg[14].l, cpu->reg[15].l); + args[0] = syscall(host, args[0], args[1], args[2], args[3], args[4], args[5]); break; } #ifdef DEBUG - fprintf(stderr, " return %lx\n", cpu->reg[10].l); + fprintf(stderr, " return %lx\n", args[0]); #endif + + ecall_store(args, cpu); + return 0; } diff --git a/caveat/ecall.h b/caveat/ecall.h index e0cc738..a5aed4c 100644 --- a/caveat/ecall.h +++ b/caveat/ecall.h @@ -21,7 +21,7 @@ ecall_entry(long id) { } static inline long -ecall_idargs(struct core_t const *cpu, long arguments[6]) { +ecall_fetch(struct core_t const *cpu, long arguments[6]) { arguments[0] = cpu->reg[10].l; arguments[1] = cpu->reg[11].l; arguments[2] = cpu->reg[12].l; @@ -31,3 +31,14 @@ ecall_idargs(struct core_t const *cpu, long arguments[6]) { return cpu->reg[17].l; } + +static inline void +ecall_store(long const arguments[6], struct core_t *cpu) +{ + cpu->reg[10].l = arguments[0]; + cpu->reg[11].l = arguments[1]; + cpu->reg[12].l = arguments[2]; + cpu->reg[13].l = arguments[3]; + cpu->reg[14].l = arguments[4]; + cpu->reg[15].l = arguments[5]; +} -- 2.30.2