diff options
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/s390-linux-tdep.c | 16 |
2 files changed, 19 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0674836..6c33877 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 155bc66..950696e 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; |