]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
mips: Add nanoMIPS support to Valgrind 3/4
authorPetar Jovanovic <mips32r2@gmail.com>
Tue, 31 Dec 2019 09:44:42 +0000 (09:44 +0000)
committerPetar Jovanovic <mips32r2@gmail.com>
Tue, 31 Dec 2019 09:44:42 +0000 (09:44 +0000)
Necessary changes to support nanoMIPS on Linux.

Part 3/4 - Coregrind and tools changes

Patch by Aleksandar Rikalo, Dimitrije Nikolic, Tamara Vlahovic,
Nikola Milutinovic and Aleksandra Karadzic.

Related KDE issue: #400872.

14 files changed:
Makefile.tool.am
cachegrind/cg_arch.c
cachegrind/cg_branchpred.c
coregrind/m_aspacemgr/aspacemgr-linux.c
coregrind/m_libcproc.c
coregrind/m_signals.c
coregrind/m_syscall.c
coregrind/m_syswrap/syswrap-generic.c
coregrind/m_syswrap/syswrap-linux.c
coregrind/m_syswrap/syswrap-main.c
coregrind/pub_core_syscall.h
drd/drd_bitmap.h
drd/drd_load_store.c
memcheck/mc_machine.c

index 677571fadb243f1b6c9a06313634ced59ea9e5f0..cc2fa0ee6fa42e99141c6466e14b9c365b107c04 100644 (file)
@@ -75,6 +75,10 @@ TOOL_LDFLAGS_MIPS32_LINUX = \
        -static -nodefaultlibs -nostartfiles -u __start @FLAG_NO_BUILD_ID@ \
        @FLAG_M32@
 
+TOOL_LDFLAGS_NANOMIPS_LINUX = \
+       -static -nodefaultlibs -nostartfiles -u __start @FLAG_NO_BUILD_ID@ \
+       @FLAG_M32@ -Wl,-no-relax
+
 TOOL_LDFLAGS_MIPS64_LINUX = \
        -static -nodefaultlibs -nostartfiles -u __start @FLAG_NO_BUILD_ID@ \
        @FLAG_M64@
index 7d03f21ad3c5ec02a33144c07f10586083501a81..57570dd6387c38a40d87b08b3e6d29b41c10cb27 100644 (file)
@@ -455,7 +455,7 @@ configure_caches(cache_t *I1c, cache_t *D1c, cache_t *LLc,
    *D1c = (cache_t) {   131072,  8, 256 };
    *LLc = (cache_t) { 50331648, 24, 256 };
 
-#elif defined(VGA_mips32)
+#elif defined(VGA_mips32) || defined(VGA_nanomips)
 
    // Set caches to default (for MIPS32-r2(mips 74kc))
    *I1c = (cache_t) {  32768, 4, 32 };
index eb7bf99c4fdf4989fbdfa484bc9c814fe86d384a..ba433ec2ce429fd8a2671eb6c4c3a6626e5add65 100644 (file)
@@ -43,7 +43,8 @@
 /* How many bits at the bottom of an instruction address are
    guaranteed to be zero? */
 #if defined(VGA_ppc32) || defined(VGA_ppc64be)  || defined(VGA_ppc64le) \
-    || defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_arm64)
+    || defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_nanomips) \
+    || defined(VGA_arm64)
 #  define N_IADDR_LO_ZERO_BITS 2
 #elif defined(VGA_x86) || defined(VGA_amd64)
 #  define N_IADDR_LO_ZERO_BITS 0
index 7c4c4eb734dde6166e713d650beee22d7ff1e519..0eb314316169f79651b92c55e3bca2c3e6460849 100644 (file)
@@ -2680,7 +2680,7 @@ static SysRes VG_(am_mmap_file_float_valgrind_flags) ( SizeT length, UInt prot,
    req.rkind = MAny;
    req.start = 0;
    #if defined(VGA_arm) || defined(VGA_arm64) \
-      || defined(VGA_mips32) || defined(VGA_mips64)
+      || defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_nanomips)
    aspacem_assert(VKI_SHMLBA >= VKI_PAGE_SIZE);
    #else
    aspacem_assert(VKI_SHMLBA == VKI_PAGE_SIZE);
index fc5da96974a8e5ba510c7daa0821bcb0c41ce6c7..e7aef7fe66e94a21e4ddd6d2e531aea1bd2f7d3a 100644 (file)
@@ -1252,6 +1252,10 @@ void VG_(invalidate_icache) ( void *ptr, SizeT nbytes )
                                  (UWord) nbytes, (UWord) 3);
    vg_assert( !sr_isError(sres) );
 
