]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
mips64: support for prctl(GET/SET_FP_MODE) syscalls
authorPetar Jovanovic <mips32r2@gmail.com>
Tue, 4 Oct 2016 15:19:10 +0000 (15:19 +0000)
committerPetar Jovanovic <mips32r2@gmail.com>
Tue, 4 Oct 2016 15:19:10 +0000 (15:19 +0000)
Add MIPS specific wrapper for prctl(GET/SET_FP_MODE) syscalls to
support FP32/FP64 mode switch.

Patch by Aleksandar Rikalo.

Related VEX change r3253.

Related bug - BZ #366079.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@16003

coregrind/m_syswrap/syswrap-mips64-linux.c
include/vki/vki-mips64-linux.h

index 7c5fbdbb519bec1e66f4023667f4daf0fc3bbfde..db051541e9d9fb463c79530f693fe2a8aea9c677 100644 (file)
@@ -312,7 +312,7 @@ DECL_TEMPLATE (mips_linux, sys_reboot);
 DECL_TEMPLATE (mips_linux, sys_cacheflush);
 DECL_TEMPLATE (mips_linux, sys_sched_rr_get_interval);
 DECL_TEMPLATE (mips_linux, sys_unshare);
-DECL_TEMPLATE (mips_linux, sys_arch_prctl);
+DECL_TEMPLATE (mips_linux, sys_prctl);
 DECL_TEMPLATE (mips_linux, sys_ptrace);
 DECL_TEMPLATE (mips_linux, sys_mmap);
 DECL_TEMPLATE (mips_linux, sys_rt_sigreturn);
@@ -616,6 +616,52 @@ POST(sys_pipe)
    }
 }
 
+PRE (sys_prctl)
+{
+   switch (ARG1) {
+      case VKI_PR_SET_FP_MODE:
+      {
+         VexArchInfo vai;
+         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))) {
+            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 |=
+                        MIPS_CP0_STATUS_FR;
+                     } else {
+                        VG_(threads)[t].arch.vex.guest_CP0_status &=
+                        ~MIPS_CP0_STATUS_FR;
+                     }
+                  }
+               }
+               /* Discard all translations */
+               VG_(discard_translations)(0, (ULong)(-1ll), "prctl(PR_SET_FP_MODE)");
+            }
+            SET_STATUS_Success(0);
+         }
+         break;
+      }
+      case VKI_PR_GET_FP_MODE:
+         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);
+         break;
+      default:
+         WRAPPER_PRE_NAME(linux, sys_prctl)(tid, layout, arrghs, status, flags);
+         break;
+   }
+}
+
 #undef PRE
 #undef POST
 
@@ -787,7 +833,7 @@ static SyscallTableEntry syscall_main_table[] = {
    LINX_ (__NR_vhangup, sys_vhangup),
    LINX_ (__NR_pivot_root,sys_pivot_root),
    LINXY (__NR__sysctl, sys_sysctl),
-   LINXY (__NR_prctl, sys_prctl),
+   PLAX_ (__NR_prctl, sys_prctl),
    LINXY (__NR_adjtimex, sys_adjtimex),
    GENX_ (__NR_setrlimit, sys_setrlimit),
    GENX_ (__NR_chroot, sys_chroot),
index 397509bcef8c046b126b159408d5f1e0063e4dbc..bfd86923483739a525ac2518d2282749158c6b04 100644 (file)
@@ -1011,6 +1011,13 @@ enum vki_sock_type {
 #define        VKI_ENOSYS       89  /* Function not implemented */
 #define        VKI_EOVERFLOW    79  /* Value too large for defined data type */
 
+//----------------------------------------------------------------------
+// From linux-3.7.0/arch/mips/include/uapi/asm/errno.h
+//----------------------------------------------------------------------
+
+#define VKI_EOPNOTSUPP   122 /* Operation not supported on transport
+                                endpoint */
+
 #endif // __VKI_MIPS64_LINUX_H
 
 /*--------------------------------------------------------------------*/