|
From: Petar J. <mip...@gm...> - 2012-09-24 14:36:07
|
Hi Julian,
thanks for the reply. Sure it makes sense.
Check the patch below.
Regards,
Petar
Index: coregrind/m_signals.c
===================================================================
--- coregrind/m_signals.c (revision 13012)
+++ coregrind/m_signals.c (working copy)
@@ -1919,27 +1919,6 @@
info.si_signo = VKI_SIGTRAP;
info.si_code = VKI_TRAP_BRKPT; /* tjh: only ever called for a brkpt ins */
-# if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
- /* This is for teq on mips. Teq on mips for ins: 0xXXX1f4
- * cases VKI_SIGFPE not VKI_SIGTRAP
- */
- // JRS 2012-Jun-06: commented out until we know we need it
- // This isn't a clean solution; need something that avoids looking
- // at the guest code.
- //UInt *ins = (void*)(vgPlain_threads[tid].arch.vex.guest_PC-4);
- //UInt tcode = (((*ins) >> 6) & ((1 << 10) - 1));
- //if (tcode == VKI_BRK_OVERFLOW || tcode == VKI_BRK_DIVZERO) {
- // if (tcode == VKI_BRK_DIVZERO)
- // info.si_code = VKI_FPE_INTDIV;
- // else
- // info.si_code = VKI_FPE_INTOVF;
- // info.si_signo = VKI_SIGFPE;
- // info.si_errno = 0;
- // info.VKI_SIGINFO_si_addr
- // = (void*)(vgPlain_threads[tid].arch.vex.guest_PC-4);
- //}
-# endif
-
# if defined(VGP_x86_linux) || defined(VGP_amd64_linux)
uc.uc_mcontext.trapno = 3; /* tjh: this is the x86 trap number
for a breakpoint trap... */
@@ -1962,6 +1941,27 @@
resume_scheduler(tid);
}
+// Synthesise a SIGFPE.
+void VG_(synth_sigfpe)(ThreadId tid)
+{
+ vki_siginfo_t info;
+ struct vki_ucontext uc;
+
+ vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
+
+ VG_(memset)(&info, 0, sizeof(info));
+ VG_(memset)(&uc, 0, sizeof(uc));
+ info.si_signo = VKI_SIGFPE;
+ info.si_code = VKI_TRAP_BRKPT;
+
+ if (VG_(gdbserver_report_signal) (VKI_SIGFPE, tid)) {
+ resume_scheduler(tid);
+ deliver_signal(tid, &info, &uc);
+ }
+ else
+ resume_scheduler(tid);
+}
+
/* Make a signal pending for a thread, for later delivery.
VG_(poll_signals) will arrange for it to be delivered at the right
time.
Index: coregrind/pub_core_signals.h
===================================================================
--- coregrind/pub_core_signals.h (revision 13012)
+++ coregrind/pub_core_signals.h (working copy)
@@ -77,6 +77,7 @@
extern void VG_(synth_sigill) (ThreadId tid, Addr addr);
extern void VG_(synth_sigtrap) (ThreadId tid);
extern void VG_(synth_sigbus) (ThreadId tid);
+extern void VG_(synth_sigfpe) (ThreadId tid);
/* Extend the stack to cover addr, if possible */
extern Bool VG_(extend_stack)(Addr addr, UInt maxsize);
Index: coregrind/m_scheduler/scheduler.c
===================================================================
--- coregrind/m_scheduler/scheduler.c (revision 13012)
+++ coregrind/m_scheduler/scheduler.c (working copy)
@@ -200,6 +200,7 @@
case VEX_TRC_JMP_SIGTRAP: return "SIGTRAP";
case VEX_TRC_JMP_SIGSEGV: return "SIGSEGV";
case VEX_TRC_JMP_SIGBUS: return "SIGBUS";
+ case VEX_TRC_JMP_SIGFPE: return "SIGFPE";
case VEX_TRC_JMP_EMWARN: return "EMWARN";
case VEX_TRC_JMP_EMFAIL: return "EMFAIL";
case VEX_TRC_JMP_CLIENTREQ: return "CLIENTREQ";
@@ -1424,6 +1425,10 @@
VG_(synth_sigbus)(tid);
break;
+ case VEX_TRC_JMP_SIGFPE:
+ VG_(synth_sigfpe)(tid);
+ break;
+
case VEX_TRC_JMP_NODECODE: {
Addr addr = VG_(get_IP)(tid);
Index: VEX/priv/host_mips_defs.c
===================================================================
--- VEX/priv/host_mips_defs.c (revision 2544)
+++ VEX/priv/host_mips_defs.c (working copy)
@@ -3296,7 +3296,8 @@
case Ijk_NoRedir: trcval = VEX_TRC_JMP_NOREDIR; break;
case Ijk_SigTRAP: trcval = VEX_TRC_JMP_SIGTRAP; break;
//case Ijk_SigSEGV: trcval = VEX_TRC_JMP_SIGSEGV; break;
- case Ijk_SigBUS: trcval = VEX_TRC_JMP_SIGBUS; break;
+ case Ijk_SigBUS: trcval = VEX_TRC_JMP_SIGBUS; break;
+ case Ijk_SigFPE: trcval = VEX_TRC_JMP_SIGFPE; break;
case Ijk_Boring: trcval = VEX_TRC_JMP_BORING; break;
/* We don't expect to see the following being assisted. */
//case Ijk_Ret:
Index: VEX/priv/ir_defs.c
===================================================================
--- VEX/priv/ir_defs.c (revision 2544)
+++ VEX/priv/ir_defs.c (working copy)
@@ -1231,6 +1231,7 @@
case Ijk_SigTRAP: vex_printf("SigTRAP"); break;
case Ijk_SigSEGV: vex_printf("SigSEGV"); break;
case Ijk_SigBUS: vex_printf("SigBUS"); break;
+ case Ijk_SigFPE: vex_printf("SigFPE"); break;
case Ijk_Sys_syscall: vex_printf("Sys_syscall"); break;
case Ijk_Sys_int32: vex_printf("Sys_int32"); break;
case Ijk_Sys_int128: vex_printf("Sys_int128"); break;
Index: VEX/priv/guest_mips_toIR.c
===================================================================
--- VEX/priv/guest_mips_toIR.c (revision 2544)
+++ VEX/priv/guest_mips_toIR.c (working copy)
@@ -3126,43 +3126,72 @@
case 0x30: { /* TGE */
/*tge */ DIP("tge r%d, r%d %d", rs, rt, trap_code);
- stmt (IRStmt_Exit (binop (Iop_CmpLT32S, getIReg (rt), getIReg (rs)),
- Ijk_SigTRAP,
- IRConst_U32 (guest_PC_curr_instr + 4), OFFB_PC));
+ if (trap_code == 6 || trap_code == 7)
+ stmt (IRStmt_Exit (binop (Iop_CmpLT32S, getIReg (rt),
getIReg (rs)),
+ Ijk_SigFPE,
+ IRConst_U32 (guest_PC_curr_instr + 4),
OFFB_PC));
+ else
+ stmt (IRStmt_Exit (binop (Iop_CmpLT32S, getIReg (rt),
getIReg (rs)),
+ Ijk_SigTRAP,
+ IRConst_U32 (guest_PC_curr_instr + 4),
OFFB_PC));
break;
}
case 0x31: { /* TGEU */
/*tgeu */ DIP("tgeu r%d, r%d %d", rs, rt, trap_code);
- stmt (IRStmt_Exit (binop (Iop_CmpLT32U, getIReg (rt), getIReg (rs)),
- Ijk_SigTRAP,
- IRConst_U32 (guest_PC_curr_instr + 4), OFFB_PC));
+ if (trap_code == 6 || trap_code == 7)
+ stmt (IRStmt_Exit (binop (Iop_CmpLT32U, getIReg (rt),
getIReg (rs)),
+ Ijk_SigFPE,
+ IRConst_U32 (guest_PC_curr_instr + 4),
OFFB_PC));
+ else
+ stmt (IRStmt_Exit (binop (Iop_CmpLT32U, getIReg (rt),
getIReg (rs)),
+ Ijk_SigTRAP,
+ IRConst_U32 (guest_PC_curr_instr + 4),
OFFB_PC));
break;
}
case 0x32: { /* TLT */
/*tlt */ DIP("tlt r%d, r%d %d", rs, rt, trap_code);
- stmt (IRStmt_Exit (binop (Iop_CmpLT32S, getIReg (rs), getIReg (rt)),
- Ijk_SigTRAP,
- IRConst_U32 (guest_PC_curr_instr + 4), OFFB_PC));
+ if (trap_code == 6 || trap_code == 7)
+ stmt (IRStmt_Exit (binop (Iop_CmpLT32S, getIReg (rs),
getIReg (rt)),
+ Ijk_SigFPE,
+ IRConst_U32 (guest_PC_curr_instr + 4),
OFFB_PC));
+ else
+ stmt (IRStmt_Exit (binop (Iop_CmpLT32S, getIReg (rs),
getIReg (rt)),
+ Ijk_SigTRAP,
+ IRConst_U32 (guest_PC_curr_instr + 4),
OFFB_PC));
break;
}
case 0x33: { /* TLTU */
/*tltu */ DIP("tltu r%d, r%d %d", rs, rt, trap_code);
- stmt (IRStmt_Exit (binop (Iop_CmpLT32U, getIReg (rs), getIReg (rt)),
- Ijk_SigTRAP,
- IRConst_U32 (guest_PC_curr_instr + 4), OFFB_PC));
+ if (trap_code == 6 || trap_code == 7)
+ stmt (IRStmt_Exit (binop (Iop_CmpLT32U, getIReg (rs),
getIReg (rt)),
+ Ijk_SigFPE,
+ IRConst_U32 (guest_PC_curr_instr + 4),
OFFB_PC));
+ else
+ stmt (IRStmt_Exit (binop (Iop_CmpLT32U, getIReg (rs),
getIReg (rt)),
+ Ijk_SigTRAP,
+ IRConst_U32 (guest_PC_curr_instr + 4),
OFFB_PC));
break;
}
case 0x34: { /* TEQ */
/*teq */ DIP("teq r%d, r%d %d", rs, rt, trap_code);
- stmt (IRStmt_Exit(binop (Iop_CmpEQ32, getIReg (rs), getIReg (rt)),
- Ijk_SigTRAP, IRConst_U32 (guest_PC_curr_instr + 4), OFFB_PC));
+ if (trap_code == 6 || trap_code == 7)
+ stmt (IRStmt_Exit(binop (Iop_CmpEQ32, getIReg (rs), getIReg (rt)),
+ Ijk_SigFPE, IRConst_U32 (guest_PC_curr_instr + 4), OFFB_PC));
+ else
+ stmt (IRStmt_Exit(binop (Iop_CmpEQ32, getIReg (rs), getIReg (rt)),
+ Ijk_SigTRAP, IRConst_U32 (guest_PC_curr_instr + 4),
OFFB_PC));
break;
}
case 0x36: { /* TNE */
/*tne */ DIP("tne r%d, r%d %d", rs, rt, trap_code);
- stmt (IRStmt_Exit (binop (Iop_CmpNE32, getIReg (rs), getIReg (rt)),
- Ijk_SigTRAP,
- IRConst_U32 (guest_PC_curr_instr + 4), OFFB_PC));
+ if (trap_code == 6 || trap_code == 7)
+ stmt (IRStmt_Exit (binop (Iop_CmpNE32, getIReg (rs), getIReg (rt)),
+ Ijk_SigFPE,
+ IRConst_U32 (guest_PC_curr_instr + 4),
OFFB_PC));
+ else
+ stmt (IRStmt_Exit (binop (Iop_CmpNE32, getIReg (rs), getIReg (rt)),
+ Ijk_SigTRAP,
+ IRConst_U32 (guest_PC_curr_instr + 4),
OFFB_PC));
break;
}
case 0x0F: {
Index: VEX/priv/host_mips_isel.c
===================================================================
--- VEX/priv/host_mips_isel.c (revision 2544)
+++ VEX/priv/host_mips_isel.c (working copy)
@@ -3049,6 +3049,7 @@
case Ijk_NoRedir:
case Ijk_SigBUS:
case Ijk_SigTRAP:
+ case Ijk_SigFPE:
case Ijk_Sys_syscall:
case Ijk_TInval:
{
Index: VEX/pub/libvex_ir.h
===================================================================
--- VEX/pub/libvex_ir.h (revision 2544)
+++ VEX/pub/libvex_ir.h (working copy)
@@ -1872,6 +1872,7 @@
Ijk_SigTRAP, /* current instruction synths SIGTRAP */
Ijk_SigSEGV, /* current instruction synths SIGSEGV */
Ijk_SigBUS, /* current instruction synths SIGBUS */
+ Ijk_SigFPE, /* current instruction synths SIGFPE */
/* Unfortunately, various guest-dependent syscall kinds. They
all mean: do a syscall before continuing. */
Ijk_Sys_syscall, /* amd64 'syscall', ppc 'sc', arm 'svc #0' */
Index: VEX/pub/libvex_trc_values.h
===================================================================
--- VEX/pub/libvex_trc_values.h (revision 2544)
+++ VEX/pub/libvex_trc_values.h (working copy)
@@ -62,6 +62,8 @@
continuing */
#define VEX_TRC_JMP_SIGBUS 93 /* deliver SIGBUS before continuing */
+#define VEX_TRC_JMP_SIGFPE 97 /* deliver SIGFPE before continuing */
+
#define VEX_TRC_JMP_EMWARN 63 /* deliver emulation warning before
continuing */
#define VEX_TRC_JMP_EMFAIL 83 /* emulation fatal error; abort system */
|