+# elif defined(VGA_nanomips)
+
+   __builtin___clear_cache(ptr, (char*)ptr + nbytes);
+
 #  endif
 }
 
index 4c3e3db177d0ce96418bc05a90f9580632eb906a..720fb5f661221cf72e945177461abb053ab6e448 100644 (file)
@@ -572,6 +572,22 @@ typedef struct SigQueue {
         (srP)->misc.MIPS64.r28 = (uc)->uc_mcontext.sc_regs[28]; \
       }
 
+#elif defined(VGP_nanomips_linux)
+#  define VG_UCONTEXT_INSTR_PTR(uc)   ((UWord)(((uc)->uc_mcontext.sc_pc)))
+#  define VG_UCONTEXT_STACK_PTR(uc)   ((UWord)((uc)->uc_mcontext.sc_regs[29]))
+#  define VG_UCONTEXT_FRAME_PTR(uc)   ((uc)->uc_mcontext.sc_regs[30])
+#  define VG_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_mcontext.sc_regs[2])
+#  define VG_UCONTEXT_SYSCALL_SYSRES(uc)                               \
+      VG_(mk_SysRes_nanomips_linux)((uc)->uc_mcontext.sc_regs[4])
+
+#  define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc)               \
+      { (srP)->r_pc = (uc)->uc_mcontext.sc_pc;                  \
+        (srP)->r_sp = (uc)->uc_mcontext.sc_regs[29];            \
+        (srP)->misc.MIPS32.r30 = (uc)->uc_mcontext.sc_regs[30]; \
+        (srP)->misc.MIPS32.r31 = (uc)->uc_mcontext.sc_regs[31]; \
+        (srP)->misc.MIPS32.r28 = (uc)->uc_mcontext.sc_regs[28]; \
+      }
+
 #elif defined(VGP_x86_solaris)
 #  define VG_UCONTEXT_INSTR_PTR(uc)       ((Addr)(uc)->uc_mcontext.gregs[VKI_EIP])
 #  define VG_UCONTEXT_STACK_PTR(uc)       ((Addr)(uc)->uc_mcontext.gregs[VKI_UESP])
@@ -985,6 +1001,13 @@ extern void my_sigreturn(void);
    "   syscall\n" \
    ".previous\n"
 
+#elif defined(VGP_nanomips_linux)
+#  define _MY_SIGRETURN(name) \
+    ".text\n" \
+   "my_sigreturn:\n" \
+   "   li $t4, " #name "\n" \
+   "   syscall[32]\n" \
+   ".previous\n"
 #elif defined(VGP_x86_solaris) || defined(VGP_amd64_solaris)
 /* Not used on Solaris. */
 #  define _MY_SIGRETURN(name) \
@@ -1084,7 +1107,7 @@ static void handle_SCSS_change ( Bool force_update )
 #        if !defined(VGP_ppc32_linux) && \
             !defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin) && \
             !defined(VGP_mips32_linux) && !defined(VGP_mips64_linux) && \
-            !defined(VGO_solaris)
+            !defined(VGP_nanomips_linux) && !defined(VGO_solaris)
          vg_assert(ksa_old.sa_restorer == my_sigreturn);
 #        endif
          VG_(sigaddset)( &ksa_old.sa_mask, VKI_SIGKILL );
