diff mbox

[alpha] : If trap is the last insn in the function, emit NOP after the insn

Message ID CAFULd4YdG2RcP05y1ujub5wK-WGUD4jbB-PNAO202xa7Uefjgw@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak Aug. 6, 2017, 3:54 p.m. UTC
Hello!

CALL_PALL 0x81 that implements trap insn updates PC to point after the
insn before exception is raised. If the trap insn is the last insn in
the noreturn function, then updated PC actually points outside of
function boundaries. This confuses both, gdb and backtrace.

The solution is to emit NOP, when trap is the last active insn in the function.

2017-08-06  Uros Bizjak  <ubizjak@gmail.com>

    * config/alpha/alpha.c (alpha_reorg): If trap is the last active
    insn in the function, emit NOP after the insn.

Bootstrapped and regression tested on alphaev68-linux-gnu, where the
patch fixes TestBreakpoint gotools failure.

Committed to mainline.

Uros.
diff mbox

Patch

Index: alpha.c
===================================================================
--- alpha.c	(revision 250900)
+++ alpha.c	(working copy)
@@ -9456,6 +9456,25 @@  And in the noreturn case:
 
   if (current_function_has_exception_handlers ())
     alpha_pad_function_end ();
+
+  /* CALL_PAL that implements trap insn, updates program counter to point
+     after the insn.  In case trap is the last insn in the function,
+     emit NOP to guarantee that PC remains inside function boundaries.
+     This workaround is needed to get reliable backtraces.  */
+  
+  rtx_insn *insn = prev_active_insn (get_last_insn ());
+
+  if (insn && NONJUMP_INSN_P (insn))
+    {
+      rtx pat = PATTERN (insn);
+      if (GET_CODE (pat) == PARALLEL)
+	{
+	  rtx vec = XVECEXP (pat, 0, 0);
+	  if (GET_CODE (vec) == TRAP_IF
+	      && XEXP (vec, 0) == const1_rtx)
+	    emit_insn_after (gen_unop (), insn);
+	}
+    }
 }
 
 static void