* sparc64nbsd-tdep.c: Include "regset.h".
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 8118a0a5a34e0e18339aea8efcad2ce3d77e8ae9..6a17368b642f1de53d87602ce1e1e804ad746607 100644 (file)
@@ -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);
 
@@ -235,6 +235,15 @@ static int overlay_events_enabled;
             B ? (TMP=B->next, 1): 0;   \
             B = TMP)
 
+/* Similar iterators for the low-level breakpoints.  */
+
+#define ALL_BP_LOCATIONS(B)  for (B = bp_location_chain; B; B = B->next)
+
+#define ALL_BP_LOCATIONS_SAFE(B,TMP)   \
+       for (B = bp_location_chain;     \
+            B ? (TMP=B->next, 1): 0;   \
+            B = TMP)
+
 /* True if SHIFT_INST_REGS defined, false otherwise.  */
 
 int must_shift_inst_regs =
@@ -249,10 +258,12 @@ int must_shift_inst_regs =
 
 int show_breakpoint_hit_counts = 1;
 
-/* Chain of all breakpoints defined.  */
+/* Chains of all breakpoints defined.  */
 
 struct breakpoint *breakpoint_chain;
 
+struct bp_location *bp_location_chain;
+
 /* Number of last breakpoint made.  */
 
 int breakpoint_count;
@@ -321,6 +332,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
@@ -552,7 +570,7 @@ condition_command (char *arg, int from_tty)
          /* I don't know if it matters whether this is the string the user
             typed in or the decompiled expression.  */
          b->cond_string = savestring (arg, strlen (arg));
-         b->cond = parse_exp_1 (&arg, block_for_pc (b->address), 0);
+         b->cond = parse_exp_1 (&arg, block_for_pc (b->loc->address), 0);
          if (*arg)
            error ("Junk at end of expression");
        }
@@ -614,7 +632,7 @@ int
 read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len)
 {
   int status;
-  struct breakpoint *b;
+  struct bp_location *b;
   CORE_ADDR bp_addr = 0;
   int bp_size = 0;
 
@@ -622,19 +640,14 @@ read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len)
     /* No breakpoints on this machine. */
     return target_read_memory (memaddr, myaddr, len);
 
-  ALL_BREAKPOINTS (b)
+  ALL_BP_LOCATIONS (b)
   {
-    if (b->type == bp_none)
-      warning ("reading through apparently deleted breakpoint #%d?", 
-              b->number);
+    if (b->owner->type == bp_none)
+      warning ("reading through apparently deleted breakpoint #%d?",
+              b->owner->number);
 
-    /* memory breakpoint? */
-    if (b->type == bp_watchpoint
-       || b->type == bp_hardware_watchpoint
-       || b->type == bp_read_watchpoint
-       || b->type == bp_access_watchpoint)
+    if (b->loc_type != bp_loc_software_breakpoint)
       continue;
-    /* bp in memory? */
     if (!b->inserted)
       continue;
     /* Addresses and length of the part of the breakpoint that
@@ -735,373 +748,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->inserted
-       && !b->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->address, 
-                                                b->shadow_contents);
-           else
-             val = target_insert_breakpoint (b->address, b->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->address, 
-                                                              b->section);
-                   /* Set a software (trap) breakpoint at the LMA.  */
-                   val = target_insert_breakpoint (addr, b->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->address, 
-                                                    b->shadow_contents);
-               else
-                 val = target_insert_breakpoint (b->address,
-                                                 b->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->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->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->inserted = 1;
+           }
+       }
+      else
+       bpt->inserted = 1;
 
-       if (val)
-         return_val = val;     /* remember failure */
-      }
-    else if (ep_is_exception_catchpoint (b)
-            && !b->inserted
-            && !b->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->address, b->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->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->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->inserted
-            && !b->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->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->inserted = 0;
-                         }
-                       val = 0;
-                     }
-                 }
-             }
-           /* Failure to insert a watchpoint on any memory value in the
-              value chain brings us here.  */
-           if (!b->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->inserted
-            && !b->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->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\
@@ -1121,10 +1161,10 @@ 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->inserted)
       {
@@ -1139,15 +1179,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->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)
@@ -1160,21 +1197,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->inserted)
       {
        remove_breakpoint (b, mark_inserted);
-       if (b->type == bp_hardware_breakpoint)
+       if (b->loc_type == bp_loc_hardware_breakpoint)
          val = target_insert_hw_breakpoint (b->address, b->shadow_contents);
        else
          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);