@@ -2174,8 +2197,8 @@ void VG_(synth_sigtrap)(ThreadId tid)
 // Synthesise a SIGFPE.
 void VG_(synth_sigfpe)(ThreadId tid, UInt code)
 {
-// Only tested on mips32, mips64, and s390x
-#if !defined(VGA_mips32) && !defined(VGA_mips64) && !defined(VGA_s390x)
+// Only tested on mips32, mips64, s390x and nanomips.
+#if !defined(VGA_mips32) && !defined(VGA_mips64) && !defined(VGA_s390x) && !defined(VGA_nanomips)
    vg_assert(0);
 #else
    vki_siginfo_t info;
@@ -3046,7 +3069,8 @@ void VG_(sigstartup_actions) ( void )
       /* Get the old host action */
       ret = VG_(sigaction)(i, NULL, &sa);
 
-#     if defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
+#     if defined(VGP_x86_darwin) || defined(VGP_amd64_darwin) \
+      || defined(VGP_nanomips_linux)
       /* apparently we may not even ask about the disposition of these
          signals, let alone change them */
       if (ret != 0 && (i == VKI_SIGKILL || i == VKI_SIGSTOP))
index e4fb70c69324e634276760cf3e3e4a8e0af68511..4053d402474fe89986e1ae6aa62b75934c9bca91 100644 (file)
@@ -106,6 +106,13 @@ SysRes VG_(mk_SysRes_SuccessEx) ( UWord res, UWord resEx ) {
    safely test with -4095.
 */
 
+SysRes VG_(mk_SysRes_nanomips_linux) ( UWord a0 ) {
+   SysRes res;
+   res._isError = (a0 > 0xFFFFF000ul);
+   res._val = a0;
+   return res;
+}
+
 SysRes VG_(mk_SysRes_x86_linux) ( Int val ) {
    SysRes res;
    res._isError = val >= -4095 && val <= -1;
@@ -180,20 +187,30 @@ SysRes VG_(mk_SysRes_arm64_linux) ( Long val ) {
 }
 
 /* Generic constructors. */
+SysRes VG_(mk_SysRes_Success) ( UWord res ) {
+   SysRes r;
+   r._isError = False;
+   r._val     = res;
+   return r;
+}
+
+#if defined(VGP_nanomips_linux)
 SysRes VG_(mk_SysRes_Error) ( UWord err ) {
    SysRes r;
    r._isError = True;
-   r._val     = err;
+   r._val     = (UWord)(-(Word)err);
    return r;
 }
-
-SysRes VG_(mk_SysRes_Success) ( UWord res ) {
+#else
+SysRes VG_(mk_SysRes_Error) ( UWord err ) {
    SysRes r;
-   r._isError = False;
-   r._val     = res;
+   r._isError = True;
+   r._val     = err;
    return r;
 }
 
+#endif
+
 
 #elif defined(VGO_darwin)
 
@@ -824,6 +841,29 @@ asm (
    ".previous                              \n\t"
 );
 
+#elif defined(VGP_nanomips_linux)
+extern void do_syscall_WRK (
+         RegWord a1, RegWord a2, RegWord a3,
+         RegWord a4, RegWord a5, RegWord a6,
+         RegWord syscall_no, RegWord *res_a0);
+asm (
+   ".text                                  \n\t"
+   ".globl do_syscall_WRK                  \n\t"
+   ".type  do_syscall_WRK, @function       \n\t"
+   ".set push                              \n\t"
+   ".set noreorder                         \n\t"
+   "do_syscall_WRK:                        \n\t"
+   "   save 32, $a7                        \n\t"
+   "   move $t4, $a6                       \n\t"
+   "   syscall[32]                         \n\t"
+   "   restore 32, $a7                     \n\t"
+   "   sw $a0, 0($a7)                      \n\t"
+   "   jrc $ra                             \n\t"
+   ".size do_syscall_WRK, .-do_syscall_WRK \n\t"
+   ".set pop                               \n\t"
+   ".previous                              \n\t"
+);
+
 #elif defined(VGP_x86_solaris)
 
 extern ULong
@@ -1039,6 +1079,11 @@ SysRes VG_(do_syscall) ( UWord sysno, RegWord a1, RegWord a2, RegWord a3,
    RegWord A3 = (RegWord)v1_a3[1];
    return VG_(mk_SysRes_mips64_linux)( V0, V1, A3 );
 
+#elif defined(VGP_nanomips_linux)
+   RegWord reg_a0 = 0;
+   do_syscall_WRK(a1, a2, a3, a4, a5, a6, sysno, &reg_a0);
+   return VG_(mk_SysRes_nanomips_linux)(reg_a0);
+
 #  elif defined(VGP_x86_solaris)
    UInt val, val2, err = False;
    Bool restart;
index ab966485839f7b57cac449ef3a81adb55eeac88a..280c48f1b4a7e91bba028b36d2aee6e123d4491a 100644 (file)
@@ -2733,6 +2733,7 @@ PRE(sys_sync)
    PRE_REG_READ0(long, "sync");
 }
 
+#if !defined(VGP_nanomips_linux)
 PRE(sys_fstatfs)
 {
    FUSE_COMPATIBLE_MAY_BLOCK();
@@ -2760,6 +2761,7 @@ POST(sys_fstatfs64)
 {
    POST_MEM_WRITE( ARG3, ARG2 );
 }
+#endif
 
 PRE(sys_getsid)
 {
@@ -3299,6 +3301,7 @@ PRE(sys_fchmod)
    PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode);
 }
 
+#if !defined(VGP_nanomips_linux)
 PRE(sys_newfstat)
 {
    FUSE_COMPATIBLE_MAY_BLOCK();
@@ -3311,8 +3314,10 @@ POST(sys_newfstat)
 {
    POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
 }
+#endif
 
-#if !defined(VGO_solaris) && !defined(VGP_arm64_linux)
+#if !defined(VGO_solaris) && !defined(VGP_arm64_linux) && \
+    !defined(VGP_nanomips_linux)
 static vki_sigset_t fork_saved_mask;
 
 // In Linux, the sys_fork() function varies across architectures, but we
@@ -3817,6 +3822,7 @@ PRE(sys_link)
    PRE_MEM_RASCIIZ( "link(newpath)", ARG2);
 }
 
+#if !defined(VGP_nanomips_linux)
 PRE(sys_newlstat)
 {
    PRINT("sys_newlstat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )", ARG1,
@@ -3831,6 +3837,7 @@ POST(sys_newlstat)
    vg_assert(SUCCESS);
    POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
 }
+#endif
 
 PRE(sys_mkdir)
 {
@@ -4434,6 +4441,7 @@ PRE(sys_setuid)
    PRE_REG_READ1(long, "setuid", vki_uid_t, uid);
 }
 
+#if !defined(VGP_nanomips_linux)
 PRE(sys_newstat)
 {
    FUSE_COMPATIBLE_MAY_BLOCK();
@@ -4476,6 +4484,7 @@ POST(sys_statfs64)
 {
    POST_MEM_WRITE( ARG3, ARG2 );
 }
+#endif
 
 PRE(sys_symlink)
 {
index 6852366dda34b8d80a1c314f740686e442029135..87c513a21717fd02447d4bf654eee197ebde2f9c 100644 (file)
@@ -532,7 +532,7 @@ static SysRes clone_new_thread ( Word (*fn)(void *),
    ret = do_syscall_clone_nanomips_linux
       (ML_(start_thread_NORETURN), stack, flags, ctst,
        child_tidptr, parent_tidptr, NULL);
-   res = VG_ (mk_SysRes_nanomips_linux) (ret, 0);
+   res = VG_ (mk_SysRes_nanomips_linux) (ret);
 #else
 # error Unknown platform
 #endif
index 868645e4bca202332ae93d2aa78b264a93d4c268..cdb2663a2202cbe61b19d2d3a2fd05da04797dd3 100644 (file)
@@ -1039,8 +1039,7 @@ void getSyscallStatusFromGuestState ( /*OUT*/SyscallStatus*     canonical,
 #  elif defined(VGP_nanomips_linux)
    VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla;
    RegWord  a0 = gst->guest_r4;    // a0
-   RegWord  a1 = gst->guest_r5;    // a1
-   canonical->sres = VG_(mk_SysRes_nanomips_linux)(a0, a1);
+   canonical->sres = VG_(mk_SysRes_nanomips_linux)(a0);
    canonical->what = SsComplete;
 
 #  elif defined(VGP_x86_darwin)
@@ -1347,11 +1346,8 @@ void putSyscallStatusIntoGuestState ( /*IN*/ ThreadId tid,
    VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla;
    vg_assert(canonical->what == SsComplete);
    gst->guest_r4 = canonical->sres._val;
-   gst->guest_r5 = canonical->sres._valEx;
    VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
              OFFSET_mips32_r4, sizeof(UWord) );
-   VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
-             OFFSET_mips32_r5, sizeof(UWord) );
 
 #  elif defined(VGP_x86_solaris)
    VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
@@ -2480,8 +2476,7 @@ void ML_(fixup_guest_state_to_restart_syscall) ( ThreadArchState* arch )
       vg_assert(p[0] == 0x0A);
    }
 
-#elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
-   || defined(VGP_nanomips_linux)
+#elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
 
    arch->vex.guest_PC -= 4;             // sizeof(mips instr)
 
@@ -2513,6 +2508,27 @@ void ML_(fixup_guest_state_to_restart_syscall) ( ThreadArchState* arch )
 #     endif
    }
 
+#elif defined(VGP_nanomips_linux)
+   {
+      /* Make sure our caller is actually sane, and we're really backing
+         back over a syscall.
+      */
+      arch->vex.guest_PC -= 2;
+      /* PC has to be 16-bit aligned. */
+      vg_assert((arch->vex.guest_PC & 1) == 0);
+
+      UShort *p = ASSUME_ALIGNED(UShort *, (Addr)(arch->vex.guest_PC));
+
+      if (((*p) & 0xFFFD) != 0x1008) {
+         if (((*(p - 1)) & 0xFFFD) != 0x0008) {
+            VG_(message)(Vg_DebugMsg,
+                         "?! restarting over syscall at %#x %08lx\n",
+                         arch->vex.guest_PC, (UWord)(*p));
+            vg_assert(0);
+         }
+         arch->vex.guest_PC -= 2;
+      }
+   }
 #elif defined(VGP_x86_solaris)
    arch->vex.guest_EIP -= 2;   // sizeof(int $0x91) or sizeof(syscall)
 
index 854fca9e2f45d30b45b669c5b335e83a640214d9..49b8586a80c68e1ea6185d8308940473fab389b3 100644 (file)
@@ -84,7 +84,7 @@ extern SysRes VG_(mk_SysRes_mips32_linux)( UWord v0, UWord v1,
                                            UWord a3 );
 extern SysRes VG_(mk_SysRes_mips64_linux)( ULong v0, ULong v1,
                                            ULong a3 );
-extern SysRes VG_(mk_SysRes_nanomips_linux)( UWord a0, UWord a1 );
+extern SysRes VG_(mk_SysRes_nanomips_linux)( UWord a0);
 extern SysRes VG_(mk_SysRes_x86_solaris) ( Bool isErr, UInt val, UInt val2 );
 extern SysRes VG_(mk_SysRes_amd64_solaris) ( Bool isErr, ULong val, ULong val2 );
 extern SysRes VG_(mk_SysRes_Error)       ( UWord val );
index 95253dd6a26005e653cbd0b08a40e3bcf9492107..b288bee814f3f6adc92e1f0968249e0cac0c4324 100644 (file)
@@ -135,7 +135,8 @@ Addr make_address(const UWord a1, const UWord a0)
 
 /** Log2 of BITS_PER_UWORD. */
 #if defined(VGA_x86) || defined(VGA_ppc32) || defined(VGA_arm) \
-    || defined(VGA_mips32) || (defined(VGA_mips64) && defined(VGABI_N32))
+    || defined(VGA_mips32) || defined(VGA_nanomips) \
+    || (defined(VGA_mips64) && defined(VGABI_N32))
 #define BITS_PER_BITS_PER_UWORD 5
 #elif defined(VGA_amd64) || defined(VGA_ppc64be) || defined(VGA_ppc64le) \
       || defined(VGA_s390x) || (defined(VGA_mips64) && !defined(VGABI_N32)) \
index d7b4fdb729d3349b36dd18975e056d36896bfc06..c5b1306a98f8e19e1b874fa859653a15a8f250d9 100644 (file)
@@ -49,7 +49,7 @@
 #define STACK_POINTER_OFFSET OFFSET_arm64_XSP
 #elif defined(VGA_s390x)
 #define STACK_POINTER_OFFSET OFFSET_s390x_r15
-#elif defined(VGA_mips32)
+#elif defined(VGA_mips32) || defined(VGA_nanomips)
 #define STACK_POINTER_OFFSET OFFSET_mips32_r29
 #elif defined(VGA_mips64)
 #define STACK_POINTER_OFFSET OFFSET_mips64_r29
index c1031f7229abd292849540188598577636a7e726..7a87143b5347928b32d6136d4255d60486657b02 100644 (file)
@@ -1058,7 +1058,7 @@ static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB )
 
    /* --------------------- mips32 --------------------- */
 
-#  elif defined(VGA_mips32)
+#  elif defined(VGA_mips32) || defined(VGA_nanomips)
 
 #  define GOF(_fieldname) \
       (offsetof(VexGuestMIPS32State,guest_##_fieldname))
@@ -1433,6 +1433,12 @@ IRType MC_(get_otrack_reg_array_equiv_int_type) ( IRRegArray* arr )
    ppIRRegArray(arr);
    VG_(printf)("\n");
    tl_assert(0);
+/* --------------------- nanomips ------------------- */
+#  elif defined(VGA_nanomips)
+   VG_(printf)("get_reg_array_equiv_int_type(nanomips): unhandled: ");
+   ppIRRegArray(arr);
+   VG_(printf)("\n");
+   tl_assert(0);
 
    /* --------------------- mips64 --------------------- */
 #  elif defined(VGA_mips64)