Index: none/tests/s390x/op00.stderr.exp1 =================================================================== --- none/tests/s390x/op00.stderr.exp1 (revision 12776) +++ none/tests/s390x/op00.stderr.exp1 (working copy) @@ -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) Index: none/tests/s390x/op00.stderr.exp2 =================================================================== --- none/tests/s390x/op00.stderr.exp2 (revision 12776) +++ none/tests/s390x/op00.stderr.exp2 (working copy) @@ -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) Index: none/tests/s390x/op_exception.stderr.exp =================================================================== --- none/tests/s390x/op_exception.stderr.exp (revision 12776) +++ none/tests/s390x/op_exception.stderr.exp (working copy) @@ -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 Index: coregrind/m_signals.c =================================================================== --- coregrind/m_signals.c (revision 12775) +++ coregrind/m_signals.c (working copy) @@ -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 ); } Index: coregrind/m_scheduler/scheduler.c =================================================================== --- coregrind/m_scheduler/scheduler.c (revision 12774) +++ coregrind/m_scheduler/scheduler.c (working copy) @@ -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,