aboutsummaryrefslogtreecommitdiff
path: root/gdb/ppc-linux-nat.c
diff options
context:
space:
mode:
authorThiago Jung Bauermann <bauerman@br.ibm.com>2011-03-31 14:32:49 +0000
committerThiago Jung Bauermann <bauerman@br.ibm.com>2011-03-31 14:32:49 +0000
commitf13101077fe972666625fa9d12952a9465f26f94 (patch)
tree129f11de0e72b593cc70b71882326ec23cb3857d /gdb/ppc-linux-nat.c
parentbbda34159e3b58cdd3f9b5ab715df213ed53b16b (diff)
downloadgdb-f13101077fe972666625fa9d12952a9465f26f94.zip
gdb-f13101077fe972666625fa9d12952a9465f26f94.tar.gz
gdb-f13101077fe972666625fa9d12952a9465f26f94.tar.bz2
2011-03-31 Thiago Jung Bauermann <bauerman@br.ibm.com>
Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Implement support for PowerPC BookE ranged breakpoints. gdb/ * NEWS: Mention support for ranged breakpoints on embedded PowerPC. * breakpoint.h (struct bp_target_info) <length>: New member variable. (struct breakpoint_ops) <breakpoint_hit>: Take struct bp_location instead of struct breakpoint as argument, and also add ASPACE and BP_ADDR arguments. Update all callers. (struct breakpoint_ops) <print_one_detail>: New method. (struct breakpoint) <addr_string_range_end>: New member variable. * breakpoint.c (breakpoint_location_address_match): Add function prototype. (insert_bp_location): Set bl->target_info.length. (breakpoint_here_p): Call breakpoint_location_address_match. (moribund_breakpoint_here_p): Likewise. (regular_breakpoint_inserted_here_p): Likewise. (breakpoint_thread_match): Likewise. (bpstat_stop_status): Likewise. (bpstat_check_location): Move call to breakpoint_ops.breakpoint_hit to the top. (print_one_breakpoint_location): Call breakpoint_ops.print_one_detail if available. (breakpoint_address_match_range): New function. (breakpoint_location_address_match): Likewise. (breakpoint_locations_match): Compare the length field of the locations too. (hw_breakpoint_used_count): Count resources used by all locations in a breakpoint, and use breakpoint_ops.resources_needed if available. (breakpoint_hit_ranged_breakpoint): New function. (resources_needed_ranged_breakpoint): Likewise. (print_it_ranged_breakpoint): Likewise. (print_one_ranged_breakpoint): Likewise. (print_one_detail_ranged_breakpoint): Likewise. (print_mention_ranged_breakpoint): Likewise. (print_recreate_ranged_breakpoint): Likewise. (ranged_breakpoint_ops): New structure. (find_breakpoint_range_end): New function. (break_range_command): Likewise. (delete_breakpoint): Free addr_string_range_end. (update_breakpoint_locations): Add SALS_END argument. Update all callers. Calculate breakpoint length if a non-zero SALS_END is given. Call breakpoint_locations_match instead of breakpoint_address_match. (reset_breakpoint): Find SaL of the end of the range if B is a ranged breakpoint. (_initialize_breakpoint): Register break-range command. * defs.h (print_core_address): Add function prototype. * ppc-linux-nat.c (ppc_linux_ranged_break_num_registers): New function. (ppc_linux_insert_hw_breakpoint): Support ranged breakpoints. (ppc_linux_remove_hw_breakpoint): Likewise. (_initialize_ppc_linux_nat): Initialize to_ranged_break_num_registers. * target.c (update_current_target): Add comment about to_ranged_break_num_registers. (target_ranged_break_num_registers): New function. * target.h (struct target_ops) <to_ranged_break_num_registers>: New method. (target_ranged_break_num_registers): Add function prototype. * ui-out.c (ui_out_field_core_addr): Move address-printing logic to ... * utils.c (print_core_address): ... here. gdb/doc/ * gdb.texinfo (PowerPC Embedded): Document ranged breakpoints.
Diffstat (limited to 'gdb/ppc-linux-nat.c')
-rw-r--r--gdb/ppc-linux-nat.c46
1 files changed, 42 insertions, 4 deletions
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index 049cde8..f0c7f61 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -1637,6 +1637,19 @@ booke_remove_point (struct ppc_hw_breakpoint *b, int tid)
hw_breaks[i].hw_break = NULL;
}
+/* Return the number of registers needed for a ranged breakpoint. */
+
+static int
+ppc_linux_ranged_break_num_registers (struct target_ops *target)
+{
+ return ((have_ptrace_booke_interface ()
+ && booke_debug_info.features & PPC_DEBUG_FEATURE_INSN_BP_RANGE)?
+ 2 : -1);
+}
+
+/* Insert the hardware breakpoint described by BP_TGT. Returns 0 for
+ success, 1 if hardware breakpoints are not supported or -1 for failure. */
+
static int
ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch,
struct bp_target_info *bp_tgt)
@@ -1650,12 +1663,24 @@ ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch,
p.version = PPC_DEBUG_CURRENT_VERSION;
p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
- p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
p.addr = (uint64_t) bp_tgt->placed_address;
- p.addr2 = 0;
p.condition_value = 0;
+ if (bp_tgt->length)
+ {
+ p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
+
+ /* The breakpoint will trigger if the address of the instruction is
+ within the defined range, as follows: p.addr <= address < p.addr2. */
+ p.addr2 = (uint64_t) bp_tgt->placed_address + bp_tgt->length;
+ }
+ else
+ {
+ p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
+ p.addr2 = 0;
+ }
+
ALL_LWPS (lp, ptid)
booke_insert_point (&p, TIDGET (ptid));
@@ -1675,12 +1700,24 @@ ppc_linux_remove_hw_breakpoint (struct gdbarch *gdbarch,
p.version = PPC_DEBUG_CURRENT_VERSION;
p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
- p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
p.addr = (uint64_t) bp_tgt->placed_address;
- p.addr2 = 0;
p.condition_value = 0;
+ if (bp_tgt->length)
+ {
+ p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
+
+ /* The breakpoint will trigger if the address of the instruction is within
+ the defined range, as follows: p.addr <= address < p.addr2. */
+ p.addr2 = (uint64_t) bp_tgt->placed_address + bp_tgt->length;
+ }
+ else
+ {
+ p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
+ p.addr2 = 0;
+ }
+
ALL_LWPS (lp, ptid)
booke_remove_point (&p, TIDGET (ptid));
@@ -2392,6 +2429,7 @@ _initialize_ppc_linux_nat (void)
t->to_watchpoint_addr_within_range = ppc_linux_watchpoint_addr_within_range;
t->to_can_accel_watchpoint_condition
= ppc_linux_can_accel_watchpoint_condition;
+ t->to_ranged_break_num_registers = ppc_linux_ranged_break_num_registers;
t->to_read_description = ppc_linux_read_description;
t->to_auxv_parse = ppc_linux_auxv_parse;