]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 511713 - Refactor syscall argument handling master
authorPaul Floyd <pjfloyd@wanadoo.fr>
Thu, 6 Nov 2025 18:40:15 +0000 (19:40 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Thu, 6 Nov 2025 19:36:03 +0000 (20:36 +0100)
NEWS
coregrind/m_syswrap/priv_types_n_macros.h
coregrind/m_syswrap/syswrap-linux.c
coregrind/m_syswrap/syswrap-main.c
coregrind/m_syswrap/syswrap-xen.c
include/vki/vki-scnums-freebsd.h

diff --git a/NEWS b/NEWS
index 0941034a6d0650518259841f8cda3b49872a4add..a52af5119b3ef2bc8fe371d303aeeba42519fb77 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -29,6 +29,7 @@ are not entered into bugzilla tend to get forgotten about or ignored.
 487055  memcheck/tests/x86-linux/scalar fails running in Docker
 511329  Darwin and FreeBSD: Move setting of carry flag out of
         ML_(do_syscall_for_client_WRK)
+511713  Refactor syscall argument handling
 
 To see details of a given bug, visit
   https://bugs.kde.org/show_bug.cgi?id=XXXXXX
index ff5d6a2de71ca0559d29917cd1cc18fa72b375f5..66a11879e580d21f80a14ac6bafb8ced6c0e0967 100644 (file)
 /* Arguments for a syscall. */
 typedef
    struct SyscallArgs {
-      Word sysno;
+      Word canonical_sysno;
+#if defined(VGO_freebsd)
+      /*
+        * This may be the same as canonical_sysno (normal syscalls)
+       * Or it may be __NR_syscall or __NR___syscall
+       */
+      Word original_sysno;
+#endif
       RegWord arg1;
       RegWord arg2;
       RegWord arg3;
@@ -59,9 +66,6 @@ typedef
       RegWord arg6;
       RegWord arg7;
       RegWord arg8;
-#if defined(VGO_freebsd)
-      Word klass;
-#endif
    }
    SyscallArgs;
 
@@ -360,7 +364,7 @@ const SyscallTableEntry* ML_(get_freebsd_syscall_entry)( UInt sysno );
 
 /* Reference to the syscall's arguments -- the ones which the
    pre-wrapper may have modified, not the original copy. */
-#define SYSNO  (arrghs->sysno)
+#define SYSNO  (arrghs->canonical_sysno)
 #define ARG1   (arrghs->arg1)
 #define ARG2   (arrghs->arg2)
 #define ARG3   (arrghs->arg3)
index e8b200385b8f1b64ce948aeb8a6a342cf85f1fcd..0105fb98f38d866beb48b74d7c434b3c13c11bbb 100644 (file)
@@ -9577,7 +9577,7 @@ PRE(sys_ioctl)
          break;
 
       VG_(memset)(&harrghs, 0, sizeof(harrghs));
-      harrghs.sysno = args->op;
+      harrghs.canonical_sysno = args->op;
       harrghs.arg1 = args->arg[0];
       harrghs.arg2 = args->arg[1];
       harrghs.arg3 = args->arg[2];
@@ -12316,7 +12316,7 @@ POST(sys_ioctl)
           break;
 
        VG_(memset)(&harrghs, 0, sizeof(harrghs));
-       harrghs.sysno = args->op;
+       harrghs.canonical_sysno = args->op;
        harrghs.arg1 = args->arg[0];
        harrghs.arg2 = args->arg[1];
        harrghs.arg3 = args->arg[2];
index 45ece95cbf8cc528ef2308247c4ccd4fd24349bd..49f841ff7489bfdea8a05bd85b61c34a1ab59f52 100644 (file)
@@ -359,17 +359,10 @@ void do_syscall_for_client ( Int syscallno,
             syscall_mask, &saved, sizeof(vki_sigset_t)
          );
 #  elif defined(VGO_freebsd)
-   Word real_syscallno;
    UChar cflag;
    VG_(sigemptyset)(&saved);
-   if (tst->arch.vex.guest_SC_CLASS == VG_FREEBSD_SYSCALL0)
-      real_syscallno = __NR_syscall;
-   else if (tst->arch.vex.guest_SC_CLASS == VG_FREEBSD_SYSCALL198)
-      real_syscallno = __NR___syscall;
-   else
-      real_syscallno = syscallno;
    err = ML_(do_syscall_for_client_WRK)(
-            real_syscallno, &tst->arch.vex,
+            syscallno, &tst->arch.vex,
             syscall_mask, &saved, sizeof(vki_sigset_t),
             &cflag
          );
@@ -466,7 +459,10 @@ void do_syscall_for_client ( Int syscallno,
 static
 Bool eq_SyscallArgs ( SyscallArgs* a1, SyscallArgs* a2 )
 {
-   return a1->sysno == a2->sysno
+   return a1->canonical_sysno == a2->canonical_sysno
+#if defined(VGO_freebsd)
+          && a1->original_sysno == a2->original_sysno
+#endif
           && a1->arg1 == a2->arg1
           && a1->arg2 == a2->arg2
           && a1->arg3 == a2->arg3
@@ -517,7 +513,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
 {
 #if defined(VGP_x86_linux)
    VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
-   canonical->sysno = gst->guest_EAX;
+   canonical->canonical_sysno = gst->guest_EAX;
    canonical->arg1  = gst->guest_EBX;
    canonical->arg2  = gst->guest_ECX;
    canonical->arg3  = gst->guest_EDX;
@@ -529,7 +525,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
 
 #elif defined(VGP_amd64_linux)
    VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
-   canonical->sysno = gst->guest_RAX;
+   canonical->canonical_sysno = gst->guest_RAX;
    canonical->arg1  = gst->guest_RDI;
    canonical->arg2  = gst->guest_RSI;
    canonical->arg3  = gst->guest_RDX;
@@ -541,7 +537,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
 
 #elif defined(VGP_ppc32_linux)
    VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
-   canonical->sysno = gst->guest_GPR0;
+   canonical->canonical_sysno = gst->guest_GPR0;
    canonical->arg1  = gst->guest_GPR3;
    canonical->arg2  = gst->guest_GPR4;
    canonical->arg3  = gst->guest_GPR5;
@@ -553,7 +549,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
 
 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
    VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
-   canonical->sysno = gst->guest_GPR0;
+   canonical->canonical_sysno = gst->guest_GPR0;
    canonical->arg1  = gst->guest_GPR3;
    canonical->arg2  = gst->guest_GPR4;
    canonical->arg3  = gst->guest_GPR5;
@@ -576,20 +572,20 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
    // FreeBSD supports different calling conventions
    switch (gst->guest_EAX) {
    case __NR_syscall:
-      canonical->klass = VG_FREEBSD_SYSCALL0;
-      canonical->sysno = stack[1];
+      canonical->canonical_sysno = stack[1];
       stack += 1;
       break;
    case __NR___syscall:
-      canonical->klass = VG_FREEBSD_SYSCALL198;
-      canonical->sysno = stack[1];
+      canonical->canonical_sysno = stack[1];
       stack += 2;
       break;
    default:
-      canonical->klass = 0;
-      canonical->sysno = gst->guest_EAX;
+      canonical->canonical_sysno = gst->guest_EAX;
       break;
    }
+
+   canonical->original_sysno = gst->guest_EAX;
+
    // stack[0] is a (fake) return address
    canonical->arg1  = stack[1];
    canonical->arg2  = stack[2];
@@ -604,29 +600,22 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
    VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
    UWord *stack = (UWord *)gst->guest_RSP;
 
-   // FreeBSD supports different calling conventions
-   // @todo PJF this all seems over complicated to me
-   // SYSCALL_STD is OK but for the other
-   // two here we overwrite canonical->sysno with
-   // the final syscall number but then in do_syscall_for_client
-   // we switch real_syscallno back to __NR_syscall or __NR___syscall
    switch (gst->guest_RAX) {
    case __NR_syscall:
-      canonical->klass = VG_FREEBSD_SYSCALL0;
-      canonical->sysno = gst->guest_RDI;
+      canonical->canonical_sysno = gst->guest_RDI;
       break;
    case __NR___syscall:
-      canonical->klass = VG_FREEBSD_SYSCALL198;
-      canonical->sysno = gst->guest_RDI;
+      canonical->canonical_sysno = gst->guest_RDI;
       break;
    default:
-      canonical->klass = VG_FREEBSD_SYSCALL_STD;
-      canonical->sysno = gst->guest_RAX;
+      canonical->canonical_sysno = gst->guest_RAX;
       break;
    }
 
+   canonical->original_sysno = gst->guest_RAX;
+
    // stack[0] is a (fake) return address
-   if (canonical->klass == VG_FREEBSD_SYSCALL0 || canonical->klass == VG_FREEBSD_SYSCALL198) {
+   if (gst->guest_RAX == __NR_syscall || gst->guest_RAX == __NR___syscall) {
       // stack[0] is return address
       canonical->arg1  = gst->guest_RSI;
       canonical->arg2  = gst->guest_RDX;
@@ -652,19 +641,20 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
    VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla;
    switch (gst->guest_X8) {
    case __NR_syscall:
-      canonical->klass = VG_FREEBSD_SYSCALL0;
-      canonical->sysno = gst->guest_X0;
+      canonical->canonical_sysno = gst->guest_X0;
       break;
    case __NR___syscall:
-      canonical->klass = VG_FREEBSD_SYSCALL198;
-      canonical->sysno = gst->guest_X0;
+      canonical->canonical_sysno = gst->guest_X0;
       break;
    default:
-      canonical->klass = 0;
-      canonical->sysno = gst->guest_X8;
+      canonical->canonical_sysno = gst->guest_X8;
       break;
    }
-   if (canonical->klass == VG_FREEBSD_SYSCALL0 || canonical->klass == VG_FREEBSD_SYSCALL198) {
+
+   canonical->original_sysno = gst->guest_X8;
+
+   if (gst->guest_X8 == __NR_syscall ||
+       gst->guest_X8 == __NR___syscall) {
       canonical->arg1  = gst->guest_X1;
       canonical->arg2  = gst->guest_X2;
       canonical->arg3  = gst->guest_X3;
@@ -684,7 +674,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
 
 #elif defined(VGP_arm_linux)
    VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla;
-   canonical->sysno = gst->guest_R7;
+   canonical->canonical_sysno = gst->guest_R7;
    canonical->arg1  = gst->guest_R0;
    canonical->arg2  = gst->guest_R1;
    canonical->arg3  = gst->guest_R2;
@@ -696,7 +686,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
 
 #elif defined(VGP_arm64_linux)
    VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla;
-   canonical->sysno = gst->guest_X8;
+   canonical->canonical_sysno = gst->guest_X8;
    canonical->arg1  = gst->guest_X0;
    canonical->arg2  = gst->guest_X1;
    canonical->arg3  = gst->guest_X2;
@@ -708,8 +698,8 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
 
 #elif defined(VGP_mips32_linux)
    VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla;
-   canonical->sysno = gst->guest_r2;    // v0
-   if (canonical->sysno == __NR_exit) {
+   canonical->canonical_sysno = gst->guest_r2;    // v0
+   if (canonical->canonical_sysno == __NR_exit) {
       canonical->arg1 = gst->guest_r4;    // a0
       canonical->arg2 = 0;
       canonical->arg3 = 0;
@@ -717,7 +707,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
       canonical->arg5 = 0;
       canonical->arg6 = 0;
       canonical->arg8 = 0;
-   } else if (canonical->sysno != __NR_syscall) {
+   } else if (canonical->canonical_sysno != __NR_syscall) {
       canonical->arg1  = gst->guest_r4;    // a0
       canonical->arg2  = gst->guest_r5;    // a1
       canonical->arg3  = gst->guest_r6;    // a2
@@ -728,7 +718,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
       canonical->arg8 = 0;
    } else {
       // Fixme hack handle syscall()
-      canonical->sysno = gst->guest_r4;    // a0
+      canonical->canonical_sysno = gst->guest_r4;    // a0
       canonical->arg1  = gst->guest_r5;    // a1
       canonical->arg2  = gst->guest_r6;    // a2
       canonical->arg3  = gst->guest_r7;    // a3
@@ -741,7 +731,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
 
 #elif defined(VGP_mips64_linux)
    VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla;
-   canonical->sysno = gst->guest_r2;    // v0
+   canonical->canonical_sysno = gst->guest_r2;    // v0
    canonical->arg1  = gst->guest_r4;    // a0
    canonical->arg2  = gst->guest_r5;    // a1
    canonical->arg3  = gst->guest_r6;    // a2
@@ -753,7 +743,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
 
 #elif defined(VGP_nanomips_linux)
   VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla;
-   canonical->sysno = gst->guest_r2;    // t4
+   canonical->canonical_sysno = gst->guest_r2;    // t4
    canonical->arg1  = gst->guest_r4;    // a0
    canonical->arg2  = gst->guest_r5;    // a1
    canonical->arg3  = gst->guest_r6;    // a2
@@ -766,8 +756,8 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
    VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
    UWord *stack = (UWord *)gst->guest_ESP;
    // GrP fixme hope syscalls aren't called with really shallow stacks...
-   canonical->sysno = gst->guest_EAX;
-   if (canonical->sysno != 0) {
+   canonical->canonical_sysno = gst->guest_EAX;
+   if (canonical->canonical_sysno != 0) {
       // stack[0] is return address
       canonical->arg1  = stack[1];
       canonical->arg2  = stack[2];
@@ -784,8 +774,8 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
       // DDD: the tool can't see that the params have been shifted!  Can
       //      lead to incorrect checking, I think, because the PRRAn/PSARn
       //      macros will mention the pre-shifted args.
-      canonical->sysno = stack[1];
-      vg_assert(canonical->sysno != 0);
+      canonical->canonical_sysno = stack[1];
+      vg_assert(canonical->canonical_sysno != 0);
       canonical->arg1  = stack[2];
       canonical->arg2  = stack[3];
       canonical->arg3  = stack[4];
@@ -797,7 +787,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
       
       PRINT("SYSCALL[%d,?](0) syscall(%s, ...); please stand by...\n",
             VG_(getpid)(), /*tid,*/
-            VG_SYSNUM_STRING(canonical->sysno));
+            VG_SYSNUM_STRING(canonical->canonical_sysno));
    }
 
    // Here we determine what kind of syscall it was by looking at the
@@ -809,29 +799,29 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
    switch (trc) {
    case VEX_TRC_JMP_SYS_INT128:
       // int $0x80 = Unix, 64-bit result
-      vg_assert(canonical->sysno >= 0);
-      canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(canonical->sysno);
+      vg_assert(canonical->canonical_sysno >= 0);
+      canonical->canonical_sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(canonical->canonical_sysno);
       break;
    case VEX_TRC_JMP_SYS_SYSENTER:
       // syscall = Unix, 32-bit result
       // OR        Mach, 32-bit result
-      if (canonical->sysno >= 0) {
+      if (canonical->canonical_sysno >= 0) {
          // GrP fixme hack:  0xffff == I386_SYSCALL_NUMBER_MASK
-         canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(canonical->sysno
+         canonical->canonical_sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(canonical->canonical_sysno
                                                              & 0xffff);
       } else {
-         canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MACH(-canonical->sysno);
+         canonical->canonical_sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MACH(-canonical->canonical_sysno);
       }
       break;
    case VEX_TRC_JMP_SYS_INT129:
       // int $0x81 = Mach, 32-bit result
-      vg_assert(canonical->sysno < 0);
-      canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MACH(-canonical->sysno);
+      vg_assert(canonical->canonical_sysno < 0);
+      canonical->canonical_sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MACH(-canonical->canonical_sysno);
       break;
    case VEX_TRC_JMP_SYS_INT130:
       // int $0x82 = mdep, 32-bit result
-      vg_assert(canonical->sysno >= 0);
-      canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MDEP(canonical->sysno);
+      vg_assert(canonical->canonical_sysno >= 0);
+      canonical->canonical_sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MDEP(canonical->canonical_sysno);
       break;
    default: 
       vg_assert(0);
@@ -845,8 +835,8 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
    vg_assert(trc == VEX_TRC_JMP_SYS_SYSCALL);
 
    // GrP fixme hope syscalls aren't called with really shallow stacks...
-   canonical->sysno = gst->guest_RAX;
-   if (canonical->sysno != __NR_syscall) {
+   canonical->canonical_sysno = gst->guest_RAX;
+   if (canonical->canonical_sysno != __NR_syscall) {
       // stack[0] is return address
       canonical->arg1  = gst->guest_RDI;
       canonical->arg2  = gst->guest_RSI;
@@ -863,8 +853,8 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
       // DDD: the tool can't see that the params have been shifted!  Can
       //      lead to incorrect checking, I think, because the PRRAn/PSARn
       //      macros will mention the pre-shifted args.
-      canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(gst->guest_RDI);
-      vg_assert(canonical->sysno != __NR_syscall);
+      canonical->canonical_sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(gst->guest_RDI);
+      vg_assert(canonical->canonical_sysno != __NR_syscall);
       canonical->arg1  = gst->guest_RSI;
       canonical->arg2  = gst->guest_RDX;
       canonical->arg3  = gst->guest_R10;  // not rcx with syscall insn
@@ -876,14 +866,14 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
  
       PRINT("SYSCALL[%d,?](0) syscall(%s, ...); please stand by...\n",
             VG_(getpid)(), /*tid,*/
-            VG_SYSNUM_STRING(canonical->sysno));
+            VG_SYSNUM_STRING(canonical->canonical_sysno));
    }
 
-   // no canonical->sysno adjustment needed
+   // no canonical->canonical_sysno adjustment needed
 
 #elif defined(VGP_s390x_linux)
    VexGuestS390XState* gst = (VexGuestS390XState*)gst_vanilla;
-   canonical->sysno = gst->guest_SYSNO;
+   canonical->canonical_sysno = gst->guest_SYSNO;
    canonical->arg1  = gst->guest_r2;
    canonical->arg2  = gst->guest_r3;
    canonical->arg3  = gst->guest_r4;
@@ -895,7 +885,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
 
 #elif defined(VGP_riscv64_linux)
    VexGuestRISCV64State* gst = (VexGuestRISCV64State*)gst_vanilla;
-   canonical->sysno = gst->guest_x17; /* a7 */
+   canonical->canonical_sysno = gst->guest_x17; /* a7 */
    canonical->arg1  = gst->guest_x10; /* a0 */
    canonical->arg2  = gst->guest_x11; /* a1 */
    canonical->arg3  = gst->guest_x12; /* a2 */
@@ -908,7 +898,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
 #elif defined(VGP_x86_solaris)
    VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
    UWord *stack = (UWord *)gst->guest_ESP;
-   canonical->sysno = gst->guest_EAX;
+   canonical->canonical_sysno = gst->guest_EAX;
    /* stack[0] is a return address. */
    canonical->arg1  = stack[1];
    canonical->arg2  = stack[2];
@@ -932,8 +922,8 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
       break;
    case VEX_TRC_JMP_SYS_INT210:
       /* int $0xD2 = fasttrap */
-      canonical->sysno
-         = VG_SOLARIS_SYSCALL_CONSTRUCT_FASTTRAP(canonical->sysno);
+      canonical->canonical_sysno
+         = VG_SOLARIS_SYSCALL_CONSTRUCT_FASTTRAP(canonical->canonical_sysno);
       break;
    default:
       vg_assert(0);
@@ -943,7 +933,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
 #elif defined(VGP_amd64_solaris)
    VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
    UWord *stack = (UWord *)gst->guest_RSP;
-   canonical->sysno = gst->guest_RAX;
+   canonical->canonical_sysno = gst->guest_RAX;
    /* stack[0] is a return address. */
    canonical->arg1 = gst->guest_RDI;
    canonical->arg2 = gst->guest_RSI;
@@ -960,8 +950,8 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
       break;
    case VEX_TRC_JMP_SYS_INT210:
       /* int $0xD2 = fasttrap */
-      canonical->sysno
-         = VG_SOLARIS_SYSCALL_CONSTRUCT_FASTTRAP(canonical->sysno);
+      canonical->canonical_sysno
+         = VG_SOLARIS_SYSCALL_CONSTRUCT_FASTTRAP(canonical->canonical_sysno);
       break;
    default:
       vg_assert(0);
@@ -979,7 +969,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
 {
 #if defined(VGP_x86_linux)
    VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
-   gst->guest_EAX = canonical->sysno;
+   gst->guest_EAX = canonical->canonical_sysno;
    gst->guest_EBX = canonical->arg1;
    gst->guest_ECX = canonical->arg2;
    gst->guest_EDX = canonical->arg3;
@@ -989,7 +979,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
 
 #elif defined(VGP_amd64_linux)
    VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
-   gst->guest_RAX = canonical->sysno;
+   gst->guest_RAX = canonical->canonical_sysno;
    gst->guest_RDI = canonical->arg1;
    gst->guest_RSI = canonical->arg2;
    gst->guest_RDX = canonical->arg3;
@@ -999,7 +989,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
 
 #elif defined(VGP_ppc32_linux)
    VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
-   gst->guest_GPR0 = canonical->sysno;
+   gst->guest_GPR0 = canonical->canonical_sysno;
    gst->guest_GPR3 = canonical->arg1;
    gst->guest_GPR4 = canonical->arg2;
    gst->guest_GPR5 = canonical->arg3;
@@ -1009,7 +999,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
 
 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
    VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
-   gst->guest_GPR0 = canonical->sysno;
+   gst->guest_GPR0 = canonical->canonical_sysno;
    gst->guest_GPR3 = canonical->arg1;
    gst->guest_GPR4 = canonical->arg2;
    gst->guest_GPR5 = canonical->arg3;
@@ -1023,22 +1013,21 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
    UWord *stack = (UWord *)gst->guest_ESP;
 
    // stack[0] is a (fake) return address
-   switch (canonical->klass) {
-   case VG_FREEBSD_SYSCALL0:
-      gst->guest_EAX = __NR_syscall;
-      stack[1] = canonical->sysno;
+   switch (canonical->original_sysno) {
+   case __NR_syscall:
+      stack[1] = canonical->canonical_sysno;
       stack++;
       break;
-   case VG_FREEBSD_SYSCALL198:
-      gst->guest_EAX = __NR___syscall;
-      stack[1] = canonical->sysno;
+   case __NR___syscall:
+      stack[1] = canonical->canonical_sysno;
       stack += 2;
       break;
    default:
-      gst->guest_EAX = canonical->sysno;
       break;
    }
 
+   gst->guest_EAX = canonical->original_sysno;
+
    stack[1] = canonical->arg1;
    stack[2] = canonical->arg2;
    stack[3] = canonical->arg3;
@@ -1052,21 +1041,9 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
    VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
    UWord *stack = (UWord *)gst->guest_RSP;
 
-   // stack[0] is a (fake) return address
-   switch (canonical->klass) {
-   case VG_FREEBSD_SYSCALL0:
-      gst->guest_RAX = __NR_syscall;
-      break;
-   case VG_FREEBSD_SYSCALL198:
-      gst->guest_RAX = __NR___syscall;
-      break;
-   default:
-      gst->guest_RAX = canonical->sysno;
-      break;
-   }
-
-   if (canonical->klass == VG_FREEBSD_SYSCALL0 || canonical->klass == VG_FREEBSD_SYSCALL198) {
-       gst->guest_RDI = canonical->sysno;
+   if (canonical->original_sysno == __NR_syscall ||
+       canonical->original_sysno == __NR___syscall) {
+       gst->guest_RDI = canonical->canonical_sysno;
        gst->guest_RSI = canonical->arg1;
        gst->guest_RDX = canonical->arg2;
        gst->guest_R10 = canonical->arg3;
@@ -1086,21 +1063,14 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
        stack[2]       = canonical->arg8;
    }
 
+   gst->guest_RAX = canonical->original_sysno;
+
 #elif defined(VGP_arm64_freebsd)
    VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla;
-   switch (canonical->klass) {
-   case VG_FREEBSD_SYSCALL0:
-      gst->guest_X8 = __NR_syscall;
-      break;
-   case VG_FREEBSD_SYSCALL198:
-      gst->guest_X8 = __NR___syscall;
-      break;
-   default:
-      gst->guest_X8 = canonical->sysno;
-      break;
-   }
-   if (canonical->klass == VG_FREEBSD_SYSCALL0 || canonical->klass == VG_FREEBSD_SYSCALL198) {
-      gst->guest_X0 = canonical->sysno;
+
+   if (canonical->original_sysno == __NR_syscall ||
+       canonical->original_sysno == __NR___syscall) {
+      gst->guest_X0 = canonical->canonical_sysno;
       gst->guest_X1 = canonical->arg1;
       gst->guest_X2 = canonical->arg2;
       gst->guest_X3 = canonical->arg3;
@@ -1118,9 +1088,11 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
       gst->guest_X6 = canonical->arg7;
    }
 
+   gst->guest_X8 = canonical->original_sysno;
+
 #elif defined(VGP_arm_linux)
    VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla;
-   gst->guest_R7 = canonical->sysno;
+   gst->guest_R7 = canonical->canonical_sysno;
    gst->guest_R0 = canonical->arg1;
    gst->guest_R1 = canonical->arg2;
    gst->guest_R2 = canonical->arg3;
@@ -1130,7 +1102,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
 
 #elif defined(VGP_arm64_linux)
    VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla;
-   gst->guest_X8 = canonical->sysno;
+   gst->guest_X8 = canonical->canonical_sysno;
    gst->guest_X0 = canonical->arg1;
    gst->guest_X1 = canonical->arg2;
    gst->guest_X2 = canonical->arg3;
@@ -1142,7 +1114,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
    VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
    UWord *stack = (UWord *)gst->guest_ESP;
 
-   gst->guest_EAX = VG_DARWIN_SYSNO_FOR_KERNEL(canonical->sysno);
+   gst->guest_EAX = VG_DARWIN_SYSNO_FOR_KERNEL(canonical->canonical_sysno);
 
    // GrP fixme? gst->guest_TEMP_EFLAG_C = 0;
    // stack[0] is return address
@@ -1159,7 +1131,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
    VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
    UWord *stack = (UWord *)gst->guest_RSP;
 
-   gst->guest_RAX = VG_DARWIN_SYSNO_FOR_KERNEL(canonical->sysno);
+   gst->guest_RAX = VG_DARWIN_SYSNO_FOR_KERNEL(canonical->canonical_sysno);
    // GrP fixme? gst->guest_TEMP_EFLAG_C = 0;
 
    // stack[0] is return address
@@ -1174,7 +1146,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
 
 #elif defined(VGP_s390x_linux)
    VexGuestS390XState* gst = (VexGuestS390XState*)gst_vanilla;
-   gst->guest_SYSNO  = canonical->sysno;
+   gst->guest_SYSNO  = canonical->canonical_sysno;
    gst->guest_r2     = canonical->arg1;
    gst->guest_r3     = canonical->arg2;
    gst->guest_r4     = canonical->arg3;
@@ -1185,7 +1157,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
 #elif defined(VGP_mips32_linux)
    VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla;
    if (canonical->arg8 != __NR_syscall) {
-      gst->guest_r2 = canonical->sysno;
+      gst->guest_r2 = canonical->canonical_sysno;
       gst->guest_r4 = canonical->arg1;
       gst->guest_r5 = canonical->arg2;
       gst->guest_r6 = canonical->arg3;
@@ -1196,7 +1168,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
    } else {
       canonical->arg8 = 0;
       gst->guest_r2 = __NR_syscall;
-      gst->guest_r4 = canonical->sysno;
+      gst->guest_r4 = canonical->canonical_sysno;
       gst->guest_r5 = canonical->arg1;
       gst->guest_r6 = canonical->arg2;
       gst->guest_r7 = canonical->arg3;
@@ -1208,7 +1180,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
 
 #elif defined(VGP_nanomips_linux)
    VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla;
-   gst->guest_r2  = canonical->sysno;
+   gst->guest_r2  = canonical->canonical_sysno;
    gst->guest_r4  = canonical->arg1;
    gst->guest_r5  = canonical->arg2;
    gst->guest_r6  = canonical->arg3;
@@ -1219,7 +1191,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
    gst->guest_r11 = canonical->arg8;
 #elif defined(VGP_mips64_linux)
    VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla;
-   gst->guest_r2 = canonical->sysno;
+   gst->guest_r2 = canonical->canonical_sysno;
    gst->guest_r4 = canonical->arg1;
    gst->guest_r5 = canonical->arg2;
    gst->guest_r6 = canonical->arg3;
@@ -1231,7 +1203,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
 
 #elif defined(VGP_riscv64_linux)
    VexGuestRISCV64State* gst = (VexGuestRISCV64State*)gst_vanilla;
-   gst->guest_x17 = canonical->sysno; /* a7 */
+   gst->guest_x17 = canonical->canonical_sysno; /* a7 */
    gst->guest_x10 = canonical->arg1;  /* a0 */
    gst->guest_x11 = canonical->arg2;  /* a1 */
    gst->guest_x12 = canonical->arg3;  /* a2 */
@@ -1244,9 +1216,9 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
    UWord *stack = (UWord *)gst->guest_ESP;
 
    /* Fasttraps or anything else cannot go through this way. */
-   vg_assert(VG_SOLARIS_SYSNO_CLASS(canonical->sysno)
+   vg_assert(VG_SOLARIS_SYSNO_CLASS(canonical->canonical_sysno)
              == VG_SOLARIS_SYSCALL_CLASS_CLASSIC);
-   gst->guest_EAX = canonical->sysno;
+   gst->guest_EAX = canonical->canonical_sysno;
    /* stack[0] is a return address. */
    stack[1] = canonical->arg1;
    stack[2] = canonical->arg2;
@@ -1262,9 +1234,9 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
    UWord *stack = (UWord *)gst->guest_RSP;
 
    /* Fasttraps or anything else cannot go through this way. */
-   vg_assert(VG_SOLARIS_SYSNO_CLASS(canonical->sysno)
+   vg_assert(VG_SOLARIS_SYSNO_CLASS(canonical->canonical_sysno)
              == VG_SOLARIS_SYSCALL_CLASS_CLASSIC);
-   gst->guest_RAX = canonical->sysno;
+   gst->guest_RAX = canonical->canonical_sysno;
    /* stack[0] is a return address. */
    gst->guest_RDI = canonical->arg1;
    gst->guest_RSI = canonical->arg2;
@@ -2089,7 +2061,7 @@ void bad_before ( ThreadId              tid,
                   /*OUT*/UWord*         flags )
 {
    VG_(dmsg)("WARNING: unhandled %s syscall: %s\n",
-      VG_PLATFORM, VG_SYSNUM_STRING(args->sysno));
+      VG_PLATFORM, VG_SYSNUM_STRING(args->canonical_sysno));
    if (VG_(clo_verbosity) > 1) {
       VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
    }
@@ -2178,7 +2150,7 @@ Bool VG_(is_in_kernel_restart_syscall) ( ThreadId tid )
 Word VG_(is_in_syscall_no) (ThreadId tid )
 {
    vg_assert(tid < VG_N_THREADS);
-   return syscallInfo[tid].orig_args.sysno;
+   return syscallInfo[tid].orig_args.canonical_sysno;
 }
 
 static void ensure_initialised ( void )
@@ -2200,7 +2172,8 @@ static void ensure_initialised ( void )
 
 void VG_(client_syscall) ( ThreadId tid, UInt trc )
 {
-   Word                     sysno;
+   Word                     canonical_sysno;
+   Word                     original_sysno;
    ThreadState*             tst;
    const SyscallTableEntry* ent;
    SyscallArgLayout         layout;
@@ -2318,14 +2291,21 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc )
 
    /* Save the syscall number in the thread state in case the syscall 
       is interrupted by a signal. */
-   sysno = sci->orig_args.sysno;
+   canonical_sysno = sci->orig_args.canonical_sysno;
+#if defined(VGO_freebsd)
+   original_sysno = sci->orig_args.original_sysno;
+#else
+   /*
+    * When there is no "syscall syycall" the original
+    * and canonical sysno values are the same
+    */
+   original_sysno = sci->orig_args.canonical_sysno;
+#endif
+
 
-#  if defined(VGO_freebsd)
-   tst->arch.vex.guest_SC_CLASS = sci->orig_args.klass;
-#  endif
    /* It's sometimes useful, as a crude debugging hack, to get a
       stack trace at each (or selected) syscalls. */
-   if (0 && sysno == __NR_ioctl) {
+   if (0 && canonical_sysno == __NR_ioctl) {
       VG_(umsg)("\nioctl:\n");
       VG_(get_and_pp_StackTrace)(tid, 10);
       VG_(umsg)("\n");
@@ -2341,7 +2321,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc )
       because it only has a single syscall return convention and so
       there is no ambiguity involved in converting the post-signal
       machine state into a SysRes. */
-   tst->arch.vex.guest_SC_CLASS = VG_DARWIN_SYSNO_CLASS(sysno);
+   tst->arch.vex.guest_SC_CLASS = VG_DARWIN_SYSNO_CLASS(canonical_sysno);
 #  endif
 
    /* The default what-to-do-next thing is hand the syscall to the
@@ -2355,7 +2335,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc )
    /* Fetch the syscall's handlers.  If no handlers exist for this
       syscall, we are given dummy handlers which force an immediate
       return with ENOSYS. */
-   ent = get_syscall_entry(sysno);
+   ent = get_syscall_entry(canonical_sysno);
 
    /* Fetch the layout information, which tells us where in the guest
       state the syscall args reside.  This is a platform-dependent
@@ -2363,7 +2343,8 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc )
       checks (PRE_REG_READ calls) know which bits of the guest state
       they need to inspect. */
 #if defined(VGP_amd64_freebsd) || defined (VGP_arm64_freebsd)
-   if (sci->orig_args.klass == VG_FREEBSD_SYSCALL0 || sci->orig_args.klass == VG_FREEBSD_SYSCALL198) {
+   if (original_sysno == __NR_syscall ||
+       original_sysno == __NR___syscall) {
       syscall_syscall = True;
    }
 #endif
@@ -2383,7 +2364,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc )
    */
 
    PRINT("SYSCALL[%d,%u](%s) ",
-      VG_(getpid)(), tid, VG_SYSNUM_STRING(sysno));
+      VG_(getpid)(), tid, VG_SYSNUM_STRING(canonical_sysno));
 
    /* Do any pre-syscall actions */
    if (VG_(needs).syscall_wrapper) {
@@ -2396,7 +2377,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc )
       tmpv[5] = sci->orig_args.arg6;
       tmpv[6] = sci->orig_args.arg7;
       tmpv[7] = sci->orig_args.arg8;
-      VG_TDICT_CALL(tool_pre_syscall, tid, sysno,
+      VG_TDICT_CALL(tool_pre_syscall, tid, canonical_sysno,
                     &tmpv[0], sizeof(tmpv)/sizeof(tmpv[0]));
    }
 
@@ -2407,7 +2388,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc )
                   &sci->args, &sci->status, &sci->flags );
    
    /* If needed, gdbserver will report syscall entry to GDB */
-   VG_(gdbserver_report_syscall)(True, sysno, tid);
+   VG_(gdbserver_report_syscall)(True, canonical_sysno, tid);
 
    /* The pre-handler may have modified:
          sci->args
@@ -2420,7 +2401,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc )
    /* Now we proceed according to what the pre-handler decided. */
    vg_assert(sci->status.what == SsHandToKernel
              || sci->status.what == SsComplete);
-   vg_assert(sci->args.sysno == sci->orig_args.sysno);
+   vg_assert(sci->args.canonical_sysno == sci->orig_args.canonical_sysno);
 
    if (sci->status.what == SsComplete && !sr_isError(sci->status.sres)) {
       /* The pre-handler completed the syscall itself, declaring
@@ -2503,7 +2484,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc )
 
          /* Do the call, which operates directly on the guest state,
             not on our abstracted copies of the args/result. */
-         do_syscall_for_client(sysno, tst, &mask);
+         do_syscall_for_client(original_sysno, tst, &mask);
 
          /* do_syscall_for_client may not return if the syscall was
             interrupted by a signal.  In that case, flow of control is
@@ -2531,7 +2512,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc )
          /* Be decorative, if required. */
          if (VG_(clo_trace_syscalls)) {
             PRINT("SYSCALL[%d,%u](%s) ... [async] --> %s",
-                  VG_(getpid)(), tid, VG_SYSNUM_STRING(sysno),
+                  VG_(getpid)(), tid, VG_SYSNUM_STRING(canonical_sysno),
                   VG_(sr_as_string)(sci->status.sres));
          }
 
@@ -2544,7 +2525,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc )
             guest state.  Indeed doing so could be construed as
             incorrect. */
          SysRes sres 
-            = VG_(do_syscall)(sysno, sci->args.arg1, sci->args.arg2, 
+            = VG_(do_syscall)(canonical_sysno, sci->args.arg1, sci->args.arg2,
                                      sci->args.arg3, sci->args.arg4, 
                                      sci->args.arg5, sci->args.arg6,
                                      sci->args.arg7, sci->args.arg8 );
@@ -2567,7 +2548,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc )
       putSyscallStatusIntoGuestState( tid, &sci->status, &tst->arch.vex );
 
    /* If needed, gdbserver will report syscall return to GDB */
-   VG_(gdbserver_report_syscall)(False, sysno, tid);
+   VG_(gdbserver_report_syscall)(False, canonical_sysno, tid);
 
    /* Situation now:
       - the guest state is now correctly modified following the syscall
@@ -2601,7 +2582,7 @@ void VG_(post_syscall) (ThreadId tid)
    const SyscallTableEntry* ent;
    SyscallStatus            test_status;
    ThreadState*             tst;
-   Word sysno;
+   Word                     canonical_sysno;
 
    /* Preliminaries */
    vg_assert(VG_(is_valid_tid)(tid));
@@ -2627,12 +2608,12 @@ void VG_(post_syscall) (ThreadId tid)
    /* Get the system call number.  Because the pre-handler isn't
       allowed to mess with it, it should be the same for both the
       original and potentially-modified args. */
-   vg_assert(sci->args.sysno == sci->orig_args.sysno);
-   sysno = sci->args.sysno;
+   vg_assert(sci->args.canonical_sysno == sci->orig_args.canonical_sysno);
+   canonical_sysno = sci->args.canonical_sysno;
 
    getSyscallStatusFromGuestState( &test_status, &tst->arch.vex );
    if (!(sci->flags & SfNoWriteResult)) {
-      vg_assert(eq_SyscallStatus( sysno, &sci->status, &test_status ));
+      vg_assert(eq_SyscallStatus( canonical_sysno, &sci->status, &test_status ));
    }
    /* Failure of the above assertion on Darwin can indicate a problem
       in the syscall wrappers that pre-fail or pre-succeed the
@@ -2650,7 +2631,7 @@ void VG_(post_syscall) (ThreadId tid)
       - it exists, and
       - Success or (Failure and PostOnFail is set)
    */
-   ent = get_syscall_entry(sysno);
+   ent = get_syscall_entry(canonical_sysno);
    if (ent->after
        && ((!sr_isError(sci->status.sres))
            || (sr_isError(sci->status.sres)
@@ -2678,7 +2659,7 @@ void VG_(post_syscall) (ThreadId tid)
       tmpv[6] = sci->orig_args.arg7;
       tmpv[7] = sci->orig_args.arg8;
       VG_TDICT_CALL(tool_post_syscall, tid, 
-                    sysno,
+                    canonical_sysno,
                     &tmpv[0], sizeof(tmpv)/sizeof(tmpv[0]),
                     sci->status.sres);
    }
index e9f844e0d55f5cfdc75b355c88a3b66b1524a736..5abf6a992f51d62bd161e1cfcc0cf04caf19d27c 100644 (file)
@@ -2519,7 +2519,7 @@ static void bad_before ( ThreadId              tid,
                          /*OUT*/UWord*         flags )
 {
    VG_(dmsg)("WARNING: unhandled hypercall: %s\n",
-      VG_SYSNUM_STRING(args->sysno));
+      VG_SYSNUM_STRING(args->canonical_sysno));
    if (VG_(clo_verbosity) > 1) {
       VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
    }
index 924434f3fc34ab5540e55dc6d2cca208b8ea189d..83e4430c2004d9a73fb44b714689575dc5a45cb7 100644 (file)
 #include "config.h"
 #include <sys/syscall.h>
 
-// this is the syscall format used by e.g., libc functions like 'write'
-// this is the one used 99.999% of the time
-// the two others are only for experimental or testing use
-// (but we use them in the scalar tests).
-#define VG_FREEBSD_SYSCALL_STD 0
-// this is the syscall format used by 'syscall'
-#define VG_FREEBSD_SYSCALL0    1
-// this is the syscall format used by '__syscall'
-// it is the same as VG_FREEBSD_SYSCALL0 except that
-// it ensures that 64bit argument alignment is correct
-// that makes no difference for amd64, x86 not sure
-#define VG_FREEBSD_SYSCALL198  2
-
 // From sys/syscall.h
 
 // @todo PJF ugly leading double underscores