]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
mips: add support for mips32/mips64 R6 to coregrind
authorPetar Jovanovic <mips32r2@gmail.com>
Thu, 1 Feb 2018 17:26:01 +0000 (18:26 +0100)
committerPetar Jovanovic <mips32r2@gmail.com>
Thu, 1 Feb 2018 17:28:18 +0000 (18:28 +0100)
Changes in PRE(sys_prctl), necessary to support new floating-point modes
in MIPS R6.

Part of MIPS32/64 Revision 6 changes.

Contributed by:
  Tamara Vlahovic, Aleksandar Rikalo and Aleksandra Karadzic.

Related BZ issue - #387410.

coregrind/m_redir.c
coregrind/m_syswrap/syswrap-mips32-linux.c
coregrind/m_translate.c

index 992427a762e9237b871d81f15496bd0b8acb3dba..aa65eafaad6009d43f99f5b1adcd08415c7c8d96 100644 (file)
@@ -1611,6 +1611,17 @@ void VG_(redir_initialise) ( void )
          (Addr)&VG_(mips64_linux_REDIR_FOR_index),
          complain_about_stripped_glibc_ldso
       );
+
+      add_hardwired_spec(
+         "ld-linux-mipsn8.so.1", "strlen",
+         (Addr)&VG_(mips64_linux_REDIR_FOR_strlen),
+         complain_about_stripped_glibc_ldso
+      );
+      add_hardwired_spec(
+         "ld-linux-mipsn8.so.1", "index",
+         (Addr)&VG_(mips64_linux_REDIR_FOR_index),
+         complain_about_stripped_glibc_ldso
+      );
    }
 
 #  elif defined(VGP_x86_solaris)
index 3dd43ddbdd0155cf2d11a3b6c8557eb6cefa39af..aecffe80d3f9a742f3b03a84ad46d21b0a94454f 100644 (file)
@@ -656,40 +656,65 @@ PRE(sys_prctl)
       case VKI_PR_SET_FP_MODE:
       {
          VexArchInfo vai;
+         Int known_bits = VKI_PR_FP_MODE_FR | VKI_PR_FP_MODE_FRE;
          VG_(machine_get_VexArchInfo)(NULL, &vai);
          /* Reject unsupported modes */
-         if ((ARG2 & ~VKI_PR_FP_MODE_FR) ||
-             ((ARG2 & VKI_PR_FP_MODE_FR) &&
-              !VEX_MIPS_HOST_FP_MODE(vai.hwcaps))) {
+         if (ARG2 & ~known_bits) {
             SET_STATUS_Failure(VKI_EOPNOTSUPP);
-         } else {
-            if (!(VG_(threads)[tid].arch.vex.guest_CP0_status &
-                  MIPS_CP0_STATUS_FR) != !(ARG2 & VKI_PR_FP_MODE_FR)) {
-               ThreadId t;
-               for (t = 1; t < VG_N_THREADS; t++) {
-                  if (VG_(threads)[t].status != VgTs_Empty) {
-                     if (ARG2 & VKI_PR_FP_MODE_FR) {
-                        VG_(threads)[t].arch.vex.guest_CP0_status |=
+            return;
+         }
+         if ((ARG2 & VKI_PR_FP_MODE_FR) && !VEX_MIPS_HOST_FP_MODE(vai.hwcaps)) {
+            SET_STATUS_Failure(VKI_EOPNOTSUPP);
+            return;
+         }
+         if ((ARG2 & VKI_PR_FP_MODE_FRE) && !VEX_MIPS_CPU_HAS_MIPSR6(vai.hwcaps)) {
+            SET_STATUS_Failure(VKI_EOPNOTSUPP);
+            return;
+         }
+         if (!(ARG2 & VKI_PR_FP_MODE_FR) && VEX_MIPS_CPU_HAS_MIPSR6(vai.hwcaps)) {
+            SET_STATUS_Failure(VKI_EOPNOTSUPP);
+            return;
+         }
+
+         if ((!(VG_(threads)[tid].arch.vex.guest_CP0_status &
+             MIPS_CP0_STATUS_FR) != !(ARG2 & VKI_PR_FP_MODE_FR)) ||
+            (!(VG_(threads)[tid].arch.vex.guest_CP0_Config5 &
+             MIPS_CONF5_FRE) != !(ARG2 & VKI_PR_FP_MODE_FRE))) {
+            ThreadId t;
+            for (t = 1; t < VG_N_THREADS; t++) {
+               if (VG_(threads)[t].status != VgTs_Empty) {
+                  if (ARG2 & VKI_PR_FP_MODE_FRE) {
+                     VG_(threads)[t].arch.vex.guest_CP0_Config5 |=
+                        MIPS_CONF5_FRE;
+                  } else {
+                     VG_(threads)[t].arch.vex.guest_CP0_Config5 &=
+                        ~MIPS_CONF5_FRE;
+                  }
+                  if (ARG2 & VKI_PR_FP_MODE_FR) {
+                     VG_(threads)[t].arch.vex.guest_CP0_status |=
                         MIPS_CP0_STATUS_FR;
-                     } else {
-                        VG_(threads)[t].arch.vex.guest_CP0_status &=
+                  } else {
+                     VG_(threads)[t].arch.vex.guest_CP0_status &=
                         ~MIPS_CP0_STATUS_FR;
-                     }
                   }
                }
-               /* Discard all translations */
-               VG_(discard_translations)(0, 0xfffffffful, "prctl(PR_SET_FP_MODE)");
+            /* Discard all translations */
+            VG_(discard_translations)(0, 0xfffffffful, "prctl(PR_SET_FP_MODE)");
             }
-            SET_STATUS_Success(0);
+         SET_STATUS_Success(0);
          }
          break;
       }
       case VKI_PR_GET_FP_MODE:
+      {
+         UInt ret = 0;
          if (VG_(threads)[tid].arch.vex.guest_CP0_status & MIPS_CP0_STATUS_FR)
-            SET_STATUS_Success(VKI_PR_FP_MODE_FR);
-         else
-            SET_STATUS_Success(0);
+            ret |= VKI_PR_FP_MODE_FR;
+         if (VG_(threads)[tid].arch.vex.guest_CP0_Config5 & MIPS_CONF5_FRE)
+            ret |= VKI_PR_FP_MODE_FRE;
+         SET_STATUS_Success(ret);
          break;
+      }
       default:
          WRAPPER_PRE_NAME(linux, sys_prctl)(tid, layout, arrghs, status, flags);
          break;
index 480a25990ac81b4e927bb6af57dd0e71ca21deeb..cfa279d34a28beb34632031107db828f61f99999 100644 (file)
@@ -1706,8 +1706,12 @@ Bool VG_(translate) ( ThreadId tid,
 
 #  if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
    ThreadArchState* arch = &VG_(threads)[tid].arch;
-   vex_abiinfo.guest_mips_fp_mode64 =
+   vex_abiinfo.guest_mips_fp_mode =
       !!(arch->vex.guest_CP0_status & MIPS_CP0_STATUS_FR);
+#  if defined(VGP_mips32_linux)
+   vex_abiinfo.guest_mips_fp_mode |=
+      (!!(arch->vex.guest_CP0_Config5 & MIPS_CONF5_FRE)) << 1;
+#  endif
    /* Compute guest__use_fallback_LLSC, overiding any settings of
       VG_(clo_fallback_llsc) that we know would cause the guest to
       fail (loop). */