|
From: Petar J. <mip...@gm...> - 2012-09-19 13:58:06
|
@Julian, @everyone,
we commented out one part in void VG_(synth_sigtrap) in coregrind/m_signals.c in
which we raise different signals depending on the code in the TEQ instruction.
Here is the source code:
# 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
Some of the remaining tests in the test suite need this. Do you think we should
fix/model this differently, or we should go with this for the time being?
Regards,
Petar
|
|
From: Julian S. <js...@ac...> - 2012-09-24 11:05:04
|
> Some of the remaining tests in the test suite need this. Do you think we
> should fix/model this differently,
Yes. There is already a framework in place to generate SIGSEGV, SIGBUS,
SIGTRAP, without having to look at the guest insn. So we just need to
extend it to handle SIGFPE.
* in guest_mips_toIR.c, change this to Ijk_SigFPE
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));
break;
}
* add Ijk_SigFPE to the IR definition, fix up the MIPS back end
to handle it,
* add VEX_TRC_JMP_SIGFPE, plus a case for it in scheduler.c
* add VG_(synth_sigfpe)
Makes sense? I am happy to review patches if you want.
J
|
|
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 */
|
|
From: Julian S. <js...@ac...> - 2012-09-24 14:47:58
|
Yes, looks fine (OK to land). Very minor thing -- the guest_mips_toIR.c
changes, can you limit the width to 80 chars pls? I try to keep the
width to 80 chars for efficiency of screen space use.
J
On Monday, September 24, 2012, Petar Jovanovic wrote:
> 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
> */
>
> ---------------------------------------------------------------------------
> --- Live Security Virtual Conference
> Exclusive live event will cover all the ways today's security and
> threat landscape has changed and how IT managers can respond. Discussions
> will include endpoint security, mobile security and the latest in malware
> threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
> _______________________________________________
> Valgrind-developers mailing list
> Val...@li...
> https://lists.sourceforge.net/lists/listinfo/valgrind-developers
|
|
From: Tom H. <to...@co...> - 2012-09-24 14:58:17
|
On 24/09/12 15:35, Petar Jovanovic wrote:
> +// 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;
Is that really the right code value?
Tom
--
Tom Hughes (to...@co...)
http://compton.nu/
|
|
From: Julian S. <js...@ac...> - 2012-09-24 15:10:18
|
On Monday, September 24, 2012, Tom Hughes wrote:
> On 24/09/12 15:35, Petar Jovanovic wrote:
> > +// 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;
>
> Is that really the right code value?
Hmm, good point. Maybe not. Petar, if this is a mips-specific
value, then I think it would be safer to put it inside ifdef(VGA_mips32),
and put vg_assert(0) for all other platforms, since right now
it is only on mips that this will be used.
J
|
|
From: Petar J. <mip...@gm...> - 2012-09-24 17:38:01
|
@Julian
Which line has exceeded 80 chars? The extra char ('+/-') in the patch might have
caused it to look that way.
@Julian,Tom
So, for the si_code, the answer is 'no', the value was not correct. The issue is
that the si_code variable can have two values (see the part of the original code
that we are deleting with this patch). The value in si_code depends on the
'code' field in the TEQ instruction. So, with a single synth_sigfpe we can only
cover one case, and ignore the second case (or maybe even assert for this case
in priv/guest_mips_toIR.c, which we should avoid, if possible - see the change
in the attached patch - I would like to remove that but I am leaving it for the
sake of conversation). Should we have two Ijk_SigFPEs, like Ijk_SigFPE1 and
Ijk_SigFPE2, and multiply the rest of the code needed for this? Or something
else?
P.
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,32 @@
resume_scheduler(tid);
}
+// Synthesise a SIGFPE.
+void VG_(synth_sigfpe)(ThreadId tid)
+{
+// Only tested on mips32
+#if !defined(VGA_mips32)
+ vg_assert(0);
+#else
+ 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_FPE_INTDIV;
+
+ if (VG_(gdbserver_report_signal) (VKI_SIGFPE, tid)) {
+ resume_scheduler(tid);
+ deliver_signal(tid, &info, &uc);
+ }
+ else
+ resume_scheduler(tid);
+#endif
+}
+
/* 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/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: 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: 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/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,84 @@
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 == 7)
+ stmt (IRStmt_Exit (binop (Iop_CmpLT32S, getIReg (rt),
getIReg (rs)),
+ Ijk_SigFPE,
+ IRConst_U32 (guest_PC_curr_instr + 4),
OFFB_PC));
+ else if (trap_code == 6)
+ goto decode_failure;
+ 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 == 7)
+ stmt (IRStmt_Exit (binop (Iop_CmpLT32U, getIReg (rt),
getIReg (rs)),
+ Ijk_SigFPE,
+ IRConst_U32 (guest_PC_curr_instr + 4),
OFFB_PC));
+ else if (trap_code == 6)
+ goto decode_failure;
+ 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 == 7)
+ stmt (IRStmt_Exit (binop (Iop_CmpLT32S, getIReg (rs),
getIReg (rt)),
+ Ijk_SigFPE,
+ IRConst_U32 (guest_PC_curr_instr + 4),
OFFB_PC));
+ else if (trap_code == 6)
+ goto decode_failure;
+ 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 == 7)
+ stmt (IRStmt_Exit (binop (Iop_CmpLT32U, getIReg (rs),
getIReg (rt)),
+ Ijk_SigFPE,
+ IRConst_U32 (guest_PC_curr_instr + 4),
OFFB_PC));
+ else if (trap_code == 6)
+ goto decode_failure;
+ 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 == 7)
+ stmt (IRStmt_Exit(binop (Iop_CmpEQ32, getIReg (rs), getIReg (rt)),
+ Ijk_SigFPE, IRConst_U32 (guest_PC_curr_instr + 4), OFFB_PC));
+ else if (trap_code == 6)
+ goto decode_failure;
+ 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 == 7)
+ stmt (IRStmt_Exit (binop (Iop_CmpNE32, getIReg (rs), getIReg (rt)),
+ Ijk_SigFPE,
+ IRConst_U32 (guest_PC_curr_instr + 4),
OFFB_PC));
+ else if (trap_code == 6)
+ goto decode_failure;
+ 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_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/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 */
|
|
From: Tom H. <to...@co...> - 2012-09-24 17:40:53
|
On 24/09/12 18:37, Petar Jovanovic wrote: > @Julian,Tom > So, for the si_code, the answer is 'no', the value was not correct. The issue is > that the si_code variable can have two values (see the part of the original code > that we are deleting with this patch). The value in si_code depends on the > 'code' field in the TEQ instruction. So, with a single synth_sigfpe we can only > cover one case, and ignore the second case (or maybe even assert for this case > in priv/guest_mips_toIR.c, which we should avoid, if possible - see the change > in the attached patch - I would like to remove that but I am leaving it for the > sake of conversation). Should we have two Ijk_SigFPEs, like Ijk_SigFPE1 and > Ijk_SigFPE2, and multiply the rest of the code needed for this? Or something > else? Yes, generating the right code is a sticky issue. I'm pretty sure some of the existing synthesised signals get it wrong because of this lack of information. What we've generally done I think is punted and just generated one of the codes, or maybe zero and hoped nothing minds too much about the details being exactly right. Tom -- Tom Hughes (to...@co...) http://compton.nu/ |
|
From: Petar J. <mip...@gm...> - 2012-10-09 12:56:53
|
Any additional feedback on this one?
More specific, any response on:
> Should we have two Ijk_SigFPEs, like Ijk_SigFPE1 and Ijk_SigFPE2, and
> multiply the rest of the code needed for this? Or something else?
Thanks.
Petar
On Mon, Sep 24, 2012 at 7:37 PM, Petar Jovanovic <mip...@gm...> wrote:
> @Julian
> Which line has exceeded 80 chars? The extra char ('+/-') in the patch might have
> caused it to look that way.
>
> @Julian,Tom
> So, for the si_code, the answer is 'no', the value was not correct. The issue is
> that the si_code variable can have two values (see the part of the original code
> that we are deleting with this patch). The value in si_code depends on the
> 'code' field in the TEQ instruction. So, with a single synth_sigfpe we can only
> cover one case, and ignore the second case (or maybe even assert for this case
> in priv/guest_mips_toIR.c, which we should avoid, if possible - see the change
> in the attached patch - I would like to remove that but I am leaving it for the
> sake of conversation). Should we have two Ijk_SigFPEs, like Ijk_SigFPE1 and
> Ijk_SigFPE2, and multiply the rest of the code needed for this? Or something
> else?
>
> P.
>
>
> 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,32 @@
> resume_scheduler(tid);
> }
>
> +// Synthesise a SIGFPE.
> +void VG_(synth_sigfpe)(ThreadId tid)
> +{
> +// Only tested on mips32
> +#if !defined(VGA_mips32)
> + vg_assert(0);
> +#else
> + 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_FPE_INTDIV;
> +
> + if (VG_(gdbserver_report_signal) (VKI_SIGFPE, tid)) {
> + resume_scheduler(tid);
> + deliver_signal(tid, &info, &uc);
> + }
> + else
> + resume_scheduler(tid);
> +#endif
> +}
> +
> /* 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/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: 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: 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/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,84 @@
>
> 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 == 7)
> + stmt (IRStmt_Exit (binop (Iop_CmpLT32S, getIReg (rt),
> getIReg (rs)),
> + Ijk_SigFPE,
> + IRConst_U32 (guest_PC_curr_instr + 4),
> OFFB_PC));
> + else if (trap_code == 6)
> + goto decode_failure;
> + 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 == 7)
> + stmt (IRStmt_Exit (binop (Iop_CmpLT32U, getIReg (rt),
> getIReg (rs)),
> + Ijk_SigFPE,
> + IRConst_U32 (guest_PC_curr_instr + 4),
> OFFB_PC));
> + else if (trap_code == 6)
> + goto decode_failure;
> + 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 == 7)
> + stmt (IRStmt_Exit (binop (Iop_CmpLT32S, getIReg (rs),
> getIReg (rt)),
> + Ijk_SigFPE,
> + IRConst_U32 (guest_PC_curr_instr + 4),
> OFFB_PC));
> + else if (trap_code == 6)
> + goto decode_failure;
> + 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 == 7)
> + stmt (IRStmt_Exit (binop (Iop_CmpLT32U, getIReg (rs),
> getIReg (rt)),
> + Ijk_SigFPE,
> + IRConst_U32 (guest_PC_curr_instr + 4),
> OFFB_PC));
> + else if (trap_code == 6)
> + goto decode_failure;
> + 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 == 7)
> + stmt (IRStmt_Exit(binop (Iop_CmpEQ32, getIReg (rs), getIReg (rt)),
> + Ijk_SigFPE, IRConst_U32 (guest_PC_curr_instr + 4), OFFB_PC));
> + else if (trap_code == 6)
> + goto decode_failure;
> + 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 == 7)
> + stmt (IRStmt_Exit (binop (Iop_CmpNE32, getIReg (rs), getIReg (rt)),
> + Ijk_SigFPE,
> + IRConst_U32 (guest_PC_curr_instr + 4),
> OFFB_PC));
> + else if (trap_code == 6)
> + goto decode_failure;
> + 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_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/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 */
|
|
From: Julian S. <js...@ac...> - 2012-10-11 13:30:34
|
On Tuesday, October 09, 2012, Petar Jovanovic wrote: > Any additional feedback on this one? > > More specific, any response on: > > Should we have two Ijk_SigFPEs, like Ijk_SigFPE1 and Ijk_SigFPE2, and > > multiply the rest of the code needed for this? Or something else? If it is only 2 cases you need, I would be OK with Ijk_SigFPE_IntDiv and Ijk_SigFPE_IntOvf (or whatever the names are). If it is more then I guess we should fix it properly. I prefer to avoid fixing it properly right now :-) since it will be a bit of work + extra complexity. Basically we'd have to make Ijk_SigFPE carry a value (eg, 32-bit int) from JIT generated code back to the scheduler. J |
|
From: Petar J. <mip...@gm...> - 2012-10-12 16:51:51
|
> If it is only 2 cases you need, I would be OK with Ijk_SigFPE_IntDiv and > Ijk_SigFPE_IntOvf (or whatever the names are). Two cases will be fine. Petar |