S390: Recognize special jumps in prologue parser
authorAndreas Arnez <arnez@linux.vnet.ibm.com>
Wed, 9 Mar 2016 16:12:29 +0000 (17:12 +0100)
committerAndreas Arnez <arnez@linux.vnet.ibm.com>
Wed, 9 Mar 2016 16:12:29 +0000 (17:12 +0100)
Functions compiled with the gcc option `-mhotpatch' may start with a
branch-never BRCL instruction as a 6-byte NOP.  And functions compiled
with `-mstack-size' contain a BRC instruction in their prologue that is
actually a conditional trap.  Both of these special jumps cause the
prologue parser to stop and yield bad unwinding results.

This change makes the prologue analyzer recognize such special jumps and
ignore them.

gdb/ChangeLog:

* s390-linux-tdep.c (s390_analyze_prologue): Ignore BRC and BRCL
instructions that do nothing or are conditional traps.

gdb/ChangeLog
gdb/s390-linux-tdep.c

index 0674836fb28cf67c0623919b3d4f65bde41aa65b..6c33877d9d24a7f160a9eba5dc56c7f1a0642ae4 100644 (file)
@@ -1,3 +1,8 @@
+2016-03-09  Andreas Arnez  <arnez@linux.vnet.ibm.com>
+
+       * s390-linux-tdep.c (s390_analyze_prologue): Ignore BRC and BRCL
+       instructions that do nothing or are conditional traps.
+
 2016-03-09  Andreas Arnez  <arnez@linux.vnet.ibm.com>
 
        * s390-linux-tdep.c (s390_prologue_frame_unwind_cache): Store
index 155bc66bd7c0c189ea6bae9f3d4ff0a5bac2aaa8..950696ea328a28d032e20d38ad9bb995be5e4d7c 100644 (file)
@@ -1567,13 +1567,25 @@ s390_analyze_prologue (struct gdbarch *gdbarch,
            break;
        }
 
+      /* BRC/BRCL -- branch relative on condition.  Ignore "branch
+        never", branch to following instruction, and "conditional
+        trap" (BRC +2).  Otherwise terminate search.  */
+      else if (is_ri (insn, op1_brc, op2_brc, &r1, &i2))
+       {
+         if (r1 != 0 && i2 != 1 && i2 != 2)
+           break;
+       }
+      else if (is_ril (insn, op1_brcl, op2_brcl, &r1, &i2))
+       {
+         if (r1 != 0 && i2 != 3)
+           break;
+       }
+
       /* Terminate search when hitting any other branch instruction.  */
       else if (is_rr (insn, op_basr, &r1, &r2)
               || is_rx (insn, op_bas, &r1, &d2, &x2, &b2)
               || is_rr (insn, op_bcr, &r1, &r2)
               || is_rx (insn, op_bc, &r1, &d2, &x2, &b2)
-              || is_ri (insn, op1_brc, op2_brc, &r1, &i2)
-              || is_ril (insn, op1_brcl, op2_brcl, &r1, &i2)
               || is_ril (insn, op1_brasl, op2_brasl, &r2, &i2))
        break;