From 118e6252ca1cabce6d4480a4f24c53e5456a2cfa Mon Sep 17 00:00:00 2001 From: Markus Metzger Date: Wed, 18 Dec 2013 11:09:34 +0100 Subject: [PATCH] target: allow decr_pc_after_break to be defined by the target Allow the target to define which value to use in decr_pc_after_break. It defaults to gdbarch_decr_pc_after_break (GDBARCH). 2014-01-16 Markus Metzger * target.h (struct target_ops) : New. (forward_target_decr_pc_after_break) (target_decr_pc_after_break): New. * target.c (forward_target_decr_pc_after_break) (target_decr_pc_after_break): New. * aix-thread.c (aix_thread_wait): Call target_decr_pc_after_break instead of gdbarch_decr_pc_after_break. * darwin-nat.c (cancel_breakpoint): Call target_decr_pc_after_break instead of gdbarch_decr_pc_after_break. * infrun.c (adjust_pc_after_break): Call target_decr_pc_after_break instead of gdbarch_decr_pc_after_break. * linux-nat.c (cancel_breakpoint): Call target_decr_pc_after_break instead of gdbarch_decr_pc_after_break. * linux-thread-db.c (check_event): Call target_decr_pc_after_break instead of gdbarch_decr_pc_after_break. * record-full.c (record_full_wait_1): Call target_decr_pc_after_break instead of gdbarch_decr_pc_after_break. --- gdb/ChangeLog | 20 ++++++++++++++++++++ gdb/aix-thread.c | 2 +- gdb/darwin-nat.c | 4 ++-- gdb/infrun.c | 9 +++++---- gdb/linux-nat.c | 4 ++-- gdb/linux-thread-db.c | 2 +- gdb/record-full.c | 6 +++--- gdb/target.c | 21 +++++++++++++++++++++ gdb/target.h | 13 +++++++++++++ 9 files changed, 68 insertions(+), 13 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 103b52ef04..ad768a1ab1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,23 @@ +2014-01-16 Markus Metzger + + * target.h (struct target_ops) : New. + (forward_target_decr_pc_after_break) + (target_decr_pc_after_break): New. + * target.c (forward_target_decr_pc_after_break) + (target_decr_pc_after_break): New. + * aix-thread.c (aix_thread_wait): Call target_decr_pc_after_break + instead of gdbarch_decr_pc_after_break. + * darwin-nat.c (cancel_breakpoint): Call target_decr_pc_after_break + instead of gdbarch_decr_pc_after_break. + * infrun.c (adjust_pc_after_break): Call target_decr_pc_after_break + instead of gdbarch_decr_pc_after_break. + * linux-nat.c (cancel_breakpoint): Call target_decr_pc_after_break + instead of gdbarch_decr_pc_after_break. + * linux-thread-db.c (check_event): Call target_decr_pc_after_break + instead of gdbarch_decr_pc_after_break. + * record-full.c (record_full_wait_1): Call target_decr_pc_after_break + instead of gdbarch_decr_pc_after_break. + 2014-01-16 Markus Metzger * btrace.c: Include regcache.h. diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c index d6f9f7b742..7218abed16 100644 --- a/gdb/aix-thread.c +++ b/gdb/aix-thread.c @@ -1044,7 +1044,7 @@ aix_thread_wait (struct target_ops *ops, struct gdbarch *gdbarch = get_regcache_arch (regcache); if (regcache_read_pc (regcache) - - gdbarch_decr_pc_after_break (gdbarch) == pd_brk_addr) + - target_decr_pc_after_break (gdbarch) == pd_brk_addr) return pd_activate (0); } diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c index 53622ce9e7..dd4b3ce177 100644 --- a/gdb/darwin-nat.c +++ b/gdb/darwin-nat.c @@ -1011,14 +1011,14 @@ cancel_breakpoint (ptid_t ptid) struct gdbarch *gdbarch = get_regcache_arch (regcache); CORE_ADDR pc; - pc = regcache_read_pc (regcache) - gdbarch_decr_pc_after_break (gdbarch); + pc = regcache_read_pc (regcache) - target_decr_pc_after_break (gdbarch); if (breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc)) { inferior_debug (4, "cancel_breakpoint for thread 0x%x\n", ptid_get_tid (ptid)); /* Back up the PC if necessary. */ - if (gdbarch_decr_pc_after_break (gdbarch)) + if (target_decr_pc_after_break (gdbarch)) regcache_write_pc (regcache, pc); return 1; diff --git a/gdb/infrun.c b/gdb/infrun.c index 311bf9c435..71d9615582 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -2963,7 +2963,7 @@ adjust_pc_after_break (struct execution_control_state *ecs) struct regcache *regcache; struct gdbarch *gdbarch; struct address_space *aspace; - CORE_ADDR breakpoint_pc; + CORE_ADDR breakpoint_pc, decr_pc; /* If we've hit a breakpoint, we'll normally be stopped with SIGTRAP. If we aren't, just return. @@ -3025,15 +3025,16 @@ adjust_pc_after_break (struct execution_control_state *ecs) we have nothing to do. */ regcache = get_thread_regcache (ecs->ptid); gdbarch = get_regcache_arch (regcache); - if (gdbarch_decr_pc_after_break (gdbarch) == 0) + + decr_pc = target_decr_pc_after_break (gdbarch); + if (decr_pc == 0) return; aspace = get_regcache_aspace (regcache); /* Find the location where (if we've hit a breakpoint) the breakpoint would be. */ - breakpoint_pc = regcache_read_pc (regcache) - - gdbarch_decr_pc_after_break (gdbarch); + breakpoint_pc = regcache_read_pc (regcache) - decr_pc; /* Check whether there actually is a software breakpoint inserted at that location. diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 2371ad4db3..d144c7772e 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -2736,7 +2736,7 @@ cancel_breakpoint (struct lwp_info *lp) struct gdbarch *gdbarch = get_regcache_arch (regcache); CORE_ADDR pc; - pc = regcache_read_pc (regcache) - gdbarch_decr_pc_after_break (gdbarch); + pc = regcache_read_pc (regcache) - target_decr_pc_after_break (gdbarch); if (breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc)) { if (debug_linux_nat) @@ -2745,7 +2745,7 @@ cancel_breakpoint (struct lwp_info *lp) target_pid_to_str (lp->ptid)); /* Back up the PC if necessary. */ - if (gdbarch_decr_pc_after_break (gdbarch)) + if (target_decr_pc_after_break (gdbarch)) regcache_write_pc (regcache, pc); return 1; diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c index 0daf24cbe5..c05ebdf22a 100644 --- a/gdb/linux-thread-db.c +++ b/gdb/linux-thread-db.c @@ -1402,7 +1402,7 @@ check_event (ptid_t ptid) /* Bail out early if we're not at a thread event breakpoint. */ stop_pc = regcache_read_pc (regcache) - - gdbarch_decr_pc_after_break (gdbarch); + - target_decr_pc_after_break (gdbarch); if (stop_pc != info->td_create_bp_addr && stop_pc != info->td_death_bp_addr) return; diff --git a/gdb/record-full.c b/gdb/record-full.c index a44af1014c..9a2b5e6630 100644 --- a/gdb/record-full.c +++ b/gdb/record-full.c @@ -1283,7 +1283,7 @@ record_full_wait_1 (struct target_ops *ops, struct gdbarch *gdbarch = get_regcache_arch (regcache); CORE_ADDR decr_pc_after_break - = gdbarch_decr_pc_after_break (gdbarch); + = target_decr_pc_after_break (gdbarch); if (decr_pc_after_break) regcache_write_pc (regcache, tmp_pc + decr_pc_after_break); @@ -1356,7 +1356,7 @@ record_full_wait_1 (struct target_ops *ops, tmp_pc = regcache_read_pc (regcache); if (breakpoint_inserted_here_p (aspace, tmp_pc)) { - int decr_pc_after_break = gdbarch_decr_pc_after_break (gdbarch); + int decr_pc_after_break = target_decr_pc_after_break (gdbarch); if (record_debug) fprintf_unfiltered (gdb_stdlog, @@ -1438,7 +1438,7 @@ record_full_wait_1 (struct target_ops *ops, if (breakpoint_inserted_here_p (aspace, tmp_pc)) { int decr_pc_after_break - = gdbarch_decr_pc_after_break (gdbarch); + = target_decr_pc_after_break (gdbarch); if (record_debug) fprintf_unfiltered (gdb_stdlog, diff --git a/gdb/target.c b/gdb/target.c index a771893d51..576d6c73a6 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -4532,6 +4532,27 @@ target_get_tailcall_unwinder (void) return NULL; } +/* See target.h. */ + +CORE_ADDR +forward_target_decr_pc_after_break (struct target_ops *ops, + struct gdbarch *gdbarch) +{ + for (; ops != NULL; ops = ops->beneath) + if (ops->to_decr_pc_after_break != NULL) + return ops->to_decr_pc_after_break (ops, gdbarch); + + return gdbarch_decr_pc_after_break (gdbarch); +} + +/* See target.h. */ + +CORE_ADDR +target_decr_pc_after_break (struct gdbarch *gdbarch) +{ + return forward_target_decr_pc_after_break (current_target.beneath, gdbarch); +} + static int deprecated_debug_xfer_memory (CORE_ADDR memaddr, bfd_byte *myaddr, int len, int write, struct mem_attrib *attrib, diff --git a/gdb/target.h b/gdb/target.h index d6de52af33..dee8d3e4dc 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -911,6 +911,12 @@ struct target_ops const struct frame_unwind *to_get_unwinder; const struct frame_unwind *to_get_tailcall_unwinder; + /* Return the number of bytes by which the PC needs to be decremented + after executing a breakpoint instruction. + Defaults to gdbarch_decr_pc_after_break (GDBARCH). */ + CORE_ADDR (*to_decr_pc_after_break) (struct target_ops *ops, + struct gdbarch *gdbarch); + int to_magic; /* Need sub-structure for target machine related rather than comm related? */ @@ -2051,4 +2057,11 @@ extern void target_call_history_from (ULONGEST begin, int size, int flags); /* See to_call_history_range. */ extern void target_call_history_range (ULONGEST begin, ULONGEST end, int flags); +/* See to_decr_pc_after_break. Start searching for the target at OPS. */ +extern CORE_ADDR forward_target_decr_pc_after_break (struct target_ops *ops, + struct gdbarch *gdbarch); + +/* See to_decr_pc_after_break. */ +extern CORE_ADDR target_decr_pc_after_break (struct gdbarch *gdbarch); + #endif /* !defined (TARGET_H) */