diff options
42 files changed, 619 insertions, 410 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index aa2e399..b2f1e91 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,115 @@ +2006-04-18 Daniel Jacobowitz <dan@codesourcery.com> + + * breakpoint.c (deprecated_read_memory_nobpt): Update to use + shadow_len. + (insert_bp_location, reattach_breakpoints, remove_breakpoint) + (delete_breakpoint): Update calls to changed methods. + (deprecated_insert_raw_breakpoint, deprecated_remove_raw_breakpoint) + (single_step_breakpoints, insert_single_step_breakpoint) + (remove_single_step_breakpoints): New. + * breakpoint.h (struct bp_target_info): New. + (struct bp_location): Replace shadow_contents with + target_info and overlay_target_info. + (deprecated_insert_raw_breakpoint, deprecated_remove_raw_breakpoint) + (insert_single_step_breakpoint, remove_single_step_breakpoints): New + prototypes. + * gdbarch.sh: Forward declare struct bp_target_info in gdbarch.h. + (memory_insert_breakpoint, memory_remove_breakpoint): Update second + argument. + * mem-break.c (default_memory_insert_breakpoint): Update. Set + placed_address, placed_size, and shadow_len. + (default_memory_remove_breakpoint): Update. Don't use + BREAKPOINT_FROM_PC. + (memory_insert_breakpoint, memory_remove_breakpoint): Update. + * target.c (update_current_target): Update prototypes for changed + functions. + (debug_to_insert_breakpoint, debug_to_remove_breakpoint) + (debug_to_insert_hw_breakpoint, debug_to_remove_hw_breakpoint): + Update. + * target.h: Forward declare struct bp_target_info. + (struct target_ops): Use a bp_target_info argument for + to_insert_breakpoint, to_remove_breakpoint, + to_insert_hw_breakpoint, and to_remove_hw_breakpoint. + (target_insert_breakpoint, target_remove_breakpoint) + (target_insert_hw_breakpoint, target_remove_hw_breakpoint) + (memory_insert_breakpoint, memory_remove_breakpoint) + (default_memory_insert_breakpoint, default_memory_remove_breakpoint): + Update. + * config/i386/nm-i386.h: Forward declare struct bp_target_info. + (i386_insert_hw_breakpoint, i386_remove_hw_breakpoint): Update. + (target_insert_hw_breakpoint, target_remove_hw_breakpoint): Likewise. + + * gdbarch.c, gdbarch.h: Regenerated. + + * alpha-tdep.c (alpha_software_single_step): Use + insert_single_step_breakpoint and remove_single_step_breakpoints. + Remove unused statics. + * arm-tdep.c (arm_software_single_step): Likewise. Add a note. + * cris-tdep.c (cris_software_single_step): Likewise. + * mips-tdep.c (mips_software_single_step): Likewise. + * rs6000-tdep.c (rs6000_software_single_step): Likewise. + * sparc-tdep.c (sparc_software_single_step): Likewise. + * wince.c (struct thread_info_struct): Remove step_prev. + (undoSStep): Use remove_single_step_breakpoints. + (wince_software_single_step): Use insert_single_step_breakpoint. + + * corelow.c (ignore): Remove unneeded prototype. Update arguments. + * exec.c (ignore): Likewise. + * sol-thread.c (ignore): Likewise. + + * procfs.c (dbx_link_shadow_contents): Delete. + (dbx_link_bpt): New. + (procfs_mourn_inferior): Remove it if necessary. + (remove_dbx_link_breakpoint): Use it. + (insert_dbx_link_bpt_in_file): Set it. + (procfs_init_inferior): Don't update dbx_link_bpt_addr. + * rs6000-nat.c (exec_one_dummy_insn): Use + deprecated_insert_raw_breakpoint and + deprecated_remove_raw_breakpoint. + * solib-irix.c (shadow_contents, breakpoint_addr): Delete. + (base_breakpoint): New. + (disable_break): Use it. + (enable_break): Set it. + + * i386-nat.c (i386_insert_hw_breakpoint, i386_remove_hw_breakpoint): + Update. + * ia64-tdep.c (ia64_memory_insert_breakpoint) + (ia64_memory_remove_breakpoint): Likewise. + * m32r-tdep.c (m32r_memory_insert_breakpoint) + (m32r_memory_remove_breakpoint): Likewise. + * monitor.c (monitor_insert_breakpoint, monitor_remove_breakpoint): + Likewise. Remove unnecessary prototypes. Use placed_address + and placed_size. Removed useless read from memory. + * nto-procfs.c (procfs_insert_breakpoint) + (procfs_remove_breakpoint, procfs_insert_hw_breakpoint) + (procfs_remove_hw_breakpoint): Update. + * ocd.c (ocd_insert_breakpoint, ocd_remove_breakpoint): Likewise. + * ocd.h (ocd_insert_breakpoint, ocd_remove_breakpoint): Likewise. + * ppc-linux-tdep.c (ppc_linux_memory_remove_breakpoint): Likewise. + * ppc-tdep.h (ppc_linux_memory_remove_breakpoint): Likewise. + * remote-e7000.c (e7000_insert_breakpoint) + (e7000_remove_breakpoint): Likewise. + * remote-m32r-sdi.c (m32r_insert_breakpoint) + (m32r_remove_breakpoint): Likewise. + * remote-mips.c (mips_insert_breakpoint) + (mips_remove_breakpoint): Likewise. + * remote-rdp.c (remote_rdp_insert_breakpoint) + (remote_rdp_remove_breakpoint): Likewise. + (rdp_step): Use deprecated_insert_raw_breakpoint and + deprecated_remove_raw_breakpoint. + * remote-sds.c (sds_insert_breakpoint, sds_remove_breakpoint): + Update. + * remote-sim.c (gdbsim_insert_breakpoint, gdbsim_remove_breakpoint): + Delete. + (init_gdbsim_ops): Use memory_insert_breakpoint and + memory_remove_breakpoint. + * remote-st.c (st2000_insert_breakpoint) + (st2000_remove_breakpoint): Update. Remove unused + BREAKPOINT_FROM_PC. + * remote.c (remote_insert_breakpoint, remote_remove_breakpoint): + Update. Use placed_address and placed_size. + (remote_insert_hw_breakpoint, remote_remove_hw_breakpoint): Likewise. + 2006-04-12 Daniel Jacobowitz <dan@codesourcery.com> * remote.c (extended_remote_restart): Pass the correct length diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index 960b051..4480b21 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -1493,8 +1493,6 @@ void alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p) { static CORE_ADDR next_pc; - typedef char binsn_quantum[BREAKPOINT_MAX]; - static binsn_quantum break_mem; CORE_ADDR pc; if (insert_breakpoints_p) @@ -1502,11 +1500,11 @@ alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p) pc = read_pc (); next_pc = alpha_next_pc (pc); - target_insert_breakpoint (next_pc, break_mem); + insert_single_step_breakpoint (next_pc); } else { - target_remove_breakpoint (next_pc, break_mem); + remove_single_step_breakpoints (); write_pc (next_pc); } } diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 6b57465..a5da56c 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -1849,16 +1849,18 @@ arm_get_next_pc (CORE_ADDR pc) static void arm_software_single_step (enum target_signal sig, int insert_bpt) { - static int next_pc; /* State between setting and unsetting. */ - static char break_mem[BREAKPOINT_MAX]; /* Temporary storage for mem@bpt */ + /* NOTE: This may insert the wrong breakpoint instruction when + single-stepping over a mode-changing instruction, if the + CPSR heuristics are used. */ if (insert_bpt) { - next_pc = arm_get_next_pc (read_register (ARM_PC_REGNUM)); - target_insert_breakpoint (next_pc, break_mem); + CORE_ADDR next_pc = arm_get_next_pc (read_register (ARM_PC_REGNUM)); + + insert_single_step_breakpoint (next_pc); } else - target_remove_breakpoint (next_pc, break_mem); + remove_single_step_breakpoints (); } #include "bfd-in2.h" diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index bcb2de9..130b684 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -663,16 +663,10 @@ deprecated_read_memory_nobpt (CORE_ADDR memaddr, gdb_byte *myaddr, continue; /* Addresses and length of the part of the breakpoint that we need to copy. */ - /* XXXX The m68k, sh and h8300 have different local and remote - breakpoint values. BREAKPOINT_FROM_PC still manages to - correctly determine the breakpoints memory address and size - for these targets. */ - bp_addr = b->address; - bp_size = 0; - if (BREAKPOINT_FROM_PC (&bp_addr, &bp_size) == NULL) - continue; + bp_addr = b->target_info.placed_address; + bp_size = b->target_info.shadow_len; if (bp_size == 0) - /* bp isn't valid */ + /* bp isn't valid, or doesn't shadow memory. */ continue; if (bp_addr + bp_size <= memaddr) /* The breakpoint is entirely before the chunk of memory we @@ -703,7 +697,7 @@ deprecated_read_memory_nobpt (CORE_ADDR memaddr, gdb_byte *myaddr, } memcpy (myaddr + bp_addr - memaddr, - b->shadow_contents + bptoffset, bp_size); + b->target_info.shadow_contents + bptoffset, bp_size); if (bp_addr > memaddr) { @@ -793,6 +787,10 @@ insert_bp_location (struct bp_location *bpt, if (bpt->inserted || bpt->duplicate) return 0; + /* Initialize the target-specific information. */ + memset (&bpt->target_info, 0, sizeof (bpt->target_info)); + bpt->target_info.placed_address = bpt->address; + if (bpt->loc_type == bp_loc_software_breakpoint || bpt->loc_type == bp_loc_hardware_breakpoint) { @@ -804,11 +802,9 @@ insert_bp_location (struct bp_location *bpt, /* No overlay handling: just set the breakpoint. */ if (bpt->loc_type == bp_loc_hardware_breakpoint) - val = target_insert_hw_breakpoint (bpt->address, - bpt->shadow_contents); + val = target_insert_hw_breakpoint (&bpt->target_info); else - val = target_insert_breakpoint (bpt->address, - bpt->shadow_contents); + val = target_insert_breakpoint (&bpt->target_info); } else { @@ -827,7 +823,9 @@ insert_bp_location (struct bp_location *bpt, CORE_ADDR addr = overlay_unmapped_address (bpt->address, bpt->section); /* Set a software (trap) breakpoint at the LMA. */ - val = target_insert_breakpoint (addr, bpt->shadow_contents); + bpt->overlay_target_info = bpt->target_info; + bpt->overlay_target_info.placed_address = addr; + val = target_insert_breakpoint (&bpt->overlay_target_info); if (val != 0) fprintf_unfiltered (tmp_error_stream, "Overlay breakpoint %d failed: in ROM?", @@ -839,11 +837,9 @@ insert_bp_location (struct bp_location *bpt, { /* Yes. This overlay section is mapped into memory. */ if (bpt->loc_type == bp_loc_hardware_breakpoint) - val = target_insert_hw_breakpoint (bpt->address, - bpt->shadow_contents); + val = target_insert_hw_breakpoint (&bpt->target_info); else - val = target_insert_breakpoint (bpt->address, - bpt->shadow_contents); + val = target_insert_breakpoint (&bpt->target_info); } else { @@ -1045,7 +1041,7 @@ in which its expression is valid.\n"), /* If we get here, we must have a callback mechanism for exception events -- with g++ style embedded label support, we insert ordinary breakpoints and not catchpoints. */ - val = target_insert_breakpoint (bpt->address, bpt->shadow_contents); + val = target_insert_breakpoint (&bpt->target_info); if (val) { /* Couldn't set breakpoint for some reason */ @@ -1240,9 +1236,9 @@ reattach_breakpoints (int pid) { remove_breakpoint (b, mark_inserted); if (b->loc_type == bp_loc_hardware_breakpoint) - val = target_insert_hw_breakpoint (b->address, b->shadow_contents); + val = target_insert_hw_breakpoint (&b->target_info); else - val = target_insert_breakpoint (b->address, b->shadow_contents); + val = target_insert_breakpoint (&b->target_info); /* FIXME drow/2003-10-07: This doesn't handle any other kinds of breakpoints. It's wrong for watchpoints, for example. */ if (val != 0) @@ -1446,10 +1442,9 @@ remove_breakpoint (struct bp_location *b, insertion_state_t is) /* No overlay handling: just remove the breakpoint. */ if (b->loc_type == bp_loc_hardware_breakpoint) - val = target_remove_hw_breakpoint (b->address, - b->shadow_contents); + val = target_remove_hw_breakpoint (&b->target_info); else - val = target_remove_breakpoint (b->address, b->shadow_contents); + val = target_remove_breakpoint (&b->target_info); } else { @@ -1460,14 +1455,12 @@ remove_breakpoint (struct bp_location *b, insertion_state_t is) /* Yes -- overlay event support is not active, so we should have set a breakpoint at the LMA. Remove it. */ - CORE_ADDR addr = overlay_unmapped_address (b->address, - b->section); /* Ignore any failures: if the LMA is in ROM, we will have already warned when we failed to insert it. */ if (b->loc_type == bp_loc_hardware_breakpoint) - target_remove_hw_breakpoint (addr, b->shadow_contents); + target_remove_hw_breakpoint (&b->overlay_target_info); else - target_remove_breakpoint (addr, b->shadow_contents); + target_remove_breakpoint (&b->overlay_target_info); } /* Did we set a breakpoint at the VMA? If so, we will have marked the breakpoint 'inserted'. */ @@ -1478,11 +1471,9 @@ remove_breakpoint (struct bp_location *b, insertion_state_t is) unmapped, but let's not rely on that being safe. We don't know what the overlay manager might do. */ if (b->loc_type == bp_loc_hardware_breakpoint) - val = target_remove_hw_breakpoint (b->address, - b->shadow_contents); + val = target_remove_hw_breakpoint (&b->target_info); else - val = target_remove_breakpoint (b->address, - b->shadow_contents); + val = target_remove_breakpoint (&b->target_info); } else { @@ -1570,8 +1561,7 @@ remove_breakpoint (struct bp_location *b, insertion_state_t is) && breakpoint_enabled (b->owner) && !b->duplicate) { - - val = target_remove_breakpoint (b->address, b->shadow_contents); + val = target_remove_breakpoint (&b->target_info); if (val) return val; b->inserted = (is == mark_inserted); @@ -1581,8 +1571,7 @@ remove_breakpoint (struct bp_location *b, insertion_state_t is) && breakpoint_enabled (b->owner) && !b->duplicate) { - - val = target_remove_breakpoint (b->address, b->shadow_contents); + val = target_remove_breakpoint (&b->target_info); if (val) return val; @@ -6852,10 +6841,12 @@ delete_breakpoint (struct breakpoint *bpt) _("another breakpoint was inserted on top of " "a permanent breakpoint")); + memset (&b->loc->target_info, 0, sizeof (b->loc->target_info)); + b->loc->target_info.placed_address = b->loc->address; if (b->type == bp_hardware_breakpoint) - val = target_insert_hw_breakpoint (b->loc->address, b->loc->shadow_contents); + val = target_insert_hw_breakpoint (&b->loc->target_info); else - val = target_insert_breakpoint (b->loc->address, b->loc->shadow_contents); + val = target_insert_breakpoint (&b->loc->target_info); /* If there was an error in the insert, print a message, then stop execution. */ if (val != 0) @@ -7658,6 +7649,97 @@ decode_line_spec_1 (char *string, int funfirstline) error (_("Junk at end of line specification: %s"), string); return sals; } + +/* Create and insert a raw software breakpoint at PC. Return an + identifier, which should be used to remove the breakpoint later. + In general, places which call this should be using something on the + breakpoint chain instead; this function should be eliminated + someday. */ + +void * +deprecated_insert_raw_breakpoint (CORE_ADDR pc) +{ + struct bp_target_info *bp_tgt; + + bp_tgt = xmalloc (sizeof (struct bp_target_info)); + memset (bp_tgt, 0, sizeof (struct bp_target_info)); + + bp_tgt->placed_address = pc; + if (target_insert_breakpoint (bp_tgt) != 0) + { + /* Could not insert the breakpoint. */ + xfree (bp_tgt); + return NULL; + } + + return bp_tgt; +} + +/* Remove a breakpoint BP inserted by deprecated_insert_raw_breakpoint. */ + +int +deprecated_remove_raw_breakpoint (void *bp) +{ + struct bp_target_info *bp_tgt = bp; + int ret; + + ret = target_remove_breakpoint (bp_tgt); + xfree (bp_tgt); + + return ret; +} + +/* One (or perhaps two) breakpoints used for software single stepping. */ + +static void *single_step_breakpoints[2]; + +/* Create and insert a breakpoint for software single step. */ + +void +insert_single_step_breakpoint (CORE_ADDR next_pc) +{ + void **bpt_p; + + if (single_step_breakpoints[0] == NULL) + bpt_p = &single_step_breakpoints[0]; + else + { + gdb_assert (single_step_breakpoints[1] == NULL); + bpt_p = &single_step_breakpoints[1]; + } + + /* NOTE drow/2006-04-11: A future improvement to this function would be + to only create the breakpoints once, and actually put them on the + breakpoint chain. That would let us use set_raw_breakpoint. We could + adjust the addresses each time they were needed. Doing this requires + corresponding changes elsewhere where single step breakpoints are + handled, however. So, for now, we use this. */ + + *bpt_p = deprecated_insert_raw_breakpoint (next_pc); + if (*bpt_p == NULL) + warning (_("Could not insert single-step breakpoint at 0x%s"), + paddr_nz (next_pc)); +} + +/* Remove and delete any breakpoints used for software single step. */ + +void +remove_single_step_breakpoints (void) +{ + gdb_assert (single_step_breakpoints[0] != NULL); + + /* See insert_single_step_breakpoint for more about this deprecated + call. */ + deprecated_remove_raw_breakpoint (single_step_breakpoints[0]); + single_step_breakpoints[0] = NULL; + + if (single_step_breakpoints[1] != NULL) + { + deprecated_remove_raw_breakpoint (single_step_breakpoints[1]); + single_step_breakpoints[1] = NULL; + } +} + /* This help string is used for the break, hbreak, tbreak and thbreak commands. It is defined as a macro to prevent duplication. diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index d1e2fd8..607fd77 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -185,6 +185,36 @@ enum target_hw_bp_type hw_execute = 3 /* Execute HW breakpoint */ }; + +/* Information used by targets to insert and remove breakpoints. */ + +struct bp_target_info +{ + /* Address at which the breakpoint was placed. This is normally the + same as ADDRESS from the bp_location, except when adjustment + happens in BREAKPOINT_FROM_PC. The most common form of + adjustment is stripping an alternate ISA marker from the PC which + is used to determine the type of breakpoint to insert. */ + CORE_ADDR placed_address; + + /* If the breakpoint lives in memory and reading that memory would + give back the breakpoint, instead of the original contents, then + the original contents are cached here. Only SHADOW_LEN bytes of + this buffer are valid, and only when the breakpoint is inserted. */ + gdb_byte shadow_contents[BREAKPOINT_MAX]; + + /* The length of the data cached in SHADOW_CONTENTS. */ + int shadow_len; + + /* The size of the placed breakpoint, according to + BREAKPOINT_FROM_PC, when the breakpoint was inserted. This is + generally the same as SHADOW_LEN, unless we did not need + to read from the target to implement the memory breakpoint + (e.g. if a remote stub handled the details). We may still + need the size to remove the breakpoint safely. */ + int placed_size; +}; + /* GDB maintains two types of information about each breakpoint (or watchpoint, or other related event). The first type corresponds to struct breakpoint; this is a relatively high-level structure @@ -242,13 +272,6 @@ struct bp_location associated with the address. Used primarily for overlay debugging. */ asection *section; - /* "Real" contents of byte where breakpoint has been inserted. - Valid only when breakpoints are in the program. Under the complete - control of the target insert_breakpoint and remove_breakpoint routines. - No other code should assume anything about the value(s) here. - Valid only for bp_loc_software_breakpoint. */ - gdb_byte shadow_contents[BREAKPOINT_MAX]; - /* Address at which breakpoint was requested, either by the user or by GDB for internal breakpoints. This will usually be the same as ``address'' (above) except for cases in which @@ -256,6 +279,12 @@ struct bp_location which to place the breakpoint in order to comply with a processor's architectual constraints. */ CORE_ADDR requested_address; + + /* Details of the placed breakpoint, when inserted. */ + struct bp_target_info target_info; + + /* Similarly, for the breakpoint at an overlay's LMA, if necessary. */ + struct bp_target_info overlay_target_info; }; /* This structure is a collection of function pointers that, if available, @@ -796,6 +825,16 @@ extern void delete_command (char *arg, int from_tty); remove fails. */ extern int remove_hw_watchpoints (void); +/* Manage a software single step breakpoint (or two). Insert may be called + twice before remove is called. */ +extern void insert_single_step_breakpoint (CORE_ADDR); +extern void remove_single_step_breakpoints (void); + +/* Manage manual breakpoints, separate from the normal chain of + breakpoints. These functions are used in murky target-specific + ways. Please do not add more uses! */ +extern void *deprecated_insert_raw_breakpoint (CORE_ADDR); +extern int deprecated_remove_raw_breakpoint (void *); /* Indicator of whether exception catchpoints should be nuked between runs of a program. */ diff --git a/gdb/config/i386/nm-i386.h b/gdb/config/i386/nm-i386.h index 265c8e0..26215eb 100644 --- a/gdb/config/i386/nm-i386.h +++ b/gdb/config/i386/nm-i386.h @@ -52,13 +52,14 @@ extern int i386_stopped_by_hwbp (void); true. Otherwise, return false. */ extern int i386_stopped_data_address (CORE_ADDR *); -/* Insert a hardware-assisted breakpoint at address ADDR. SHADOW is - unused. Return 0 on success, EBUSY on failure. */ -extern int i386_insert_hw_breakpoint (CORE_ADDR addr, void *shadow); +/* Insert a hardware-assisted breakpoint at BP_TGT->placed_address. + Return 0 on success, EBUSY on failure. */ +struct bp_target_info; +extern int i386_insert_hw_breakpoint (struct bp_target_info *bp_tgt); -/* Remove a hardware-assisted breakpoint at address ADDR. SHADOW is - unused. Return 0 on success, -1 on failure. */ -extern int i386_remove_hw_breakpoint (CORE_ADDR addr, void *shadow); +/* Remove a hardware-assisted breakpoint at BP_TGT->placed_address. + Return 0 on success, -1 on failure. */ +extern int i386_remove_hw_breakpoint (struct bp_target_info *bp_tgt); /* Returns the number of hardware watchpoints of type TYPE that we can set. Value is positive if we can set CNT watchpoints, zero if @@ -105,11 +106,11 @@ extern int i386_stopped_by_watchpoint (void); #define target_remove_watchpoint(addr, len, type) \ i386_remove_watchpoint (addr, len, type) -#define target_insert_hw_breakpoint(addr, shadow) \ - i386_insert_hw_breakpoint (addr, shadow) +#define target_insert_hw_breakpoint(bp_tgt) \ + i386_insert_hw_breakpoint (bp_tgt) -#define target_remove_hw_breakpoint(addr, shadow) \ - i386_remove_hw_breakpoint (addr, shadow) +#define target_remove_hw_breakpoint(bp_tgt) \ + i386_remove_hw_breakpoint (bp_tgt) /* child_post_startup_inferior used to reset all debug registers by calling i386_cleanup_dregs (). */ diff --git a/gdb/corelow.c b/gdb/corelow.c index 226b48b..fa61bf3 100644 --- a/gdb/corelow.c +++ b/gdb/corelow.c @@ -86,8 +86,6 @@ static void get_core_registers (int); static void add_to_thread_list (bfd *, asection *, void *); -static int ignore (CORE_ADDR, bfd_byte *); - static int core_file_thread_alive (ptid_t tid); static void init_core_ops (void); @@ -603,7 +601,7 @@ core_xfer_partial (struct target_ops *ops, enum target_object object, `gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */ static int -ignore (CORE_ADDR addr, bfd_byte *contents) +ignore (struct bp_target_info *bp_tgt) { return 0; } diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c index 4c81d6e..4e1540e 100644 --- a/gdb/cris-tdep.c +++ b/gdb/cris-tdep.c @@ -558,15 +558,6 @@ struct instruction_environment int disable_interrupt; } inst_env_type; -/* Save old breakpoints in order to restore the state before a single_step. - At most, two breakpoints will have to be remembered. */ -typedef -char binsn_quantum[BREAKPOINT_MAX]; -static binsn_quantum break_mem[2]; -static CORE_ADDR next_pc = 0; -static CORE_ADDR branch_target_address = 0; -static unsigned char branch_break_inserted = 0; - /* Machine-dependencies in CRIS for opcodes. */ /* Instruction sizes. */ @@ -2130,7 +2121,7 @@ static void cris_software_single_step (enum target_signal ignore, int insert_breakpoints) { inst_env_type inst_env; - + if (insert_breakpoints) { /* Analyse the present instruction environment and insert @@ -2146,28 +2137,19 @@ cris_software_single_step (enum target_signal ignore, int insert_breakpoints) { /* Insert at most two breakpoints. One for the next PC content and possibly another one for a branch, jump, etc. */ - next_pc = (CORE_ADDR) inst_env.reg[PC_REGNUM]; - target_insert_breakpoint (next_pc, break_mem[0]); + CORE_ADDR next_pc = (CORE_ADDR) inst_env.reg[PC_REGNUM]; + insert_single_step_breakpoint (next_pc); if (inst_env.branch_found && (CORE_ADDR) inst_env.branch_break_address != next_pc) { - branch_target_address = - (CORE_ADDR) inst_env.branch_break_address; - target_insert_breakpoint (branch_target_address, break_mem[1]); - branch_break_inserted = 1; + CORE_ADDR branch_target_address + = (CORE_ADDR) inst_env.branch_break_address; + insert_single_step_breakpoint (branch_target_address); } } } else - { - /* Remove breakpoints. */ - target_remove_breakpoint (next_pc, break_mem[0]); - if (branch_break_inserted) - { - target_remove_breakpoint (branch_target_address, break_mem[1]); - branch_break_inserted = 0; - } - } + remove_single_step_breakpoints (); } /* Calculates the prefix value for quick offset addressing mode. */ diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 16e8abf..66ff9d7 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,12 @@ +2006-04-18 Daniel Jacobowitz <dan@codesourcery.com> + + * gdbint.texinfo (x86 Watchpoints, Target Conditionals): Update insert + and remove breakpoint prototypes. + (Watchpoints): Move description of target_insert_hw_breakpoint and + target_remove_hw_breakpoint ... + (Breakpoints): ... to here. Document target_insert_breakpoint and + target_remove_breakpoint. + 2006-04-17 Jim Blandy <jimb@codesourcery.com> * gdb.texinfo (Packets): Note that 'addr' arguments to s, S, c, diff --git a/gdb/doc/gdbint.texinfo b/gdb/doc/gdbint.texinfo index e14aa2c..e1d1557 100644 --- a/gdb/doc/gdbint.texinfo +++ b/gdb/doc/gdbint.texinfo @@ -527,6 +527,47 @@ The basic definition of the software breakpoint is the macro Basic breakpoint object handling is in @file{breakpoint.c}. However, much of the interesting breakpoint action is in @file{infrun.c}. +@table @code +@cindex insert or remove software breakpoint +@findex target_remove_breakpoint +@findex target_insert_breakpoint +@item target_remove_breakpoint (@var{bp_tgt}) +@itemx target_insert_breakpoint (@var{bp_tgt}) +Insert or remove a software breakpoint at address +@code{@var{bp_tgt}->placed_address}. Returns zero for success, +non-zero for failure. On input, @var{bp_tgt} contains the address of the +breakpoint, and is otherwise initialized to zero. The fields of the +@code{struct bp_target_info} pointed to by @var{bp_tgt} are updated +to contain other information about the breakpoint on output. The field +@code{placed_address} may be updated if the breakpoint was placed at a +related address; the field @code{shadow_contents} contains the real +contents of the bytes where the breakpoint has been inserted, +if reading memory would return the breakpoint instead of the +underlying memory; the field @code{shadow_len} is the length of +memory cached in @code{shadow_contents}, if any; and the field +@code{placed_size} is optionally set and used by the target, if +it could differ from @code{shadow_len}. + +For example, the remote target @samp{Z0} packet does not require +shadowing memory, so @code{shadow_len} is left at zero. However, +the length reported by @code{BREAKPOINT_FROM_PC} is cached in +@code{placed_size}, so that a matching @samp{z0} packet can be +used to remove the breakpoint. + +@cindex insert or remove hardware breakpoint +@findex target_remove_hw_breakpoint +@findex target_insert_hw_breakpoint +@item target_remove_hw_breakpoint (@var{bp_tgt}) +@itemx target_insert_hw_breakpoint (@var{bp_tgt}) +Insert or remove a hardware-assisted breakpoint at address +@code{@var{bp_tgt}->placed_address}. Returns zero for success, +non-zero for failure. See @code{target_insert_breakpoint} for +a description of the @code{struct bp_target_info} pointed to by +@var{bp_tgt}; the @code{shadow_contents} and +@code{shadow_len} members are not used for hardware breakpoints, +but @code{placed_size} may be. +@end table + @section Single Stepping @section Signal Handling @@ -657,18 +698,6 @@ defined by @file{breakpoint.h} as follows: @noindent These two macros should return 0 for success, non-zero for failure. -@cindex insert or remove hardware breakpoint -@findex target_remove_hw_breakpoint -@findex target_insert_hw_breakpoint -@item target_remove_hw_breakpoint (@var{addr}, @var{shadow}) -@itemx target_insert_hw_breakpoint (@var{addr}, @var{shadow}) -Insert or remove a hardware-assisted breakpoint at address @var{addr}. -Returns zero for success, non-zero for failure. @var{shadow} is the -real contents of the byte where the breakpoint has been inserted; it -is generally not valid when hardware breakpoints are used, but since -no other code touches these values, the implementations of the above -two macros can use them for their internal purposes. - @findex target_stopped_data_address @item target_stopped_data_address (@var{addr_p}) If the inferior has some watchpoint that triggered, place the address @@ -858,11 +887,13 @@ the count goes to zero. @findex i386_insert_hw_breakpoint @findex i386_remove_hw_breakpoint -@item i386_insert_hw_breakpoint (@var{addr}, @var{shadow} -@itemx i386_remove_hw_breakpoint (@var{addr}, @var{shadow}) +@item i386_insert_hw_breakpoint (@var{bp_tgt}) +@itemx i386_remove_hw_breakpoint (@var{bp_tgt}) These functions insert and remove hardware-assisted breakpoints. The macros @code{target_insert_hw_breakpoint} and @code{target_remove_hw_breakpoint} are set to call these functions. +The argument is a @code{struct bp_target_info *}, as described in +the documentation for @code{target_insert_breakpoint}. These functions work like @code{i386_insert_watchpoint} and @code{i386_remove_watchpoint}, respectively, except that they set up the debug registers to watch instruction execution, and each @@ -3229,8 +3260,8 @@ instruction of the architecture. Replaces all the other @var{BREAKPOINT} macros. -@item MEMORY_INSERT_BREAKPOINT (@var{addr}, @var{contents_cache}) -@itemx MEMORY_REMOVE_BREAKPOINT (@var{addr}, @var{contents_cache}) +@item MEMORY_INSERT_BREAKPOINT (@var{bp_tgt}) +@itemx MEMORY_REMOVE_BREAKPOINT (@var{bp_tgt}) @findex MEMORY_REMOVE_BREAKPOINT @findex MEMORY_INSERT_BREAKPOINT Insert or remove memory based breakpoints. Reasonable defaults @@ -59,8 +59,6 @@ static void set_section_command (char *, int); static void exec_files_info (struct target_ops *); -static int ignore (CORE_ADDR, bfd_byte *); - static void init_exec_ops (void); void _initialize_exec (void); @@ -691,7 +689,7 @@ exec_set_section_address (const char *filename, int index, CORE_ADDR address) breakpoint_init_inferior). */ static int -ignore (CORE_ADDR addr, bfd_byte *contents) +ignore (struct bp_target_info *bp_tgt) { return 0; } diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 4fa5ea4..706bd13 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -1250,8 +1250,8 @@ gdbarch_dump (struct gdbarch *current_gdbarch, struct ui_file *file) #ifdef MEMORY_INSERT_BREAKPOINT fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", - "MEMORY_INSERT_BREAKPOINT(addr, contents_cache)", - XSTRING (MEMORY_INSERT_BREAKPOINT (addr, contents_cache))); + "MEMORY_INSERT_BREAKPOINT(bp_tgt)", + XSTRING (MEMORY_INSERT_BREAKPOINT (bp_tgt))); #endif fprintf_unfiltered (file, "gdbarch_dump: memory_insert_breakpoint = <0x%lx>\n", @@ -1259,8 +1259,8 @@ gdbarch_dump (struct gdbarch *current_gdbarch, struct ui_file *file) #ifdef MEMORY_REMOVE_BREAKPOINT fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", - "MEMORY_REMOVE_BREAKPOINT(addr, contents_cache)", - XSTRING (MEMORY_REMOVE_BREAKPOINT (addr, contents_cache))); + "MEMORY_REMOVE_BREAKPOINT(bp_tgt)", + XSTRING (MEMORY_REMOVE_BREAKPOINT (bp_tgt))); #endif fprintf_unfiltered (file, "gdbarch_dump: memory_remove_breakpoint = <0x%lx>\n", @@ -2934,13 +2934,13 @@ set_gdbarch_adjust_breakpoint_address (struct gdbarch *gdbarch, } int -gdbarch_memory_insert_breakpoint (struct gdbarch *gdbarch, CORE_ADDR addr, gdb_byte *contents_cache) +gdbarch_memory_insert_breakpoint (struct gdbarch *gdbarch, struct bp_target_info *bp_tgt) { gdb_assert (gdbarch != NULL); gdb_assert (gdbarch->memory_insert_breakpoint != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_memory_insert_breakpoint called\n"); - return gdbarch->memory_insert_breakpoint (addr, contents_cache); + return gdbarch->memory_insert_breakpoint (bp_tgt); } void @@ -2951,13 +2951,13 @@ set_gdbarch_memory_insert_breakpoint (struct gdbarch *gdbarch, } int -gdbarch_memory_remove_breakpoint (struct gdbarch *gdbarch, CORE_ADDR addr, gdb_byte *contents_cache) +gdbarch_memory_remove_breakpoint (struct gdbarch *gdbarch, struct bp_target_info *bp_tgt) { gdb_assert (gdbarch != NULL); gdb_assert (gdbarch->memory_remove_breakpoint != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_memory_remove_breakpoint called\n"); - return gdbarch->memory_remove_breakpoint (addr, contents_cache); + return gdbarch->memory_remove_breakpoint (bp_tgt); } void diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 75ac81f..48bcd7a 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -49,6 +49,7 @@ struct regset; struct disassemble_info; struct target_ops; struct obstack; +struct bp_target_info; extern struct gdbarch *current_gdbarch; @@ -899,24 +900,24 @@ typedef CORE_ADDR (gdbarch_adjust_breakpoint_address_ftype) (struct gdbarch *gdb extern CORE_ADDR gdbarch_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr); extern void set_gdbarch_adjust_breakpoint_address (struct gdbarch *gdbarch, gdbarch_adjust_breakpoint_address_ftype *adjust_breakpoint_address); -typedef int (gdbarch_memory_insert_breakpoint_ftype) (CORE_ADDR addr, gdb_byte *contents_cache); -extern int gdbarch_memory_insert_breakpoint (struct gdbarch *gdbarch, CORE_ADDR addr, gdb_byte *contents_cache); +typedef int (gdbarch_memory_insert_breakpoint_ftype) (struct bp_target_info *bp_tgt); +extern int gdbarch_memory_insert_breakpoint (struct gdbarch *gdbarch, struct bp_target_info *bp_tgt); extern void set_gdbarch_memory_insert_breakpoint (struct gdbarch *gdbarch, gdbarch_memory_insert_breakpoint_ftype *memory_insert_breakpoint); #if !defined (GDB_TM_FILE) && defined (MEMORY_INSERT_BREAKPOINT) #error "Non multi-arch definition of MEMORY_INSERT_BREAKPOINT" #endif #if !defined (MEMORY_INSERT_BREAKPOINT) -#define MEMORY_INSERT_BREAKPOINT(addr, contents_cache) (gdbarch_memory_insert_breakpoint (current_gdbarch, addr, contents_cache)) +#define MEMORY_INSERT_BREAKPOINT(bp_tgt) (gdbarch_memory_insert_breakpoint (current_gdbarch, bp_tgt)) #endif -typedef int (gdbarch_memory_remove_breakpoint_ftype) (CORE_ADDR addr, gdb_byte *contents_cache); -extern int gdbarch_memory_remove_breakpoint (struct gdbarch *gdbarch, CORE_ADDR addr, gdb_byte *contents_cache); +typedef int (gdbarch_memory_remove_breakpoint_ftype) (struct bp_target_info *bp_tgt); +extern int gdbarch_memory_remove_breakpoint (struct gdbarch *gdbarch, struct bp_target_info *bp_tgt); extern void set_gdbarch_memory_remove_breakpoint (struct gdbarch *gdbarch, gdbarch_memory_remove_breakpoint_ftype *memory_remove_breakpoint); #if !defined (GDB_TM_FILE) && defined (MEMORY_REMOVE_BREAKPOINT) #error "Non multi-arch definition of MEMORY_REMOVE_BREAKPOINT" #endif #if !defined (MEMORY_REMOVE_BREAKPOINT) -#define MEMORY_REMOVE_BREAKPOINT(addr, contents_cache) (gdbarch_memory_remove_breakpoint (current_gdbarch, addr, contents_cache)) +#define MEMORY_REMOVE_BREAKPOINT(bp_tgt) (gdbarch_memory_remove_breakpoint (current_gdbarch, bp_tgt)) #endif extern CORE_ADDR gdbarch_decr_pc_after_break (struct gdbarch *gdbarch); diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index afcfd82..9e36fb6 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -549,8 +549,8 @@ f:=:CORE_ADDR:skip_prologue:CORE_ADDR ip:ip:0:0 f:=:int:inner_than:CORE_ADDR lhs, CORE_ADDR rhs:lhs, rhs:0:0 f:=:const gdb_byte *:breakpoint_from_pc:CORE_ADDR *pcptr, int *lenptr:pcptr, lenptr::0: M::CORE_ADDR:adjust_breakpoint_address:CORE_ADDR bpaddr:bpaddr -f:=:int:memory_insert_breakpoint:CORE_ADDR addr, gdb_byte *contents_cache:addr, contents_cache:0:default_memory_insert_breakpoint::0 -f:=:int:memory_remove_breakpoint:CORE_ADDR addr, gdb_byte *contents_cache:addr, contents_cache:0:default_memory_remove_breakpoint::0 +f:=:int:memory_insert_breakpoint:struct bp_target_info *bp_tgt:bp_tgt:0:default_memory_insert_breakpoint::0 +f:=:int:memory_remove_breakpoint:struct bp_target_info *bp_tgt:bp_tgt:0:default_memory_remove_breakpoint::0 v:=:CORE_ADDR:decr_pc_after_break:::0:::0 # A function can be addressed by either it's "pointer" (possibly a @@ -771,6 +771,7 @@ struct regset; struct disassemble_info; struct target_ops; struct obstack; +struct bp_target_info; extern struct gdbarch *current_gdbarch; EOF diff --git a/gdb/i386-nat.c b/gdb/i386-nat.c index 770b66d..dea1206 100644 --- a/gdb/i386-nat.c +++ b/gdb/i386-nat.c @@ -625,12 +625,13 @@ i386_stopped_by_hwbp (void) return 0; } -/* Insert a hardware-assisted breakpoint at address ADDR. SHADOW is - unused. Return 0 on success, EBUSY on failure. */ +/* Insert a hardware-assisted breakpoint at BP_TGT->placed_address. + Return 0 on success, EBUSY on failure. */ int -i386_insert_hw_breakpoint (CORE_ADDR addr, void *shadow) +i386_insert_hw_breakpoint (struct bp_target_info *bp_tgt) { unsigned len_rw = i386_length_and_rw_bits (1, hw_execute); + CORE_ADDR addr = bp_tgt->placed_address; int retval = i386_insert_aligned_watchpoint (addr, len_rw) ? EBUSY : 0; if (maint_show_dr) @@ -639,13 +640,14 @@ i386_insert_hw_breakpoint (CORE_ADDR addr, void *shadow) return retval; } -/* Remove a hardware-assisted breakpoint at address ADDR. SHADOW is - unused. Return 0 on success, -1 on failure. */ +/* Remove a hardware-assisted breakpoint at BP_TGT->placed_address. + Return 0 on success, -1 on failure. */ int -i386_remove_hw_breakpoint (CORE_ADDR addr, void *shadow) +i386_remove_hw_breakpoint (struct bp_target_info *bp_tgt) { unsigned len_rw = i386_length_and_rw_bits (1, hw_execute); + CORE_ADDR addr = bp_tgt->placed_address; int retval = i386_remove_aligned_watchpoint (addr, len_rw); if (maint_show_dr) diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c index f78f1fc..897d272 100644 --- a/gdb/ia64-tdep.c +++ b/gdb/ia64-tdep.c @@ -550,8 +550,9 @@ fetch_instruction (CORE_ADDR addr, instruction_type *it, long long *instr) #define IA64_BREAKPOINT 0x00003333300LL static int -ia64_memory_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) +ia64_memory_insert_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; char bundle[BUNDLE_LEN]; int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER; long long instr; @@ -574,7 +575,8 @@ ia64_memory_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) } instr = slotN_contents (bundle, slotnum); - memcpy(contents_cache, &instr, sizeof(instr)); + memcpy (bp_tgt->shadow_contents, &instr, sizeof (instr)); + bp_tgt->placed_size = bp_tgt->shadow_len = sizeof (instr); replace_slotN_contents (bundle, IA64_BREAKPOINT, slotnum); if (val == 0) target_write_memory (addr, bundle, BUNDLE_LEN); @@ -583,8 +585,9 @@ ia64_memory_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) } static int -ia64_memory_remove_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) +ia64_memory_remove_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; char bundle[BUNDLE_LEN]; int slotnum = (addr & 0x0f) / SLOT_MULTIPLIER; long long instr; @@ -603,7 +606,7 @@ ia64_memory_remove_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) slotnum = 2; } - memcpy (&instr, contents_cache, sizeof instr); + memcpy (&instr, bp_tgt->shadow_contents, sizeof instr); replace_slotN_contents (bundle, instr, slotnum); if (val == 0) target_write_memory (addr, bundle, BUNDLE_LEN); diff --git a/gdb/m32r-tdep.c b/gdb/m32r-tdep.c index c95dbd1..e792c4c 100644 --- a/gdb/m32r-tdep.c +++ b/gdb/m32r-tdep.c @@ -81,10 +81,12 @@ m32r_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp) The following functions take care of this behavior. */ static int -m32r_memory_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) +m32r_memory_insert_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; int val; gdb_byte buf[4]; + gdb_byte *contents_cache = bp_tgt->shadow_contents; gdb_byte bp_entry[] = { 0x10, 0xf1 }; /* dpt */ /* Save the memory contents. */ @@ -92,6 +94,8 @@ m32r_memory_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) if (val != 0) return val; /* return error */ + bp_tgt->placed_size = bp_tgt->shadow_len = 4; + /* Determine appropriate breakpoint contents and size for this address. */ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) { @@ -134,10 +138,12 @@ m32r_memory_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) } static int -m32r_memory_remove_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) +m32r_memory_remove_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; int val; gdb_byte buf[4]; + gdb_byte *contents_cache = bp_tgt->shadow_contents; buf[0] = contents_cache[0]; buf[1] = contents_cache[1]; diff --git a/gdb/mem-break.c b/gdb/mem-break.c index 810f8ae..2d9851b 100644 --- a/gdb/mem-break.c +++ b/gdb/mem-break.c @@ -33,60 +33,57 @@ #include "target.h" -/* Insert a breakpoint on targets that don't have any better breakpoint - support. We read the contents of the target location and stash it, - then overwrite it with a breakpoint instruction. ADDR is the target - location in the target machine. CONTENTS_CACHE is a pointer to - memory allocated for saving the target contents. It is guaranteed - by the caller to be long enough to save BREAKPOINT_LEN bytes (this - is accomplished via BREAKPOINT_MAX). */ +/* Insert a breakpoint on targets that don't have any better + breakpoint support. We read the contents of the target location + and stash it, then overwrite it with a breakpoint instruction. + BP_TGT->placed_address is the target location in the target + machine. BP_TGT->shadow_contents is some memory allocated for + saving the target contents. It is guaranteed by the caller to be + long enough to save BREAKPOINT_LEN bytes (this is accomplished via + BREAKPOINT_MAX). */ int -default_memory_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) +default_memory_insert_breakpoint (struct bp_target_info *bp_tgt) { int val; const unsigned char *bp; int bplen; /* Determine appropriate breakpoint contents and size for this address. */ - bp = BREAKPOINT_FROM_PC (&addr, &bplen); + bp = BREAKPOINT_FROM_PC (&bp_tgt->placed_address, &bp_tgt->placed_size); if (bp == NULL) error (_("Software breakpoints not implemented for this target.")); /* Save the memory contents. */ - val = target_read_memory (addr, contents_cache, bplen); + bp_tgt->shadow_len = bp_tgt->placed_size; + val = target_read_memory (bp_tgt->placed_address, bp_tgt->shadow_contents, + bp_tgt->placed_size); /* Write the breakpoint. */ if (val == 0) - val = target_write_memory (addr, bp, bplen); + val = target_write_memory (bp_tgt->placed_address, bp, + bp_tgt->placed_size); return val; } int -default_memory_remove_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) +default_memory_remove_breakpoint (struct bp_target_info *bp_tgt) { - const bfd_byte *bp; - int bplen; - - /* Determine appropriate breakpoint contents and size for this address. */ - bp = BREAKPOINT_FROM_PC (&addr, &bplen); - if (bp == NULL) - error (_("Software breakpoints not implemented for this target.")); - - return target_write_memory (addr, contents_cache, bplen); + return target_write_memory (bp_tgt->placed_address, bp_tgt->shadow_contents, + bp_tgt->placed_size); } int -memory_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) +memory_insert_breakpoint (struct bp_target_info *bp_tgt) { - return MEMORY_INSERT_BREAKPOINT(addr, contents_cache); + return MEMORY_INSERT_BREAKPOINT (bp_tgt); } int -memory_remove_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) +memory_remove_breakpoint (struct bp_target_info *bp_tgt) { - return MEMORY_REMOVE_BREAKPOINT(addr, contents_cache); + return MEMORY_REMOVE_BREAKPOINT (bp_tgt); } diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 880dfcc..dcb4406 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -2188,20 +2188,17 @@ mips_addr_bits_remove (CORE_ADDR addr) void mips_software_single_step (enum target_signal sig, int insert_breakpoints_p) { - static CORE_ADDR next_pc; - typedef char binsn_quantum[BREAKPOINT_MAX]; - static binsn_quantum break_mem; - CORE_ADDR pc; + CORE_ADDR pc, next_pc; if (insert_breakpoints_p) { pc = read_register (mips_regnum (current_gdbarch)->pc); next_pc = mips_next_pc (pc); - target_insert_breakpoint (next_pc, break_mem); + insert_single_step_breakpoint (next_pc); } else - target_remove_breakpoint (next_pc, break_mem); + remove_single_step_breakpoints (); } /* Test whether the PC points to the return instruction at the diff --git a/gdb/monitor.c b/gdb/monitor.c index 3b7619e..a6c0823 100644 --- a/gdb/monitor.c +++ b/gdb/monitor.c @@ -85,8 +85,6 @@ static int monitor_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, struct mem_attrib *attrib, struct target_ops *target); static void monitor_files_info (struct target_ops *ops); -static int monitor_insert_breakpoint (CORE_ADDR addr, gdb_byte *shadow); -static int monitor_remove_breakpoint (CORE_ADDR addr, gdb_byte *shadow); static void monitor_kill (void); static void monitor_load (char *file, int from_tty); static void monitor_mourn_inferior (void); @@ -2037,8 +2035,9 @@ monitor_mourn_inferior (void) /* Tell the monitor to add a breakpoint. */ static int -monitor_insert_breakpoint (CORE_ADDR addr, gdb_byte *shadow) +monitor_insert_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; int i; const unsigned char *bp; int bplen; @@ -2052,13 +2051,14 @@ monitor_insert_breakpoint (CORE_ADDR addr, gdb_byte *shadow) /* Determine appropriate breakpoint size for this address. */ bp = gdbarch_breakpoint_from_pc (current_gdbarch, &addr, &bplen); + bp_tgt->placed_address = addr; + bp_tgt->placed_size = bplen; for (i = 0; i < current_monitor->num_breakpoints; i++) { if (breakaddr[i] == 0) { breakaddr[i] = addr; - monitor_read_memory (addr, shadow, bplen); monitor_printf (current_monitor->set_break, addr); monitor_expect_prompt (NULL, 0); return 0; @@ -2071,17 +2071,15 @@ monitor_insert_breakpoint (CORE_ADDR addr, gdb_byte *shadow) /* Tell the monitor to remove a breakpoint. */ static int -monitor_remove_breakpoint (CORE_ADDR addr, gdb_byte *shadow) +monitor_remove_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; int i; monitor_debug ("MON rmbkpt %s\n", paddr (addr)); if (current_monitor->clr_break == NULL) error (_("No clr_break defined for this monitor")); - if (current_monitor->flags & MO_ADDR_BITS_REMOVE) - addr = ADDR_BITS_REMOVE (addr); - for (i = 0; i < current_monitor->num_breakpoints; i++) { if (breakaddr[i] == addr) diff --git a/gdb/nto-procfs.c b/gdb/nto-procfs.c index 7854d2a..6dc056a 100644 --- a/gdb/nto-procfs.c +++ b/gdb/nto-procfs.c @@ -76,10 +76,6 @@ static ptid_t do_attach (ptid_t ptid); static int procfs_can_use_hw_breakpoint (int, int, int); -static int procfs_insert_hw_breakpoint (CORE_ADDR, char *); - -static int procfs_remove_hw_breakpoint (CORE_ADDR addr, char *); - static int procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type); static int procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type); @@ -812,27 +808,29 @@ procfs_breakpoint (CORE_ADDR addr, int type, int size) } static int -procfs_insert_breakpoint (CORE_ADDR addr, char *contents_cache) +procfs_insert_breakpoint (struct bp_target_info *bp_tgt) { - return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC, 0); + return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, 0); } static int -procfs_remove_breakpoint (CORE_ADDR addr, char *contents_cache) +procfs_remove_breakpoint (struct bp_target_info *bp_tgt) { - return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC, -1); + return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, -1); } static int -procfs_insert_hw_breakpoint (CORE_ADDR addr, char *contents_cache) +procfs_insert_hw_breakpoint (struct bp_target_info *bp_tgt) { - return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0); + return procfs_breakpoint (bp_tgt->placed_address, + _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0); } static int -procfs_remove_hw_breakpoint (CORE_ADDR addr, char *contents_cache) +procfs_remove_hw_breakpoint (struct bp_target_info *bp_tgt) { - return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1); + return procfs_breakpoint (bp_tgt->placed_address, + _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1); } static void @@ -1048,28 +1048,27 @@ ocd_load (char *args, int from_tty) /* BDM (at least on CPU32) uses a different breakpoint */ int -ocd_insert_breakpoint (CORE_ADDR addr, char *contents_cache) +ocd_insert_breakpoint (struct bp_target_info *bp_tgt) { static char break_insn[] = BDM_BREAKPOINT; int val; - val = target_read_memory (addr, contents_cache, sizeof (break_insn)); + bp_tgt->placed_size = bp_tgt->shadow_len = sizeof (break_insn); + val = target_read_memory (bp_tgt->placed_address, bp_tgt->shadow_contents, + bp_tgt->placed_size); if (val == 0) - val = target_write_memory (addr, break_insn, sizeof (break_insn)); + val = target_write_memory (bp_tgt->placed_address, break_insn, + bp_tgt->placed_size); return val; } int -ocd_remove_breakpoint (CORE_ADDR addr, char *contents_cache) +ocd_remove_breakpoint (struct bp_target_info *bp_tgt) { - static char break_insn[] = BDM_BREAKPOINT; - int val; - - val = target_write_memory (addr, contents_cache, sizeof (break_insn)); - - return val; + return target_write_memory (bp_tgt->placed_address, bp_tgt->shadow_contents, + bp_tgt->placed_size); } static void @@ -135,8 +135,8 @@ void ocd_write_bdm_register (int bdm_regno, CORE_ADDR reg); int ocd_wait (void); -int ocd_insert_breakpoint (CORE_ADDR addr, char *contents_cache); -int ocd_remove_breakpoint (CORE_ADDR addr, char *contents_cache); +int ocd_insert_breakpoint (struct bp_target_info *bp_tgt); +int ocd_remove_breakpoint (struct bp_target_info *bp_tgt); int ocd_write_bytes (CORE_ADDR memaddr, char *myaddr, int len); diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index 0452084..5e1bc00 100644 --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -457,9 +457,9 @@ ppc_linux_skip_trampoline_code (CORE_ADDR pc) regard to removing breakpoints in some potentially self modifying code. */ int -ppc_linux_memory_remove_breakpoint (CORE_ADDR addr, - gdb_byte *contents_cache) +ppc_linux_memory_remove_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; const unsigned char *bp; int val; int bplen; @@ -476,7 +476,7 @@ ppc_linux_memory_remove_breakpoint (CORE_ADDR addr, program modified the code on us, so it is wrong to put back the old value */ if (val == 0 && memcmp (bp, old_contents, bplen) == 0) - val = target_write_memory (addr, contents_cache, bplen); + val = target_write_memory (addr, bp_tgt->shadow_contents, bplen); return val; } diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h index 1a25648..f781f1b 100644 --- a/gdb/ppc-tdep.h +++ b/gdb/ppc-tdep.h @@ -56,8 +56,7 @@ CORE_ADDR ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR struct_addr); CORE_ADDR ppc64_sysv_abi_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr); -int ppc_linux_memory_remove_breakpoint (CORE_ADDR addr, - gdb_byte *contents_cache); +int ppc_linux_memory_remove_breakpoint (struct bp_target_info *bp_tgt); struct link_map_offsets *ppc_linux_svr4_fetch_link_map_offsets (void); void ppc_linux_supply_gregset (struct regcache *regcache, int regnum, const void *gregs, size_t size, diff --git a/gdb/procfs.c b/gdb/procfs.c index 1fd45a3..03fcadd 100644 --- a/gdb/procfs.c +++ b/gdb/procfs.c @@ -3375,7 +3375,7 @@ static void remove_dbx_link_breakpoint (void); the address of the breakpoint, and the code that was replaced by a breakpoint. */ static int dbx_link_bpt_addr = 0; -static char dbx_link_shadow_contents[BREAKPOINT_MAX]; +static void *dbx_link_bpt; /* * Function: procfs_debug_inferior @@ -4777,6 +4777,14 @@ procfs_mourn_inferior (void) destroy_procinfo (pi); } unpush_target (&procfs_ops); + + if (dbx_link_bpt != NULL) + { + deprecated_remove_raw_breakpoint (dbx_link_bpt); + dbx_link_bpt_addr = 0; + dbx_link_bpt = NULL; + } + generic_mourn_inferior (); } @@ -4886,7 +4894,6 @@ procfs_init_inferior (int pid) has been inserted, the syssgi() notifications are no longer necessary, so they should be canceled. */ proc_trace_syscalls_1 (pi, SYS_syssgi, PR_SYSEXIT, FLAG_SET, 0); - dbx_link_bpt_addr = 0; #endif } @@ -5571,11 +5578,11 @@ remove_dbx_link_breakpoint (void) if (dbx_link_bpt_addr == 0) return; - if (memory_remove_breakpoint (dbx_link_bpt_addr, - dbx_link_shadow_contents) != 0) + if (deprecated_remove_raw_breakpoint (dbx_link_bpt) != 0) warning (_("Unable to remove __dbx_link breakpoint.")); dbx_link_bpt_addr = 0; + dbx_link_bpt = NULL; } /* Return the address of the __dbx_link() function in the file @@ -5643,7 +5650,8 @@ insert_dbx_link_bpt_in_file (int fd, CORE_ADDR ignored) { /* Insert the breakpoint. */ dbx_link_bpt_addr = sym_addr; - if (target_insert_breakpoint (sym_addr, dbx_link_shadow_contents) != 0) + dbx_link_bpt = deprecated_insert_raw_breakpoint (sym_addr); + if (dbx_link_bpt == NULL) { warning (_("Failed to insert dbx_link breakpoint.")); bfd_close (abfd); diff --git a/gdb/remote-e7000.c b/gdb/remote-e7000.c index 09a9460..c1575ca 100644 --- a/gdb/remote-e7000.c +++ b/gdb/remote-e7000.c @@ -1702,8 +1702,9 @@ static CORE_ADDR breakaddr[MAX_BREAKPOINTS] = {0}; static int -e7000_insert_breakpoint (CORE_ADDR addr, bfd_byte *shadow) +e7000_insert_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; int i; char buf[200]; #if 0 @@ -1728,7 +1729,8 @@ e7000_insert_breakpoint (CORE_ADDR addr, bfd_byte *shadow) } #else #if 0 - e7000_read_inferior_memory (addr, shadow, 2); + bp_tgt->shadow_len = 2; + e7000_read_inferior_memory (addr, bp_tgt->shadow_contents, 2); e7000_write_inferior_memory (addr, nop, 2); #endif @@ -1745,8 +1747,9 @@ e7000_insert_breakpoint (CORE_ADDR addr, bfd_byte *shadow) } static int -e7000_remove_breakpoint (CORE_ADDR addr, bfd_byte *shadow) +e7000_remove_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; int i; char buf[200]; @@ -1773,7 +1776,8 @@ e7000_remove_breakpoint (CORE_ADDR addr, bfd_byte *shadow) #if 0 /* Replace the insn under the break */ - e7000_write_inferior_memory (addr, shadow, 2); + e7000_write_inferior_memory (addr, bp_tgt->shadow_contents, + bp_tgt->shadow_len); #endif #endif diff --git a/gdb/remote-m32r-sdi.c b/gdb/remote-m32r-sdi.c index 9ef526f..8da4fd3 100644 --- a/gdb/remote-m32r-sdi.c +++ b/gdb/remote-m32r-sdi.c @@ -1141,15 +1141,16 @@ m32r_mourn_inferior (void) } static int -m32r_insert_breakpoint (CORE_ADDR addr, bfd_byte *shadow) +m32r_insert_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; int ib_breakpoints; unsigned char buf[13]; int i, c; if (remote_debug) - fprintf_unfiltered (gdb_stdlog, "m32r_insert_breakpoint(%08lx,\"%s\")\n", - addr, shadow); + fprintf_unfiltered (gdb_stdlog, "m32r_insert_breakpoint(%08lx,...)\n", + addr); if (use_ib_breakpoints) ib_breakpoints = max_ib_breakpoints; @@ -1183,13 +1184,14 @@ m32r_insert_breakpoint (CORE_ADDR addr, bfd_byte *shadow) } static int -m32r_remove_breakpoint (CORE_ADDR addr, bfd_byte *shadow) +m32r_remove_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; int i; if (remote_debug) - fprintf_unfiltered (gdb_stdlog, "m32r_remove_breakpoint(%08lx,\"%s\")\n", - addr, shadow); + fprintf_unfiltered (gdb_stdlog, "m32r_remove_breakpoint(%08lx)\n", + addr); for (i = 0; i < MAX_BREAKPOINTS; i++) { diff --git a/gdb/remote-mips.c b/gdb/remote-mips.c index e47aa6e..1144e8d 100644 --- a/gdb/remote-mips.c +++ b/gdb/remote-mips.c @@ -2216,27 +2216,28 @@ mips_mourn_inferior (void) /* Insert a breakpoint. On targets that don't have built-in breakpoint support, we read the contents of the target location and stash it, then overwrite it with a breakpoint instruction. ADDR is - the target location in the target machine. CONTENTS_CACHE is a - pointer to memory allocated for saving the target contents. It is - guaranteed by the caller to be long enough to save the breakpoint - length returned by BREAKPOINT_FROM_PC. */ + the target location in the target machine. BPT is the breakpoint + being inserted or removed, which contains memory for saving the + target contents. */ static int -mips_insert_breakpoint (CORE_ADDR addr, char *contents_cache) +mips_insert_breakpoint (struct bp_target_info *bp_tgt) { if (monitor_supports_breakpoints) - return set_breakpoint (addr, MIPS_INSN32_SIZE, BREAK_FETCH); + return set_breakpoint (bp_tgt->placed_address, MIPS_INSN32_SIZE, + BREAK_FETCH); else - return memory_insert_breakpoint (addr, contents_cache); + return memory_insert_breakpoint (bp_tgt); } static int -mips_remove_breakpoint (CORE_ADDR addr, char *contents_cache) +mips_remove_breakpoint (struct bp_target_info *bp_tgt) { if (monitor_supports_breakpoints) - return clear_breakpoint (addr, MIPS_INSN32_SIZE, BREAK_FETCH); + return clear_breakpoint (bp_tgt->placed_address, MIPS_INSN32_SIZE, + BREAK_FETCH); else - return memory_remove_breakpoint (addr, contents_cache); + return memory_remove_breakpoint (bp_tgt); } /* Tell whether this target can support a hardware breakpoint. CNT diff --git a/gdb/remote-rdp.c b/gdb/remote-rdp.c index 695156d..e94821f 100644 --- a/gdb/remote-rdp.c +++ b/gdb/remote-rdp.c @@ -1050,8 +1050,10 @@ rdp_execute (void) } static int -remote_rdp_insert_breakpoint (CORE_ADDR addr, bfd_byte *save) +remote_rdp_insert_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; + int res; if (ds.rdi_level > 0) { @@ -1059,7 +1061,7 @@ remote_rdp_insert_breakpoint (CORE_ADDR addr, bfd_byte *save) RDP_SET_BREAK, addr, RDP_SET_BREAK_TYPE_PC_EQUAL | RDP_SET_BREAK_TYPE_GET_HANDLE, - save, + bp_tgt->shadow_contents, &res); } else @@ -1074,14 +1076,15 @@ remote_rdp_insert_breakpoint (CORE_ADDR addr, bfd_byte *save) } static int -remote_rdp_remove_breakpoint (CORE_ADDR addr, bfd_byte *save) +remote_rdp_remove_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; int res; if (ds.rdi_level > 0) { send_rdp ("b-p-S-B", RDP_CLEAR_BREAK, - save, 4, + bp_tgt->shadow_contents, 4, &res); } else @@ -1108,12 +1111,12 @@ rdp_step (void) } else { - char handle[4]; + void *b; CORE_ADDR pc = read_register (ARM_PC_REGNUM); pc = arm_get_next_pc (pc); - remote_rdp_insert_breakpoint (pc, handle); + b = deprecated_insert_raw_breakpoint (pc); rdp_execute (); - remote_rdp_remove_breakpoint (pc, handle); + deprecated_remove_raw_breakpoint (b); } } diff --git a/gdb/remote-sds.c b/gdb/remote-sds.c index 7533107..8394ae5 100644 --- a/gdb/remote-sds.c +++ b/gdb/remote-sds.c @@ -99,10 +99,6 @@ static void interrupt_query (void); static int read_frame (char *); -static int sds_insert_breakpoint (CORE_ADDR, char *); - -static int sds_remove_breakpoint (CORE_ADDR, char *); - static void init_sds_ops (void); static void sds_command (char *args, int from_tty); @@ -1004,8 +1000,9 @@ sds_load (char *filename, int from_tty) replaced instruction back to the debugger. */ static int -sds_insert_breakpoint (CORE_ADDR addr, char *contents_cache) +sds_insert_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; int i, retlen; unsigned char *p, buf[PBUFSIZ]; @@ -1020,14 +1017,15 @@ sds_insert_breakpoint (CORE_ADDR addr, char *contents_cache) retlen = sds_send (buf, p - buf); for (i = 0; i < 4; ++i) - contents_cache[i] = buf[i + 2]; + bp_tgt->shadow_contents[i] = buf[i + 2]; return 0; } static int -sds_remove_breakpoint (CORE_ADDR addr, char *contents_cache) +sds_remove_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; int i, retlen; unsigned char *p, buf[PBUFSIZ]; @@ -1039,7 +1037,7 @@ sds_remove_breakpoint (CORE_ADDR addr, char *contents_cache) *p++ = (int) (addr >> 8) & 0xff; *p++ = (int) (addr) & 0xff; for (i = 0; i < 4; ++i) - *p++ = contents_cache[i]; + *p++ = bp_tgt->shadow_contents[i]; retlen = sds_send (buf, p - buf); diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c index e96018d..4e36f54 100644 --- a/gdb/remote-sim.c +++ b/gdb/remote-sim.c @@ -805,18 +805,6 @@ gdbsim_mourn_inferior (void) generic_mourn_inferior (); } -static int -gdbsim_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) -{ - return memory_insert_breakpoint (addr, contents_cache); -} - -static int -gdbsim_remove_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) -{ - return memory_remove_breakpoint (addr, contents_cache); -} - /* Pass the command argument through to the simulator verbatim. The simulator must do any command interpretation work. */ @@ -866,8 +854,8 @@ init_gdbsim_ops (void) gdbsim_ops.to_prepare_to_store = gdbsim_prepare_to_store; gdbsim_ops.deprecated_xfer_memory = gdbsim_xfer_inferior_memory; gdbsim_ops.to_files_info = gdbsim_files_info; - gdbsim_ops.to_insert_breakpoint = gdbsim_insert_breakpoint; - gdbsim_ops.to_remove_breakpoint = gdbsim_remove_breakpoint; + gdbsim_ops.to_insert_breakpoint = memory_insert_breakpoint; + gdbsim_ops.to_remove_breakpoint = memory_remove_breakpoint; gdbsim_ops.to_kill = gdbsim_kill; gdbsim_ops.to_load = gdbsim_load; gdbsim_ops.to_create_inferior = gdbsim_create_inferior; diff --git a/gdb/remote-st.c b/gdb/remote-st.c index c7c39a1..c2bcf3d 100644 --- a/gdb/remote-st.c +++ b/gdb/remote-st.c @@ -599,20 +599,16 @@ static CORE_ADDR breakaddr[MAX_STDEBUG_BREAKPOINTS] = {0}; static int -st2000_insert_breakpoint (CORE_ADDR addr, char *shadow) +st2000_insert_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; int i; - CORE_ADDR bp_addr = addr; - int bp_size = 0; - - BREAKPOINT_FROM_PC (&bp_addr, &bp_size); for (i = 0; i <= MAX_STDEBUG_BREAKPOINTS; i++) if (breakaddr[i] == 0) { breakaddr[i] = addr; - st2000_read_inferior_memory (bp_addr, shadow, bp_size); printf_stdebug ("BR %x H\r", addr); expect_prompt (1); return 0; @@ -623,8 +619,9 @@ st2000_insert_breakpoint (CORE_ADDR addr, char *shadow) } static int -st2000_remove_breakpoint (CORE_ADDR addr, char *shadow) +st2000_remove_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; int i; for (i = 0; i < MAX_STDEBUG_BREAKPOINTS; i++) diff --git a/gdb/remote.c b/gdb/remote.c index 07c8007..22581a5 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -136,10 +136,6 @@ static void skip_frame (void); static long read_frame (char **buf_p, long *sizeof_buf); -static int remote_insert_breakpoint (CORE_ADDR, bfd_byte *); - -static int remote_remove_breakpoint (CORE_ADDR, bfd_byte *); - static int hexnumlen (ULONGEST num); static void init_remote_ops (void); @@ -4356,22 +4352,18 @@ static unsigned char little_break_insn[] = DEPRECATED_LITTLE_REMOTE_BREAKPOINT; #endif /* DEPRECATED_REMOTE_BREAKPOINT */ -/* Insert a breakpoint on targets that don't have any better - breakpoint support. We read the contents of the target location - and stash it, then overwrite it with a breakpoint instruction. - ADDR is the target location in the target machine. CONTENTS_CACHE - is a pointer to memory allocated for saving the target contents. - It is guaranteed by the caller to be long enough to save the number - of bytes returned by BREAKPOINT_FROM_PC. */ +/* Insert a breakpoint. On targets that have software breakpoint + support, we ask the remote target to do the work; on targets + which don't, we insert a traditional memory breakpoint. */ static int -remote_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) +remote_insert_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; struct remote_state *rs = get_remote_state (); #ifdef DEPRECATED_REMOTE_BREAKPOINT int val; #endif - int bp_size; /* Try the "Z" s/w breakpoint packet if it is not already disabled. If it succeeds, then set the support to PACKET_ENABLE. If it @@ -4382,13 +4374,13 @@ remote_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) { char *p = rs->buf; - addr = remote_address_masked (addr); *(p++) = 'Z'; *(p++) = '0'; *(p++) = ','; - p += hexnumstr (p, (ULONGEST) addr); - BREAKPOINT_FROM_PC (&addr, &bp_size); - sprintf (p, ",%d", bp_size); + BREAKPOINT_FROM_PC (&bp_tgt->placed_address, &bp_tgt->placed_size); + addr = (ULONGEST) remote_address_masked (bp_tgt->placed_address); + p += hexnumstr (p, addr); + sprintf (p, ",%d", bp_tgt->placed_size); putpkt (rs->buf); getpkt (&rs->buf, &rs->buf_size, 0); @@ -4405,7 +4397,8 @@ remote_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) } #ifdef DEPRECATED_REMOTE_BREAKPOINT - val = target_read_memory (addr, contents_cache, sizeof big_break_insn); + bp_tgt->placed_size = bp_tgt->shadow_len = sizeof big_break_insn; + val = target_read_memory (addr, bp_tgt->shadow_contents, bp_tgt->shadow_len); if (val == 0) { @@ -4419,13 +4412,14 @@ remote_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) return val; #else - return memory_insert_breakpoint (addr, contents_cache); + return memory_insert_breakpoint (bp_tgt); #endif /* DEPRECATED_REMOTE_BREAKPOINT */ } static int -remote_remove_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) +remote_remove_breakpoint (struct bp_target_info *bp_tgt) { + CORE_ADDR addr = bp_tgt->placed_address; struct remote_state *rs = get_remote_state (); int bp_size; @@ -4437,10 +4431,9 @@ remote_remove_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) *(p++) = '0'; *(p++) = ','; - addr = remote_address_masked (addr); - p += hexnumstr (p, (ULONGEST) addr); - BREAKPOINT_FROM_PC (&addr, &bp_size); - sprintf (p, ",%d", bp_size); + addr = (ULONGEST) remote_address_masked (bp_tgt->placed_address); + p += hexnumstr (p, addr); + sprintf (p, ",%d", bp_tgt->placed_size); putpkt (rs->buf); getpkt (&rs->buf, &rs->buf_size, 0); @@ -4449,9 +4442,10 @@ remote_remove_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache) } #ifdef DEPRECATED_REMOTE_BREAKPOINT - return target_write_memory (addr, contents_cache, sizeof big_break_insn); + return target_write_memory (bp_tgt->placed_address, bp_tgt->shadow_contents, + bp_tgt->shadow_len); #else - return memory_remove_breakpoint (addr, contents_cache); + return memory_remove_breakpoint (bp_tgt); #endif /* DEPRECATED_REMOTE_BREAKPOINT */ } @@ -4595,16 +4589,16 @@ remote_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p) static int -remote_insert_hw_breakpoint (CORE_ADDR addr, gdb_byte *shadow) +remote_insert_hw_breakpoint (struct bp_target_info *bp_tgt) { - int len = 0; + CORE_ADDR addr; struct remote_state *rs = get_remote_state (); char *p = rs->buf; /* The length field should be set to the size of a breakpoint - instruction. */ + instruction, even though we aren't inserting one ourselves. */ - BREAKPOINT_FROM_PC (&addr, &len); + BREAKPOINT_FROM_PC (&bp_tgt->placed_address, &bp_tgt->placed_size); if (remote_protocol_packets[PACKET_Z1].support == PACKET_DISABLE) error (_("Can't set hardware breakpoint without the '%s' (%s) packet."), @@ -4615,9 +4609,9 @@ remote_insert_hw_breakpoint (CORE_ADDR addr, gdb_byte *shadow) *(p++) = '1'; *(p++) = ','; - addr = remote_address_masked (addr); + addr = remote_address_masked (bp_tgt->placed_address); p += hexnumstr (p, (ULONGEST) addr); - sprintf (p, ",%x", len); + sprintf (p, ",%x", bp_tgt->placed_size); putpkt (rs->buf); getpkt (&rs->buf, &rs->buf_size, 0); @@ -4636,17 +4630,12 @@ remote_insert_hw_breakpoint (CORE_ADDR addr, gdb_byte *shadow) static int -remote_remove_hw_breakpoint (CORE_ADDR addr, gdb_byte *shadow) +remote_remove_hw_breakpoint (struct bp_target_info *bp_tgt) { - int len; + CORE_ADDR addr; struct remote_state *rs = get_remote_state (); char *p = rs->buf; - /* The length field should be set to the size of a breakpoint - instruction. */ - - BREAKPOINT_FROM_PC (&addr, &len); - if (remote_protocol_packets[PACKET_Z1].support == PACKET_DISABLE) error (_("Can't clear hardware breakpoint without the '%s' (%s) packet."), remote_protocol_packets[PACKET_Z1].name, @@ -4656,9 +4645,9 @@ remote_remove_hw_breakpoint (CORE_ADDR addr, gdb_byte *shadow) *(p++) = '1'; *(p++) = ','; - addr = remote_address_masked (addr); + addr = remote_address_masked (bp_tgt->placed_address); p += hexnumstr (p, (ULONGEST) addr); - sprintf (p, ",%x", len); + sprintf (p, ",%x", bp_tgt->placed_size); putpkt (rs->buf); getpkt (&rs->buf, &rs->buf_size, 0); diff --git a/gdb/rs6000-nat.c b/gdb/rs6000-nat.c index 4b2dc65..705016c 100644 --- a/gdb/rs6000-nat.c +++ b/gdb/rs6000-nat.c @@ -527,15 +527,15 @@ exec_one_dummy_insn (void) { #define DUMMY_INSN_ADDR (TEXT_SEGMENT_BASE)+0x200 - char shadow_contents[BREAKPOINT_MAX]; /* Stash old bkpt addr contents */ int ret, status, pid; CORE_ADDR prev_pc; + void *bp; /* We plant one dummy breakpoint into DUMMY_INSN_ADDR address. We assume that this address will never be executed again by the real code. */ - target_insert_breakpoint (DUMMY_INSN_ADDR, shadow_contents); + bp = deprecated_insert_raw_breakpoint (DUMMY_INSN_ADDR); /* You might think this could be done with a single ptrace call, and you'd be correct for just about every platform I've ever worked @@ -559,7 +559,7 @@ exec_one_dummy_insn (void) while (pid != PIDGET (inferior_ptid)); write_pc (prev_pc); - target_remove_breakpoint (DUMMY_INSN_ADDR, shadow_contents); + deprecated_remove_raw_breakpoint (bp); } /* Fetch registers from the register section in core bfd. */ diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index f782800..f932b4c 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -110,17 +110,6 @@ struct reg register number. */ }; -/* Breakpoint shadows for the single step instructions will be kept here. */ - -static struct sstep_breaks -{ - /* Address, or 0 if this is not in use. */ - CORE_ADDR address; - /* Shadow contents. */ - gdb_byte data[4]; -} -stepBreaks[2]; - /* Hook for determining the TOC address when calling functions in the inferior under AIX. The initialization code in rs6000-nat.c sets this hook to point to find_toc_address. */ @@ -730,7 +719,6 @@ rs6000_software_single_step (enum target_signal signal, if (insert_breakpoints_p) { - loc = read_pc (); insn = read_memory_integer (loc, 4); @@ -743,28 +731,17 @@ rs6000_software_single_step (enum target_signal signal, if (breaks[1] == breaks[0]) breaks[1] = -1; - stepBreaks[1].address = 0; - for (ii = 0; ii < 2; ++ii) { - /* ignore invalid breakpoint. */ if (breaks[ii] == -1) continue; - target_insert_breakpoint (breaks[ii], stepBreaks[ii].data); - stepBreaks[ii].address = breaks[ii]; + insert_single_step_breakpoint (breaks[ii]); } - } else - { + remove_single_step_breakpoints (); - /* remove step breakpoints. */ - for (ii = 0; ii < 2; ++ii) - if (stepBreaks[ii].address != 0) - target_remove_breakpoint (stepBreaks[ii].address, - stepBreaks[ii].data); - } errno = 0; /* FIXME, don't ignore errors! */ /* What errors? {read,write}_memory call error(). */ } diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c index ed4e8e5..106ec19 100644 --- a/gdb/sol-thread.c +++ b/gdb/sol-thread.c @@ -1524,7 +1524,7 @@ sol_make_note_section (bfd *obfd, int *note_size) } static int -ignore (CORE_ADDR addr, gdb_byte *contents) +ignore (struct bp_target_info *bp_tgt) { return 0; } diff --git a/gdb/solib-irix.c b/gdb/solib-irix.c index ffbb252..994953a 100644 --- a/gdb/solib-irix.c +++ b/gdb/solib-irix.c @@ -227,10 +227,9 @@ fetch_lm_info (CORE_ADDR addr) /* The symbol which starts off the list of shared libraries. */ #define DEBUG_BASE "__rld_obj_head" -char shadow_contents[BREAKPOINT_MAX]; /* Stash old bkpt addr contents */ +static void *base_breakpoint; static CORE_ADDR debug_base; /* Base of dynamic linker structures */ -static CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */ /* @@ -319,11 +318,13 @@ disable_break (void) /* Note that breakpoint address and original contents are in our address space, so we just need to write the original contents back. */ - if (memory_remove_breakpoint (breakpoint_addr, shadow_contents) != 0) + if (deprecated_remove_raw_breakpoint (base_breakpoint) != 0) { status = 0; } + base_breakpoint = NULL; + /* Note that it is possible that we have stopped at a location that is different from the location where we inserted our breakpoint. On mips-irix, we can actually land in __dbx_init(), so we should @@ -352,12 +353,13 @@ disable_break (void) static int enable_break (void) { - if (symfile_objfile != NULL - && target_insert_breakpoint (entry_point_address (), - shadow_contents) == 0) + if (symfile_objfile != NULL) { - breakpoint_addr = entry_point_address (); - return 1; + base_breakpoint + = deprecated_insert_raw_breakpoint (entry_point_address ()); + + if (base_breakpoint != NULL) + return 1; } return 0; diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index 77169a7..797e240 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -1136,8 +1136,7 @@ sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p) { struct gdbarch *arch = current_gdbarch; struct gdbarch_tdep *tdep = gdbarch_tdep (arch); - static CORE_ADDR npc, nnpc; - static gdb_byte npc_save[4], nnpc_save[4]; + CORE_ADDR npc, nnpc; if (insert_breakpoints_p) { @@ -1149,9 +1148,10 @@ sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p) /* Analyze the instruction at PC. */ nnpc = sparc_analyze_control_transfer (arch, pc, &npc); if (npc != 0) - target_insert_breakpoint (npc, npc_save); + insert_single_step_breakpoint (npc); + if (nnpc != 0) - target_insert_breakpoint (nnpc, nnpc_save); + insert_single_step_breakpoint (nnpc); /* Assert that we have set at least one breakpoint, and that they're not set at the same spot - unless we're going @@ -1160,12 +1160,7 @@ sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p) gdb_assert (nnpc != npc || orig_npc == 0); } else - { - if (npc != 0) - target_remove_breakpoint (npc, npc_save); - if (nnpc != 0) - target_remove_breakpoint (nnpc, nnpc_save); - } + remove_single_step_breakpoints (); } static void diff --git a/gdb/target.c b/gdb/target.c index fbfc58a..52e4527 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -111,15 +111,15 @@ static void debug_to_prepare_to_store (void); static void debug_to_files_info (struct target_ops *); -static int debug_to_insert_breakpoint (CORE_ADDR, gdb_byte *); +static int debug_to_insert_breakpoint (struct bp_target_info *); -static int debug_to_remove_breakpoint (CORE_ADDR, gdb_byte *); +static int debug_to_remove_breakpoint (struct bp_target_info *); static int debug_to_can_use_hw_breakpoint (int, int, int); -static int debug_to_insert_hw_breakpoint (CORE_ADDR, gdb_byte *); +static int debug_to_insert_hw_breakpoint (struct bp_target_info *); -static int debug_to_remove_hw_breakpoint (CORE_ADDR, gdb_byte *); +static int debug_to_remove_hw_breakpoint (struct bp_target_info *); static int debug_to_insert_watchpoint (CORE_ADDR, int, int); @@ -515,10 +515,10 @@ update_current_target (void) (int (*) (int, int, int)) return_zero); de_fault (to_insert_hw_breakpoint, - (int (*) (CORE_ADDR, gdb_byte *)) + (int (*) (struct bp_target_info *)) return_minus_one); de_fault (to_remove_hw_breakpoint, - (int (*) (CORE_ADDR, gdb_byte *)) + (int (*) (struct bp_target_info *)) return_minus_one); de_fault (to_insert_watchpoint, (int (*) (CORE_ADDR, int, int)) @@ -2075,29 +2075,29 @@ debug_to_files_info (struct target_ops *target) } static int -debug_to_insert_breakpoint (CORE_ADDR addr, gdb_byte *save) +debug_to_insert_breakpoint (struct bp_target_info *bp_tgt) { int retval; - retval = debug_target.to_insert_breakpoint (addr, save); + retval = debug_target.to_insert_breakpoint (bp_tgt); fprintf_unfiltered (gdb_stdlog, "target_insert_breakpoint (0x%lx, xxx) = %ld\n", - (unsigned long) addr, + (unsigned long) bp_tgt->placed_address, (unsigned long) retval); return retval; } static int -debug_to_remove_breakpoint (CORE_ADDR addr, gdb_byte *save) +debug_to_remove_breakpoint (struct bp_target_info *bp_tgt) { int retval; - retval = debug_target.to_remove_breakpoint (addr, save); + retval = debug_target.to_remove_breakpoint (bp_tgt); fprintf_unfiltered (gdb_stdlog, "target_remove_breakpoint (0x%lx, xxx) = %ld\n", - (unsigned long) addr, + (unsigned long) bp_tgt->placed_address, (unsigned long) retval); return retval; } @@ -2161,29 +2161,29 @@ debug_to_stopped_data_address (struct target_ops *target, CORE_ADDR *addr) } static int -debug_to_insert_hw_breakpoint (CORE_ADDR addr, gdb_byte *save) +debug_to_insert_hw_breakpoint (struct bp_target_info *bp_tgt) { int retval; - retval = debug_target.to_insert_hw_breakpoint (addr, save); + retval = debug_target.to_insert_hw_breakpoint (bp_tgt); fprintf_unfiltered (gdb_stdlog, "target_insert_hw_breakpoint (0x%lx, xxx) = %ld\n", - (unsigned long) addr, + (unsigned long) bp_tgt->placed_address, (unsigned long) retval); return retval; } static int -debug_to_remove_hw_breakpoint (CORE_ADDR addr, gdb_byte *save) +debug_to_remove_hw_breakpoint (struct bp_target_info *bp_tgt) { int retval; - retval = debug_target.to_remove_hw_breakpoint (addr, save); + retval = debug_target.to_remove_hw_breakpoint (bp_tgt); fprintf_unfiltered (gdb_stdlog, "target_remove_hw_breakpoint (0x%lx, xxx) = %ld\n", - (unsigned long) addr, + (unsigned long) bp_tgt->placed_address, (unsigned long) retval); return retval; } diff --git a/gdb/target.h b/gdb/target.h index b804b05..7decfd7 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -30,6 +30,7 @@ struct objfile; struct ui_file; struct mem_attrib; struct target_ops; +struct bp_target_info; /* This include file defines the interface between the main part of the debugger, and the part which is target-specific, or @@ -336,11 +337,11 @@ struct target_ops struct target_ops *target); void (*to_files_info) (struct target_ops *); - int (*to_insert_breakpoint) (CORE_ADDR, gdb_byte *); - int (*to_remove_breakpoint) (CORE_ADDR, gdb_byte *); + int (*to_insert_breakpoint) (struct bp_target_info *); + int (*to_remove_breakpoint) (struct bp_target_info *); int (*to_can_use_hw_breakpoint) (int, int, int); - int (*to_insert_hw_breakpoint) (CORE_ADDR, gdb_byte *); - int (*to_remove_hw_breakpoint) (CORE_ADDR, gdb_byte *); + int (*to_insert_hw_breakpoint) (struct bp_target_info *); + int (*to_remove_hw_breakpoint) (struct bp_target_info *); int (*to_remove_watchpoint) (CORE_ADDR, int, int); int (*to_insert_watchpoint) (CORE_ADDR, int, int); int (*to_stopped_by_watchpoint) (void); @@ -612,22 +613,17 @@ extern void print_section_info (struct target_ops *, bfd *); #define target_files_info() \ (*current_target.to_files_info) (¤t_target) -/* Insert a breakpoint at address ADDR in the target machine. SAVE is - a pointer to memory allocated for saving the target contents. It - is guaranteed by the caller to be long enough to save the number of - breakpoint bytes indicated by BREAKPOINT_FROM_PC. Result is 0 for - success, or an errno value. */ +/* Insert a breakpoint at address BP_TGT->placed_address in the target + machine. Result is 0 for success, or an errno value. */ -#define target_insert_breakpoint(addr, save) \ - (*current_target.to_insert_breakpoint) (addr, save) +#define target_insert_breakpoint(bp_tgt) \ + (*current_target.to_insert_breakpoint) (bp_tgt) -/* Remove a breakpoint at address ADDR in the target machine. - SAVE is a pointer to the same save area - that was previously passed to target_insert_breakpoint. - Result is 0 for success, or an errno value. */ +/* Remove a breakpoint at address BP_TGT->placed_address in the target + machine. Result is 0 for success, or an errno value. */ -#define target_remove_breakpoint(addr, save) \ - (*current_target.to_remove_breakpoint) (addr, save) +#define target_remove_breakpoint(bp_tgt) \ + (*current_target.to_remove_breakpoint) (bp_tgt) /* Initialize the terminal settings we record for the inferior, before we actually run the inferior. */ @@ -1057,11 +1053,11 @@ extern void (*deprecated_target_new_objfile_hook) (struct objfile *); #endif #ifndef target_insert_hw_breakpoint -#define target_insert_hw_breakpoint(addr, save) \ - (*current_target.to_insert_hw_breakpoint) (addr, save) +#define target_insert_hw_breakpoint(bp_tgt) \ + (*current_target.to_insert_hw_breakpoint) (bp_tgt) -#define target_remove_hw_breakpoint(addr, save) \ - (*current_target.to_remove_hw_breakpoint) (addr, save) +#define target_remove_hw_breakpoint(bp_tgt) \ + (*current_target.to_remove_hw_breakpoint) (bp_tgt) #endif extern int target_stopped_data_address_p (struct target_ops *); @@ -1142,13 +1138,13 @@ struct section_table *target_section_by_addr (struct target_ops *target, /* From mem-break.c */ -extern int memory_remove_breakpoint (CORE_ADDR, gdb_byte *); +extern int memory_remove_breakpoint (struct bp_target_info *); -extern int memory_insert_breakpoint (CORE_ADDR, gdb_byte *); +extern int memory_insert_breakpoint (struct bp_target_info *); -extern int default_memory_remove_breakpoint (CORE_ADDR, gdb_byte *); +extern int default_memory_remove_breakpoint (struct bp_target_info *); -extern int default_memory_insert_breakpoint (CORE_ADDR, gdb_byte *); +extern int default_memory_insert_breakpoint (struct bp_target_info *); /* From target.c */ diff --git a/gdb/wince.c b/gdb/wince.c index 56f4b95..86bfaf6 100644 --- a/gdb/wince.c +++ b/gdb/wince.c @@ -146,7 +146,6 @@ typedef struct thread_info_struct int suspend_count; int stepped; /* True if stepped. */ CORE_ADDR step_pc; - unsigned long step_prev; CONTEXT context; } thread_info; @@ -834,7 +833,7 @@ undoSStep (thread_info * th) { if (th->stepped) { - memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev); + remove_single_step_breakpoints (); th->stepped = 0; } } @@ -857,8 +856,7 @@ wince_software_single_step (enum target_signal ignore, th->stepped = 1; pc = read_register (PC_REGNUM); th->step_pc = mips_next_pc (pc); - th->step_prev = 0; - memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev); + insert_single_step_breakpoint (th->step_pc); return; } #elif SHx @@ -971,7 +969,7 @@ undoSStep (thread_info * th) { if (th->stepped) { - memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev); + remove_single_step_breakpoints (); th->stepped = 0; } return; @@ -996,8 +994,7 @@ wince_software_single_step (enum target_signal ignore, th->stepped = 1; th->step_pc = sh_get_next_pc (&th->context); - th->step_prev = 0; - memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev); + insert_single_step_breakpoint (th->step_pc); return; } #elif defined (ARM) @@ -1024,7 +1021,7 @@ undoSStep (thread_info * th) { if (th->stepped) { - memory_remove_breakpoint (th->step_pc, (void *) &th->step_prev); + remove_single_step_breakpoints (); th->stepped = 0; } } @@ -1047,8 +1044,7 @@ wince_software_single_step (enum target_signal ignore, th->stepped = 1; pc = read_register (PC_REGNUM); th->step_pc = arm_get_next_pc (pc); - th->step_prev = 0; - memory_insert_breakpoint (th->step_pc, (void *) &th->step_prev); + insert_single_step_breakpoint (th->step_pc); return; } #endif |