]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
mips: pass 7th argument in syscalls
authorPetar Jovanovic <mips32r2@gmail.com>
Tue, 13 Aug 2019 12:19:30 +0000 (12:19 +0000)
committerPetar Jovanovic <mips32r2@gmail.com>
Tue, 13 Aug 2019 12:20:38 +0000 (12:20 +0000)
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
coregrind/m_syswrap/priv_types_n_macros.h
coregrind/m_syswrap/syscall-mips32-linux.S
coregrind/m_syswrap/syscall-mips64-linux.S
coregrind/m_syswrap/syswrap-main.c

index cbc491bdd277ceb02454f416ea72e12d7dac7bd1..a3461e84f63a98dafaec48d417dd73766cafe879 100644 (file)
@@ -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 );
index 32165fd693f93b13c21b0e5dc84621380c48e71e..bd9176c75bbf7f4caff58523e0472b1f46759bba 100644 (file)
@@ -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
index 286cea3694880b589a5465c34cb4f99e2a6bd2bd..8a99f931b8c42d8103b70f52332fce99407a83d8 100644 (file)
@@ -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)
index 569dee9fea85fe75aa0e770511590f57b2c6ef0a..9fbd0b677448ffda6a287a46230e924af0bb552e 100644 (file)
@@ -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 */
index 49a42345532f525f3adce41169309cc272aea4ae..3bff7a92238c5212f1223fa76e84b19c911966f5 100644 (file)
@@ -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;