*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index c8e15d915541c8a9dd5ba56aede299ac0b0cce58..59cb151b516dee7b82d0c6b5be27a9d1ae5d0d74 100644 (file)
@@ -1,7 +1,7 @@
 /* Everything about breakpoints, for GDB.
 
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
-   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -18,8 +18,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include <ctype.h>
@@ -53,6 +53,8 @@
 #include "solist.h"
 #include "observer.h"
 #include "exceptions.h"
+#include "memattr.h"
+#include "ada-lang.h"
 
 #include "gdb-events.h"
 #include "mi/mi-common.h"
@@ -102,7 +104,7 @@ static void breakpoint_adjustment_warning (CORE_ADDR, CORE_ADDR, int, int);
 static CORE_ADDR adjust_breakpoint_address (CORE_ADDR bpaddr,
                                             enum bptype bptype);
 
-static void describe_other_breakpoints (CORE_ADDR, asection *);
+static void describe_other_breakpoints (CORE_ADDR, asection *, int);
 
 static void breakpoints_info (char *, int);
 
@@ -200,6 +202,8 @@ static void tcatch_command (char *arg, int from_tty);
 
 static void ep_skip_leading_whitespace (char **s);
 
+static int single_step_breakpoint_inserted_here_p (CORE_ADDR pc);
+
 /* Prototypes for exported functions. */
 
 /* If FALSE, gdb will not use hardware support for watchpoints, even
@@ -231,6 +235,22 @@ Debugger's behavior regarding pending breakpoints is %s.\n"),
                    value);
 }
 
+/* If 1, gdb will automatically use hardware breakpoints for breakpoints
+   set with "break" but falling in read-only memory. 
+   If 0, gdb will warn about such breakpoints, but won't automatically
+   use hardware breakpoints.  */
+static int automatic_hardware_breakpoints;
+static void
+show_automatic_hardware_breakpoints (struct ui_file *file, int from_tty,
+                                    struct cmd_list_element *c,
+                                    const char *value)
+{
+  fprintf_filtered (file, _("\
+Automatic usage of hardware breakpoints is %s.\n"),
+                   value);
+}
+
+
 void _initialize_breakpoint (void);
 
 extern int addressprint;       /* Print machine addresses? */
@@ -385,6 +405,8 @@ int default_breakpoint_line;
    Currently the string can either be a number or "$" followed by the name
    of a convenience variable.  Making it an expression wouldn't work well
    for map_breakpoint_numbers (e.g. "4 + 5 + 6").
