Index: ChangeLog
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 87ce33c6849760a59132a2daa37fc429802df5d6..19e8454ea482f334d804df64449e70ad4d72f3fb 100644 (file)
@@ -1,8 +1,8 @@
 /* Everything about breakpoints, for GDB.
 
    Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
-   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software
-   Foundation, Inc.
+   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -128,7 +128,7 @@ typedef enum
   }
 insertion_state_t;
 
-static int remove_breakpoint (struct breakpoint *, insertion_state_t);
+static int remove_breakpoint (struct bp_location *, insertion_state_t);
 
 static enum print_stop_action print_it_typical (bpstat);
 
@@ -244,16 +244,6 @@ static int overlay_events_enabled;
             B ? (TMP=B->next, 1): 0;   \
             B = TMP)
 
-/* True if SHIFT_INST_REGS defined, false otherwise.  */
-
-int must_shift_inst_regs =
-#if defined(SHIFT_INST_REGS)
-1
-#else
-0
-#endif
- ;
-
 /* True if breakpoint hit counts should be displayed in breakpoint info.  */
 
 int show_breakpoint_hit_counts = 1;
@@ -332,6 +322,13 @@ int exception_support_initialized = 0;
    error ("catch of library unloads not yet implemented on this platform")
 #endif
 
+/* Return whether a breakpoint is an active enabled breakpoint.  */
+static int
+breakpoint_enabled (struct breakpoint *b)
+{
+  return b->enable_state == bp_enabled;
+}
+
 /* Set breakpoint count to NUM.  */
 
 void
@@ -741,373 +738,400 @@ insert_catchpoint (struct ui_out *uo, void *args)
   return 0;
 }
 