@@ -1261,7 +1300,7 @@ update_breakpoints_after_exec (void)
        (b->type == bp_catch_vfork) ||
        (b->type == bp_catch_fork))
       {
-       b->address = (CORE_ADDR) NULL;
+       b->loc->address = (CORE_ADDR) NULL;
        continue;
       }
 
@@ -1314,7 +1353,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->address = (CORE_ADDR) NULL;
+    b->loc->address = (CORE_ADDR) NULL;
   }
   /* FIXME what about longjmp breakpoints?  Re-create them here?  */
   create_overlay_event_breakpoint ("_ovly_debug_event");
@@ -1323,7 +1362,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 ();
 
@@ -1332,7 +1371,7 @@ 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->inserted)
       {
@@ -1349,27 +1388,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
@@ -1382,7 +1414,7 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
        {
          /* No overlay handling: just remove the breakpoint.  */
 
-         if (b->type == bp_hardware_breakpoint)
+         if (b->loc_type == bp_loc_hardware_breakpoint)
            val = target_remove_hw_breakpoint (b->address, 
                                               b->shadow_contents);
          else
@@ -1401,7 +1433,7 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
                                                           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)
+               if (b->loc_type == bp_loc_hardware_breakpoint)
                  target_remove_hw_breakpoint (addr, b->shadow_contents);
                else
                  target_remove_breakpoint (addr, b->shadow_contents);
@@ -1414,7 +1446,7 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
                 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)
+             if (b->loc_type == bp_loc_hardware_breakpoint)
                val = target_remove_hw_breakpoint (b->address, 
                                                   b->shadow_contents);
              else
@@ -1431,10 +1463,8 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
        return val;
       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
+  else if (b->loc_type == bp_loc_hardware_watchpoint
+          && breakpoint_enabled (b->owner)
           && !b->duplicate)
     {
       struct value *v;
@@ -1442,7 +1472,7 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
 
       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.  */
@@ -1451,7 +1481,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))
                {
@@ -1461,9 +1491,9 @@ 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);
@@ -1476,25 +1506,25 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
       /* Failure to remove any of the hardware watchpoints comes here.  */
       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
+  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));
@@ -1513,9 +1543,9 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
        return val;
       b->inserted = (is == mark_inserted);
     }
-  else if ((b->type == bp_catch_catch ||
-           b->type == bp_catch_throw)
-          && b->enable_state == bp_enabled
+  else if ((b->owner->type == bp_catch_catch ||
+           b->owner->type == bp_catch_throw)
+          && breakpoint_enabled (b->owner)
           && !b->duplicate)
     {
 
@@ -1524,9 +1554,9 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
        return val;
       b->inserted = (is == mark_inserted);
     }
-  else if (ep_is_exception_catchpoint (b)
+  else if (ep_is_exception_catchpoint (b->owner)
           && b->inserted       /* sometimes previous insert doesn't happen */
-          && b->enable_state == bp_enabled
+          && breakpoint_enabled (b->owner)
           && !b->duplicate)
     {
 
@@ -1545,10 +1575,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->inserted = 0;
+  ALL_BP_LOCATIONS (bpt)
+    bpt->inserted = 0;
 }
 
 /* Clear the "inserted" flag in all breakpoints and delete any
@@ -1567,12 +1597,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->inserted = 0;
-
     switch (b->type)
       {
       case bp_call_dummy:
@@ -1641,23 +1673,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->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;
 }
@@ -1670,18 +1708,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->inserted
-       && b->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;
@@ -1710,38 +1754,43 @@ deprecated_frame_in_dummy (struct frame_info *frame)
     /* We need to check the PC as well as the frame on the sparc,
        for signals.exp in the testsuite.  */
        && (get_frame_pc (frame)
-           >= (b->address
+           >= (b->loc->address
                - DEPRECATED_SIZEOF_CALL_DUMMY_WORDS / sizeof (LONGEST) * DEPRECATED_REGISTER_SIZE))
-       && get_frame_pc (frame) <= b->address)
+       && get_frame_pc (frame) <= b->loc->address)
       return 1;
   }
   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->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;
