|
From: <sv...@va...> - 2012-07-26 02:41:47
|
florian 2012-07-26 03:41:31 +0100 (Thu, 26 Jul 2012)
New Revision: 12787
Log:
Due to s390's dealings with invalid insns we need to do two things
- advance the guest_IA to the next insn after raising the signal
- adjusting the address in a complaint to point to the failing insn
(after guest_IA has been advanced)
Update testcases .exp files.
Modified files:
trunk/coregrind/m_scheduler/scheduler.c
trunk/coregrind/m_signals.c
trunk/none/tests/s390x/op00.stderr.exp1
trunk/none/tests/s390x/op00.stderr.exp2
trunk/none/tests/s390x/op_exception.stderr.exp
Modified: trunk/none/tests/s390x/op00.stderr.exp2 (+2 -2)
===================================================================
--- trunk/none/tests/s390x/op00.stderr.exp2 2012-07-26 03:14:28 +01:00 (rev 12786)
+++ trunk/none/tests/s390x/op00.stderr.exp2 2012-07-26 03:41:31 +01:00 (rev 12787)
@@ -1,7 +1,7 @@
vex s390->IR: unknown insn: 0000
valgrind: Unrecognised instruction at address 0x.........
- at 0x........: main (op00.c:5)
+ at 0x........: main (op00.c:3)
Your program just tried to execute an instruction that Valgrind
did not recognise. There are two possible reasons for this.
1. Your program has a bug and erroneously jumped to a non-code
@@ -15,5 +15,5 @@
Process terminating with default action of signal 4 (SIGILL)
Illegal opcode at address 0x........
- at 0x........: main (op00.c:5)
+ at 0x........: main (op00.c:3)
Modified: trunk/none/tests/s390x/op00.stderr.exp1 (+2 -2)
===================================================================
--- trunk/none/tests/s390x/op00.stderr.exp1 2012-07-26 03:14:28 +01:00 (rev 12786)
+++ trunk/none/tests/s390x/op00.stderr.exp1 2012-07-26 03:41:31 +01:00 (rev 12787)
@@ -1,7 +1,7 @@
vex s390->IR: unknown insn: 0000
valgrind: Unrecognised instruction at address 0x.........
- at 0x........: main (op00.c:5)
+ at 0x........: main (op00.c:3)
Your program just tried to execute an instruction that Valgrind
did not recognise. There are two possible reasons for this.
1. Your program has a bug and erroneously jumped to a non-code
@@ -15,5 +15,5 @@
Process terminating with default action of signal 4 (SIGILL)
Illegal opcode at address 0x........
- at 0x........: main (op00.c:5)
+ at 0x........: main (op00.c:3)
Modified: trunk/coregrind/m_scheduler/scheduler.c (+22 -5)
===================================================================
--- trunk/coregrind/m_scheduler/scheduler.c 2012-07-26 03:14:28 +01:00 (rev 12786)
+++ trunk/coregrind/m_scheduler/scheduler.c 2012-07-26 03:41:31 +01:00 (rev 12787)
@@ -1424,10 +1424,11 @@
VG_(synth_sigbus)(tid);
break;
- case VEX_TRC_JMP_NODECODE:
+ case VEX_TRC_JMP_NODECODE: {
+ Addr addr = VG_(get_IP)(tid);
+
VG_(umsg)(
- "valgrind: Unrecognised instruction at address %#lx.\n",
- VG_(get_IP)(tid));
+ "valgrind: Unrecognised instruction at address %#lx.\n", addr);
VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
#define M(a) VG_(umsg)(a "\n");
M("Your program just tried to execute an instruction that Valgrind" );
@@ -1441,9 +1442,25 @@
M("Either way, Valgrind will now raise a SIGILL signal which will" );
M("probably kill your program." );
#undef M
- VG_(synth_sigill)(tid, VG_(get_IP)(tid));
+
+#if defined(VGA_s390x)
+ /* Now that the complaint is out we need to adjust the guest_IA. The
+ reason is that -- after raising the exception -- execution will
+ continue with the insn that follows the invalid insn. As the first
+ 2 bits of the invalid insn determine its length in the usual way,
+ we can compute the address of the next insn here and adjust the
+ guest_IA accordingly. This adjustment is essential and tested by
+ none/tests/s390x/op_exception.c (which would loop forever
+ otherwise) */
+ UChar byte = ((UChar *)addr)[0];
+ UInt insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
+ Addr next_insn_addr = addr + insn_length;
+
+ VG_(set_IP)(tid, next_insn_addr);
+#endif
+ VG_(synth_sigill)(tid, addr);
break;
-
+ }
case VEX_TRC_JMP_TINVAL:
VG_(discard_translations)(
(Addr64)VG_(threads)[tid].arch.vex.guest_TISTART,
Modified: trunk/none/tests/s390x/op_exception.stderr.exp (+2 -2)
===================================================================
--- trunk/none/tests/s390x/op_exception.stderr.exp 2012-07-26 03:14:28 +01:00 (rev 12786)
+++ trunk/none/tests/s390x/op_exception.stderr.exp 2012-07-26 03:41:31 +01:00 (rev 12787)
@@ -14,7 +14,7 @@
probably kill your program.
vex s390->IR: unknown insn: 0000
valgrind: Unrecognised instruction at address 0x.........
- at 0x........: main (op_exception.c:27)
+ at 0x........: main (op_exception.c:23)
Your program just tried to execute an instruction that Valgrind
did not recognise. There are two possible reasons for this.
1. Your program has a bug and erroneously jumped to a non-code
@@ -40,7 +40,7 @@
probably kill your program.
vex s390->IR: unknown insn: 0000
valgrind: Unrecognised instruction at address 0x.........
- at 0x........: main (op_exception.c:34)
+ at 0x........: main (op_exception.c:30)
Your program just tried to execute an instruction that Valgrind
did not recognise. There are two possible reasons for this.
1. Your program has a bug and erroneously jumped to a non-code
Modified: trunk/coregrind/m_signals.c (+17 -3)
===================================================================
--- trunk/coregrind/m_signals.c 2012-07-26 03:14:28 +01:00 (rev 12786)
+++ trunk/coregrind/m_signals.c 2012-07-26 03:41:31 +01:00 (rev 12787)
@@ -1638,7 +1638,7 @@
obviously stupid place (not mapped readable) that would
likely cause a segfault. */
if (VG_(is_valid_tid)(tid)) {
-
+ Word first_ip_delta = 0;
#if defined(VGO_linux)
/* Make sure that the address stored in the stack pointer is
located in a mapped page. That is not necessarily so. E.g.
@@ -1658,11 +1658,25 @@
}
}
#endif
+#if defined(VGA_s390x)
+ if (sigNo == VKI_SIGILL) {
+ /* The guest instruction address has been adjusted earlier to
+ point to the insn following the one that could not be decoded.
+ When printing the back-trace here we need to undo that
+ adjustment so the first line in the back-trace reports the
+ correct address. */
+ Addr addr = (Addr)info->VKI_SIGINFO_si_addr;
+ UChar byte = ((UChar *)addr)[0];
+ Int insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
+
+ first_ip_delta = -insn_length;
+ }
+#endif
ExeContext* ec = VG_(am_is_valid_for_client)
(VG_(get_SP)(tid), sizeof(Addr), VKI_PROT_READ)
- ? VG_(record_ExeContext)( tid, 0/*first_ip_delta*/ )
+ ? VG_(record_ExeContext)( tid, first_ip_delta )
: VG_(record_depth_1_ExeContext)( tid,
- 0/*first_ip_delta*/ );
+ first_ip_delta );
vg_assert(ec);
VG_(pp_ExeContext)( ec );
}
|