caveat/ecall.c: refactor proxy ecall
authorDmitry Selyutin <ghostmansd@gmail.com>
Thu, 21 Sep 2023 20:19:15 +0000 (23:19 +0300)
committerDmitry Selyutin <ghostmansd@gmail.com>
Thu, 21 Sep 2023 21:13:48 +0000 (00:13 +0300)
caveat/ecall.c
caveat/ecall.h

index 2de27f0e2e8201dcdaf6ee26c26872af5949e2d2..327a51d7851f93443986bef64d23465151dc9e53 100644 (file)
@@ -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, &current);
+    args[0] = emulate_brk(args[0], &current);
     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;
 }
 
index e0cc738fa42d8b9a69d107ab96ebfe8c38da2fcc..a5aed4cb9ca1d3b36fbee8fa0b2492402f3c3829 100644 (file)
@@ -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];
+}