@@ -1943,7 +1992,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.  */
@@ -1968,7 +2016,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);
@@ -1978,14 +2042,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);
 }
@@ -2027,9 +2093,9 @@ print_it_typical (bpstat bs)
     {
     case bp_breakpoint:
     case bp_hardware_breakpoint:
-      if (bs->breakpoint_at->address != bs->breakpoint_at->requested_address)
-       breakpoint_adjustment_warning (bs->breakpoint_at->requested_address,
-                                      bs->breakpoint_at->address,
+      if (bs->breakpoint_at->loc->address != bs->breakpoint_at->loc->requested_address)
+       breakpoint_adjustment_warning (bs->breakpoint_at->loc->requested_address,
+                                      bs->breakpoint_at->loc->address,
                                       bs->breakpoint_at->number, 1);
       annotate_breakpoint (bs->breakpoint_at->number);
       ui_out_text (uiout, "\nBreakpoint ");
@@ -2532,9 +2598,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
@@ -2548,21 +2612,21 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_sw_breakpoint)
        && b->type != bp_catch_catch
        && b->type != bp_catch_throw)   /* a non-watchpoint bp */
       {
-       if (b->address != bp_addr)      /* address doesn't match */
+       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->address != (*pc - DECR_PC_AFTER_HW_BREAK))
+       if (b->loc->address != (*pc - DECR_PC_AFTER_HW_BREAK))
          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;
       }
 
@@ -2799,8 +2863,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;
@@ -3137,7 +3201,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;
 }
@@ -3146,13 +3210,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->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;
 }
@@ -3418,13 +3480,13 @@ print_one_breakpoint (struct breakpoint *b,
        if (addressprint)
          {
            annotate_field (4);
-           ui_out_field_core_addr (uiout, "addr", b->address);
+           ui_out_field_core_addr (uiout, "addr", b->loc->address);
          }
        annotate_field (5);
-       *last_addr = b->address;
+       *last_addr = b->loc->address;
        if (b->source_file)
          {
-           sym = find_pc_sect_function (b->address, b->section);
+           sym = find_pc_sect_function (b->loc->address, b->loc->section);
            if (sym)
              {
                ui_out_text (uiout, "in ");
@@ -3439,7 +3501,7 @@ print_one_breakpoint (struct breakpoint *b,
          }
        else
          {
-           print_address_symbolic (b->address, stb->stream, demangle, "");
+           print_address_symbolic (b->loc->address, stb->stream, demangle, "");
            ui_out_field_stream (uiout, "at", stb);
          }
        break;
@@ -3703,15 +3765,15 @@ describe_other_breakpoints (CORE_ADDR pc, asection *section)
   struct breakpoint *b;
 
   ALL_BREAKPOINTS (b)
-    if (b->address == pc)      /* address match / overlay match */
-      if (!overlay_debugging || b->section == section)
+    if (b->loc->address == pc) /* address match / overlay match */
+      if (!overlay_debugging || b->loc->section == section)
        others++;
   if (others > 0)
     {
       printf_filtered ("Note: breakpoint%s ", (others > 1) ? "s" : "");
       ALL_BREAKPOINTS (b)
-       if (b->address == pc)   /* address match / overlay match */
-         if (!overlay_debugging || b->section == section)
+       if (b->loc->address == pc)      /* address match / overlay match */
+         if (!overlay_debugging || b->loc->section == section)
            {
              others--;
              printf_filtered ("%d%s%s ",
@@ -3788,25 +3850,25 @@ 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;
-  CORE_ADDR address = bpt->address;
-  asection *section = bpt->section;
+  struct bp_location *perm_bp = 0;
+  CORE_ADDR address = bpt->loc->address;
+  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
+  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;
@@ -3829,21 +3891,23 @@ check_duplicates (struct breakpoint *bpt)
                        "allegedly permanent breakpoint is not "
                        "actually inserted");
 
-      ALL_BREAKPOINTS (b)
+      ALL_BP_LOCATIONS (b)
        if (b != perm_bp)
          {
-           if (b->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
+           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->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;
+             }
          }
     }
 }
@@ -3896,6 +3960,71 @@ adjust_breakpoint_address (CORE_ADDR bpaddr)
     }
 }
 
+/* Allocate a struct bp_location.  */
+
+static struct bp_location *
+allocate_bp_location (struct breakpoint *bpt, enum bptype bp_type)
+{
+  struct bp_location *loc, *loc_p;
+
+  loc = xmalloc (sizeof (struct bp_location));
+  memset (loc, 0, sizeof (*loc));
+
+  loc->owner = bpt;
+
+  switch (bp_type)
+    {
+    case bp_breakpoint:
+    case bp_until:
+    case bp_finish:
+    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:
+    case bp_thread_event:
+    case bp_overlay_event:
+    case bp_catch_load:
+    case bp_catch_unload:
+      loc->loc_type = bp_loc_software_breakpoint;
+      break;
+    case bp_hardware_breakpoint:
+      loc->loc_type = bp_loc_hardware_breakpoint;
+      break;
+    case bp_hardware_watchpoint:
+    case bp_read_watchpoint:
+    case bp_access_watchpoint:
+      loc->loc_type = bp_loc_hardware_watchpoint;
+      break;
+    case bp_watchpoint:
+    case bp_catch_fork:
+    case bp_catch_vfork:
+    case bp_catch_exec:
+    case bp_catch_catch:
+    case bp_catch_throw:
+      loc->loc_type = bp_loc_other;
+      break;
+    default:
+      internal_error (__FILE__, __LINE__, "unknown breakpoint type");
+    }
+
+  /* Add this breakpoint to the end of the chain.  */
+
+  loc_p = bp_location_chain;
+  if (loc_p == 0)
+    bp_location_chain = loc;
+  else
+    {
+      while (loc_p->next)
+       loc_p = loc_p->next;
+      loc_p->next = loc;
+    }
+
+  return loc;
+}
+
 /* set_raw_breakpoint() is a low level routine for allocating and
    partially initializing a breakpoint of type BPTYPE.  The newly
    created breakpoint's address, section, source file name, and line
@@ -3918,14 +4047,15 @@ set_raw_breakpoint (struct symtab_and_line sal, enum bptype bptype)
 
   b = (struct breakpoint *) xmalloc (sizeof (struct breakpoint));
   memset (b, 0, sizeof (*b));
-  b->requested_address = sal.pc;
-  b->address = adjust_breakpoint_address (b->requested_address);
+  b->loc = allocate_bp_location (b, bptype);
+  b->loc->requested_address = sal.pc;
+  b->loc->address = adjust_breakpoint_address (b->loc->requested_address);
   if (sal.symtab == NULL)
     b->source_file = NULL;
   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;
@@ -3972,7 +4102,7 @@ make_breakpoint_permanent (struct breakpoint *b)
   b->enable_state = bp_permanent;
 
   /* By definition, permanent breakpoints are already present in the code.  */
-  b->inserted = 1;
+  b->loc->inserted = 1;
 }
 
 static struct breakpoint *