+
+   If the string is a NULL pointer, that denotes the last breakpoint.
    
    TRAILER is a character which can be found after the number; most
    commonly this is `-'.  If you don't want a trailer, use \0.  */ 
@@ -629,6 +651,52 @@ commands_command (char *arg, int from_tty)
     }
   error (_("No breakpoint number %d."), bnum);
 }
+
+/* Like commands_command, but instead of reading the commands from
+   input stream, takes them from an already parsed command structure.
+
+   This is used by cli-script.c to DTRT with breakpoint commands
+   that are part of if and while bodies.  */
+enum command_control_type
+commands_from_control_command (char *arg, struct command_line *cmd)
+{
+  struct breakpoint *b;
+  char *p;
+  int bnum;
+
+  /* If we allowed this, we would have problems with when to
+     free the storage, if we change the commands currently
+     being read from.  */
+
+  if (executing_breakpoint_commands)
+    error (_("Can't use the \"commands\" command among a breakpoint's commands."));
+
+  /* An empty string for the breakpoint number means the last
+     breakpoint, but get_number expects a NULL pointer.  */
+  if (arg && !*arg)
+    p = NULL;
+  else
+    p = arg;
+  bnum = get_number (&p);
+
+  if (p && *p)
+    error (_("Unexpected extra arguments following breakpoint number."));
+
+  ALL_BREAKPOINTS (b)
+    if (b->number == bnum)
+      {
+       free_command_lines (&b->commands);
+       if (cmd->body_count != 1)
+         error (_("Invalid \"commands\" block structure."));
+       /* We need to copy the commands because if/while will free the
+          list after it finishes execution.  */
+       b->commands = copy_command_lines (cmd->body_list[0]);
+       breakpoints_changed ();
+       breakpoint_modify_event (b->number);
+       return simple_control;
+    }
+  error (_("No breakpoint number %d."), bnum);
+}
 \f
 /* Like target_read_memory() but if breakpoints are inserted, return
    the shadow contents instead of the breakpoints themselves.
@@ -639,8 +707,7 @@ commands_command (char *arg, int from_tty)
    shadow contents, not the breakpoints themselves.  From breakpoint.c.  */
 
 int
-deprecated_read_memory_nobpt (CORE_ADDR memaddr, gdb_byte *myaddr,
-                             unsigned len)
+read_memory_nobpt (CORE_ADDR memaddr, gdb_byte *myaddr, unsigned len)
 {
   int status;
   struct bp_location *b;
@@ -663,16 +730,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,12 +764,12 @@ 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)
        {
          /* Copy the section of memory before the breakpoint.  */
-         status = deprecated_read_memory_nobpt (memaddr, myaddr, bp_addr - memaddr);
+         status = read_memory_nobpt (memaddr, myaddr, bp_addr - memaddr);
          if (status != 0)
            return status;
        }
@@ -716,7 +777,7 @@ deprecated_read_memory_nobpt (CORE_ADDR memaddr, gdb_byte *myaddr,
       if (bp_addr + bp_size < memaddr + len)
        {
          /* Copy the section of memory after the breakpoint.  */
-         status = deprecated_read_memory_nobpt (bp_addr + bp_size,
+         status = read_memory_nobpt (bp_addr + bp_size,
                                      myaddr + bp_addr + bp_size - memaddr,
                                      memaddr + len - (bp_addr + bp_size));
          if (status != 0)
@@ -756,7 +817,8 @@ insert_catchpoint (struct ui_out *uo, void *args)
 
 /* Helper routine: free the value chain for a breakpoint (watchpoint).  */
 
-static void free_valchain (struct bp_location *b)
+static void
+free_valchain (struct bp_location *b)
 {
   struct value *v;
   struct value *n;
@@ -793,9 +855,64 @@ 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)
     {
+      if (bpt->owner->type != bp_hardware_breakpoint)
+       {
+         /* If the explicitly specified breakpoint type
+            is not hardware breakpoint, check the memory map to see
+            if the breakpoint address is in read only memory or not.
+            Two important cases are:
+            - location type is not hardware breakpoint, memory
+            is readonly.  We change the type of the location to
+            hardware breakpoint.
+            - location type is hardware breakpoint, memory is read-write.
+            This means we've previously made the location hardware one, but
+            then the memory map changed, so we undo.
+            
+            When breakpoints are removed, remove_breakpoints will
+            use location types we've just set here, the only possible
+            problem is that memory map has changed during running program,
+            but it's not going to work anyway with current gdb.  */
+         struct mem_region *mr 
+           = lookup_mem_region (bpt->target_info.placed_address);
+         
+         if (mr)
+           {
+             if (automatic_hardware_breakpoints)
+               {
+                 int changed = 0;
+                 enum bp_loc_type new_type;
+                 
+                 if (mr->attrib.mode != MEM_RW)
+                   new_type = bp_loc_hardware_breakpoint;
+                 else 
+                   new_type = bp_loc_software_breakpoint;
+                 
+                 if (new_type != bpt->loc_type)
+                   {
+                     static int said = 0;
+                     bpt->loc_type = new_type;
+                     if (!said)
+                       {
+                         fprintf_filtered (gdb_stdout, _("\
+Note: automatically using hardware breakpoints for read-only addresses.\n"));
+                         said = 1;
+                       }
+                   }
+               }
+             else if (bpt->loc_type == bp_loc_software_breakpoint
+                      && mr->attrib.mode != MEM_RW)        
+               warning (_("cannot set software breakpoint at readonly address %s"),
+                        paddr (bpt->address));
+           }
+       }
+        
       /* First check to see if we have to handle an overlay.  */
       if (overlay_debugging == ovly_off
          || bpt->section == NULL
@@ -804,11 +921,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 +942,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 +956,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
            {
@@ -932,7 +1047,7 @@ insert_bp_location (struct bp_location *bpt,
       /* FIXME drow/2003-09-09: It would be nice if evaluate_expression
         took a frame parameter, so that we didn't have to change the
         selected frame.  */
-      saved_frame_id = get_frame_id (deprecated_selected_frame);
+      saved_frame_id = get_frame_id (get_selected_frame (NULL));
 
       /* Determine if the watchpoint is within scope.  */
       if (bpt->owner->exp_valid_block == NULL)
@@ -1045,7 +1160,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 */
@@ -1142,6 +1257,12 @@ insert_breakpoints (void)
       if (!breakpoint_enabled (b->owner))
        continue;
 
+      /* There is no point inserting thread-specific breakpoints if the
+        thread no longer exists.  */
+      if (b->owner->thread != -1
+         && !valid_thread_id (b->owner->thread))
+       continue;
+
       /* FIXME drow/2003-10-07: This code should be pushed elsewhere when
         hardware watchpoints are split into multiple loc breakpoints.  */
       if ((b->loc_type == bp_loc_hardware_watchpoint
@@ -1233,10 +1354,13 @@ reattach_breakpoints (int pid)
     if (b->inserted)
       {
        remove_breakpoint (b, mark_inserted);
+       /* Note: since we insert a breakpoint right after removing,
+          any decisions about automatically using hardware breakpoints
+          made in insert_bp_location are preserved.  */
        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)
@@ -1285,13 +1409,6 @@ update_breakpoints_after_exec (void)
        continue;
       }
 
-    /* Ditto the sigtramp handler breakpoints. */
-    if (b->type == bp_through_sigtramp)
-      {
-       delete_breakpoint (b);
-       continue;
-      }
-
     /* Ditto the exception-handling catchpoints. */
     if ((b->type == bp_catch_catch) || (b->type == bp_catch_throw))
       {
@@ -1325,7 +1442,7 @@ update_breakpoints_after_exec (void)
        (b->type == bp_catch_vfork) ||
        (b->type == bp_catch_fork))
       {
-       b->loc->address = (CORE_ADDR) NULL;
+       b->loc->address = (CORE_ADDR) 0;
        continue;
       }
 
@@ -1378,7 +1495,7 @@ update_breakpoints_after_exec (void)
        unnecessary.  A call to breakpoint_re_set_one always recomputes
        the breakpoint's address from scratch, or deletes it if it can't.
        So I think this assignment could be deleted without effect.  */
-    b->loc->address = (CORE_ADDR) NULL;
+    b->loc->address = (CORE_ADDR) 0;
   }
   /* FIXME what about longjmp breakpoints?  Re-create them here?  */
   create_overlay_event_breakpoint ("_ovly_debug_event");
@@ -1440,10 +1557,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
        {
@@ -1454,14 +1570,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'.  */
@@ -1472,11 +1586,15 @@ 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);
+
+             /* However, we should remove *software* breakpoints only
+                if the section is still mapped, or else we overwrite
+                wrong code with the saved shadow contents.  */
+             else if (section_is_mapped (b->section))
+               val = target_remove_breakpoint (&b->target_info);
              else
-               val = target_remove_breakpoint (b->address,
-                                               b->shadow_contents);
+               val = 0;
            }
          else
            {
@@ -1564,24 +1682,11 @@ 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);
     }
-  else if (ep_is_exception_catchpoint (b->owner)
-          && b->inserted       /* sometimes previous insert doesn't happen */
-          && breakpoint_enabled (b->owner)
-          && !b->duplicate)
-    {
-
-      val = target_remove_breakpoint (b->address, b->shadow_contents);
-      if (val)
-       return val;
-
-      b->inserted = (is == mark_inserted);
-    }
 
   return 0;
 }
@@ -1744,6 +1849,10 @@ breakpoint_inserted_here_p (CORE_ADDR pc)
        }
     }
 
+  /* Also check for software single-step breakpoints.  */
+  if (single_step_breakpoint_inserted_here_p (pc))
+    return 1;
+
   return 0;
 }
 
@@ -1775,6 +1884,10 @@ software_breakpoint_inserted_here_p (CORE_ADDR pc)
        }
     }
 
+  /* Also check for software single-step breakpoints.  */
+  if (single_step_breakpoint_inserted_here_p (pc))
+    return 1;
+
   return 0;
 }
 
@@ -1950,28 +2063,30 @@ bpstat_find_step_resume_breakpoint (bpstat bsp)
 }
 
 
-/* Return the breakpoint number of the first breakpoint we are stopped
+/* Put in *NUM the breakpoint number of the first breakpoint we are stopped
    at.  *BSP upon return is a bpstat which points to the remaining
    breakpoints stopped at (but which is not guaranteed to be good for
    anything but further calls to bpstat_num).
-   Return 0 if passed a bpstat which does not indicate any breakpoints.  */
+   Return 0 if passed a bpstat which does not indicate any breakpoints.
+   Return -1 if stopped at a breakpoint that has been deleted since
+   we set it.
+   Return 1 otherwise.  */
 
 int
-bpstat_num (bpstat *bsp)
+bpstat_num (bpstat *bsp, int *num)
 {
   struct breakpoint *b;
 
   if ((*bsp) == NULL)
     return 0;                  /* No more breakpoint values */
-  else
-    {
-      b = (*bsp)->breakpoint_at;
-      *bsp = (*bsp)->next;
-      if (b == NULL)
-       return -1;              /* breakpoint that's been deleted since */
-      else
-       return b->number;       /* We have its number */
-    }
+
+  b = (*bsp)->breakpoint_at;
+  *bsp = (*bsp)->next;
+  if (b == NULL)
+    return -1;                 /* breakpoint that's been deleted since */
+
+  *num = b->number;            /* We have its number */
+  return 1;
 }
 
 /* Modify BS so that the actions will not be performed.  */
@@ -2333,7 +2448,9 @@ print_it_typical (bpstat bs)
 
     case bp_until:
       if (ui_out_is_mi_like_p (uiout))
-       ui_out_field_string (uiout, "reason", "location-reached");
+       ui_out_field_string
+         (uiout, "reason",
+          async_reason_lookup (EXEC_ASYNC_LOCATION_REACHED));
       return PRINT_UNKNOWN;
       break;
 
@@ -2341,7 +2458,6 @@ print_it_typical (bpstat bs)
     case bp_longjmp:
     case bp_longjmp_resume:
     case bp_step_resume:
-    case bp_through_sigtramp:
     case bp_watchpoint_scope:
     case bp_call_dummy:
     default:
@@ -2496,6 +2612,13 @@ watchpoint_check (void *p)
       reinit_frame_cache ();
       fr = frame_find_by_id (b->watchpoint_frame);
       within_current_scope = (fr != NULL);
+
+      /* If we've gotten confused in the unwinder, we might have
+        returned a frame that can't describe this variable.  */
+      if (within_current_scope
+         && block_function (b->exp_valid_block) != get_frame_function (fr))
+       within_current_scope = 0;
+
       /* in_function_epilogue_p() returns a non-zero value if we're still
         in the function but the stack frame has already been invalidated.
         Since we can't rely on the values of local variables after the
@@ -2951,9 +3074,6 @@ bpstat_what (bpstat bs)
       /* We hit the step_resume breakpoint.  */
       step_resume,
 
-      /* We hit the through_sigtramp breakpoint.  */
-      through_sig,
-
       /* We hit the shared library event breakpoint.  */
       shlib_event,
 
@@ -2975,7 +3095,6 @@ bpstat_what (bpstat bs)
 #define clr BPSTAT_WHAT_CLEAR_LONGJMP_RESUME
 #define clrs BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE
 #define sr BPSTAT_WHAT_STEP_RESUME
-#define ts BPSTAT_WHAT_THROUGH_SIGTRAMP
 #define shl BPSTAT_WHAT_CHECK_SHLIBS
 #define shlr BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK
 
@@ -2998,17 +3117,16 @@ bpstat_what (bpstat bs)
      back and decide something of a lower priority is better.  The
      ordering is:
 
-     kc   < clr sgl shl shlr slr sn sr ss ts
-     sgl  < clrs shl shlr slr sn sr ss ts
-     slr  < err shl shlr sn sr ss ts
-     clr  < clrs err shl shlr sn sr ss ts
-     clrs < err shl shlr sn sr ss ts
-     ss   < shl shlr sn sr ts
-     sn   < shl shlr sr ts
-     sr   < shl shlr ts
-     shl  < shlr
-     ts   < 
-     shlr <
+     kc   < clr sgl shl shlr slr sn sr ss
+     sgl  < clrs shl shlr slr sn sr ss
+     slr  < err shl shlr sn sr ss
+     clr  < clrs err shl shlr sn sr ss
+     clrs < err shl shlr sn sr ss
+     ss   < shl shlr sn sr
+     sn   < shl shlr sr
+     shl  < shlr sr
+     shlr < sr
+     sr   <
 
      What I think this means is that we don't need a damned table
      here.  If you just put the rows and columns in the right order,
@@ -3021,39 +3139,35 @@ bpstat_what (bpstat bs)
   /* step_resume entries: a step resume breakpoint overrides another
      breakpoint of signal handling (see comment in wait_for_inferior
      at where we set the step_resume breakpoint).  */
-  /* We handle the through_sigtramp_breakpoint the same way; having both
-     one of those and a step_resume_breakpoint is probably very rare (?).  */
 
   static const enum bpstat_what_main_action
     table[(int) class_last][(int) BPSTAT_WHAT_LAST] =
   {
   /*                              old action */
-  /*       kc    ss    sn    sgl    slr   clr    clrs   sr    ts   shl   shlr
+  /*       kc    ss    sn    sgl    slr   clr    clrs   sr   shl   shlr
    */
 /*no_effect */
-    {kc, ss, sn, sgl, slr, clr, clrs, sr, ts, shl, shlr},
+    {kc, ss, sn, sgl, slr, clr, clrs, sr, shl, shlr},
 /*wp_silent */
-    {ss, ss, sn, ss, ss, ss, ss, sr, ts, shl, shlr},
+    {ss, ss, sn, ss, ss, ss, ss, sr, shl, shlr},
 /*wp_noisy */
-    {sn, sn, sn, sn, sn, sn, sn, sr, ts, shl, shlr},
+    {sn, sn, sn, sn, sn, sn, sn, sr, shl, shlr},
 /*bp_nostop */
-    {sgl, ss, sn, sgl, slr, clrs, clrs, sr, ts, shl, shlr},
+    {sgl, ss, sn, sgl, slr, clrs, clrs, sr, shl, shlr},
 /*bp_silent */
-    {ss, ss, sn, ss, ss, ss, ss, sr, ts, shl, shlr},
+    {ss, ss, sn, ss, ss, ss, ss, sr, shl, shlr},
 /*bp_noisy */
-    {sn, sn, sn, sn, sn, sn, sn, sr, ts, shl, shlr},
+    {sn, sn, sn, sn, sn, sn, sn, sr, shl, shlr},
 /*long_jump */
-    {slr, ss, sn, slr, slr, err, err, sr, ts, shl, shlr},
+    {slr, ss, sn, slr, slr, err, err, sr, shl, shlr},
 /*long_resume */
-    {clr, ss, sn, clrs, err, err, err, sr, ts, shl, shlr},
+    {clr, ss, sn, clrs, err, err, err, sr, shl, shlr},
 /*step_resume */
-    {sr, sr, sr, sr, sr, sr, sr, sr, ts, shl, shlr},
-/*through_sig */
-    {ts, ts, ts, ts, ts, ts, ts, ts, ts, shl, shlr},
+    {sr, sr, sr, sr, sr, sr, sr, sr, sr, sr},
 /*shlib */
-    {shl, shl, shl, shl, shl, shl, shl, shl, ts, shl, shlr},
+    {shl, shl, shl, shl, shl, shl, shl, sr, shl, shlr},
 /*catch_shlib */
-    {shlr, shlr, shlr, shlr, shlr, shlr, shlr, shlr, ts, shlr, shlr}
+    {shlr, shlr, shlr, shlr, shlr, shlr, shlr, sr, shlr, shlr}
   };
 
 #undef kc
@@ -3129,9 +3243,6 @@ bpstat_what (bpstat bs)
            /* It is for the wrong frame.  */
            bs_class = bp_nostop;
          break;
-       case bp_through_sigtramp:
-         bs_class = through_sig;
-         break;
        case bp_watchpoint_scope:
          bs_class = bp_nostop;
          break;
@@ -3309,7 +3420,6 @@ print_one_breakpoint (struct breakpoint *b,
     {bp_longjmp, "longjmp"},
     {bp_longjmp_resume, "longjmp resume"},
     {bp_step_resume, "step resume"},
-    {bp_through_sigtramp, "sigtramp"},
     {bp_watchpoint_scope, "watchpoint scope"},
     {bp_call_dummy, "call dummy"},
     {bp_shlib_event, "shlib events"},
@@ -3426,6 +3536,7 @@ print_one_breakpoint (struct breakpoint *b,
            ui_out_field_int (uiout, "what", b->forked_inferior_pid);
            ui_out_spaces (uiout, 1);
          }
+       break;
 
       case bp_catch_exec:
        /* Field 4, the address, is omitted (which makes the columns
@@ -3471,7 +3582,6 @@ print_one_breakpoint (struct breakpoint *b,
       case bp_longjmp:
       case bp_longjmp_resume:
       case bp_step_resume:
-      case bp_through_sigtramp:
       case bp_watchpoint_scope:
       case bp_call_dummy:
       case bp_shlib_event:
@@ -3500,6 +3610,16 @@ print_one_breakpoint (struct breakpoint *b,
              }
            ui_out_field_string (uiout, "file", b->source_file);
            ui_out_text (uiout, ":");
+
+            if (ui_out_is_mi_like_p (uiout))
+              {
+                struct symtab_and_line sal = find_pc_line (b->loc->address, 0);
+                char *fullname = symtab_to_fullname (sal.symtab);
+
+                if (fullname)
+                  ui_out_field_string (uiout, "fullname", fullname);
+              }
+
            ui_out_field_int (uiout, "line", b->line_number);
          }
        else if (b->pending)
@@ -3534,8 +3654,11 @@ print_one_breakpoint (struct breakpoint *b,
       ui_out_text (uiout, "\n");
     }
   
-  if (b->cond)
+  if (b->cond && !ada_exception_catchpoint_p (b))
     {
+      /* We do not print the condition for Ada exception catchpoints
+         because the condition is an internal implementation detail
+         that we do not want to expose to the user.  */
       annotate_field (7);
       ui_out_text (uiout, "\tstop only if ");
       print_expression (b->cond, stb->stream);
@@ -3630,8 +3753,11 @@ gdb_breakpoint_query (struct ui_out *uiout, int bnum, char **error_message)
   args.bnum = bnum;
   /* For the moment we don't trust print_one_breakpoint() to not throw
      an error. */
-  return catch_exceptions_with_msg (uiout, do_captured_breakpoint_query, &args,
-                                   error_message, RETURN_MASK_ALL);
+  if (catch_exceptions_with_msg (uiout, do_captured_breakpoint_query, &args,
+                                error_message, RETURN_MASK_ALL) < 0)
+    return GDB_RC_FAIL;
+  else
+    return GDB_RC_OK;
 }
 
 /* Return non-zero if B is user settable (breakpoints, watchpoints,
@@ -3774,7 +3900,7 @@ maintenance_info_breakpoints (char *bnum_exp, int from_tty)
 /* Print a message describing any breakpoints set at PC.  */
 
 static void
-describe_other_breakpoints (CORE_ADDR pc, asection *section)
+describe_other_breakpoints (CORE_ADDR pc, asection *section, int thread)
 {
   int others = 0;
   struct breakpoint *b;
@@ -3794,12 +3920,16 @@ describe_other_breakpoints (CORE_ADDR pc, asection *section)
          if (!b->pending && (!overlay_debugging || b->loc->section == section))
            {
              others--;
-             printf_filtered ("%d%s%s ",
-                              b->number,
+             printf_filtered ("%d", b->number);
+             if (b->thread == -1 && thread != -1)
+               printf_filtered (" (all threads)");
+             else if (b->thread != -1)
+               printf_filtered (" (thread %d)", b->thread);
+             printf_filtered ("%s%s ",
                               ((b->enable_state == bp_disabled || 
                                 b->enable_state == bp_shlib_disabled || 
                                 b->enable_state == bp_call_disabled) 
-                               ? " (disabled)" 
+                               ? " (disabled)"
                                : b->enable_state == bp_permanent 
                                ? " (permanent)"
                                : ""),
@@ -4012,7 +4142,6 @@ allocate_bp_location (struct breakpoint *bpt, enum bptype bp_type)
     case bp_longjmp:
     case bp_longjmp_resume:
     case bp_step_resume:
-    case bp_through_sigtramp:
     case bp_watchpoint_scope:
     case bp_call_dummy:
     case bp_shlib_event:
@@ -4076,13 +4205,23 @@ struct breakpoint *
 set_raw_breakpoint (struct symtab_and_line sal, enum bptype bptype)
 {
   struct breakpoint *b, *b1;
+  CORE_ADDR adjusted_address;
 
   b = (struct breakpoint *) xmalloc (sizeof (struct breakpoint));
   memset (b, 0, sizeof (*b));
+
+  /* Adjust the breakpoint's address prior to allocating a location.
+     Once we call allocate_bp_location(), that mostly uninitialized
+     location will be placed on the location chain.  Adjustment of the
+     breakpoint may cause read_memory_nobpt() to be called and we do
+     not want its scan of the location chain to find a breakpoint and
+     location that's only been partially initialized.  */
+  adjusted_address = adjust_breakpoint_address (sal.pc, bptype);
+
   b->loc = allocate_bp_location (b, bptype);
   b->loc->requested_address = sal.pc;
-  b->loc->address = adjust_breakpoint_address (b->loc->requested_address,
-                                               bptype);
+  b->loc->address = adjusted_address;
+
   if (sal.symtab == NULL)
     b->source_file = NULL;
   else
@@ -4873,7 +5012,6 @@ mention (struct breakpoint *b)
       case bp_longjmp:
       case bp_longjmp_resume:
       case bp_step_resume:
-      case bp_through_sigtramp:
       case bp_call_dummy:
       case bp_watchpoint_scope:
       case bp_shlib_event:
@@ -4952,7 +5090,7 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
        struct symtab_and_line sal = sals.sals[i];
 
        if (from_tty)
-         describe_other_breakpoints (sal.pc, sal.section);
+         describe_other_breakpoints (sal.pc, sal.section, thread);
        
        b = set_raw_breakpoint (sal, type);
        set_breakpoint_count (breakpoint_count + 1);
@@ -5469,8 +5607,11 @@ gdb_breakpoint (char *address, char *condition,
   args.tempflag = tempflag;
   args.thread = thread;
   args.ignore_count = ignore_count;
-  return catch_exceptions_with_msg (uiout, do_captured_breakpoint, &args,
-                                   error_message, RETURN_MASK_ALL);
+  if (catch_exceptions_with_msg (uiout, do_captured_breakpoint, &args,
+                                error_message, RETURN_MASK_ALL) < 0)
+    return GDB_RC_FAIL;
+  else
+    return GDB_RC_OK;
 }
 
 
@@ -5791,11 +5932,6 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
    in hardware.  If the watchpoint can not be handled
    in hardware return zero.  */
 
-#if !defined(TARGET_REGION_OK_FOR_HW_WATCHPOINT)
-#define TARGET_REGION_OK_FOR_HW_WATCHPOINT(ADDR,LEN) \
-     (TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(LEN))
-#endif
-
 static int
 can_use_hardware_watchpoint (struct value *v)
 {
@@ -5927,7 +6063,8 @@ until_break_command (char *arg, int from_tty, int anywhere)
 {
   struct symtabs_and_lines sals;
   struct symtab_and_line sal;
-  struct frame_info *prev_frame = get_prev_frame (deprecated_selected_frame);
+  struct frame_info *frame = get_selected_frame (NULL);
+  struct frame_info *prev_frame = get_prev_frame (frame);
   struct breakpoint *breakpoint;
   struct cleanup *old_chain;
   struct continuation_arg *arg1;
@@ -5963,8 +6100,7 @@ until_break_command (char *arg, int from_tty, int anywhere)
   else
     /* Otherwise, specify the current frame, because we want to stop only
        at the very same frame.  */
-    breakpoint = set_momentary_breakpoint (sal,
-                                          get_frame_id (deprecated_selected_frame),
+    breakpoint = set_momentary_breakpoint (sal, get_frame_id (frame),
                                           bp_until);
 
   if (!target_can_async_p ())
@@ -6433,6 +6569,86 @@ catch_exception_command_1 (enum exception_event_kind ex_event, char *arg,
   warning (_("Unsupported with this platform/compiler combination."));
 }
 
+/* Create a breakpoint struct for Ada exception catchpoints.  */
+
+static void
+create_ada_exception_breakpoint (struct symtab_and_line sal,
+                                 char *addr_string,
+                                 char *exp_string,
+                                 char *cond_string,
+                                 struct expression *cond,
+                                 struct breakpoint_ops *ops,
+                                 int tempflag,
+                                 int from_tty)
+{
+  struct breakpoint *b;
+
+  if (from_tty)
+    {
+      describe_other_breakpoints (sal.pc, sal.section, -1);
+      /* FIXME: brobecker/2006-12-28: Actually, re-implement a special
+         version for exception catchpoints, because two catchpoints
+         used for different exception names will use the same address.
+         In this case, a "breakpoint ... also set at..." warning is
+         unproductive.  Besides. the warning phrasing is also a bit
+         inapropriate, we should use the word catchpoint, and tell
+         the user what type of catchpoint it is.  The above is good
+         enough for now, though.  */
+    }
+
+  b = set_raw_breakpoint (sal, bp_breakpoint);
+  set_breakpoint_count (breakpoint_count + 1);
+
+  b->enable_state = bp_enabled;
+  b->disposition = tempflag ? disp_del : disp_donttouch;
+  b->number = breakpoint_count;
+  b->ignore_count = 0;
+  b->cond = cond;
+  b->addr_string = addr_string;
+  b->language = language_ada;
+  b->cond_string = cond_string;
+  b->exp_string = exp_string;
+  b->thread = -1;
+  b->ops = ops;
+  b->from_tty = from_tty;
+
+  mention (b);
+}
+
+/* Implement the "catch exception" command.  */
+
+static void
+catch_ada_exception_command (char *arg, int tempflag, int from_tty)
+{
+  struct symtab_and_line sal;
+  enum bptype type;
+  char *addr_string = NULL;
+  char *exp_string = NULL;
+  char *cond_string = NULL;
+  struct expression *cond = NULL;
+  struct breakpoint_ops *ops = NULL;
+
+  sal = ada_decode_exception_location (arg, &addr_string, &exp_string,
+                                       &cond_string, &cond, &ops);
+  create_ada_exception_breakpoint (sal, addr_string, exp_string,
+                                   cond_string, cond, ops, tempflag,
+                                   from_tty);
+}
+
+/* Implement the "catch assert" command.  */
+
+static void
+catch_assert_command (char *arg, int tempflag, int from_tty)
+{
+  struct symtab_and_line sal;
+  char *addr_string = NULL;
+  struct breakpoint_ops *ops = NULL;
+
+  sal = ada_decode_assert_location (arg, &addr_string, &ops);
+  create_ada_exception_breakpoint (sal, addr_string, NULL, NULL, NULL, ops,
+                                   tempflag, from_tty);
+}
+
 /* Cover routine to allow wrapping target_enable_exception_catchpoints
    inside a catch_errors */
 
@@ -6537,6 +6753,15 @@ catch_command_1 (char *arg, int tempflag, int from_tty)
     {
       error (_("Catch of stop not yet implemented"));
     }
+  else if (strncmp (arg1_start, "exception", arg1_length) == 0)
+    {
+      catch_ada_exception_command (arg1_end + 1, tempflag, from_tty);
+    }
+
+  else if (strncmp (arg1_start, "assert", arg1_length) == 0)
+    {
+      catch_assert_command (arg1_end + 1, tempflag, from_tty);
+    }
 
   /* This doesn't appear to be an event name */
 
@@ -6840,10 +7065,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)
@@ -6956,7 +7183,10 @@ delete_command (char *arg, int from_tty)
            b->type != bp_thread_event &&
            b->type != bp_overlay_event &&
            b->number >= 0)
-         breaks_to_delete = 1;
+         {
+           breaks_to_delete = 1;
+           break;
+         }
       }
 
       /* Ask user only if there are some breakpoints to delete.  */
@@ -7523,7 +7753,7 @@ is valid is not currently in scope.\n"), bpt->number);
              int mem_cnt = can_use_hardware_watchpoint (bpt->val);
              
              /* Hack around 'unused var' error for some targets here */
-             (void) mem_cnt, i;
+             (void) mem_cnt, (void) i;
              target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT (
                                                                        bpt->type, i + mem_cnt, other_type_used);
              /* we can consider of type is bp_hardware_watchpoint, convert to 
@@ -7646,7 +7876,134 @@ 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)
+    error (_("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;
+    }
+}
+
+/* Check whether a software single-step breakpoint is inserted at PC.  */
+
+static int
+single_step_breakpoint_inserted_here_p (CORE_ADDR pc)
+{
+  int i;
+
+  for (i = 0; i < 2; i++)
+    {
+      struct bp_target_info *bp_tgt = single_step_breakpoints[i];
+      if (bp_tgt && bp_tgt->placed_address == pc)
+       return 1;
+    }
+
+  return 0;
+}
+
 \f
+/* This help string is used for the break, hbreak, tbreak and thbreak commands.
+   It is defined as a macro to prevent duplication.
+   COMMAND should be a string constant containing the name of the command.  */
+#define BREAK_ARGS_HELP(command) \
+command" [LOCATION] [thread THREADNUM] [if CONDITION]\n\
+LOCATION may be a line number, function name, or \"*\" and an address.\n\
+If a line number is specified, break at start of code for that line.\n\
+If a function is specified, break at start of code for that function.\n\
+If an address is specified, break at that exact address.\n\
+With no LOCATION, uses current execution address of selected stack frame.\n\
+This is useful for breaking on return to a stack frame.\n\
+\n\
+THREADNUM is the number from \"info threads\".\n\
+CONDITION is a boolean expression.\n\
+\n\
+Multiple breakpoints at one place are permitted, and useful if conditional.\n\
+\n\
+Do \"help breakpoints\" for info on other commands dealing with breakpoints."
+
 void
 _initialize_breakpoint (void)
 {
@@ -7682,22 +8039,28 @@ Usage is `condition N COND', where N is an integer and COND is an\n\
 expression to be evaluated whenever breakpoint N is reached."));
 
   c = add_com ("tbreak", class_breakpoint, tbreak_command, _("\
-Set a temporary breakpoint.  Args like \"break\" command.\n\
+Set a temporary breakpoint.\n\
 Like \"break\" except the breakpoint is only temporary,\n\
 so it will be deleted when hit.  Equivalent to \"break\" followed\n\
-by using \"enable delete\" on the breakpoint number."));
+by using \"enable delete\" on the breakpoint number.\n\
+\n"
+BREAK_ARGS_HELP ("tbreak")));
   set_cmd_completer (c, location_completer);
 
   c = add_com ("hbreak", class_breakpoint, hbreak_command, _("\
-Set a hardware assisted  breakpoint. Args like \"break\" command.\n\
+Set a hardware assisted  breakpoint.\n\
 Like \"break\" except the breakpoint requires hardware support,\n\
-some target hardware may not have this support."));
+some target hardware may not have this support.\n\
+\n"
+BREAK_ARGS_HELP ("hbreak")));
   set_cmd_completer (c, location_completer);
 
   c = add_com ("thbreak", class_breakpoint, thbreak_command, _("\
-Set a temporary hardware assisted breakpoint. Args like \"break\" command.\n\
+Set a temporary hardware assisted breakpoint.\n\
 Like \"hbreak\" except the breakpoint is only temporary,\n\
-so it will be deleted when hit."));
+so it will be deleted when hit.\n\
+\n"
+BREAK_ARGS_HELP ("thbreak")));
   set_cmd_completer (c, location_completer);
 
   add_prefix_cmd ("enable", class_breakpoint, enable_command, _("\
@@ -7776,6 +8139,7 @@ Also a prefix command for deletion of other GDB objects.\n\
 The \"unset\" command is also an alias for \"delete\"."),
                  &deletelist, "delete ", 1, &cmdlist);
   add_com_alias ("d", "delete", class_breakpoint, 1);
