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
{
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;
}