@@ -4005,7 +4135,7 @@ create_longjmp_breakpoint (char *func_name)
     b = create_internal_breakpoint (0, bp_longjmp_resume);
   else
     {
-      if ((m = lookup_minimal_symbol_text (func_name, NULL, NULL)) == NULL)
+      if ((m = lookup_minimal_symbol_text (func_name, NULL)) == NULL)
        return;
  
       b = create_internal_breakpoint (SYMBOL_VALUE_ADDRESS (m), bp_longjmp);
@@ -4054,7 +4184,7 @@ create_overlay_event_breakpoint (char *func_name)
   struct breakpoint *b;
   struct minimal_symbol *m;
 
-  if ((m = lookup_minimal_symbol_text (func_name, NULL, NULL)) == NULL)
+  if ((m = lookup_minimal_symbol_text (func_name, NULL)) == NULL)
     return;
  
   b = create_internal_breakpoint (SYMBOL_VALUE_ADDRESS (m), 
@@ -4110,7 +4240,7 @@ create_thread_event_breakpoint (CORE_ADDR address)
   
   b->enable_state = bp_enabled;
   /* addr_string has to be used or breakpoint_re_set will delete me.  */
-  xasprintf (&b->addr_string, "*0x%s", paddr (b->address));
+  xasprintf (&b->addr_string, "*0x%s", paddr (b->loc->address));
 
   return b;
 }
@@ -4160,9 +4290,9 @@ 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 &&
-       !b->duplicate &&
-       PC_SOLIB (b->address))
+       breakpoint_enabled (b) &&
+       !b->loc->duplicate &&
+       PC_SOLIB (b->loc->address))
       {
        b->enable_state = bp_shlib_disabled;
        if (!silent)
@@ -4189,11 +4319,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->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;
     }
 }
