From: Petar Jovanovic Date: Thu, 1 Feb 2018 17:26:01 +0000 (+0100) Subject: mips: add support for mips32/mips64 R6 to coregrind X-Git-Tag: VALGRIND_3_14_0~168 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fd120874fbee2715a36e9eaaceccf6166c6d45c5;p=thirdparty%2Fvalgrind.git mips: add support for mips32/mips64 R6 to coregrind 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. --- diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c index 992427a762..aa65eafaad 100644 --- a/coregrind/m_redir.c +++ b/coregrind/m_redir.c @@ -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) diff --git a/coregrind/m_syswrap/syswrap-mips32-linux.c b/coregrind/m_syswrap/syswrap-mips32-linux.c index 3dd43ddbdd..aecffe80d3 100644 --- a/coregrind/m_syswrap/syswrap-mips32-linux.c +++ b/coregrind/m_syswrap/syswrap-mips32-linux.c @@ -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; diff --git a/coregrind/m_translate.c b/coregrind/m_translate.c index 480a25990a..cfa279d34a 100644 --- a/coregrind/m_translate.c +++ b/coregrind/m_translate.c @@ -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). */