|
From: Petar J. <pe...@so...> - 2019-08-13 14:32:21
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=9d1b64dd4d5da843fe7a74caa4f86bc672b0eb33 commit 9d1b64dd4d5da843fe7a74caa4f86bc672b0eb33 Author: Petar Jovanovic <mip...@gm...> Date: Tue Aug 13 12:19:30 2019 +0000 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. Diff: --- 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 cbc491b..a3461e8 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 32165fd..bd9176c 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 286cea3..8a99f93 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 569dee9..9fbd0b6 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 49a4234..3bff7a9 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; |