@@ -4214,7 +4345,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)
@@ -4382,14 +4513,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;
       }
   }
@@ -4410,8 +4540,8 @@ set_longjmp_resume_breakpoint (CORE_ADDR pc, struct frame_id frame_id)
   ALL_BREAKPOINTS (b)
     if (b->type == bp_longjmp_resume)
     {
-      b->requested_address = pc;
-      b->address = adjust_breakpoint_address (b->requested_address);
+      b->loc->requested_address = pc;
+      b->loc->address = adjust_breakpoint_address (b->loc->requested_address);
       b->enable_state = bp_enabled;
       b->frame_id = frame_id;
       check_duplicates (b);
@@ -4431,7 +4561,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);
@@ -4611,7 +4741,7 @@ mention (struct breakpoint *b)
       if (addressprint || b->source_file == NULL)
        {
          printf_filtered (" at ");
-         print_address_numeric (b->address, 1, gdb_stdout);
+         print_address_numeric (b->loc->address, 1, gdb_stdout);
        }
       if (b->source_file)
        printf_filtered (": file %s, line %d.",
@@ -4673,7 +4803,7 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
        else
          /* addr_string has to be used or breakpoint_re_set will delete
             me.  */
-         xasprintf (&b->addr_string, "*0x%s", paddr (b->address));
+         xasprintf (&b->addr_string, "*0x%s", paddr (b->loc->address));
        b->cond_string = cond_string[i];
        b->ignore_count = ignore_count;
        b->enable_state = bp_enabled;
@@ -4732,9 +4862,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)
@@ -5180,7 +5310,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);
@@ -5526,9 +5656,10 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
          scope_breakpoint->frame_id = get_frame_id (prev_frame);
 
          /* Set the address at which we will stop.  */
-         scope_breakpoint->requested_address = get_frame_pc (prev_frame);
-         scope_breakpoint->address =
-           adjust_breakpoint_address (scope_breakpoint->requested_address);
+         scope_breakpoint->loc->requested_address
+           = get_frame_pc (prev_frame);
+         scope_breakpoint->loc->address
+           = adjust_breakpoint_address (scope_breakpoint->loc->requested_address);
 
          /* The scope breakpoint is related to the watchpoint.  We
             will need to act on them together.  */
@@ -5696,10 +5827,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.");
@@ -6120,10 +6251,10 @@ print_one_exception_catchpoint (struct breakpoint *b, CORE_ADDR *last_addr)
   if (addressprint)
     {
       annotate_field (4);
-      ui_out_field_core_addr (uiout, "addr", b->address);
+      ui_out_field_core_addr (uiout, "addr", b->loc->address);
     }
   annotate_field (5);
-  *last_addr = b->address;
+  *last_addr = b->loc->address;
   if (strstr (b->addr_string, "throw") != NULL)
     ui_out_field_string (uiout, "what", "exception throw");
   else
@@ -6159,7 +6290,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);
@@ -6479,14 +6610,14 @@ clear_command (char *arg, int from_tty)
              && b->type != bp_read_watchpoint
              && b->type != bp_access_watchpoint
              /* Not if b is a watchpoint of any sort... */
