diff options
Diffstat (limited to 'gdb/aarch64-tdep.c')
-rw-r--r-- | gdb/aarch64-tdep.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index d1e1549..3ac0564 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -3099,15 +3099,22 @@ aarch64_displaced_step_others (const uint32_t insn, struct aarch64_displaced_step_data *dsd = (struct aarch64_displaced_step_data *) data; - aarch64_emit_insn (dsd->insn_buf, insn); - dsd->insn_count = 1; - - if ((insn & 0xfffffc1f) == 0xd65f0000) + uint32_t masked_insn = (insn & CLEAR_Rn_MASK); + if (masked_insn == BLR) { - /* RET */ - dsd->dsc->pc_adjust = 0; + /* Emit a BR to the same register and then update LR to the original + address (similar to aarch64_displaced_step_b). */ + aarch64_emit_insn (dsd->insn_buf, insn & 0xffdfffff); + regcache_cooked_write_unsigned (dsd->regs, AARCH64_LR_REGNUM, + data->insn_addr + 4); } else + aarch64_emit_insn (dsd->insn_buf, insn); + dsd->insn_count = 1; + + if (masked_insn == RET || masked_insn == BR || masked_insn == BLR) + dsd->dsc->pc_adjust = 0; + else dsd->dsc->pc_adjust = 4; } |