From 9d1b64dd4d5da843fe7a74caa4f86bc672b0eb33 Mon Sep 17 00:00:00 2001 From: Petar Jovanovic Date: Tue, 13 Aug 2019 12:19:30 +0000 Subject: [PATCH] mips: pass 7th argument in syscalls Only arg1 to arg6 have been passed down to kernel for syscalls. This patch ensures that arg7 is also passed down for syscalls. In addition to this, ensure that we have 16-byte aligned stack during mips64 syscall. Along with the change for sync_file_range, this will fix sync_file_range01 failure within LTP test suite. Patch by Nikola Milutinovic. --- coregrind/m_syscall.c | 37 ++++++++++------------ coregrind/m_syswrap/priv_types_n_macros.h | 11 ++++++- coregrind/m_syswrap/syscall-mips32-linux.S | 6 ++-- coregrind/m_syswrap/syscall-mips64-linux.S | 2 ++ coregrind/m_syswrap/syswrap-main.c | 11 +++++-- 5 files changed, 42 insertions(+), 25 deletions(-) diff --git a/coregrind/m_syscall.c b/coregrind/m_syscall.c index cbc491bdd2..a3461e84f6 100644 --- a/coregrind/m_syscall.c +++ b/coregrind/m_syscall.c @@ -774,7 +774,7 @@ static UWord do_syscall_WRK ( */ extern int do_syscall_WRK ( int a1, int a2, int a3, - int a4, int a5, int a6, int syscall_no, UWord *err, + int a4, int a5, int a6, int a7, int syscall_no, UWord *err, UWord *valHi, UWord* valLo ); asm ( @@ -784,15 +784,15 @@ asm ( ".set push \n\t" ".set noreorder \n\t" "do_syscall_WRK: \n\t" - " lw $2, 24($29) \n\t" - " syscall \n\t" - " lw $8, 28($29) \n\t" - " sw $7, ($8) \n\t" - " lw $8, 32($29) \n\t" - " sw $3, ($8) \n\t" /* store valHi */ - " lw $8, 36($29) \n\t" - " jr $31 \n\t" - " sw $2, ($8) \n\t" /* store valLo */ + " lw $2, 28($29) \n\t" + " syscall \n\t" + " lw $8, 32($29) \n\t" + " sw $7, ($8) \n\t" + " lw $8, 36($29) \n\t" + " sw $3, ($8) \n\t" /* store valHi */ + " lw $8, 40($29) \n\t" + " jr $31 \n\t" + " sw $2, ($8) \n\t" /* store valLo */ ".size do_syscall_WRK, .-do_syscall_WRK \n\t" ".set pop \n\t" ".previous \n\t" @@ -800,7 +800,7 @@ asm ( #elif defined(VGP_mips64_linux) extern RegWord do_syscall_WRK ( RegWord a1, RegWord a2, RegWord a3, RegWord a4, - RegWord a5, RegWord a6, RegWord syscall_no, + RegWord a5, RegWord a6, RegWord a7, RegWord syscall_no, RegWord* V1_A3_val ); asm ( ".text \n\t" @@ -809,15 +809,12 @@ asm ( ".set push \n\t" ".set noreorder \n\t" "do_syscall_WRK: \n\t" - " daddiu $29, $29, -8 \n\t" - " sd $11, 0($29) \n\t" - " move $2, $10 \n\t" + " move $2, $11 \n\t" " syscall \n\t" - " ld $11, 0($29) \n\t" - " daddiu $29, $29, 8 \n\t" - " sd $3, 0($11) \n\t" /* store v1 in last param */ + " ld $12, 0($29) \n\t" + " sd $3, 0($12) \n\t" /* store v1 in V1_A3_val */ " jr $31 \n\t" - " sd $7, 8($11) \n\t" /* store a3 in last param */ + " sd $7, 8($12) \n\t" /* store a3 in V1_A3_val */ ".size do_syscall_WRK, .-do_syscall_WRK \n\t" ".set pop \n\t" ".previous \n\t" @@ -1026,14 +1023,14 @@ SysRes VG_(do_syscall) ( UWord sysno, RegWord a1, RegWord a2, RegWord a3, UWord err = 0; UWord valHi = 0; UWord valLo = 0; - (void) do_syscall_WRK(a1,a2,a3,a4,a5,a6, sysno,&err,&valHi,&valLo); + (void) do_syscall_WRK(a1, a2, a3, a4, a5, a6, a7, sysno, &err, &valHi, &valLo); return VG_(mk_SysRes_mips32_linux)( valLo, valHi, (ULong)err ); #elif defined(VGP_mips64_linux) RegWord v1_a3[2]; v1_a3[0] = 0xFF00; v1_a3[1] = 0xFF00; - RegWord V0 = do_syscall_WRK(a1,a2,a3,a4,a5,a6,sysno,v1_a3); + RegWord V0 = do_syscall_WRK(a1, a2, a3, a4, a5, a6, a7, sysno, v1_a3); RegWord V1 = (RegWord)v1_a3[0]; RegWord A3 = (RegWord)v1_a3[1]; return VG_(mk_SysRes_mips64_linux)( V0, V1, A3 ); diff --git a/coregrind/m_syswrap/priv_types_n_macros.h b/coregrind/m_syswrap/priv_types_n_macros.h index 32165fd693..bd9176c75b 100644 --- a/coregrind/m_syswrap/priv_types_n_macros.h +++ b/coregrind/m_syswrap/priv_types_n_macros.h @@ -91,7 +91,7 @@ typedef || defined(VGP_ppc32_linux) \ || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \ || defined(VGP_arm_linux) || defined(VGP_s390x_linux) \ - || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) + || defined(VGP_arm64_linux) Int o_arg1; Int o_arg2; Int o_arg3; @@ -127,6 +127,15 @@ typedef Int o_arg6; Int s_arg7; Int s_arg8; +# elif defined(VGP_mips64_linux) + Int o_arg1; + Int o_arg2; + Int o_arg3; + Int o_arg4; + Int o_arg5; + Int o_arg6; + Int o_arg7; + Int o_arg8; # else # error "Unknown platform" # endif diff --git a/coregrind/m_syswrap/syscall-mips32-linux.S b/coregrind/m_syswrap/syscall-mips32-linux.S index 286cea3694..8a99f931b8 100644 --- a/coregrind/m_syswrap/syscall-mips32-linux.S +++ b/coregrind/m_syswrap/syscall-mips32-linux.S @@ -115,16 +115,18 @@ ML_(do_syscall_for_client_WRK): lw $5, OFFSET_mips32_r5($8) lw $6, OFFSET_mips32_r6($8) lw $7, OFFSET_mips32_r7($8) - subu $29, $29, 24 #set up the steck frame, + subu $29, $29, 32 #set up the steck frame, lw $9, OFFSET_mips32_r29($8) lw $10, 16($9) sw $10, 16($29) lw $10, 20($9) sw $10, 20($29) + lw $10, 24($9) + sw $10, 24($29) 2: syscall -3: addu $29, $29, 24 #set up the steck frame, +3: addu $29, $29, 32 #set up the steck frame, lw $8, 48($29) /* t0 == ThreadState */ sw $2, OFFSET_mips32_r2($8) diff --git a/coregrind/m_syswrap/syscall-mips64-linux.S b/coregrind/m_syswrap/syscall-mips64-linux.S index 569dee9fea..9fbd0b6774 100644 --- a/coregrind/m_syswrap/syscall-mips64-linux.S +++ b/coregrind/m_syswrap/syscall-mips64-linux.S @@ -96,6 +96,8 @@ ML_(do_syscall_for_client_WRK): ld $7, OFFSET_mips64_r7($5) /* a3 */ ld $8, OFFSET_mips64_r8($5) /* a4 */ ld $9, OFFSET_mips64_r9($5) /* a5 */ + ld $10, OFFSET_mips64_r10($5) /* a6 */ + ld $11, OFFSET_mips64_r11($5) /* a7 */ ld $5, OFFSET_mips64_r5($5) /* a1 */ ld $2, 0($29) /* syscallno */ diff --git a/coregrind/m_syswrap/syswrap-main.c b/coregrind/m_syswrap/syswrap-main.c index 49a4234553..3bff7a9223 100644 --- a/coregrind/m_syswrap/syswrap-main.c +++ b/coregrind/m_syswrap/syswrap-main.c @@ -560,6 +560,7 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, canonical->arg4 = *((UInt*) (gst->guest_r29 + 16)); // 16(guest_SP/sp) canonical->arg5 = *((UInt*) (gst->guest_r29 + 20)); // 20(guest_SP/sp) canonical->arg6 = *((UInt*) (gst->guest_r29 + 24)); // 24(guest_SP/sp) + canonical->arg7 = *((UInt*) (gst->guest_r29 + 28)); // 28(guest_SP/sp) canonical->arg8 = __NR_syscall; } @@ -572,6 +573,8 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, canonical->arg4 = gst->guest_r7; // a3 canonical->arg5 = gst->guest_r8; // a4 canonical->arg6 = gst->guest_r9; // a5 + canonical->arg7 = gst->guest_r10; // a6 + canonical->arg8 = gst->guest_r11; // a7 #elif defined(VGP_x86_darwin) VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; @@ -890,6 +893,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, gst->guest_r7 = canonical->arg4; *((UInt*) (gst->guest_r29 + 16)) = canonical->arg5; // 16(guest_GPR29/sp) *((UInt*) (gst->guest_r29 + 20)) = canonical->arg6; // 20(sp) + *((UInt*) (gst->guest_r29 + 24)) = canonical->arg7; // 24(sp) } else { canonical->arg8 = 0; gst->guest_r2 = __NR_syscall; @@ -900,6 +904,7 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, *((UInt*) (gst->guest_r29 + 16)) = canonical->arg4; // 16(guest_GPR29/sp) *((UInt*) (gst->guest_r29 + 20)) = canonical->arg5; // 20(sp) *((UInt*) (gst->guest_r29 + 24)) = canonical->arg6; // 24(sp) + *((UInt*) (gst->guest_r29 + 28)) = canonical->arg7; // 28(sp) } #elif defined(VGP_mips64_linux) @@ -911,6 +916,8 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, gst->guest_r7 = canonical->arg4; gst->guest_r8 = canonical->arg5; gst->guest_r9 = canonical->arg6; + gst->guest_r10 = canonical->arg7; + gst->guest_r11 = canonical->arg8; #elif defined(VGP_x86_solaris) VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; @@ -1461,8 +1468,8 @@ void getSyscallArgLayout ( /*OUT*/SyscallArgLayout* layout ) layout->o_arg4 = OFFSET_mips64_r7; layout->o_arg5 = OFFSET_mips64_r8; layout->o_arg6 = OFFSET_mips64_r9; - layout->uu_arg7 = -1; /* impossible value */ - layout->uu_arg8 = -1; /* impossible value */ + layout->o_arg7 = OFFSET_mips64_r10; + layout->o_arg8 = OFFSET_mips64_r11; #elif defined(VGP_x86_darwin) layout->o_sysno = OFFSET_x86_EAX; -- 2.47.2