-/* insert_breakpoints is used when starting or continuing the program.
-   remove_breakpoints is used when the program stops.
-   Both return zero if successful,
-   or an `errno' value if could not write the inferior.  */
+/* Insert a low-level "breakpoint" of some type.  BPT is the breakpoint.
+   Any error messages are printed to TMP_ERROR_STREAM; and DISABLED_BREAKS,
+   PROCESS_WARNING, and HW_BREAKPOINT_ERROR are used to report problems.
 
-int
-insert_breakpoints (void)
+   NOTE drow/2003-09-09: This routine could be broken down to an object-style
+   method for each breakpoint or catchpoint type.  */
+static int
+insert_bp_location (struct bp_location *bpt,
+                   struct ui_file *tmp_error_stream,
+                   int *disabled_breaks, int *process_warning,
+                   int *hw_breakpoint_error)
 {
-  struct breakpoint *b, *temp;
-  int return_val = 0;  /* return success code. */
   int val = 0;
-  int disabled_breaks = 0;
-  int hw_breakpoint_error = 0;
-#ifdef ONE_PROCESS_WRITETEXT
-  int process_warning = 0;
-#endif
-
-  struct ui_file *tmp_error_stream = mem_fileopen ();
-  make_cleanup_ui_file_delete (tmp_error_stream);
 
-  /* Explicitly mark the warning -- this will only be printed if
-     there was an error.  */
-  fprintf_unfiltered (tmp_error_stream, "Warning:\n");
+  /* Permanent breakpoints cannot be inserted or removed.  Disabled
+     breakpoints should not be inserted.  */
+  if (!breakpoint_enabled (bpt->owner))
+    return 0;
 
-  ALL_BREAKPOINTS_SAFE (b, temp)
-  {
-    /* Permanent breakpoints cannot be inserted or removed.  Disabled
-       breakpoints should not be inserted.  */
-    if (b->enable_state != bp_enabled)
-      continue;
+  if (bpt->inserted || bpt->duplicate)
+    return 0;
 
-    if ((b->type == bp_watchpoint
-        || b->type == bp_hardware_watchpoint
-        || b->type == bp_read_watchpoint
-        || b->type == bp_access_watchpoint) && (!b->val))
-      {
-       struct value *val;
-       val = evaluate_expression (b->exp);
-       release_value (val);
-       if (VALUE_LAZY (val))
-         value_fetch_lazy (val);
-       b->val = val;
-      } 
-    if (b->type != bp_watchpoint
-       && b->type != bp_hardware_watchpoint
-       && b->type != bp_read_watchpoint
-       && b->type != bp_access_watchpoint
-       && b->type != bp_catch_fork
-       && b->type != bp_catch_vfork
-       && b->type != bp_catch_exec
-       && b->type != bp_catch_throw
-       && b->type != bp_catch_catch
-       && !b->loc->inserted
-       && !b->loc->duplicate)
-      {
-       /* "Normal" instruction breakpoint: either the standard
-          trap-instruction bp (bp_breakpoint), or a
-          bp_hardware_breakpoint.  */
-
-       /* First check to see if we have to handle an overlay.  */
-       if (overlay_debugging == ovly_off
-           || b->section == NULL
-           || !(section_is_overlay (b->section)))
-         {
-           /* No overlay handling: just set the breakpoint.  */
+  if (bpt->loc_type == bp_loc_software_breakpoint
+      || bpt->loc_type == bp_loc_hardware_breakpoint)
+    {
+      /* First check to see if we have to handle an overlay.  */
+      if (overlay_debugging == ovly_off
+         || bpt->section == NULL
+         || !(section_is_overlay (bpt->section)))
+       {
+         /* No overlay handling: just set the breakpoint.  */
 
-           if (b->type == bp_hardware_breakpoint)
-             val = target_insert_hw_breakpoint (b->loc->address, 
-                                                b->loc->shadow_contents);
-           else
-             val = target_insert_breakpoint (b->loc->address, b->loc->shadow_contents);
-         }
-       else
-         {
-           /* This breakpoint is in an overlay section.  
-              Shall we set a breakpoint at the LMA?  */
-           if (!overlay_events_enabled)
-             {
-               /* Yes -- overlay event support is not active, 
-                  so we must try to set a breakpoint at the LMA.
-                  This will not work for a hardware breakpoint.  */
-               if (b->type == bp_hardware_breakpoint)
-                 warning ("hardware breakpoint %d not supported in overlay!\n",
-                          b->number);
-               else
-                 {
-                   CORE_ADDR addr = overlay_unmapped_address (b->loc->address, 
-                                                              b->section);
-                   /* Set a software (trap) breakpoint at the LMA.  */
-                   val = target_insert_breakpoint (addr, b->loc->shadow_contents);
-                   if (val != 0)
-                     fprintf_unfiltered (tmp_error_stream, 
-                                         "Overlay breakpoint %d failed: in ROM?", 
-                                         b->number);
-                 }
-             }
-           /* Shall we set a breakpoint at the VMA? */
-           if (section_is_mapped (b->section))
-             {
-               /* Yes.  This overlay section is mapped into memory.  */
-               if (b->type == bp_hardware_breakpoint)
-                 val = target_insert_hw_breakpoint (b->loc->address, 
-                                                    b->loc->shadow_contents);
-               else
-                 val = target_insert_breakpoint (b->loc->address,
-                                                 b->loc->shadow_contents);
-             }
-           else
-             {
-               /* No.  This breakpoint will not be inserted.  
-                  No error, but do not mark the bp as 'inserted'.  */
-               continue;
-             }
-         }
+         if (bpt->loc_type == bp_loc_hardware_breakpoint)
+           val = target_insert_hw_breakpoint (bpt->address, 
+                                              bpt->shadow_contents);
+         else
+           val = target_insert_breakpoint (bpt->address,
+                                           bpt->shadow_contents);
+       }
+      else
+       {
+         /* This breakpoint is in an overlay section.  
+            Shall we set a breakpoint at the LMA?  */
+         if (!overlay_events_enabled)
+           {
+             /* Yes -- overlay event support is not active, 
+                so we must try to set a breakpoint at the LMA.
+                This will not work for a hardware breakpoint.  */
+             if (bpt->loc_type == bp_loc_hardware_breakpoint)
+               warning ("hardware breakpoint %d not supported in overlay!\n",
+                        bpt->owner->number);
+             else
+               {
+                 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);
+                 if (val != 0)
+                   fprintf_unfiltered (tmp_error_stream, 
+                                       "Overlay breakpoint %d failed: in ROM?", 
+                                       bpt->owner->number);
+               }
+           }
+         /* Shall we set a breakpoint at the VMA? */
+         if (section_is_mapped (bpt->section))
+           {
+             /* 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);
+             else
+               val = target_insert_breakpoint (bpt->address,
+                                               bpt->shadow_contents);
+           }
+         else
+           {
+             /* No.  This breakpoint will not be inserted.  
+                No error, but do not mark the bp as 'inserted'.  */
+             return 0;
+           }
+       }
 
-       if (val)
-         {
-           /* Can't set the breakpoint.  */
+      if (val)
+       {
+         /* Can't set the breakpoint.  */
 #if defined (DISABLE_UNSETTABLE_BREAK)
-           if (DISABLE_UNSETTABLE_BREAK (b->loc->address))
-             {
-               /* See also: disable_breakpoints_in_shlibs. */
-               val = 0;
-               b->enable_state = bp_shlib_disabled;
-               if (!disabled_breaks)
-                 {
-                   fprintf_unfiltered (tmp_error_stream, 
-                                       "Cannot insert breakpoint %d.\n", 
-                                       b->number);
-                   fprintf_unfiltered (tmp_error_stream, 
-                                       "Temporarily disabling shared library breakpoints:\n");
-                 }
-               disabled_breaks = 1;
-               fprintf_unfiltered (tmp_error_stream, 
-                                   "breakpoint #%d\n", b->number);
-             }
-           else
+         if (DISABLE_UNSETTABLE_BREAK (bpt->address))
+           {
+             /* See also: disable_breakpoints_in_shlibs. */
+             val = 0;
+             bpt->owner->enable_state = bp_shlib_disabled;
+             if (!*disabled_breaks)
+               {
+                 fprintf_unfiltered (tmp_error_stream, 
+                                     "Cannot insert breakpoint %d.\n", 
+                                     bpt->owner->number);
+                 fprintf_unfiltered (tmp_error_stream, 
+                                     "Temporarily disabling shared library breakpoints:\n");
+               }
+             *disabled_breaks = 1;
+             fprintf_unfiltered (tmp_error_stream,
+                                 "breakpoint #%d\n", bpt->owner->number);
+           }
+         else
 #endif
-             {
+           {
 #ifdef ONE_PROCESS_WRITETEXT
-               process_warning = 1;
+             *process_warning = 1;
 #endif
-               if (b->type == bp_hardware_breakpoint)
-                 {
-                   hw_breakpoint_error = 1;
-                   fprintf_unfiltered (tmp_error_stream, 
-                                       "Cannot insert hardware breakpoint %d.\n",
-                                       b->number);
-                 }
-               else
-                 {
-                   fprintf_unfiltered (tmp_error_stream, 
-                                       "Cannot insert breakpoint %d.\n", 
-                                       b->number);
-                   fprintf_filtered (tmp_error_stream, 
-                                     "Error accessing memory address ");
-                   print_address_numeric (b->loc->address, 1, tmp_error_stream);
-                   fprintf_filtered (tmp_error_stream, ": %s.\n",
-                                     safe_strerror (val));
-                 }
+             if (bpt->loc_type == bp_loc_hardware_breakpoint)
+               {
+                 *hw_breakpoint_error = 1;
+                 fprintf_unfiltered (tmp_error_stream, 
+                                     "Cannot insert hardware breakpoint %d.\n",
+                                     bpt->owner->number);
+               }
+             else
+               {
+                 fprintf_unfiltered (tmp_error_stream, 
+                                     "Cannot insert breakpoint %d.\n", 
+                                     bpt->owner->number);
+                 fprintf_filtered (tmp_error_stream, 
+                                   "Error accessing memory address ");
+                 print_address_numeric (bpt->address, 1, tmp_error_stream);
+                 fprintf_filtered (tmp_error_stream, ": %s.\n",
+                                   safe_strerror (val));
+               }
 
-             }
-         }
-       else
-         b->loc->inserted = 1;
+           }
+       }
+      else
+       bpt->inserted = 1;
 
-       if (val)
-         return_val = val;     /* remember failure */
-      }
-    else if (ep_is_exception_catchpoint (b)
-            && !b->loc->inserted
-            && !b->loc->duplicate)
+      return val;
+    }
 
-      {
-       /* 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 (b->loc->address, b->loc->shadow_contents);
-       if (val)
-         {
-           /* Couldn't set breakpoint for some reason */
-           fprintf_unfiltered (tmp_error_stream, 
-                               "Cannot insert catchpoint %d; disabling it.\n",
-                               b->number);
-           fprintf_filtered (tmp_error_stream, 
-                             "Error accessing memory address ");
-           print_address_numeric (b->loc->address, 1, tmp_error_stream);
-           fprintf_filtered (tmp_error_stream, ": %s.\n",
-                             safe_strerror (val));
-           b->enable_state = bp_disabled;
-         }
-       else
-         {
-           /* Bp set, now make sure callbacks are enabled */
-           /* Format possible error msg */
-           char *message = xstrprintf ("Error inserting catchpoint %d:\n",
-                                       b->number);
-           struct cleanup *cleanups = make_cleanup (xfree, message);
-           int val;
-           args_for_catchpoint_enable args;
-           args.kind = b->type == bp_catch_catch ? 
-             EX_EVENT_CATCH : EX_EVENT_THROW;
-           args.enable_p = 1;
-           val = catch_errors (cover_target_enable_exception_callback,
-                               &args, message, RETURN_MASK_ALL);
-           do_cleanups (cleanups);
-           if (val != 0 && val != -1)
-             {
-               b->loc->inserted = 1;
-             }
-           /* Check if something went wrong; val == 0 can be ignored */
-           if (val == -1)
-             {
-               /* something went wrong */
-               fprintf_unfiltered (tmp_error_stream, 
-                                   "Cannot insert catchpoint %d; disabling it.\n",
-                                   b->number);
-               b->enable_state = bp_disabled;
-             }
-         }
+  else if (bpt->loc_type == bp_loc_hardware_watchpoint
+          /* NOTE drow/2003-09-08: This state only exists for removing
+             watchpoints.  It's not clear that it's necessary... */
+          && bpt->owner->disposition != disp_del_at_next_stop)
+    {
+      /* FIXME drow/2003-09-08: This code sets multiple hardware watchpoints
+        based on the expression.  Ideally this should happen at a higher level,
+        and there should be one bp_location for each computed address we
+        must watch.  As soon as a many-to-one mapping is available I'll
+        convert this.  */
 
-       if (val)
-         return_val = val;     /* remember failure */
-      }
+      struct frame_info *saved_frame;
+      int saved_level, within_current_scope;
+      struct value *mark = value_mark ();
+      struct value *v;
 
-    else if ((b->type == bp_hardware_watchpoint ||
-             b->type == bp_read_watchpoint ||
-             b->type == bp_access_watchpoint)
-            && b->disposition != disp_del_at_next_stop
-            && !b->loc->inserted
-            && !b->loc->duplicate)
-      {
-       struct frame_info *saved_frame;
-       int saved_level, within_current_scope;
-       struct value *mark = value_mark ();
-       struct value *v;
+      /* Save the current frame and level so we can restore it after
+        evaluating the watchpoint expression on its own frame.  */
+      /* 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 = deprecated_selected_frame;
+      saved_level = frame_relative_level (deprecated_selected_frame);
+
+      /* Determine if the watchpoint is within scope.  */
+      if (bpt->owner->exp_valid_block == NULL)
+       within_current_scope = 1;
+      else
+       {
+         struct frame_info *fi;
+         fi = frame_find_by_id (bpt->owner->watchpoint_frame);
+         within_current_scope = (fi != NULL);
+         if (within_current_scope)
+           select_frame (fi);
+       }
 
-       /* Save the current frame and level so we can restore it after
-          evaluating the watchpoint expression on its own frame.  */
-       saved_frame = deprecated_selected_frame;
-       saved_level = frame_relative_level (deprecated_selected_frame);
+      if (within_current_scope)
+       {
+         /* Evaluate the expression and cut the chain of values
+            produced off from the value chain.
 
-       /* Determine if the watchpoint is within scope.  */
-       if (b->exp_valid_block == NULL)
-         within_current_scope = 1;
-       else
-         {
-           struct frame_info *fi;
-           fi = frame_find_by_id (b->watchpoint_frame);
-           within_current_scope = (fi != NULL);
-           if (within_current_scope)
-             select_frame (fi);
-         }
+            Make sure the value returned isn't lazy; we use
+            laziness to determine what memory GDB actually needed
+            in order to compute the value of the expression.  */
+         v = evaluate_expression (bpt->owner->exp);
+         VALUE_CONTENTS (v);
+         value_release_to_mark (mark);
 
-       if (within_current_scope)
-         {
-           /* Evaluate the expression and cut the chain of values
-              produced off from the value chain.
+         bpt->owner->val_chain = v;
+         bpt->inserted = 1;
 
-              Make sure the value returned isn't lazy; we use
-              laziness to determine what memory GDB actually needed
-              in order to compute the value of the expression.  */
-           v = evaluate_expression (b->exp);
-           VALUE_CONTENTS(v);
-           value_release_to_mark (mark);
+         /* Look at each value on the value chain.  */
+         for (; v; v = v->next)
+           {
+             /* If it's a memory location, and GDB actually needed
+                its contents to evaluate the expression, then we
+                must watch it.  */
+             if (VALUE_LVAL (v) == lval_memory
+                 && ! VALUE_LAZY (v))
+               {
+                 struct type *vtype = check_typedef (VALUE_TYPE (v));
+
+                 /* We only watch structs and arrays if user asked
+                    for it explicitly, never if they just happen to
+                    appear in the middle of some value chain.  */
+                 if (v == bpt->owner->val_chain
+                     || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+                         && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
+                   {
+                     CORE_ADDR addr;
+                     int len, type;
+
+                     addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+                     len = TYPE_LENGTH (VALUE_TYPE (v));
+                     type = hw_write;
+                     if (bpt->owner->type == bp_read_watchpoint)
+                       type = hw_read;
+                     else if (bpt->owner->type == bp_access_watchpoint)
+                       type = hw_access;
+
+                     val = target_insert_watchpoint (addr, len, type);
+                     if (val == -1)
+                       {
+                         /* Don't exit the loop, try to insert
+                            every value on the value chain.  That's
+                            because we will be removing all the
+                            watches below, and removing a
+                            watchpoint we didn't insert could have
+                            adverse effects.  */
+                         bpt->inserted = 0;
+                       }
+                     val = 0;
+                   }
+               }
+           }
+         /* Failure to insert a watchpoint on any memory value in the
+            value chain brings us here.  */
+         if (!bpt->inserted)
+           {
+             remove_breakpoint (bpt, mark_uninserted);
+             *hw_breakpoint_error = 1;
+             fprintf_unfiltered (tmp_error_stream,
+                                 "Could not insert hardware watchpoint %d.\n", 
+                                 bpt->owner->number);
+             val = -1;
+           }               
+       }
+      else
+       {
+         printf_filtered ("Hardware watchpoint %d deleted ", bpt->owner->number);
+         printf_filtered ("because the program has left the block \n");
+         printf_filtered ("in which its expression is valid.\n");
+         if (bpt->owner->related_breakpoint)
+           bpt->owner->related_breakpoint->disposition = disp_del_at_next_stop;
+         bpt->owner->disposition = disp_del_at_next_stop;
+       }
 
-           b->val_chain = v;
-           b->loc->inserted = 1;
+      /* Restore the frame and level.  */
+      if (saved_frame != deprecated_selected_frame
+         || saved_level != frame_relative_level (deprecated_selected_frame))
+       select_frame (saved_frame);
 
-           /* Look at each value on the value chain.  */
-           for (; v; v = v->next)
-             {
-               /* If it's a memory location, and GDB actually needed
-                   its contents to evaluate the expression, then we
-                   must watch it.  */
-               if (VALUE_LVAL (v) == lval_memory
-                   && ! VALUE_LAZY (v))
-                 {
-                   struct type *vtype = check_typedef (VALUE_TYPE (v));
-
-                   /* We only watch structs and arrays if user asked
-                      for it explicitly, never if they just happen to
-                      appear in the middle of some value chain.  */
-                   if (v == b->val_chain
-                       || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
-                           && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
-                     {
-                       CORE_ADDR addr;
-                       int len, type;
-
-                       addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
-                       len = TYPE_LENGTH (VALUE_TYPE (v));
-                       type = hw_write;
-                       if (b->type == bp_read_watchpoint)
-                         type = hw_read;
-                       else if (b->type == bp_access_watchpoint)
-                         type = hw_access;
-
-                       val = target_insert_watchpoint (addr, len, type);
-                       if (val == -1)
-                         {
-                           /* Don't exit the loop, try to insert
-                              every value on the value chain.  That's
-                              because we will be removing all the
-                              watches below, and removing a
-                              watchpoint we didn't insert could have
-                              adverse effects.  */
-                           b->loc->inserted = 0;
-                         }
-                       val = 0;
-                     }
-                 }
-             }
-           /* Failure to insert a watchpoint on any memory value in the
-              value chain brings us here.  */
-           if (!b->loc->inserted)
-             {
-               remove_breakpoint (b, mark_uninserted);
-               hw_breakpoint_error = 1;
-               fprintf_unfiltered (tmp_error_stream,
-                                   "Could not insert hardware watchpoint %d.\n", 
-                                   b->number);
-               val = -1;
-             }               
-         }
-       else
-         {
-           printf_filtered ("Hardware watchpoint %d deleted ", b->number);
-           printf_filtered ("because the program has left the block \n");
-           printf_filtered ("in which its expression is valid.\n");
-           if (b->related_breakpoint)
-             b->related_breakpoint->disposition = disp_del_at_next_stop;
-           b->disposition = disp_del_at_next_stop;
-         }
+      return val;
+    }
 
-       /* Restore the frame and level.  */
-       if ((saved_frame != deprecated_selected_frame) ||
-           (saved_level != frame_relative_level (deprecated_selected_frame)))
-         select_frame (saved_frame);
+  else if (ep_is_exception_catchpoint (bpt->owner))
+    {
+      /* FIXME drow/2003-09-09: This code sets both a catchpoint and a
+        breakpoint.  Once again, it would be better if this was represented
+        as two bp_locations.  */
 
-       if (val)
-         return_val = val;     /* remember failure */
-      }
-    else if ((b->type == bp_catch_fork
-             || b->type == bp_catch_vfork
-             || b->type == bp_catch_exec)
-            && !b->loc->inserted
-            && !b->loc->duplicate)
-      {
-       char *prefix = xstrprintf ("warning: inserting catchpoint %d: ",
-                                  b->number);
-       struct cleanup *cleanups = make_cleanup (xfree, prefix);
-       val = catch_exceptions (uiout, insert_catchpoint, b, prefix,
-                               RETURN_MASK_ERROR);
-       do_cleanups (cleanups);
-       if (val < 0)
-         b->enable_state = bp_disabled;
-       else
-         b->loc->inserted = 1;
-      }
-  }
-  
-  if (return_val) 
+      /* 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);
+      if (val)
+       {
+         /* Couldn't set breakpoint for some reason */
+         fprintf_unfiltered (tmp_error_stream, 
+                             "Cannot insert catchpoint %d; disabling it.\n",
+                             bpt->owner->number);
+         fprintf_filtered (tmp_error_stream, 
+                           "Error accessing memory address ");
+         print_address_numeric (bpt->address, 1, tmp_error_stream);
+         fprintf_filtered (tmp_error_stream, ": %s.\n",
+                           safe_strerror (val));
+         bpt->owner->enable_state = bp_disabled;
+       }
+      else
+       {
+         /* Bp set, now make sure callbacks are enabled */
+         /* Format possible error msg */
+         char *message = xstrprintf ("Error inserting catchpoint %d:\n",
+                                     bpt->owner->number);
+         struct cleanup *cleanups = make_cleanup (xfree, message);
+         int val;
+         args_for_catchpoint_enable args;
+         args.kind = bpt->owner->type == bp_catch_catch ? 
+           EX_EVENT_CATCH : EX_EVENT_THROW;
+         args.enable_p = 1;
+         val = catch_errors (cover_target_enable_exception_callback,
+                             &args, message, RETURN_MASK_ALL);
+         do_cleanups (cleanups);
+         if (val != 0 && val != -1)
+           bpt->inserted = 1;
+
+         /* Check if something went wrong; val == 0 can be ignored */
+         if (val == -1)
+           {
+             /* something went wrong */
+             fprintf_unfiltered (tmp_error_stream, 
+                                 "Cannot insert catchpoint %d; disabling it.\n",
+                                 bpt->owner->number);
+             bpt->owner->enable_state = bp_disabled;
+           }
+       }
+
+      return val;
+    }
+
+  else if (bpt->owner->type == bp_catch_fork
+          || bpt->owner->type == bp_catch_vfork
+          || bpt->owner->type == bp_catch_exec)
+    {
+      char *prefix = xstrprintf ("warning: inserting catchpoint %d: ",
+                                bpt->owner->number);
+      struct cleanup *cleanups = make_cleanup (xfree, prefix);
+      val = catch_exceptions (uiout, insert_catchpoint, bpt->owner, prefix,
+                             RETURN_MASK_ERROR);
+      do_cleanups (cleanups);
+      if (val < 0)
+       bpt->owner->enable_state = bp_disabled;
+      else
+       bpt->inserted = 1;
+
+      /* We've already printed an error message if there was a problem
+        inserting this catchpoint, and we've disabled the catchpoint,
+        so just return success.  */
+      return 0;
+    }
+
+  return 0;
+}
+
+/* insert_breakpoints is used when starting or continuing the program.
+   remove_breakpoints is used when the program stops.
+   Both return zero if successful,
+   or an `errno' value if could not write the inferior.  */
+
+int
+insert_breakpoints (void)
+{
+  struct bp_location *b, *temp;
+  int return_val = 0;  /* return success code. */
+  int val = 0;
+  int disabled_breaks = 0;
+  int hw_breakpoint_error = 0;
+  int process_warning = 0;
+
+  struct ui_file *tmp_error_stream = mem_fileopen ();
+  make_cleanup_ui_file_delete (tmp_error_stream);
+
+  /* Explicitly mark the warning -- this will only be printed if
+     there was an error.  */
+  fprintf_unfiltered (tmp_error_stream, "Warning:\n");
+
+  ALL_BP_LOCATIONS_SAFE (b, temp)
+    {
+      /* Permanent breakpoints cannot be inserted or removed.  Disabled
+        breakpoints should not be inserted.  */
+      if (!breakpoint_enabled (b->owner))
+       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
+          || b->owner->type == bp_watchpoint) && !b->owner->val)
+       {
+         struct value *val;
+         val = evaluate_expression (b->owner->exp);
+         release_value (val);
+         if (VALUE_LAZY (val))
+           value_fetch_lazy (val);
+         b->owner->val = val;
+       }
+
+      val = insert_bp_location (b, tmp_error_stream,
+                                   &disabled_breaks, &process_warning,
+                                   &hw_breakpoint_error);
+      if (val)
+       return_val = val;
+    }
+
+  if (return_val)
     {
       /* If a hardware breakpoint or watchpoint was inserted, add a
          message about possibly exhausted resources.  */
-      if (hw_breakpoint_error)  
+      if (hw_breakpoint_error)
        {
          fprintf_unfiltered (tmp_error_stream, 
                              "Could not insert hardware breakpoints:\n\
@@ -1127,12 +1151,12 @@ You may have requested too many hardware breakpoints/watchpoints.\n");
 int
 remove_breakpoints (void)
 {
-  struct breakpoint *b;
+  struct bp_location *b;
   int val;
 
-  ALL_BREAKPOINTS (b)
+  ALL_BP_LOCATIONS (b)
   {
-    if (b->loc->inserted)
+    if (b->inserted)
       {
        val = remove_breakpoint (b, mark_uninserted);
        if (val != 0)
@@ -1145,15 +1169,12 @@ remove_breakpoints (void)
 int
 remove_hw_watchpoints (void)
 {
-  struct breakpoint *b;
+  struct bp_location *b;
   int val;
 
-  ALL_BREAKPOINTS (b)
+  ALL_BP_LOCATIONS (b)
   {
-    if (b->loc->inserted
-       && (b->type == bp_hardware_watchpoint
-           || b->type == bp_read_watchpoint
-           || b->type == bp_access_watchpoint))
+    if (b->inserted && b->loc_type == bp_loc_hardware_watchpoint)
       {
        val = remove_breakpoint (b, mark_uninserted);
        if (val != 0)
@@ -1166,21 +1187,23 @@ remove_hw_watchpoints (void)
 int
 reattach_breakpoints (int pid)
 {
-  struct breakpoint *b;
+  struct bp_location *b;
   int val;
   struct cleanup *old_chain = save_inferior_ptid ();
 
   /* Set inferior_ptid; remove_breakpoint uses this global.  */
   inferior_ptid = pid_to_ptid (pid);
-  ALL_BREAKPOINTS (b)
+  ALL_BP_LOCATIONS (b)
   {
-    if (b->loc->inserted)
+    if (b->inserted)
       {
        remove_breakpoint (b, mark_inserted);
-       if (b->type == bp_hardware_breakpoint)
-         val = target_insert_hw_breakpoint (b->loc->address, b->loc->shadow_contents);
+       if (b->loc_type == bp_loc_hardware_breakpoint)
+         val = target_insert_hw_breakpoint (b->address, b->shadow_contents);
        else
-         val = target_insert_breakpoint (b->loc->address, b->loc->shadow_contents);
+         val = target_insert_breakpoint (b->address, b->shadow_contents);
+       /* FIXME drow/2003-10-07: This doesn't handle any other kinds of
+          breakpoints.  It's wrong for watchpoints, for example.  */
        if (val != 0)
          {
            do_cleanups (old_chain);
@@ -1329,7 +1352,7 @@ update_breakpoints_after_exec (void)
 int
 detach_breakpoints (int pid)
 {
-  struct breakpoint *b;
+  struct bp_location *b;
   int val;
   struct cleanup *old_chain = save_inferior_ptid ();
 
@@ -1338,9 +1361,9 @@ detach_breakpoints (int pid)
 
   /* Set inferior_ptid; remove_breakpoint uses this global.  */
   inferior_ptid = pid_to_ptid (pid);
-  ALL_BREAKPOINTS (b)
+  ALL_BP_LOCATIONS (b)
   {
-    if (b->loc->inserted)
+    if (b->inserted)
       {
        val = remove_breakpoint (b, mark_inserted);
        if (val != 0)
@@ -1355,27 +1378,20 @@ detach_breakpoints (int pid)
 }
 
 static int
-remove_breakpoint (struct breakpoint *b, insertion_state_t is)
+remove_breakpoint (struct bp_location *b, insertion_state_t is)
 {
   int val;
 
-  if (b->enable_state == bp_permanent)
+  if (b->owner->enable_state == bp_permanent)
     /* Permanent breakpoints cannot be inserted or removed.  */
     return 0;
 
-  if (b->type == bp_none)
+  if (b->owner->type == bp_none)
     warning ("attempted to remove apparently deleted breakpoint #%d?", 
-            b->number);
-
-  if (b->type != bp_watchpoint
-      && b->type != bp_hardware_watchpoint
-      && b->type != bp_read_watchpoint
-      && b->type != bp_access_watchpoint
-      && b->type != bp_catch_fork
-      && b->type != bp_catch_vfork
-      && b->type != bp_catch_exec
-      && b->type != bp_catch_catch
-      && b->type != bp_catch_throw)
+            b->owner->number);
+
+  if (b->loc_type == bp_loc_software_breakpoint
+      || b->loc_type == bp_loc_hardware_breakpoint)
     {
       /* "Normal" instruction breakpoint: either the standard
         trap-instruction bp (bp_breakpoint), or a
@@ -1388,11 +1404,11 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
        {
          /* No overlay handling: just remove the breakpoint.  */
 
-         if (b->type == bp_hardware_breakpoint)
-           val = target_remove_hw_breakpoint (b->loc->address, 
-                                              b->loc->shadow_contents);
+         if (b->loc_type == bp_loc_hardware_breakpoint)
+           val = target_remove_hw_breakpoint (b->address, 
+                                              b->shadow_contents);
          else
-           val = target_remove_breakpoint (b->loc->address, b->loc->shadow_contents);
+           val = target_remove_breakpoint (b->address, b->shadow_contents);
        }
       else
        {
@@ -1403,29 +1419,29 @@ remove_breakpoint (struct breakpoint *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->loc->address, 
+               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->type != bp_hardware_breakpoint)
-                 target_remove_hw_breakpoint (addr, b->loc->shadow_contents);
+               if (b->loc_type == bp_loc_hardware_breakpoint)
+                 target_remove_hw_breakpoint (addr, b->shadow_contents);
                else
-                 target_remove_breakpoint (addr, b->loc->shadow_contents);
+                 target_remove_breakpoint (addr, b->shadow_contents);
              }
          /* Did we set a breakpoint at the VMA? 
             If so, we will have marked the breakpoint 'inserted'.  */
-         if (b->loc->inserted)
+         if (b->inserted)
            {
              /* Yes -- remove it.  Previously we did not bother to
                 remove the breakpoint if the section had been
                 unmapped, but let's not rely on that being safe.  We
                 don't know what the overlay manager might do.  */
-             if (b->type == bp_hardware_breakpoint)
-               val = target_remove_hw_breakpoint (b->loc->address, 
-                                                  b->loc->shadow_contents);
+             if (b->loc_type == bp_loc_hardware_breakpoint)
+               val = target_remove_hw_breakpoint (b->address, 
+                                                  b->shadow_contents);
              else
-               val = target_remove_breakpoint (b->loc->address,
-                                               b->loc->shadow_contents);
+               val = target_remove_breakpoint (b->address,
+                                               b->shadow_contents);
            }
          else
            {
@@ -1435,20 +1451,18 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
        }
       if (val)
        return val;
-      b->loc->inserted = (is == mark_inserted);
+      b->inserted = (is == mark_inserted);
     }
-  else if ((b->type == bp_hardware_watchpoint ||
-           b->type == bp_read_watchpoint ||
-           b->type == bp_access_watchpoint)
-          && b->enable_state == bp_enabled
-          && !b->loc->duplicate)
+  else if (b->loc_type == bp_loc_hardware_watchpoint
+          && breakpoint_enabled (b->owner)
+          && !b->duplicate)
     {
       struct value *v;
       struct value *n;
 
-      b->loc->inserted = (is == mark_inserted);
+      b->inserted = (is == mark_inserted);
       /* Walk down the saved value chain.  */
-      for (v = b->val_chain; v; v = v->next)
+      for (v = b->owner->val_chain; v; v = v->next)
        {
          /* For each memory reference remove the watchpoint
             at that address.  */
@@ -1457,7 +1471,7 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
            {
              struct type *vtype = check_typedef (VALUE_TYPE (v));
 
-             if (v == b->val_chain
+             if (v == b->owner->val_chain
                  || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
                      && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
                {
@@ -1467,40 +1481,40 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
                  addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
                  len = TYPE_LENGTH (VALUE_TYPE (v));
                  type   = hw_write;
-                 if (b->type == bp_read_watchpoint)
+                 if (b->owner->type == bp_read_watchpoint)
                    type = hw_read;
-                 else if (b->type == bp_access_watchpoint)
+                 else if (b->owner->type == bp_access_watchpoint)
                    type = hw_access;
 
                  val = target_remove_watchpoint (addr, len, type);
                  if (val == -1)
-                   b->loc->inserted = 1;
+                   b->inserted = 1;
                  val = 0;
                }
            }
        }
       /* Failure to remove any of the hardware watchpoints comes here.  */
-      if ((is == mark_uninserted) && (b->loc->inserted))
+      if ((is == mark_uninserted) && (b->inserted))
        warning ("Could not remove hardware watchpoint %d.",
-                b->number);
+                b->owner->number);
 
       /* Free the saved value chain.  We will construct a new one
          the next time the watchpoint is inserted.  */
-      for (v = b->val_chain; v; v = n)
+      for (v = b->owner->val_chain; v; v = n)
        {
          n = v->next;
          value_free (v);
        }
-      b->val_chain = NULL;
+      b->owner->val_chain = NULL;
     }
-  else if ((b->type == bp_catch_fork ||
-           b->type == bp_catch_vfork ||
-           b->type == bp_catch_exec)
-          && b->enable_state == bp_enabled
-          && !b->loc->duplicate)
+  else if ((b->owner->type == bp_catch_fork ||
+           b->owner->type == bp_catch_vfork ||
+           b->owner->type == bp_catch_exec)
+          && breakpoint_enabled (b->owner)
+          && !b->duplicate)
     {
       val = -1;
-      switch (b->type)
+      switch (b->owner->type)
        {
        case bp_catch_fork:
          val = target_remove_fork_catchpoint (PIDGET (inferior_ptid));
@@ -1517,30 +1531,30 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
        }
       if (val)
        return val;
-      b->loc->inserted = (is == mark_inserted);
+      b->inserted = (is == mark_inserted);
     }
-  else if ((b->type == bp_catch_catch ||
-           b->type == bp_catch_throw)
-          && b->enable_state == bp_enabled
-          && !b->loc->duplicate)
+  else if ((b->owner->type == bp_catch_catch ||
+           b->owner->type == bp_catch_throw)
+          && breakpoint_enabled (b->owner)
+          && !b->duplicate)
     {
 
-      val = target_remove_breakpoint (b->loc->address, b->loc->shadow_contents);
+      val = target_remove_breakpoint (b->address, b->shadow_contents);
       if (val)
        return val;
-      b->loc->inserted = (is == mark_inserted);
+      b->inserted = (is == mark_inserted);
     }
-  else if (ep_is_exception_catchpoint (b)
-          && b->loc->inserted  /* sometimes previous insert doesn't happen */
-          && b->enable_state == bp_enabled
-          && !b->loc->duplicate)
+  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->loc->address, b->loc->shadow_contents);
+      val = target_remove_breakpoint (b->address, b->shadow_contents);
       if (val)
        return val;
 
-      b->loc->inserted = (is == mark_inserted);
+      b->inserted = (is == mark_inserted);
     }
 
   return 0;
@@ -1551,10 +1565,10 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
 void
 mark_breakpoints_out (void)
 {
-  struct breakpoint *b;
+  struct bp_location *bpt;
 
-  ALL_BREAKPOINTS (b)
-    b->loc->inserted = 0;
+  ALL_BP_LOCATIONS (bpt)
+    bpt->inserted = 0;
 }
 
 /* Clear the "inserted" flag in all breakpoints and delete any
@@ -1573,12 +1587,14 @@ void
 breakpoint_init_inferior (enum inf_context context)
 {
   struct breakpoint *b, *temp;
+  struct bp_location *bpt;
   static int warning_needed = 0;
 
+  ALL_BP_LOCATIONS (bpt)
+    bpt->inserted = 0;
+
   ALL_BREAKPOINTS_SAFE (b, temp)
   {
-    b->loc->inserted = 0;
-
     switch (b->type)
       {
       case bp_call_dummy:
@@ -1647,23 +1663,29 @@ breakpoint_init_inferior (enum inf_context context)
 enum breakpoint_here
 breakpoint_here_p (CORE_ADDR pc)
 {
-  struct breakpoint *b;
+  struct bp_location *bpt;
   int any_breakpoint_here = 0;
 
-  ALL_BREAKPOINTS (b)
-    if ((b->enable_state == bp_enabled
-        || b->enable_state == bp_permanent)
-       && b->loc->address == pc)       /* bp is enabled and matches pc */
-      {
-       if (overlay_debugging 
-           && section_is_overlay (b->section) 
-           && !section_is_mapped (b->section))
-         continue;             /* unmapped overlay -- can't be a match */
-       else if (b->enable_state == bp_permanent)
-         return permanent_breakpoint_here;
-       else
-         any_breakpoint_here = 1;
-      }
+  ALL_BP_LOCATIONS (bpt)
+    {
+      if (bpt->loc_type != bp_loc_software_breakpoint
+         && bpt->loc_type != bp_loc_hardware_breakpoint)
+       continue;
+
+      if ((breakpoint_enabled (bpt->owner)
+          || bpt->owner->enable_state == bp_permanent)
+         && bpt->address == pc)        /* bp is enabled and matches pc */
+       {
+         if (overlay_debugging 
+             && section_is_overlay (bpt->section) 
+             && !section_is_mapped (bpt->section))
+           continue;           /* unmapped overlay -- can't be a match */
+         else if (bpt->owner->enable_state == bp_permanent)
+           return permanent_breakpoint_here;
+         else
+           any_breakpoint_here = 1;
+       }
+    }
 
   return any_breakpoint_here ? ordinary_breakpoint_here : 0;
 }
@@ -1676,18 +1698,24 @@ breakpoint_here_p (CORE_ADDR pc)
 int
 breakpoint_inserted_here_p (CORE_ADDR pc)
 {
-  struct breakpoint *b;
+  struct bp_location *bpt;
 
-  ALL_BREAKPOINTS (b)
-    if (b->loc->inserted
-       && b->loc->address == pc)       /* bp is inserted and matches pc */
+  ALL_BP_LOCATIONS (bpt)
     {
-      if (overlay_debugging 
-         && section_is_overlay (b->section) 
-         && !section_is_mapped (b->section))
-       continue;               /* unmapped overlay -- can't be a match */
-      else
-       return 1;
+      if (bpt->loc_type != bp_loc_software_breakpoint
+         && bpt->loc_type != bp_loc_hardware_breakpoint)
+       continue;
+
+      if (bpt->inserted
+         && bpt->address == pc)        /* bp is inserted and matches pc */
+       {
+         if (overlay_debugging 
+             && section_is_overlay (bpt->section) 
+             && !section_is_mapped (bpt->section))
+           continue;           /* unmapped overlay -- can't be a match */
+         else
+           return 1;
+       }
     }
 
   return 0;
@@ -1724,30 +1752,35 @@ deprecated_frame_in_dummy (struct frame_info *frame)
   return 0;
 }
 
-/* breakpoint_thread_match (PC, PID) returns true if the breakpoint at
-   PC is valid for process/thread PID.  */
+/* breakpoint_thread_match (PC, PTID) returns true if the breakpoint at
+   PC is valid for process/thread PTID.  */
 
 int
 breakpoint_thread_match (CORE_ADDR pc, ptid_t ptid)
 {
-  struct breakpoint *b;
+  struct bp_location *bpt;
   int thread;
 
   thread = pid_to_thread_id (ptid);
 
-  ALL_BREAKPOINTS (b)
-    if (b->enable_state != bp_disabled
-       && b->enable_state != bp_shlib_disabled
-       && b->enable_state != bp_call_disabled
-       && b->loc->address == pc
-       && (b->thread == -1 || b->thread == thread))
-    {
-      if (overlay_debugging 
-         && section_is_overlay (b->section) 
-         && !section_is_mapped (b->section))
-       continue;               /* unmapped overlay -- can't be a match */
-      else
-       return 1;
+  ALL_BP_LOCATIONS (bpt)
+    {
+      if (bpt->loc_type != bp_loc_software_breakpoint
+         && bpt->loc_type != bp_loc_hardware_breakpoint)
+       continue;
+
+      if ((breakpoint_enabled (bpt->owner)
+          || bpt->owner->enable_state == bp_permanent)
+         && bpt->address == pc
+         && (bpt->owner->thread == -1 || bpt->owner->thread == thread))
+       {
+         if (overlay_debugging 
+             && section_is_overlay (bpt->section) 
+             && !section_is_mapped (bpt->section))
+           continue;           /* unmapped overlay -- can't be a match */
+         else
+           return 1;
+       }
     }
 
   return 0;
@@ -1949,7 +1982,6 @@ bpstat_do_actions (bpstat *bsp)
 {
   bpstat bs;
   struct cleanup *old_chain;
-  struct command_line *cmd;
 
   /* Avoid endless recursion if a `source' command is contained
      in bs->commands.  */
@@ -1974,7 +2006,23 @@ top:
   breakpoint_proceeded = 0;
   for (; bs != NULL; bs = bs->next)
     {
+      struct command_line *cmd;
+      struct cleanup *this_cmd_tree_chain;
+
+      /* Take ownership of the BSP's command tree, if it has one.
+
+         The command tree could legitimately contain commands like
+         'step' and 'next', which call clear_proceed_status, which
+         frees stop_bpstat's command tree.  To make sure this doesn't
+         free the tree we're executing out from under us, we need to
+         take ownership of the tree ourselves.  Since a given bpstat's
+         commands are only executed once, we don't need to copy it; we
+         can clear the pointer in the bpstat, and make sure we free
+         the tree when we're done.  */
       cmd = bs->commands;
+      bs->commands = 0;
+      this_cmd_tree_chain = make_cleanup_free_command_lines (&cmd);
+
       while (cmd != NULL)
        {
          execute_control_command (cmd);
@@ -1984,14 +2032,16 @@ top:
          else
            cmd = cmd->next;
        }
+
+      /* We can free this command tree now.  */
+      do_cleanups (this_cmd_tree_chain);
+
       if (breakpoint_proceeded)
        /* The inferior is proceeded by the command; bomb out now.
           The bpstat chain has been blown away by wait_for_inferior.
           But since execution has stopped again, there is a new bpstat
           to look at, so start over.  */
        goto top;
-      else
-       free_command_lines (&bs->commands);
     }
   do_cleanups (old_chain);
 }
@@ -2538,9 +2588,7 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_sw_breakpoint)
 
   ALL_BREAKPOINTS_SAFE (b, temp)
   {
-    if (b->enable_state == bp_disabled
-       || b->enable_state == bp_shlib_disabled
-       || b->enable_state == bp_call_disabled)
+    if (!breakpoint_enabled (b) && b->enable_state != bp_permanent)
       continue;
 
     if (b->type != bp_watchpoint
@@ -2557,18 +2605,18 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_sw_breakpoint)
        if (b->loc->address != bp_addr)         /* address doesn't match */
          continue;
        if (overlay_debugging           /* unmapped overlay section */
-           && section_is_overlay (b->section) 
-           && !section_is_mapped (b->section))
+           && section_is_overlay (b->loc->section) 
+           && !section_is_mapped (b->loc->section))
          continue;
       }
 
     if (b->type == bp_hardware_breakpoint)
       {
-       if (b->loc->address != (*pc - DECR_PC_AFTER_HW_BREAK))
+       if (b->loc->address != *pc)
          continue;
        if (overlay_debugging           /* unmapped overlay section */
-           && section_is_overlay (b->section) 
-           && !section_is_mapped (b->section))
+           && section_is_overlay (b->loc->section) 
+           && !section_is_mapped (b->loc->section))
          continue;
       }
 
@@ -2805,8 +2853,8 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_sw_breakpoint)
              bs->print = 0;
            bs->commands = b->commands;
            if (bs->commands &&
-               (STREQ ("silent", bs->commands->line) ||
-                (xdb_commands && STREQ ("Q", bs->commands->line))))
+               (strcmp ("silent", bs->commands->line) == 0
+                || (xdb_commands && strcmp ("Q", bs->commands->line) == 0)))
              {
                bs->commands = bs->commands->next;
                bs->print = 0;
@@ -2824,24 +2872,12 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_sw_breakpoint)
 
   if (real_breakpoint && bs)
     {
-      if (bs->breakpoint_at->type == bp_hardware_breakpoint)
-       {
-         if (DECR_PC_AFTER_HW_BREAK != 0)
-           {
-             *pc = *pc - DECR_PC_AFTER_HW_BREAK;
-             write_pc (*pc);
-           }
-       }
-      else
+      if (bs->breakpoint_at->type != bp_hardware_breakpoint)
        {
-         if (DECR_PC_AFTER_BREAK != 0 || must_shift_inst_regs)
+         if (DECR_PC_AFTER_BREAK != 0)
            {
              *pc = bp_addr;
-#if defined (SHIFT_INST_REGS)
-             SHIFT_INST_REGS ();
-#else /* No SHIFT_INST_REGS.  */
              write_pc (bp_addr);
-#endif /* No SHIFT_INST_REGS.  */
            }
        }
     }
@@ -3143,7 +3179,7 @@ bpstat_should_step (void)
 {
   struct breakpoint *b;
   ALL_BREAKPOINTS (b)
-    if (b->enable_state == bp_enabled && b->type == bp_watchpoint)
+    if (breakpoint_enabled (b) && b->type == bp_watchpoint)
       return 1;
   return 0;
 }
@@ -3152,13 +3188,11 @@ bpstat_should_step (void)
 int
 bpstat_have_active_hw_watchpoints (void)
 {
-  struct breakpoint *b;
-  ALL_BREAKPOINTS (b)
-    if ((b->enable_state == bp_enabled) &&
-       (b->loc->inserted) &&
-       ((b->type == bp_hardware_watchpoint) ||
-        (b->type == bp_read_watchpoint) ||
-        (b->type == bp_access_watchpoint)))
+  struct bp_location *bpt;
+  ALL_BP_LOCATIONS (bpt)
+    if (breakpoint_enabled (bpt->owner)
+       && bpt->inserted
+       && bpt->loc_type == bp_loc_hardware_watchpoint)
       return 1;
   return 0;
 }
@@ -3430,7 +3464,7 @@ print_one_breakpoint (struct breakpoint *b,
        *last_addr = b->loc->address;
        if (b->source_file)
          {
-           sym = find_pc_sect_function (b->loc->address, b->section);
+           sym = find_pc_sect_function (b->loc->address, b->loc->section);
            if (sym)
              {
                ui_out_text (uiout, "in ");
@@ -3710,14 +3744,14 @@ describe_other_breakpoints (CORE_ADDR pc, asection *section)
 
   ALL_BREAKPOINTS (b)
     if (b->loc->address == pc) /* address match / overlay match */
-      if (!overlay_debugging || b->section == section)
+      if (!overlay_debugging || b->loc->section == section)
        others++;
   if (others > 0)
     {
       printf_filtered ("Note: breakpoint%s ", (others > 1) ? "s" : "");
       ALL_BREAKPOINTS (b)
        if (b->loc->address == pc)      /* address match / overlay match */
-         if (!overlay_debugging || b->section == section)
+         if (!overlay_debugging || b->loc->section == section)
            {
              others--;
              printf_filtered ("%d%s%s ",
@@ -3794,32 +3828,32 @@ breakpoint_address_is_meaningful (struct breakpoint *bpt)
 static void
 check_duplicates (struct breakpoint *bpt)
 {
-  struct breakpoint *b;
+  struct bp_location *b;
   int count = 0;
-  struct breakpoint *perm_bp = 0;
+  struct bp_location *perm_bp = 0;
   CORE_ADDR address = bpt->loc->address;
-  asection *section = bpt->section;
+  asection *section = bpt->loc->section;
 
   if (! breakpoint_address_is_meaningful (bpt))
     return;
 
-  ALL_BREAKPOINTS (b)
-    if (b->enable_state != bp_disabled
-       && b->enable_state != bp_shlib_disabled
-       && b->enable_state != bp_call_disabled
-       && b->loc->address == address   /* address / overlay match */
+  ALL_BP_LOCATIONS (b)
+    if (b->owner->enable_state != bp_disabled
+       && b->owner->enable_state != bp_shlib_disabled
+       && b->owner->enable_state != bp_call_disabled
+       && b->address == address        /* address / overlay match */
        && (!overlay_debugging || b->section == section)
-       && breakpoint_address_is_meaningful (b))
+       && breakpoint_address_is_meaningful (b->owner))
     {
       /* Have we found a permanent breakpoint?  */
-      if (b->enable_state == bp_permanent)
+      if (b->owner->enable_state == bp_permanent)
        {
          perm_bp = b;
          break;
        }
        
       count++;
-      b->loc->duplicate = count > 1;
+      b->duplicate = count > 1;
     }
 
   /* If we found a permanent breakpoint at this address, go over the
@@ -3827,29 +3861,31 @@ check_duplicates (struct breakpoint *bpt)
      duplicates.  */
   if (perm_bp)
     {
-      perm_bp->loc->duplicate = 0;
+      perm_bp->duplicate = 0;
 
       /* Permanent breakpoint should always be inserted.  */
-      if (! perm_bp->loc->inserted)
+      if (! perm_bp->inserted)
        internal_error (__FILE__, __LINE__,
                        "allegedly permanent breakpoint is not "
                        "actually inserted");
 
-      ALL_BREAKPOINTS (b)
+      ALL_BP_LOCATIONS (b)
        if (b != perm_bp)
          {
-           if (b->loc->inserted)
-             internal_error (__FILE__, __LINE__,
-                             "another breakpoint was inserted on top of "
-                             "a permanent breakpoint");
-
-           if (b->enable_state != bp_disabled
-               && b->enable_state != bp_shlib_disabled
-               && b->enable_state != bp_call_disabled
-               && b->loc->address == address   /* address / overlay match */
+           if (b->owner->enable_state != bp_disabled
+               && b->owner->enable_state != bp_shlib_disabled
+               && b->owner->enable_state != bp_call_disabled
+               && b->address == address        /* address / overlay match */
                && (!overlay_debugging || b->section == section)
-               && breakpoint_address_is_meaningful (b))
-             b->loc->duplicate = 1;
+               && breakpoint_address_is_meaningful (b->owner))
+             {
+               if (b->inserted)
+                 internal_error (__FILE__, __LINE__,
+                                 "another breakpoint was inserted on top of "
+                                 "a permanent breakpoint");
+
+               b->duplicate = 1;
+             }
          }
     }
 }
@@ -3904,7 +3940,7 @@ adjust_breakpoint_address (CORE_ADDR bpaddr)
 
 /* Allocate a struct bp_location.  */
 
-struct bp_location *
+static struct bp_location *
 allocate_bp_location (struct breakpoint *bpt, enum bptype bp_type)
 {
   struct bp_location *loc, *loc_p;
@@ -3997,7 +4033,7 @@ set_raw_breakpoint (struct symtab_and_line sal, enum bptype bptype)
   else
     b->source_file = savestring (sal.symtab->filename,
                                 strlen (sal.symtab->filename));
-  b->section = sal.section;
+  b->loc->section = sal.section;
   b->type = bptype;
   b->language = current_language->la_language;
   b->input_radix = input_radix;
@@ -4232,7 +4268,7 @@ disable_breakpoints_in_shlibs (int silent)
 #if defined (PC_SOLIB)
     if (((b->type == bp_breakpoint) ||
         (b->type == bp_hardware_breakpoint)) &&
-       b->enable_state == bp_enabled &&
+       breakpoint_enabled (b) &&
        !b->loc->duplicate &&
        PC_SOLIB (b->loc->address))
       {
@@ -4261,11 +4297,12 @@ re_enable_breakpoints_in_shlibs (void)
   ALL_BREAKPOINTS (b)
     if (b->enable_state == bp_shlib_disabled)
     {
-      char buf[1];
+      char buf[1], *lib;
 
       /* Do not reenable the breakpoint if the shared library
          is still not mapped in.  */
-      if (target_read_memory (b->loc->address, buf, 1) == 0)
+      lib = PC_SOLIB (b->loc->address);
+      if (lib != NULL && target_read_memory (b->loc->address, buf, 1) == 0)
        b->enable_state = bp_enabled;
     }
 }
@@ -4286,7 +4323,7 @@ solib_load_unload_1 (char *hookname, int tempflag, char *dll_pathname,
   int thread = -1;             /* All threads. */
 
   /* Set a breakpoint on the specified hook. */
-  sals = decode_line_1 (&hookname, 1, (struct symtab *) NULL, 0, &canonical);
+  sals = decode_line_1 (&hookname, 1, (struct symtab *) NULL, 0, &canonical, NULL);
   addr_end = hookname;
 
   if (sals.nelts == 0)
@@ -4454,14 +4491,13 @@ hw_watchpoint_used_count (enum bptype type, int *other_type_used)
   *other_type_used = 0;
   ALL_BREAKPOINTS (b)
   {
-    if (b->enable_state == bp_enabled)
+    if (breakpoint_enabled (b))
       {
        if (b->type == type)
          i++;
        else if ((b->type == bp_hardware_watchpoint ||
                  b->type == bp_read_watchpoint ||
-                 b->type == bp_access_watchpoint)
-                && b->enable_state == bp_enabled)
+                 b->type == bp_access_watchpoint))
          *other_type_used = 1;
       }
   }
@@ -4503,7 +4539,7 @@ disable_watchpoints_before_interactive_call_start (void)
         || (b->type == bp_read_watchpoint)
         || (b->type == bp_access_watchpoint)
         || ep_is_exception_catchpoint (b))
-       && (b->enable_state == bp_enabled))
+       && breakpoint_enabled (b))
       {
        b->enable_state = bp_call_disabled;
        check_duplicates (b);
@@ -4804,9 +4840,9 @@ parse_breakpoint_sals (char **address,
              || ((strchr ("+-", (*address)[0]) != NULL)
                  && ((*address)[1] != '['))))
        *sals = decode_line_1 (address, 1, default_breakpoint_symtab,
-                              default_breakpoint_line, addr_string);
+                              default_breakpoint_line, addr_string, NULL);
       else
-       *sals = decode_line_1 (address, 1, (struct symtab *) NULL, 0, addr_string);
+       *sals = decode_line_1 (address, 1, (struct symtab *) NULL, 0, addr_string, NULL);
     }
   /* For any SAL that didn't have a canonical string, fill one in. */
   if (sals->nelts > 0 && *addr_string == NULL)
@@ -5252,7 +5288,7 @@ break_at_finish_command_1 (char *arg, int flag, int from_tty)
 
   beg_addr_string = addr_string;
   sals = decode_line_1 (&addr_string, 1, (struct symtab *) NULL, 0,
-                       (char ***) NULL);
+                       (char ***) NULL, NULL);
 
   xfree (beg_addr_string);
   old_chain = make_cleanup (xfree, sals.sals);
@@ -5769,10 +5805,10 @@ until_break_command (char *arg, int from_tty, int anywhere)
 
   if (default_breakpoint_valid)
     sals = decode_line_1 (&arg, 1, default_breakpoint_symtab,
-                         default_breakpoint_line, (char ***) NULL);
+                         default_breakpoint_line, (char ***) NULL, NULL);
   else
     sals = decode_line_1 (&arg, 1, (struct symtab *) NULL, 
-                         0, (char ***) NULL);
+                         0, (char ***) NULL, NULL);
 
   if (sals.nelts != 1)
     error ("Couldn't get information on specified line.");
@@ -6232,7 +6268,7 @@ handle_gnu_v3_exceptions (int tempflag, char *cond_string,
     trigger_func_name = xstrdup ("__cxa_throw");
 
   nameptr = trigger_func_name;
-  sals = decode_line_1 (&nameptr, 1, NULL, 0, NULL);
+  sals = decode_line_1 (&nameptr, 1, NULL, 0, NULL, NULL);
   if (sals.nelts == 0)
     {
       xfree (trigger_func_name);
@@ -6553,13 +6589,13 @@ clear_command (char *arg, int from_tty)
              && b->type != bp_access_watchpoint
              /* Not if b is a watchpoint of any sort... */
              && (((sal.pc && (b->loc->address == sal.pc)) 
-                  && (!section_is_overlay (b->section)
-                      || b->section == sal.section))
+                  && (!section_is_overlay (b->loc->section)
+                      || b->loc->section == sal.section))
                  /* Yes, if sal.pc matches b (modulo overlays).  */
                  || ((default_match || (0 == sal.pc))
                      && b->source_file != NULL
                      && sal.symtab != NULL
-                     && STREQ (b->source_file, sal.symtab->filename)
+                     && strcmp (b->source_file, sal.symtab->filename) == 0
                      && b->line_number == sal.line)))
            /* Yes, if sal source file and line matches b.  */
            {
@@ -6666,7 +6702,7 @@ delete_breakpoint (struct breakpoint *bpt)
   breakpoint_delete_event (bpt->number);
 
   if (bpt->loc->inserted)
-    remove_breakpoint (bpt, mark_inserted);
+    remove_breakpoint (bpt->loc, mark_inserted);
 
   if (breakpoint_chain == bpt)
     breakpoint_chain = bpt->next;
@@ -6723,7 +6759,7 @@ delete_breakpoint (struct breakpoint *bpt)
     {
       ALL_BREAKPOINTS (b)
        if (b->loc->address == bpt->loc->address
-           && b->section == bpt->section
+           && b->loc->section == bpt->loc->section
            && !b->loc->duplicate
            && b->enable_state != bp_disabled
            && b->enable_state != bp_shlib_disabled
@@ -6939,7 +6975,7 @@ breakpoint_re_set_one (void *bint)
       set_language (b->language);
       input_radix = b->input_radix;
       s = b->addr_string;
-      sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) NULL);
+      sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) NULL, NULL);
       for (i = 0; i < sals.nelts; i++)
        {
          resolve_sal_pc (&sals.sals[i]);
@@ -6960,7 +6996,7 @@ breakpoint_re_set_one (void *bint)
             the source file name or the line number changes...  */
              || (b->source_file != NULL
                  && sals.sals[i].symtab != NULL
-                 && (!STREQ (b->source_file, sals.sals[i].symtab->filename)
+                 && (strcmp (b->source_file, sals.sals[i].symtab->filename) != 0
                      || b->line_number != sals.sals[i].line)
              )
          /* ...or we switch between having a source file and not having
@@ -6991,7 +7027,7 @@ breakpoint_re_set_one (void *bint)
                 rather than once for every breakpoint.  */
              breakpoints_changed ();
            }
-         b->section = sals.sals[i].section;
+         b->loc->section = sals.sals[i].section;
          b->enable_state = save_enable;        /* Restore it, this worked. */
 
 
@@ -7026,7 +7062,7 @@ breakpoint_re_set_one (void *bint)
        value_free (b->val);
       b->val = evaluate_expression (b->exp);
       release_value (b->val);
-      if (VALUE_LAZY (b->val) && b->enable_state == bp_enabled)
+      if (VALUE_LAZY (b->val) && breakpoint_enabled (b))
        value_fetch_lazy (b->val);
 
       if (b->cond_string != NULL)
@@ -7036,7 +7072,7 @@ breakpoint_re_set_one (void *bint)
            xfree (b->cond);
          b->cond = parse_exp_1 (&s, (struct block *) 0, 0);
        }
-      if (b->enable_state == bp_enabled)
+      if (breakpoint_enabled (b))
        mention (b);
       value_free_to_mark (mark);
       break;
@@ -7475,10 +7511,10 @@ decode_line_spec_1 (char *string, int funfirstline)
     sals = decode_line_1 (&string, funfirstline,
                          default_breakpoint_symtab,
                          default_breakpoint_line,
-                         (char ***) NULL);
+                         (char ***) NULL, NULL);
   else
     sals = decode_line_1 (&string, funfirstline,
-                         (struct symtab *) NULL, 0, (char ***) NULL);
+                         (struct symtab *) NULL, 0, (char ***) NULL, NULL);
   if (*string)
     error ("Junk at end of line specification: %s", string);
   return sals;
This page took 0.048971 seconds and 4 git commands to generate.