From: Paul Floyd Date: Thu, 6 Nov 2025 18:40:15 +0000 (+0100) Subject: Bug 511713 - Refactor syscall argument handling X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d21428c812bf5072850b7286bb3da8e5f9469bc8;p=thirdparty%2Fvalgrind.git Bug 511713 - Refactor syscall argument handling --- diff --git a/NEWS b/NEWS index 0941034a6..a52af5119 100644 --- 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 diff --git a/coregrind/m_syswrap/priv_types_n_macros.h b/coregrind/m_syswrap/priv_types_n_macros.h index ff5d6a2de..66a11879e 100644 --- a/coregrind/m_syswrap/priv_types_n_macros.h +++ b/coregrind/m_syswrap/priv_types_n_macros.h @@ -50,7 +50,14 @@ /* 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) diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index e8b200385..0105fb98f 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -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]; diff --git a/coregrind/m_syswrap/syswrap-main.c b/coregrind/m_syswrap/syswrap-main.c index 45ece95cb..d5cbe1357 100644 --- a/coregrind/m_syswrap/syswrap-main.c +++ b/coregrind/m_syswrap/syswrap-main.c @@ -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"); @@ -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); } diff --git a/coregrind/m_syswrap/syswrap-xen.c b/coregrind/m_syswrap/syswrap-xen.c index e9f844e0d..5abf6a992 100644 --- a/coregrind/m_syswrap/syswrap-xen.c +++ b/coregrind/m_syswrap/syswrap-xen.c @@ -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)); } diff --git a/include/vki/vki-scnums-freebsd.h b/include/vki/vki-scnums-freebsd.h index 924434f3f..83e4430c2 100644 --- a/include/vki/vki-scnums-freebsd.h +++ b/include/vki/vki-scnums-freebsd.h @@ -30,19 +30,6 @@ #include "config.h" #include -// 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