summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Arnez <arnez@linux.vnet.ibm.com>2016-03-09 17:12:29 +0100
committerAndreas Arnez <arnez@linux.vnet.ibm.com>2016-03-09 17:12:29 +0100
commitbc0e3f49c84055034cae31bba169100d107b28f4 (patch)
treef5ac7171dfc3d9b3a5012ee595f3824a37bd063e
parent6d53bec88f4c1576f74e918400aa2ccac2d129db (diff)
downloadbinutils-gdb-bc0e3f49c84055034cae31bba169100d107b28f4.tar.gz
S390: Recognize special jumps in prologue parser
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.
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/s390-linux-tdep.c16
2 files changed, 19 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0674836fb28..6c33877d9d2 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
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
frame func's PC in info->func before any other failure can occur.
(s390_frame_this_id): Use frame_id_build_unavailable_stack if
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index 155bc66bd7c..950696ea328 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -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;