+  add_com_alias ("del", "delete", class_breakpoint, 1);
   if (xdb_commands)
     add_com ("db", class_breakpoint, delete_command, _("\
 Delete some breakpoints.\n\
@@ -7802,17 +8166,8 @@ is executing in.\n\
 See also the \"delete\" command which clears breakpoints by number."));
 
   c = add_com ("break", class_breakpoint, break_command, _("\
-Set breakpoint at specified line or function.\n\
-Argument may be line number, function name, or \"*\" and an address.\n\
-If line number is specified, break at start of code for that line.\n\
-If function is specified, break at start of code for that function.\n\
-If an address is specified, break at that exact address.\n\
-With no arg, uses current execution address of selected stack frame.\n\
-This is useful for breaking on return to a stack frame.\n\
-\n\
-Multiple breakpoints at one place are permitted, and useful if conditional.\n\
-\n\
-Do \"help breakpoints\" for info on other commands dealing with breakpoints."));
+Set breakpoint at specified line or function.\n"
+BREAK_ARGS_HELP ("break")));
   set_cmd_completer (c, location_completer);
 
   add_com_alias ("b", "break", class_run, 1);
@@ -7933,6 +8288,11 @@ The act of your program's execution stopping may also be caught:\n\
 C++ exceptions may be caught:\n\
 \tcatch throw               - all exceptions, when thrown\n\
 \tcatch catch               - all exceptions, when caught\n\
+Ada exceptions may be caught:\n\
+\tcatch exception           - all exceptions, when raised\n\
+\tcatch exception <name>    - a particular exception, when raised\n\
+\tcatch exception unhandled - all unhandled exceptions, when raised\n\
+\tcatch assert              - all failed assertions, when raised\n\
 \n\
 Do \"help set follow-fork-mode\" for info on debugging your program\n\
 after a fork or vfork is caught.\n\n\
@@ -8010,4 +8370,18 @@ user-query to see if a pending breakpoint should be created."),
                                &breakpoint_show_cmdlist);
 
   pending_break_support = AUTO_BOOLEAN_AUTO;
+
+  add_setshow_boolean_cmd ("auto-hw", no_class,
+                          &automatic_hardware_breakpoints, _("\
+Set automatic usage of hardware breakpoints."), _("\
+Show automatic usage of hardware breakpoints."), _("\
+If set, the debugger will automatically use hardware breakpoints for\n\
+breakpoints set with \"break\" but falling in read-only memory.  If not set,\n\
+a warning will be emitted for such breakpoints."),
+                          NULL,
+                          show_automatic_hardware_breakpoints,
+                          &breakpoint_set_cmdlist,
+                          &breakpoint_show_cmdlist);
+  
+  automatic_hardware_breakpoints = 1;
 }
This page took 0.04152 seconds and 4 git commands to generate.