From: Florian Krohm Date: Thu, 26 Jul 2012 02:41:31 +0000 (+0000) Subject: Due to s390's dealings with invalid insns we need to do two things X-Git-Tag: svn/VALGRIND_3_8_0~81 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2d5ecc012c30eef0002cd464103313254000de29;p=thirdparty%2Fvalgrind.git 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. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12787 --- diff --git a/coregrind/m_scheduler/scheduler.c b/coregrind/m_scheduler/scheduler.c index 4a43724bf4..a1a3f9d818 100644 --- a/coregrind/m_scheduler/scheduler.c +++ b/coregrind/m_scheduler/scheduler.c @@ -1424,10 +1424,11 @@ VgSchedReturnCode VG_(scheduler) ( ThreadId tid ) 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 @@ VgSchedReturnCode VG_(scheduler) ( ThreadId tid ) 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)); - break; +#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, diff --git a/coregrind/m_signals.c b/coregrind/m_signals.c index 700e1c90f8..9cdf347869 100644 --- a/coregrind/m_signals.c +++ b/coregrind/m_signals.c @@ -1638,7 +1638,7 @@ static void default_action(const vki_siginfo_t *info, ThreadId tid) 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. @@ -1657,12 +1657,26 @@ static void default_action(const vki_siginfo_t *info, ThreadId tid) VG_PGROUNDDN(esp)); } } +#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 ); } diff --git a/none/tests/s390x/op00.stderr.exp1 b/none/tests/s390x/op00.stderr.exp1 index d35d6d20d7..b7552bf58a 100644 --- a/none/tests/s390x/op00.stderr.exp1 +++ b/none/tests/s390x/op00.stderr.exp1 @@ -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 @@ probably kill your program. 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) diff --git a/none/tests/s390x/op00.stderr.exp2 b/none/tests/s390x/op00.stderr.exp2 index d35d6d20d7..b7552bf58a 100644 --- a/none/tests/s390x/op00.stderr.exp2 +++ b/none/tests/s390x/op00.stderr.exp2 @@ -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 @@ probably kill your program. 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) diff --git a/none/tests/s390x/op_exception.stderr.exp b/none/tests/s390x/op_exception.stderr.exp index c76666888f..4373ff5bb3 100644 --- a/none/tests/s390x/op_exception.stderr.exp +++ b/none/tests/s390x/op_exception.stderr.exp @@ -14,7 +14,7 @@ Either way, Valgrind will now raise a SIGILL signal which will 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 @@ Either way, Valgrind will now raise a SIGILL signal which will 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