-             && (((sal.pc && (b->address == sal.pc)) 
-                  && (!section_is_overlay (b->section)
-                      || b->section == sal.section))
+             && (((sal.pc && (b->loc->address == sal.pc)) 
+                  && (!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.  */
            {
@@ -6566,6 +6697,7 @@ delete_breakpoint (struct breakpoint *bpt)
 {
   struct breakpoint *b;
   bpstat bs;
+  struct bp_location *loc;
 
   if (bpt == NULL)
     error ("Internal error (attempted to delete a NULL breakpoint)");
@@ -6591,12 +6723,15 @@ delete_breakpoint (struct breakpoint *bpt)
     delete_breakpoint_hook (bpt);
   breakpoint_delete_event (bpt->number);
 
-  if (bpt->inserted)
-    remove_breakpoint (bpt, mark_inserted);
+  if (bpt->loc->inserted)
+    remove_breakpoint (bpt->loc, mark_inserted);
 
   if (breakpoint_chain == bpt)
     breakpoint_chain = bpt->next;
 
+  if (bp_location_chain == bpt->loc)
+    bp_location_chain = bpt->loc->next;
+
   /* If we have callback-style exception catchpoints, don't go through
      the adjustments to the C++ runtime library etc. if the inferior
      isn't actually running.  target_enable_exception_callback for a
@@ -6626,10 +6761,17 @@ delete_breakpoint (struct breakpoint *bpt)
       break;
     }
 
+  ALL_BP_LOCATIONS (loc)
+    if (loc->next == bpt->loc)
+      {
+       loc->next = bpt->loc->next;
+       break;
+      }
+
   check_duplicates (bpt);
   /* If this breakpoint was inserted, and there is another breakpoint
      at the same address, we need to insert the other breakpoint.  */
-  if (bpt->inserted
+  if (bpt->loc->inserted
       && bpt->type != bp_hardware_watchpoint
       && bpt->type != bp_read_watchpoint
       && bpt->type != bp_access_watchpoint
@@ -6638,9 +6780,9 @@ delete_breakpoint (struct breakpoint *bpt)
       && bpt->type != bp_catch_exec)
     {
       ALL_BREAKPOINTS (b)
-       if (b->address == bpt->address
-           && b->section == bpt->section
-           && !b->duplicate
+       if (b->loc->address == bpt->loc->address
+           && b->loc->section == bpt->loc->section
+           && !b->loc->duplicate
            && b->enable_state != bp_disabled
            && b->enable_state != bp_shlib_disabled
            && b->enable_state != bp_call_disabled)
@@ -6657,9 +6799,9 @@ delete_breakpoint (struct breakpoint *bpt)
                            "a permanent breakpoint");
 
          if (b->type == bp_hardware_breakpoint)
-           val = target_insert_hw_breakpoint (b->address, b->shadow_contents);
+           val = target_insert_hw_breakpoint (b->loc->address, b->loc->shadow_contents);
          else
-           val = target_insert_breakpoint (b->address, b->shadow_contents);
+           val = target_insert_breakpoint (b->loc->address, b->loc->shadow_contents);
 
          /* If there was an error in the insert, print a message, then stop execution.  */
          if (val != 0)
@@ -6679,7 +6821,7 @@ delete_breakpoint (struct breakpoint *bpt)
                  {
                    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->address, 1, tmp_error_stream);
+                   print_address_numeric (b->loc->address, 1, tmp_error_stream);
                    fprintf_filtered (tmp_error_stream, ": %s.\n",
                                      safe_strerror (val));
                  }
@@ -6689,7 +6831,7 @@ delete_breakpoint (struct breakpoint *bpt)
              error_stream(tmp_error_stream); 
            }
          else
-           b->inserted = 1;
+           b->loc->inserted = 1;
        }
     }
 
@@ -6729,6 +6871,7 @@ delete_breakpoint (struct breakpoint *bpt)
      bp, we mark it as deleted before freeing its storage. */
   bpt->type = bp_none;
 
+  xfree (bpt->loc);
   xfree (bpt);
 }
 
@@ -6854,7 +6997,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]);
@@ -6870,12 +7013,12 @@ breakpoint_re_set_one (void *bint)
            }
 
          /* We need to re-set the breakpoint if the address changes... */
-         if (b->address != sals.sals[i].pc
+         if (b->loc->address != sals.sals[i].pc
          /* ...or new and old breakpoints both have source files, and
             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
@@ -6892,8 +7035,9 @@ breakpoint_re_set_one (void *bint)
                  savestring (sals.sals[i].symtab->filename,
                              strlen (sals.sals[i].symtab->filename));
              b->line_number = sals.sals[i].line;
-             b->requested_address = sals.sals[i].pc;
-             b->address = adjust_breakpoint_address (b->requested_address);
+             b->loc->requested_address = sals.sals[i].pc;
+             b->loc->address
+               = adjust_breakpoint_address (b->loc->requested_address);
 
              /* Used to check for duplicates here, but that can
                 cause trouble, as it doesn't check for disabled
@@ -6905,7 +7049,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. */
 
 
@@ -6940,7 +7084,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)
@@ -6950,7 +7094,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;
@@ -7389,10 +7533,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.051934 seconds and 4 git commands to generate.