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);
}
}
+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
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),