* solib-sunos.c (sunos_relocate_main_executable): Remove function.
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 35d9fa943967e6d36f17fb3d6ef2e6ff05d924c3..dae098d3f21ff1264525149540c14836f213278a 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.
 
@@ -49,6 +49,8 @@
 #include "cli/cli-script.h"
 #include "gdb_assert.h"
 #include "block.h"
+#include "solist.h"
+#include "observer.h"
 
 #include "gdb-events.h"
 
@@ -89,7 +91,7 @@ extern void break_at_finish_at_depth_command (char *, int);
 
 extern void tbreak_at_finish_command (char *, int);
 
-static void break_command_1 (char *, int, int);
+static int break_command_1 (char *, int, int, struct breakpoint *);
 
 static void mention (struct breakpoint *);
 
@@ -99,7 +101,8 @@ static void check_duplicates (struct breakpoint *);
 
 static void breakpoint_adjustment_warning (CORE_ADDR, CORE_ADDR, int, int);
 
-static CORE_ADDR adjust_breakpoint_address (CORE_ADDR bpaddr);
+static CORE_ADDR adjust_breakpoint_address (CORE_ADDR bpaddr,
+                                            enum bptype bptype);
 
 static void describe_other_breakpoints (CORE_ADDR, asection *);
 
@@ -119,6 +122,8 @@ static void condition_command (char *, int);
 
 static int get_number_trailer (char **, int);
 
+static int do_captured_parse_breakpoint (struct ui_out *, void *);
+
 void set_breakpoint_count (int);
 
 typedef enum
@@ -128,7 +133,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);
 
@@ -193,10 +198,6 @@ static char *ep_parse_optional_if_clause (char **arg);
 
 static char *ep_parse_optional_filename (char **arg);
 
-#if defined(CHILD_INSERT_EXEC_CATCHPOINT)
-static void catch_exec_command_1 (char *arg, int tempflag, int from_tty);
-#endif
-
 static void create_exception_catchpoint (int tempflag, char *cond_string,
                                         enum exception_event_kind ex_event,
                                         struct symtab_and_line *sal);
@@ -214,6 +215,12 @@ static void ep_skip_leading_whitespace (char **s);
    if such is available. */
 static int can_use_hw_watchpoints;
 
+/* If AUTO_BOOLEAN_FALSE, gdb will not attempt to create pending breakpoints.
+   If AUTO_BOOLEAN_TRUE, gdb will automatically create pending breakpoints
+   for unrecognized breakpoint locations.  
+   If AUTO_BOOLEAN_AUTO, gdb will query when breakpoints are unrecognized.  */
+static enum auto_boolean pending_break_support;
+
 void _initialize_breakpoint (void);
 
 extern int addressprint;       /* Print machine addresses? */
@@ -244,16 +251,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;
@@ -271,13 +268,13 @@ int breakpoint_count;
 /* Pointer to current exception event record */
 static struct exception_event_record *current_exception_event;
 
-/* Indicator of whether exception catchpoints should be nuked
-   between runs of a program */
-int exception_catchpoints_are_fragile = 0;
+/* Indicator of whether exception catchpoints should be nuked between
+   runs of a program.  */
+int deprecated_exception_catchpoints_are_fragile = 0;
 
 /* Indicator of when exception catchpoints set-up should be
-   reinitialized -- e.g. when program is re-run */
-int exception_support_initialized = 0;
+   reinitialized -- e.g. when program is re-run */
+int deprecated_exception_support_initialized = 0;
 
 /* This function returns a pointer to the string representation of the
    pathname of the dynamically-linked library that has just been
@@ -332,6 +329,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 && !b->pending);
+}
+
 /* Set breakpoint count to NUM.  */
 
 void
@@ -563,9 +567,12 @@ 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->loc->address), 0);
-         if (*arg)
-           error ("Junk at end of expression");
+         if (!b->pending)
+           {
+             b->cond = parse_exp_1 (&arg, block_for_pc (b->loc->address), 0);
+             if (*arg)
+               error ("Junk at end of expression");
+           }
        }
       breakpoints_changed ();
       breakpoint_modify_event (b->number);
@@ -622,7 +629,7 @@ commands_command (char *arg, int from_tty)
    shadow contents, not the breakpoints themselves.  From breakpoint.c.  */
 
 int
-read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len)
+deprecated_read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len)
 {
   int status;
   struct bp_location *b;
@@ -690,7 +697,7 @@ read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len)
       if (bp_addr > memaddr)
        {
          /* Copy the section of memory before the breakpoint.  */
-         status = read_memory_nobpt (memaddr, myaddr, bp_addr - memaddr);
+         status = deprecated_read_memory_nobpt (memaddr, myaddr, bp_addr - memaddr);
          if (status != 0)
            return status;
        }
@@ -698,7 +705,7 @@ read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len)
       if (bp_addr + bp_size < memaddr + len)
        {
          /* Copy the section of memory after the breakpoint.  */
-         status = read_memory_nobpt (bp_addr + bp_size,
+         status = deprecated_read_memory_nobpt (bp_addr + bp_size,
                                      myaddr + bp_addr + bp_size - memaddr,
                                      memaddr + len - (bp_addr + bp_size));
          if (status != 0)
@@ -741,23 +748,40 @@ insert_catchpoint (struct ui_out *uo, void *args)
   return 0;
 }
 
+/* Helper routine: free the value chain for a breakpoint (watchpoint).  */
+
+static void free_valchain (struct bp_location *b)
+{
+  struct value *v;
+  struct value *n;
+
+  /* Free the saved value chain.  We will construct a new one
+     the next time the watchpoint is inserted.  */
+  for (v = b->owner->val_chain; v; v = n)
+    {
+      n = v->next;
+      value_free (v);
+    }
+  b->owner->val_chain = NULL;
+}
+
 /* 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.
 
    NOTE drow/2003-09-09: This routine could be broken down to an object-style
    method for each breakpoint or catchpoint type.  */
-int
+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 ui_file *tmp_error_stream,
+                   int *disabled_breaks, int *process_warning,
+                   int *hw_breakpoint_error)
 {
   int val = 0;
 
   /* Permanent breakpoints cannot be inserted or removed.  Disabled
      breakpoints should not be inserted.  */
-  if (bpt->owner->enable_state != bp_enabled)
+  if (!breakpoint_enabled (bpt->owner))
     return 0;
 
   if (bpt->inserted || bpt->duplicate)
@@ -888,18 +912,17 @@ insert_bp_location (struct bp_location *bpt,
         must watch.  As soon as a many-to-one mapping is available I'll
         convert this.  */
 
-      struct frame_info *saved_frame;
-      int saved_level, within_current_scope;
+      int within_current_scope;
       struct value *mark = value_mark ();
       struct value *v;
+      struct frame_id saved_frame_id;
 
-      /* Save the current frame and level so we can restore it after
+      /* Save the current frame's ID 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);
+      saved_frame_id = get_frame_id (deprecated_selected_frame);
 
       /* Determine if the watchpoint is within scope.  */
       if (bpt->owner->exp_valid_block == NULL)
@@ -915,6 +938,8 @@ insert_bp_location (struct bp_location *bpt,
 
       if (within_current_scope)
        {
+         free_valchain (bpt);
+
          /* Evaluate the expression and cut the chain of values
             produced off from the value chain.
 
@@ -976,7 +1001,7 @@ insert_bp_location (struct bp_location *bpt,
             value chain brings us here.  */
          if (!bpt->inserted)
            {
-             remove_breakpoint (bpt->owner, mark_uninserted);
+             remove_breakpoint (bpt, mark_uninserted);
              *hw_breakpoint_error = 1;
              fprintf_unfiltered (tmp_error_stream,
                                  "Could not insert hardware watchpoint %d.\n", 
@@ -994,10 +1019,8 @@ insert_bp_location (struct bp_location *bpt,
          bpt->owner->disposition = disp_del_at_next_stop;
        }
 
-      /* Restore the frame and level.  */
-      if (saved_frame != deprecated_selected_frame
-         || saved_level != frame_relative_level (deprecated_selected_frame))
-       select_frame (saved_frame);
+      /* Restore the selected frame.  */
+      select_frame (frame_find_by_id (saved_frame_id));
 
       return val;
     }
@@ -1071,7 +1094,11 @@ insert_bp_location (struct bp_location *bpt,
        bpt->owner->enable_state = bp_disabled;
       else
        bpt->inserted = 1;
-      return val;
+
+      /* 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;
@@ -1103,7 +1130,7 @@ insert_breakpoints (void)
     {
       /* Permanent breakpoints cannot be inserted or removed.  Disabled
         breakpoints should not be inserted.  */
-      if (b->owner->enable_state != bp_enabled)
+      if (!breakpoint_enabled (b->owner))
        continue;
 
       /* FIXME drow/2003-10-07: This code should be pushed elsewhere when
@@ -1150,12 +1177,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)
@@ -1168,15 +1195,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)
@@ -1189,21 +1213,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);
@@ -1352,7 +1378,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 ();
 
@@ -1361,9 +1387,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)
@@ -1378,27 +1404,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
@@ -1406,16 +1425,16 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
 
       /* First check to see if we have to handle an overlay.  */
       if (overlay_debugging == ovly_off
-         || b->loc->section == NULL
-         || !(section_is_overlay (b->loc->section)))
+         || b->section == NULL
+         || !(section_is_overlay (b->section)))
        {
          /* 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
        {
@@ -1426,29 +1445,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, 
-                                                          b->loc->section);
+               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
            {
@@ -1458,20 +1477,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.  */
@@ -1480,7 +1497,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))
                {
@@ -1490,40 +1507,31 @@ 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);
-
-      /* 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)
-       {
-         n = v->next;
-         value_free (v);
-       }
-      b->val_chain = NULL;
+                b->owner->number);
     }
-  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));
@@ -1540,30 +1548,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;
@@ -1637,8 +1645,8 @@ breakpoint_init_inferior (enum inf_context context)
       default:
        /* Likewise for exception catchpoints in dynamic-linked
           executables where required */
-       if (ep_is_exception_catchpoint (b) &&
-           exception_catchpoints_are_fragile)
+       if (ep_is_exception_catchpoint (b)
+           && deprecated_exception_catchpoints_are_fragile)
          {
            warning_needed = 1;
            delete_breakpoint (b);
@@ -1647,8 +1655,8 @@ breakpoint_init_inferior (enum inf_context context)
       }
   }
 
-  if (exception_catchpoints_are_fragile)
-    exception_support_initialized = 0;
+  if (deprecated_exception_catchpoints_are_fragile)
+    deprecated_exception_support_initialized = 0;
 
   /* Don't issue the warning unless it's really needed... */
   if (warning_needed && (context != inf_exited))
@@ -1681,7 +1689,7 @@ breakpoint_here_p (CORE_ADDR pc)
          && bpt->loc_type != bp_loc_hardware_breakpoint)
        continue;
 
-      if ((bpt->owner->enable_state == bp_enabled
+      if ((breakpoint_enabled (bpt->owner)
           || bpt->owner->enable_state == bp_permanent)
          && bpt->address == pc)        /* bp is enabled and matches pc */
        {
@@ -1730,34 +1738,34 @@ breakpoint_inserted_here_p (CORE_ADDR pc)
   return 0;
 }
 
-/* Return nonzero if FRAME is a dummy frame.  We can't use
-   DEPRECATED_PC_IN_CALL_DUMMY because figuring out the saved SP would
-   take too much time, at least using frame_register() on the 68k.
-   This means that for this function to work right a port must use the
-   bp_call_dummy breakpoint.  */
+/* This function returns non-zero iff there is a software breakpoint
+   inserted at PC.  */
 
 int
-deprecated_frame_in_dummy (struct frame_info *frame)
+software_breakpoint_inserted_here_p (CORE_ADDR pc)
 {
-  struct breakpoint *b;
+  struct bp_location *bpt;
+  int any_breakpoint_here = 0;
 
-  /* This function is used by two files: get_frame_type(), after first
-     checking that !DEPRECATED_USE_GENERIC_DUMMY_FRAMES; and
-     sparc-tdep.c, which doesn't yet use generic dummy frames anyway.  */
-  gdb_assert (!DEPRECATED_USE_GENERIC_DUMMY_FRAMES);
+  ALL_BP_LOCATIONS (bpt)
+    {
+      if (bpt->loc_type != bp_loc_software_breakpoint)
+       continue;
+
+      if ((breakpoint_enabled (bpt->owner)
+          || bpt->owner->enable_state == bp_permanent)
+         && bpt->inserted
+         && 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
+           return 1;
+       }
+    }
 
-  ALL_BREAKPOINTS (b)
-  {
-    if (b->type == bp_call_dummy
-       && frame_id_eq (b->frame_id, get_frame_id (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->loc->address
-               - DEPRECATED_SIZEOF_CALL_DUMMY_WORDS / sizeof (LONGEST) * DEPRECATED_REGISTER_SIZE))
-       && get_frame_pc (frame) <= b->loc->address)
-      return 1;
-  }
   return 0;
 }
 
@@ -1778,7 +1786,7 @@ breakpoint_thread_match (CORE_ADDR pc, ptid_t ptid)
          && bpt->loc_type != bp_loc_hardware_breakpoint)
        continue;
 
-      if ((bpt->owner->enable_state == bp_enabled
+      if ((breakpoint_enabled (bpt->owner)
           || bpt->owner->enable_state == bp_permanent)
          && bpt->address == pc
          && (bpt->owner->thread == -1 || bpt->owner->thread == thread))
@@ -1991,7 +1999,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.  */
@@ -2016,7 +2023,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);
@@ -2026,14 +2049,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);
 }
@@ -2447,9 +2472,6 @@ watchpoint_check (void *p)
   struct breakpoint *b;
   struct frame_info *fr;
   int within_current_scope;
-#if 0
-  struct frame_id current_frame_id;
-#endif
 
   b = bs->breakpoint_at;
 
@@ -2538,11 +2560,10 @@ which its expression is valid.\n");
     }
 }
 
-/* Get a bpstat associated with having just stopped at address *PC
-   and frame address CORE_ADDRESS.  Update *PC to point at the
-   breakpoint (if we hit a breakpoint).  NOT_A_SW_BREAKPOINT is nonzero
-   if this is known to not be a real breakpoint (it could still be a
-   watchpoint, though).  */
+/* Get a bpstat associated with having just stopped at address
+   BP_ADDR in thread PTID.  STOPPED_BY_WATCHPOINT is 1 if the
+   target thinks we stopped due to a hardware watchpoint, 0 if we
+   know we did not trigger a hardware watchpoint, and -1 if we do not know.  */
 
 /* Determine whether we stopped at a breakpoint, etc, or whether we
    don't understand this stop.  Result is a chain of bpstat's such that:
@@ -2559,30 +2580,20 @@ which its expression is valid.\n");
    commands, FIXME??? fields.  */
 
 bpstat
-bpstat_stop_status (CORE_ADDR *pc, int not_a_sw_breakpoint)
+bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid, int stopped_by_watchpoint)
 {
   struct breakpoint *b, *temp;
-  CORE_ADDR bp_addr;
   /* True if we've hit a breakpoint (as opposed to a watchpoint).  */
   int real_breakpoint = 0;
   /* Root of the chain of bpstat's */
   struct bpstats root_bs[1];
   /* Pointer to the last thing in the chain currently.  */
   bpstat bs = root_bs;
-
-  /* Get the address where the breakpoint would have been.  The
-     "not_a_sw_breakpoint" argument is meant to distinguish between a
-     breakpoint trap event and a trace/singlestep trap event.  For a
-     trace/singlestep trap event, we would not want to subtract
-     DECR_PC_AFTER_BREAK from the PC. */
-
-  bp_addr = *pc - (not_a_sw_breakpoint ? 0 : DECR_PC_AFTER_BREAK);
+  int thread_id = pid_to_thread_id (ptid);
 
   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
@@ -2604,9 +2615,21 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_sw_breakpoint)
          continue;
       }
 
+    /* Continuable hardware watchpoints are treated as non-existent if the 
+       reason we stopped wasn't a hardware watchpoint (we didn't stop on 
+       some data address).  Otherwise gdb won't stop on a break instruction 
+       in the code (not from a breakpoint) when a hardware watchpoint has 
+       been defined.  */
+
+    if ((b->type == bp_hardware_watchpoint
+        || b->type == bp_read_watchpoint
+        || b->type == bp_access_watchpoint)
+       && !stopped_by_watchpoint)
+      continue;
+
     if (b->type == bp_hardware_breakpoint)
       {
-       if (b->loc->address != (*pc - DECR_PC_AFTER_HW_BREAK))
+       if (b->loc->address != bp_addr)
          continue;
        if (overlay_debugging           /* unmapped overlay section */
            && section_is_overlay (b->loc->section) 
@@ -2832,6 +2855,12 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_sw_breakpoint)
            /* Don't consider this a hit.  */
            --(b->hit_count);
          }
+       else if (b->thread != -1 && b->thread != thread_id)
+         {
+           bs->stop = 0;
+           /* Don't consider this a hit.  */
+           --(b->hit_count);
+         }
        else if (b->ignore_count > 0)
          {
            b->ignore_count--;
@@ -2847,8 +2876,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;
@@ -2864,30 +2893,6 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_sw_breakpoint)
   bs->next = NULL;             /* Terminate the chain */
   bs = root_bs->next;          /* Re-grab the head of the chain */
 
-  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 (DECR_PC_AFTER_BREAK != 0 || must_shift_inst_regs)
-           {
-             *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.  */
-           }
-       }
-    }
-
   /* The value of a hardware watchpoint hasn't changed, but the
      intermediate memory locations we are watching may have.  */
   if (bs && !bs->stop &&
@@ -3004,7 +3009,7 @@ bpstat_what (bpstat bs)
 
   /* step_resume entries: a step resume breakpoint overrides another
      breakpoint of signal handling (see comment in wait_for_inferior
-     at first PC_IN_SIGTRAMP where we set the step_resume breakpoint).  */
+     at where we set the step_resume breakpoint).  */
   /* We handle the through_sigtramp_breakpoint the same way; having both
      one of those and a step_resume_breakpoint is probably very rare (?).  */
 
@@ -3185,7 +3190,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;
 }
@@ -3196,7 +3201,7 @@ bpstat_have_active_hw_watchpoints (void)
 {
   struct bp_location *bpt;
   ALL_BP_LOCATIONS (bpt)
-    if ((bpt->owner->enable_state == bp_enabled)
+    if (breakpoint_enabled (bpt->owner)
        && bpt->inserted
        && bpt->loc_type == bp_loc_hardware_watchpoint)
       return 1;
@@ -3464,7 +3469,10 @@ print_one_breakpoint (struct breakpoint *b,
        if (addressprint)
          {
            annotate_field (4);
-           ui_out_field_core_addr (uiout, "addr", b->loc->address);
+           if (b->pending)
+             ui_out_field_string (uiout, "addr", "<PENDING>");
+           else
+             ui_out_field_core_addr (uiout, "addr", b->loc->address);
          }
        annotate_field (5);
        *last_addr = b->loc->address;
@@ -3483,6 +3491,10 @@ print_one_breakpoint (struct breakpoint *b,
            ui_out_text (uiout, ":");
            ui_out_field_int (uiout, "line", b->line_number);
          }
+       else if (b->pending)
+         {
+           ui_out_field_string (uiout, "pending", b->addr_string);
+         }
        else
          {
            print_address_symbolic (b->loc->address, stb->stream, demangle, "");
@@ -3519,7 +3531,15 @@ print_one_breakpoint (struct breakpoint *b,
       ui_out_field_stream (uiout, "cond", stb);
       ui_out_text (uiout, "\n");
     }
-  
+
+  if (b->pending && b->cond_string)
+    {
+      annotate_field (7);
+      ui_out_text (uiout, "\tstop only if ");
+      ui_out_field_string (uiout, "cond", b->cond_string);
+      ui_out_text (uiout, "\n");
+    }
+
   if (b->thread != -1)
     {
       /* FIXME should make an annotation for this */
@@ -3750,14 +3770,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->loc->section == section)
+      if (!b->pending && (!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->loc->section == section)
+         if (!b->pending && (!overlay_debugging || b->loc->section == section))
            {
              others--;
              printf_filtered ("%d%s%s ",
@@ -3846,6 +3866,7 @@ check_duplicates (struct breakpoint *bpt)
   ALL_BP_LOCATIONS (b)
     if (b->owner->enable_state != bp_disabled
        && b->owner->enable_state != bp_shlib_disabled
+       && !b->owner->pending
        && b->owner->enable_state != bp_call_disabled
        && b->address == address        /* address / overlay match */
        && (!overlay_debugging || b->section == section)
@@ -3880,6 +3901,7 @@ check_duplicates (struct breakpoint *bpt)
          {
            if (b->owner->enable_state != bp_disabled
                && b->owner->enable_state != bp_shlib_disabled
+               && !b->owner->pending
                && b->owner->enable_state != bp_call_disabled
                && b->address == address        /* address / overlay match */
                && (!overlay_debugging || b->section == section)
@@ -3918,13 +3940,25 @@ breakpoint_adjustment_warning (CORE_ADDR from_addr, CORE_ADDR to_addr,
    this function is simply the identity function.  */
 
 static CORE_ADDR
-adjust_breakpoint_address (CORE_ADDR bpaddr)
+adjust_breakpoint_address (CORE_ADDR bpaddr, enum bptype bptype)
 {
   if (!gdbarch_adjust_breakpoint_address_p (current_gdbarch))
     {
       /* Very few targets need any kind of breakpoint adjustment.  */
       return bpaddr;
     }
+  else if (bptype == bp_watchpoint
+           || bptype == bp_hardware_watchpoint
+           || bptype == bp_read_watchpoint
+           || bptype == bp_access_watchpoint
+           || bptype == bp_catch_fork
+           || bptype == bp_catch_vfork
+           || bptype == bp_catch_exec)
+    {
+      /* Watchpoints and the various bp_catch_* eventpoints should not
+         have their addresses modified.  */
+      return bpaddr;
+    }
   else
     {
       CORE_ADDR adjusted_bpaddr;
@@ -3946,7 +3980,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;
@@ -4033,7 +4067,8 @@ set_raw_breakpoint (struct symtab_and_line sal, enum bptype bptype)
   memset (b, 0, sizeof (*b));
   b->loc = allocate_bp_location (b, bptype);
   b->loc->requested_address = sal.pc;
-  b->loc->address = adjust_breakpoint_address (b->loc->requested_address);
+  b->loc->address = adjust_breakpoint_address (b->loc->requested_address,
+                                               bptype);
   if (sal.symtab == NULL)
     b->source_file = NULL;
   else
@@ -4056,6 +4091,7 @@ set_raw_breakpoint (struct symtab_and_line sal, enum bptype bptype)
   b->forked_inferior_pid = 0;
   b->exec_pathname = NULL;
   b->ops = NULL;
+  b->pending = 0;
 
   /* Add this breakpoint to the end of the chain
      so that a list of breakpoints will come out in order
@@ -4224,7 +4260,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->loc->address));
+  b->addr_string = xstrprintf ("*0x%s", paddr (b->loc->address));
 
   return b;
 }
@@ -4239,6 +4275,66 @@ remove_thread_event_breakpoints (void)
       delete_breakpoint (b);
 }
 
+struct captured_parse_breakpoint_args
+  {
+    char **arg_p;
+    struct symtabs_and_lines *sals_p;
+    char ***addr_string_p;
+    int *not_found_ptr;
+  };
+
+struct lang_and_radix
+  {
+    enum language lang;
+    int radix;
+  };
+
+/* Cleanup helper routine to restore the current language and
+   input radix.  */
+static void
+do_restore_lang_radix_cleanup (void *old)
+{
+  struct lang_and_radix *p = old;
+  set_language (p->lang);
+  input_radix = p->radix;
+}
+
+/* Try and resolve a pending breakpoint.  */
+static int
+resolve_pending_breakpoint (struct breakpoint *b)
+{
+  /* Try and reparse the breakpoint in case the shared library
+     is now loaded.  */
+  struct symtabs_and_lines sals;
+  struct symtab_and_line pending_sal;
+  char **cond_string = (char **) NULL;
+  char *copy_arg = b->addr_string;
+  char **addr_string;
+  char *errmsg;
+  int rc;
+  int not_found = 0;
+  struct ui_file *old_gdb_stderr;
+  struct lang_and_radix old_lr;
+  struct cleanup *old_chain;
+  
+  /* Set language, input-radix, then reissue breakpoint command. 
+     Ensure the language and input-radix are restored afterwards.  */
+  old_lr.lang = current_language->la_language;
+  old_lr.radix = input_radix;
+  old_chain = make_cleanup (do_restore_lang_radix_cleanup, &old_lr);
+  
+  set_language (b->language);
+  input_radix = b->input_radix;
+  rc = break_command_1 (b->addr_string, b->flag, b->from_tty, b);
+  
+  if (rc == GDB_RC_OK)
+    /* Pending breakpoint has been resolved.  */
+    printf_filtered ("Pending breakpoint \"%s\" resolved\n", b->addr_string);
+
+  do_cleanups (old_chain);
+  return rc;
+}
+
 #ifdef SOLIB_ADD
 void
 remove_solib_event_breakpoints (void)
@@ -4274,7 +4370,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))
       {
@@ -4294,22 +4390,70 @@ disable_breakpoints_in_shlibs (int silent)
   }
 }
 
-/* Try to reenable any breakpoints in shared libraries.  */
+/* Disable any breakpoints that are in in an unloaded shared library.  Only
+   apply to enabled breakpoints, disabled ones can just stay disabled.  */
+
 void
-re_enable_breakpoints_in_shlibs (void)
+disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
 {
   struct breakpoint *b;
+  int disabled_shlib_breaks = 0;
 
+#if defined (PC_SOLIB)
+  /* See also: insert_breakpoints, under DISABLE_UNSETTABLE_BREAK.  */
   ALL_BREAKPOINTS (b)
-    if (b->enable_state == bp_shlib_disabled)
-    {
-      char buf[1];
+  {
+    if ((b->loc->loc_type == bp_loc_hardware_breakpoint
+       || b->loc->loc_type == bp_loc_software_breakpoint)
+       && breakpoint_enabled (b) 
+       && !b->loc->duplicate)
+      {
+       char *so_name = PC_SOLIB (b->loc->address);
+       if (so_name 
+           && !strcmp (so_name, solib->so_name))
+          {
+           b->enable_state = bp_shlib_disabled;
+           /* At this point, we cannot rely on remove_breakpoint
+              succeeding so we must mark the breakpoint as not inserted
+              to prevent future errors occurring in remove_breakpoints.  */
+           b->loc->inserted = 0;
+           if (!disabled_shlib_breaks)
+             {
+               target_terminal_ours_for_output ();
+               warning ("Temporarily disabling breakpoints for unloaded shared library \"%s\"",
+                         so_name);
+             }
+           disabled_shlib_breaks = 1;
+         }
+      }
+  }
+#endif
+}
 
-      /* Do not reenable the breakpoint if the shared library
-         is still not mapped in.  */
-      if (target_read_memory (b->loc->address, buf, 1) == 0)
-       b->enable_state = bp_enabled;
-    }
+/* Try to reenable any breakpoints in shared libraries.  */
+void
+re_enable_breakpoints_in_shlibs (void)
+{
+  struct breakpoint *b, *tmp;
+
+  ALL_BREAKPOINTS_SAFE (b, tmp)
+  {
+    if (b->enable_state == bp_shlib_disabled)
+      {
+       char buf[1], *lib;
+       
+       /* Do not reenable the breakpoint if the shared library
+          is still not mapped in.  */
+       lib = PC_SOLIB (b->loc->address);
+       if (lib != NULL && target_read_memory (b->loc->address, buf, 1) == 0)
+         b->enable_state = bp_enabled;
+      }
+    else if (b->pending && (b->enable_state == bp_enabled))
+      {
+       if (resolve_pending_breakpoint (b) == GDB_RC_OK)
+         delete_breakpoint (b);
+      }
+  }
 }
 
 #endif
@@ -4328,7 +4472,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)
@@ -4496,14 +4640,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;
       }
   }
@@ -4525,7 +4668,8 @@ set_longjmp_resume_breakpoint (CORE_ADDR pc, struct frame_id frame_id)
     if (b->type == bp_longjmp_resume)
     {
       b->loc->requested_address = pc;
-      b->loc->address = adjust_breakpoint_address (b->loc->requested_address);
+      b->loc->address = adjust_breakpoint_address (b->loc->requested_address,
+                                                   b->type);
       b->enable_state = bp_enabled;
       b->frame_id = frame_id;
       check_duplicates (b);
@@ -4545,7 +4689,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);
@@ -4610,13 +4754,13 @@ mention (struct breakpoint *b)
   stb = ui_out_stream_new (uiout);
   old_chain = make_cleanup_ui_out_stream_delete (stb);
 
-  /* FIXME: This is misplaced; mention() is called by things (like hitting a
-     watchpoint) other than breakpoint creation.  It should be possible to
-     clean this up and at the same time replace the random calls to
-     breakpoint_changed with this hook, as has already been done for
-     delete_breakpoint_hook and so on.  */
-  if (create_breakpoint_hook)
-    create_breakpoint_hook (b);
+  /* FIXME: This is misplaced; mention() is called by things (like
+     hitting a watchpoint) other than breakpoint creation.  It should
+     be possible to clean this up and at the same time replace the
+     random calls to breakpoint_changed with this hook, as has already
+     been done for deprecated_delete_breakpoint_hook and so on.  */
+  if (deprecated_create_breakpoint_hook)
+    deprecated_create_breakpoint_hook (b);
   breakpoint_create_event (b->number);
 
   if (b->ops != NULL && b->ops->print_mention != NULL)
@@ -4722,14 +4866,21 @@ mention (struct breakpoint *b)
 
   if (say_where)
     {
-      if (addressprint || b->source_file == NULL)
+      if (b->pending)
        {
-         printf_filtered (" at ");
-         print_address_numeric (b->loc->address, 1, gdb_stdout);
+         printf_filtered (" (%s) pending.", b->addr_string);
+       }
+      else
+       {
+         if (addressprint || b->source_file == NULL)
+           {
+             printf_filtered (" at ");
+             print_address_numeric (b->loc->address, 1, gdb_stdout);
+           }
+         if (b->source_file)
+           printf_filtered (": file %s, line %d.",
+                            b->source_file, b->line_number);
        }
-      if (b->source_file)
-       printf_filtered (": file %s, line %d.",
-                        b->source_file, b->line_number);
     }
   do_cleanups (old_chain);
   if (ui_out_is_mi_like_p (uiout))
@@ -4742,6 +4893,11 @@ mention (struct breakpoint *b)
    SALS.sal[i] breakpoint, include the corresponding ADDR_STRING[i],
    COND[i] and COND_STRING[i] values.
 
+   The parameter PENDING_BP points to a pending breakpoint that is
+   the basis of the breakpoints currently being created.  The pending
+   breakpoint may contain a separate condition string or commands
+   that were added after the initial pending breakpoint was created.
+
    NOTE: If the function succeeds, the caller is expected to cleanup
    the arrays ADDR_STRING, COND_STRING, COND and SALS (but not the
    array contents).  If the function fails (error() is called), the
@@ -4752,7 +4908,8 @@ static void
 create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
                    struct expression **cond, char **cond_string,
                    enum bptype type, enum bpdisp disposition,
-                   int thread, int ignore_count, int from_tty)
+                   int thread, int ignore_count, int from_tty,
+                   struct breakpoint *pending_bp)
 {
   if (type == bp_hardware_breakpoint)
     {
@@ -4787,11 +4944,35 @@ 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->loc->address));
+         b->addr_string = xstrprintf ("*0x%s", paddr (b->loc->address));
        b->cond_string = cond_string[i];
        b->ignore_count = ignore_count;
        b->enable_state = bp_enabled;
        b->disposition = disposition;
+       /* If resolving a pending breakpoint, a check must be made to see if
+          the user has specified a new condition or commands for the 
+          breakpoint.  A new condition will override any condition that was 
+          initially specified with the initial breakpoint command.  */
+       if (pending_bp)
+         {
+           char *arg;
+           if (pending_bp->cond_string)
+             {
+               arg = pending_bp->cond_string;
+               b->cond_string = savestring (arg, strlen (arg));
+               b->cond = parse_exp_1 (&arg, block_for_pc (b->loc->address), 0);
+               if (*arg)
+                 error ("Junk at end of pending breakpoint condition expression");
+             }
+           /* If there are commands associated with the breakpoint, they should 
+              be copied too.  */
+           if (pending_bp->commands)
+             b->commands = copy_command_lines (pending_bp->commands);
+           
+           /* We have to copy over the ignore_count and thread as well.  */
+           b->ignore_count = pending_bp->ignore_count;
+           b->thread = pending_bp->thread;
+         }
        mention (b);
       }
   }    
@@ -4805,7 +4986,8 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
 static void
 parse_breakpoint_sals (char **address,
                       struct symtabs_and_lines *sals,
-                      char ***addr_string)
+                      char ***addr_string,
+                      int *not_found_ptr)
 {
   char *addr_start = *address;
   *addr_string = NULL;
@@ -4846,9 +5028,11 @@ 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, 
+                              not_found_ptr);
       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, not_found_ptr);
     }
   /* For any SAL that didn't have a canonical string, fill one in. */
   if (sals->nelts > 0 && *addr_string == NULL)
@@ -4891,7 +5075,8 @@ breakpoint_sals_to_pc (struct symtabs_and_lines *sals,
 
          Give the target a chance to bless sals.sals[i].pc before we
          try to make a breakpoint for it. */
-      if (PC_REQUIRES_RUN_BEFORE_USE (sals->sals[i].pc))
+#ifdef DEPRECATED_PC_REQUIRES_RUN_BEFORE_USE
+      if (DEPRECATED_PC_REQUIRES_RUN_BEFORE_USE (sals->sals[i].pc))
        {
          if (address == NULL)
            error ("Cannot break without a running program.");
@@ -4899,29 +5084,48 @@ breakpoint_sals_to_pc (struct symtabs_and_lines *sals,
            error ("Cannot break on %s without a running program.", 
                   address);
        }
+#endif
     }
 }
 
+static int
+do_captured_parse_breakpoint (struct ui_out *ui, void *data)
+{
+  struct captured_parse_breakpoint_args *args = data;
+  
+  parse_breakpoint_sals (args->arg_p, args->sals_p, args->addr_string_p, 
+                        args->not_found_ptr);
+
+  return GDB_RC_OK;
+}
+
 /* Set a breakpoint according to ARG (function, linenum or *address)
    flag: first bit  : 0 non-temporary, 1 temporary.
-   second bit : 0 normal breakpoint, 1 hardware breakpoint. */
+   second bit : 0 normal breakpoint, 1 hardware breakpoint. 
 
-static void
-break_command_1 (char *arg, int flag, int from_tty)
+   PENDING_BP is non-NULL when this function is being called to resolve
+   a pending breakpoint.  */
+
+static int
+break_command_1 (char *arg, int flag, int from_tty, struct breakpoint *pending_bp)
 {
   int tempflag, hardwareflag;
   struct symtabs_and_lines sals;
   struct expression **cond = 0;
-  /* Pointers in arg to the start, and one past the end, of the
-     condition.  */
+  struct symtab_and_line pending_sal;
   char **cond_string = (char **) NULL;
+  char *copy_arg;
+  char *err_msg;
   char *addr_start = arg;
   char **addr_string;
   struct cleanup *old_chain;
   struct cleanup *breakpoint_chain = NULL;
-  int i;
+  struct captured_parse_breakpoint_args parse_args;
+  int i, rc;
+  int pending = 0;
   int thread = -1;
   int ignore_count = 0;
+  int not_found = 0;
 
   hardwareflag = flag & BP_HARDWAREFLAG;
   tempflag = flag & BP_TEMPFLAG;
@@ -4929,19 +5133,69 @@ break_command_1 (char *arg, int flag, int from_tty)
   sals.sals = NULL;
   sals.nelts = 0;
   addr_string = NULL;
-  parse_breakpoint_sals (&arg, &sals, &addr_string);
 
-  if (!sals.nelts)
-    return;
+  parse_args.arg_p = &arg;
+  parse_args.sals_p = &sals;
+  parse_args.addr_string_p = &addr_string;
+  parse_args.not_found_ptr = &not_found;
+
+  rc = catch_exceptions_with_msg (uiout, do_captured_parse_breakpoint, 
+                                 &parse_args, NULL, &err_msg, 
+                                 RETURN_MASK_ALL);
+
+  /* If caller is interested in rc value from parse, set value.  */
+
+  if (rc != GDB_RC_OK)
+    {
+      /* Check for file or function not found.  */
+      if (not_found)
+       {
+         /* If called to resolve pending breakpoint, just return error code.  */
+         if (pending_bp)
+           return rc;
+
+         error_output_message (NULL, err_msg);
+         xfree (err_msg);
+
+         /* If pending breakpoint support is turned off, throw error.  */
+
+         if (pending_break_support == AUTO_BOOLEAN_FALSE)
+           throw_exception (RETURN_ERROR);
+
+          /* If pending breakpoint support is auto query and the user selects 
+            no, then simply return the error code.  */
+         if (pending_break_support == AUTO_BOOLEAN_AUTO && 
+             !nquery ("Make breakpoint pending on future shared library load? "))
+           return rc;
+
+         /* At this point, either the user was queried about setting a 
+            pending breakpoint and selected yes, or pending breakpoint 
+            behavior is on and thus a pending breakpoint is defaulted 
+            on behalf of the user.  */
+         copy_arg = xstrdup (addr_start);
+         addr_string = &copy_arg;
+         sals.nelts = 1;
+         sals.sals = &pending_sal;
+         pending_sal.pc = 0;
+         pending = 1;
+       }
+      else
+       return rc;
+    }
+  else if (!sals.nelts)
+    return GDB_RC_FAIL;
 
   /* Create a chain of things that always need to be cleaned up. */
   old_chain = make_cleanup (null_cleanup, 0);
 
-  /* Make sure that all storage allocated to SALS gets freed.  */
-  make_cleanup (xfree, sals.sals);
-
-  /* Cleanup the addr_string array but not its contents. */
-  make_cleanup (xfree, addr_string);
+  if (!pending)
+    {
+      /* Make sure that all storage allocated to SALS gets freed.  */
+      make_cleanup (xfree, sals.sals);
+      
+      /* Cleanup the addr_string array but not its contents. */
+      make_cleanup (xfree, addr_string);
+    }
 
   /* Allocate space for all the cond expressions. */
   cond = xcalloc (sals.nelts, sizeof (struct expression *));
@@ -4968,62 +5222,94 @@ break_command_1 (char *arg, int flag, int from_tty)
 
   /* Resolve all line numbers to PC's and verify that the addresses
      are ok for the target.  */
-  breakpoint_sals_to_pc (&sals, addr_start);
+  if (!pending)
+    breakpoint_sals_to_pc (&sals, addr_start);
 
   /* Verify that condition can be parsed, before setting any
      breakpoints.  Allocate a separate condition expression for each
      breakpoint. */
   thread = -1;                 /* No specific thread yet */
-  for (i = 0; i < sals.nelts; i++)
+  if (!pending)
     {
-      char *tok = arg;
-      while (tok && *tok)
+      for (i = 0; i < sals.nelts; i++)
        {
-         char *end_tok;
-         int toklen;
-         char *cond_start = NULL;
-         char *cond_end = NULL;
-         while (*tok == ' ' || *tok == '\t')
-           tok++;
-
-         end_tok = tok;
-
-         while (*end_tok != ' ' && *end_tok != '\t' && *end_tok != '\000')
-           end_tok++;
-
-         toklen = end_tok - tok;
-
-         if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
-           {
-             tok = cond_start = end_tok + 1;
-             cond[i] = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), 0);
-             make_cleanup (xfree, cond[i]);
-             cond_end = tok;
-             cond_string[i] = savestring (cond_start, cond_end - cond_start);
-             make_cleanup (xfree, cond_string[i]);
-           }
-         else if (toklen >= 1 && strncmp (tok, "thread", toklen) == 0)
+         char *tok = arg;
+         while (tok && *tok)
            {
-             char *tmptok;
-
-             tok = end_tok + 1;
-             tmptok = tok;
-             thread = strtol (tok, &tok, 0);
-             if (tok == tmptok)
-               error ("Junk after thread keyword.");
-             if (!valid_thread_id (thread))
-               error ("Unknown thread %d\n", thread);
+             char *end_tok;
+             int toklen;
+             char *cond_start = NULL;
+             char *cond_end = NULL;
+             while (*tok == ' ' || *tok == '\t')
+               tok++;
+             
+             end_tok = tok;
+             
+             while (*end_tok != ' ' && *end_tok != '\t' && *end_tok != '\000')
+               end_tok++;
+             
+             toklen = end_tok - tok;
+             
+             if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
+               {
+                 tok = cond_start = end_tok + 1;
+                 cond[i] = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), 
+                                        0);
+                 make_cleanup (xfree, cond[i]);
+                 cond_end = tok;
+                 cond_string[i] = savestring (cond_start, 
+                                              cond_end - cond_start);
+                 make_cleanup (xfree, cond_string[i]);
+               }
+             else if (toklen >= 1 && strncmp (tok, "thread", toklen) == 0)
+               {
+                 char *tmptok;
+                 
+                 tok = end_tok + 1;
+                 tmptok = tok;
+                 thread = strtol (tok, &tok, 0);
+                 if (tok == tmptok)
+                   error ("Junk after thread keyword.");
+                 if (!valid_thread_id (thread))
+                   error ("Unknown thread %d\n", thread);
+               }
+             else
+               error ("Junk at end of arguments.");
            }
-         else
-           error ("Junk at end of arguments.");
        }
+      create_breakpoints (sals, addr_string, cond, cond_string,
+                         hardwareflag ? bp_hardware_breakpoint 
+                         : bp_breakpoint,
+                         tempflag ? disp_del : disp_donttouch,
+                         thread, ignore_count, from_tty,
+                         pending_bp);
     }
-
-  create_breakpoints (sals, addr_string, cond, cond_string,
-                     hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
-                     tempflag ? disp_del : disp_donttouch,
-                     thread, ignore_count, from_tty);
-
+  else
+    {
+      struct symtab_and_line sal;
+      struct breakpoint *b;
+
+      sal.symtab = NULL;
+      sal.pc = 0;
+
+      make_cleanup (xfree, copy_arg);
+
+      b = set_raw_breakpoint (sal, hardwareflag ? bp_hardware_breakpoint 
+                             : bp_breakpoint);
+      set_breakpoint_count (breakpoint_count + 1);
+      b->number = breakpoint_count;
+      b->cond = *cond;
+      b->thread = thread;
+      b->addr_string = *addr_string;
+      b->cond_string = *cond_string;
+      b->ignore_count = ignore_count;
+      b->pending = 1;
+      b->disposition = tempflag ? disp_del : disp_donttouch;
+      b->from_tty = from_tty;
+      b->flag = flag;
+      mention (b);
+    }
+  
   if (sals.nelts > 1)
     {
       warning ("Multiple breakpoints were set.");
@@ -5034,6 +5320,8 @@ break_command_1 (char *arg, int flag, int from_tty)
   discard_cleanups (breakpoint_chain);
   /* But cleanup everything else. */
   do_cleanups (old_chain);
+
+  return GDB_RC_OK;
 }
 
 /* Set a breakpoint of TYPE/DISPOSITION according to ARG (function,
@@ -5070,7 +5358,7 @@ do_captured_breakpoint (void *data)
   sals.nelts = 0;
   address_end = args->address;
   addr_string = NULL;
-  parse_breakpoint_sals (&address_end, &sals, &addr_string);
+  parse_breakpoint_sals (&address_end, &sals, &addr_string, 0);
 
   if (!sals.nelts)
     return GDB_RC_NONE;
@@ -5134,7 +5422,8 @@ do_captured_breakpoint (void *data)
   create_breakpoints (sals, addr_string, cond, cond_string,
                      args->hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
                      args->tempflag ? disp_del : disp_donttouch,
-                     args->thread, args->ignore_count, 0/*from-tty*/);
+                     args->thread, args->ignore_count, 0/*from-tty*/, 
+                     NULL/*pending_bp*/);
 
   /* That's it. Discard the cleanups for data inserted into the
      breakpoint. */
@@ -5226,7 +5515,7 @@ break_at_finish_at_depth_command_1 (char *arg, int flag, int from_tty)
            addr_string = xstrprintf ("*0x%s %s", paddr_nz (high), extra_args);
          else
            addr_string = xstrprintf ("*0x%s", paddr_nz (high));
-         break_command_1 (addr_string, flag, from_tty);
+         break_command_1 (addr_string, flag, from_tty, NULL);
          xfree (addr_string);
        }
       else
@@ -5294,7 +5583,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);
@@ -5309,7 +5598,7 @@ break_at_finish_command_1 (char *arg, int flag, int from_tty)
                                       extra_args);
          else
            break_string = xstrprintf ("*0x%s", paddr_nz (high));
-         break_command_1 (break_string, flag, from_tty);
+         break_command_1 (break_string, flag, from_tty, NULL);
          xfree (break_string);
        }
       else
@@ -5376,7 +5665,7 @@ resolve_sal_pc (struct symtab_and_line *sal)
 void
 break_command (char *arg, int from_tty)
 {
-  break_command_1 (arg, 0, from_tty);
+  break_command_1 (arg, 0, from_tty, NULL);
 }
 
 void
@@ -5394,7 +5683,7 @@ break_at_finish_at_depth_command (char *arg, int from_tty)
 void
 tbreak_command (char *arg, int from_tty)
 {
-  break_command_1 (arg, BP_TEMPFLAG, from_tty);
+  break_command_1 (arg, BP_TEMPFLAG, from_tty, NULL);
 }
 
 void
@@ -5406,13 +5695,13 @@ tbreak_at_finish_command (char *arg, int from_tty)
 static void
 hbreak_command (char *arg, int from_tty)
 {
-  break_command_1 (arg, BP_HARDWAREFLAG, from_tty);
+  break_command_1 (arg, BP_HARDWAREFLAG, from_tty, NULL);
 }
 
 static void
 thbreak_command (char *arg, int from_tty)
 {
-  break_command_1 (arg, (BP_TEMPFLAG | BP_HARDWAREFLAG), from_tty);
+  break_command_1 (arg, (BP_TEMPFLAG | BP_HARDWAREFLAG), from_tty, NULL);
 }
 
 static void
@@ -5453,7 +5742,7 @@ stopin_command (char *arg, int from_tty)
   if (badInput)
     printf_filtered ("Usage: stop in <function | address>\n");
   else
-    break_command_1 (arg, 0, from_tty);
+    break_command_1 (arg, 0, from_tty, NULL);
 }
 
 static void
@@ -5485,7 +5774,7 @@ stopat_command (char *arg, int from_tty)
   if (badInput)
     printf_filtered ("Usage: stop at <line>\n");
   else
-    break_command_1 (arg, 0, from_tty);
+    break_command_1 (arg, 0, from_tty, NULL);
 }
 
 /* accessflag:  hw_write:  watch write, 
@@ -5643,7 +5932,8 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
          scope_breakpoint->loc->requested_address
            = get_frame_pc (prev_frame);
          scope_breakpoint->loc->address
-           = adjust_breakpoint_address (scope_breakpoint->loc->requested_address);
+           = adjust_breakpoint_address (scope_breakpoint->loc->requested_address,
+                                        scope_breakpoint->type);
 
          /* The scope breakpoint is related to the watchpoint.  We
             will need to act on them together.  */
@@ -5658,11 +5948,6 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
    in hardware.  If the watchpoint can not be handled
    in hardware return zero.  */
 
-#if !defined(TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT)
-#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(BYTE_SIZE) \
-    ((BYTE_SIZE) <= (DEPRECATED_REGISTER_SIZE))
-#endif
-
 #if !defined(TARGET_REGION_OK_FOR_HW_WATCHPOINT)
 #define TARGET_REGION_OK_FOR_HW_WATCHPOINT(ADDR,LEN) \
      (TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(LEN))
@@ -5811,10 +6096,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.");
@@ -5885,30 +6170,6 @@ until_break_command (char *arg, int from_tty, int anywhere)
     do_cleanups (old_chain);
 }
 
-#if 0
-/* These aren't used; I don't konw what they were for.  */
-/* Set a breakpoint at the catch clause for NAME.  */
-static int
-catch_breakpoint (char *name)
-{
-}
-
-static int
-disable_catch_breakpoint (void)
-{
-}
-
-static int
-delete_catch_breakpoint (void)
-{
-}
-
-static int
-enable_catch_breakpoint (void)
-{
-}
-#endif /* 0 */
-
 static void
 ep_skip_leading_whitespace (char **s)
 {
@@ -6023,10 +6284,6 @@ typedef enum
 }
 catch_fork_kind;
 
-#if defined(CHILD_INSERT_FORK_CATCHPOINT) || defined(CHILD_INSERT_VFORK_CATCHPOINT)
-static void catch_fork_command_1 (catch_fork_kind fork_kind,
-                                 char *arg, int tempflag, int from_tty);
-
 static void
 catch_fork_command_1 (catch_fork_kind fork_kind, char *arg, int tempflag,
                      int from_tty)
@@ -6060,9 +6317,7 @@ catch_fork_command_1 (catch_fork_kind fork_kind, char *arg, int tempflag,
       break;
     }
 }
-#endif
 
-#if defined(CHILD_INSERT_EXEC_CATCHPOINT)
 static void
 catch_exec_command_1 (char *arg, int tempflag, int from_tty)
 {
@@ -6084,9 +6339,7 @@ catch_exec_command_1 (char *arg, int tempflag, int from_tty)
      and enable reporting of such events. */
   create_exec_event_catchpoint (tempflag, cond_string);
 }
-#endif
 
-#if defined(SOLIB_ADD)
 static void
 catch_load_command_1 (char *arg, int tempflag, int from_tty)
 {
@@ -6170,7 +6423,6 @@ catch_unload_command_1 (char *arg, int tempflag, int from_tty)
   SOLIB_CREATE_CATCH_UNLOAD_HOOK (PIDGET (inferior_ptid), tempflag, 
                                  dll_pathname, cond_string);
 }
-#endif /* SOLIB_ADD */
 
 /* Commands to deal with catching exceptions.  */
 
@@ -6274,7 +6526,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);
@@ -6419,43 +6671,23 @@ catch_command_1 (char *arg, int tempflag, int from_tty)
     }
   else if (strncmp (arg1_start, "fork", arg1_length) == 0)
     {
-#if defined(CHILD_INSERT_FORK_CATCHPOINT)
       catch_fork_command_1 (catch_fork, arg1_end + 1, tempflag, from_tty);
-#else
-      error ("Catch of fork not yet implemented");
-#endif
     }
   else if (strncmp (arg1_start, "vfork", arg1_length) == 0)
     {
-#if defined(CHILD_INSERT_VFORK_CATCHPOINT)
       catch_fork_command_1 (catch_vfork, arg1_end + 1, tempflag, from_tty);
-#else
-      error ("Catch of vfork not yet implemented");
-#endif
     }
   else if (strncmp (arg1_start, "exec", arg1_length) == 0)
     {
-#if defined(CHILD_INSERT_EXEC_CATCHPOINT)
       catch_exec_command_1 (arg1_end + 1, tempflag, from_tty);
-#else
-      error ("Catch of exec not yet implemented");
-#endif
     }
   else if (strncmp (arg1_start, "load", arg1_length) == 0)
     {
-#if defined(SOLIB_ADD)
       catch_load_command_1 (arg1_end + 1, tempflag, from_tty);
-#else
-      error ("Catch of load not implemented");
-#endif
     }
   else if (strncmp (arg1_start, "unload", arg1_length) == 0)
     {
-#if defined(SOLIB_ADD)
       catch_unload_command_1 (arg1_end + 1, tempflag, from_tty);
-#else
-      error ("Catch of load not implemented");
-#endif
     }
   else if (strncmp (arg1_start, "stop", arg1_length) == 0)
     {
@@ -6489,30 +6721,6 @@ set_breakpoint_sal (struct symtab_and_line sal)
   return b;
 }
 
-#if 0
-/* These aren't used; I don't know what they were for.  */
-/* Disable breakpoints on all catch clauses described in ARGS.  */
-static void
-disable_catch (char *args)
-{
-  /* Map the disable command to catch clauses described in ARGS.  */
-}
-
-/* Enable breakpoints on all catch clauses described in ARGS.  */
-static void
-enable_catch (char *args)
-{
-  /* Map the disable command to catch clauses described in ARGS.  */
-}
-
-/* Delete breakpoints on all catch clauses in the active scope.  */
-static void
-delete_catch (char *args)
-{
-  /* Map the delete command to catch clauses described in ARGS.  */
-}
-#endif /* 0 */
-
 static void
 catch_command (char *arg, int from_tty)
 {
@@ -6601,7 +6809,7 @@ clear_command (char *arg, int from_tty)
                  || ((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.  */
            {
@@ -6703,12 +6911,14 @@ delete_breakpoint (struct breakpoint *bpt)
   if (bpt->type == bp_none)
     return;
 
-  if (delete_breakpoint_hook)
-    delete_breakpoint_hook (bpt);
+  if (deprecated_delete_breakpoint_hook)
+    deprecated_delete_breakpoint_hook (bpt);
   breakpoint_delete_event (bpt->number);
 
   if (bpt->loc->inserted)
-    remove_breakpoint (bpt, mark_inserted);
+    remove_breakpoint (bpt->loc, mark_inserted);
+
+  free_valchain (bpt->loc);
 
   if (breakpoint_chain == bpt)
     breakpoint_chain = bpt->next;
@@ -6769,6 +6979,7 @@ delete_breakpoint (struct breakpoint *bpt)
            && !b->loc->duplicate
            && b->enable_state != bp_disabled
            && b->enable_state != bp_shlib_disabled
+           && !b->pending
            && b->enable_state != bp_call_disabled)
        {
          int val;
@@ -6931,6 +7142,8 @@ breakpoint_re_set_one (void *bint)
   struct breakpoint *b = (struct breakpoint *) bint;
   struct value *mark;
   int i;
+  int not_found;
+  int *not_found_ptr = NULL;
   struct symtabs_and_lines sals;
   char *s;
   enum enable_state save_enable;
@@ -6974,14 +7187,26 @@ breakpoint_re_set_one (void *bint)
          shlib_disabled breakpoint though.  There's a fair chance we
          can't re-set it if the shared library it's in hasn't been
          loaded yet.  */
+
+      if (b->pending)
+       break;
+
       save_enable = b->enable_state;
       if (b->enable_state != bp_shlib_disabled)
         b->enable_state = bp_disabled;
+      else
+       /* If resetting a shlib-disabled breakpoint, we don't want to
+          see an error message if it is not found since we will expect
+          this to occur until the shared library is finally reloaded.
+          We accomplish this by giving decode_line_1 a pointer to use
+          for silent notification that the symbol is not found.  */
+       not_found_ptr = &not_found;
 
       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,
+                           not_found_ptr);
       for (i = 0; i < sals.nelts; i++)
        {
          resolve_sal_pc (&sals.sals[i]);
@@ -6992,7 +7217,12 @@ breakpoint_re_set_one (void *bint)
            {
              s = b->cond_string;
              if (b->cond)
-               xfree (b->cond);
+               {
+                 xfree (b->cond);
+                 /* Avoid re-freeing b->exp if an error during the call
+                    to parse_exp_1.  */
+                 b->cond = NULL;
+               }
              b->cond = parse_exp_1 (&s, block_for_pc (sals.sals[i].pc), 0);
            }
 
@@ -7002,7 +7232,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
@@ -7021,7 +7251,8 @@ breakpoint_re_set_one (void *bint)
              b->line_number = sals.sals[i].line;
              b->loc->requested_address = sals.sals[i].pc;
              b->loc->address
-               = adjust_breakpoint_address (b->loc->requested_address);
+               = adjust_breakpoint_address (b->loc->requested_address,
+                                            b->type);
 
              /* Used to check for duplicates here, but that can
                 cause trouble, as it doesn't check for disabled
@@ -7060,25 +7291,40 @@ breakpoint_re_set_one (void *bint)
 
       /* So for now, just use a global context.  */
       if (b->exp)
-       xfree (b->exp);
+       {
+         xfree (b->exp);
+         /* Avoid re-freeing b->exp if an error during the call to
+             parse_expression.  */
+         b->exp = NULL;
+       }
       b->exp = parse_expression (b->exp_string);
       b->exp_valid_block = innermost_block;
       mark = value_mark ();
       if (b->val)
-       value_free (b->val);
+       {
+         value_free (b->val);
+         /* Avoid re-freeing b->val if an error during the call to
+             evaluate_expression.  */
+         b->val = NULL;
+       }
       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)
        {
          s = b->cond_string;
          if (b->cond)
-           xfree (b->cond);
+           {
+             xfree (b->cond);
+             /* Avoid re-freeing b->exp if an error during the call
+                to parse_exp_1.  */
+             b->cond = NULL;
+           }
          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;
@@ -7310,8 +7556,8 @@ disable_breakpoint (struct breakpoint *bpt)
 
   check_duplicates (bpt);
 
-  if (modify_breakpoint_hook)
-    modify_breakpoint_hook (bpt);
+  if (deprecated_modify_breakpoint_hook)
+    deprecated_modify_breakpoint_hook (bpt);
   breakpoint_modify_event (bpt->number);
 }
 
@@ -7351,8 +7597,6 @@ disable_command (char *args, int from_tty)
 static void
 do_enable_breakpoint (struct breakpoint *bpt, enum bpdisp disposition)
 {
-  struct frame_info *save_selected_frame = NULL;
-  int save_selected_frame_level = -1;
   int target_resources_ok, other_type_used;
   struct value *mark;
 
@@ -7369,72 +7613,92 @@ do_enable_breakpoint (struct breakpoint *bpt, enum bpdisp disposition)
        error ("Hardware breakpoints used exceeds limit.");
     }
 
-  if (bpt->enable_state != bp_permanent)
-    bpt->enable_state = bp_enabled;
-  bpt->disposition = disposition;
-  check_duplicates (bpt);
-  breakpoints_changed ();
-
-  if (bpt->type == bp_watchpoint || 
-      bpt->type == bp_hardware_watchpoint ||
-      bpt->type == bp_read_watchpoint || 
-      bpt->type == bp_access_watchpoint)
+  if (bpt->pending)
     {
-      if (bpt->exp_valid_block != NULL)
+      if (bpt->enable_state != bp_enabled)
        {
-         struct frame_info *fr =
-         fr = frame_find_by_id (bpt->watchpoint_frame);
-         if (fr == NULL)
+         /* When enabling a pending breakpoint, we need to check if the breakpoint
+            is resolvable since shared libraries could have been loaded
+            after the breakpoint was disabled.  */
+         breakpoints_changed ();
+         if (resolve_pending_breakpoint (bpt) == GDB_RC_OK)
            {
-             printf_filtered ("\
-Cannot enable watchpoint %d because the block in which its expression\n\
-is valid is not currently in scope.\n", bpt->number);
-             bpt->enable_state = bp_disabled;
+             delete_breakpoint (bpt);
              return;
            }
-
-         save_selected_frame = deprecated_selected_frame;
-         save_selected_frame_level = frame_relative_level (deprecated_selected_frame);
-         select_frame (fr);
+         bpt->enable_state = bp_enabled;
+         bpt->disposition = disposition;
        }
-
-      value_free (bpt->val);
-      mark = value_mark ();
-      bpt->val = evaluate_expression (bpt->exp);
-      release_value (bpt->val);
-      if (VALUE_LAZY (bpt->val))
-       value_fetch_lazy (bpt->val);
-
-      if (bpt->type == bp_hardware_watchpoint ||
-         bpt->type == bp_read_watchpoint ||
+    }
+  else  /* Not a pending breakpoint.  */
+    {
+      if (bpt->enable_state != bp_permanent)
+       bpt->enable_state = bp_enabled;
+      bpt->disposition = disposition;
+      check_duplicates (bpt);
+      breakpoints_changed ();
+      
+      if (bpt->type == bp_watchpoint || 
+         bpt->type == bp_hardware_watchpoint ||
+         bpt->type == bp_read_watchpoint || 
          bpt->type == bp_access_watchpoint)
        {
-         int i = hw_watchpoint_used_count (bpt->type, &other_type_used);
-         int mem_cnt = can_use_hardware_watchpoint (bpt->val);
-
-         /* Hack around 'unused var' error for some targets here */
-         (void) mem_cnt, i;
-         target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT (
-                                  bpt->type, i + mem_cnt, other_type_used);
-         /* we can consider of type is bp_hardware_watchpoint, convert to 
-            bp_watchpoint in the following condition */
-         if (target_resources_ok < 0)
+         struct frame_id saved_frame_id;
+
+         saved_frame_id = get_frame_id (get_selected_frame ());
+         if (bpt->exp_valid_block != NULL)
+           {
+             struct frame_info *fr =
+               fr = frame_find_by_id (bpt->watchpoint_frame);
+             if (fr == NULL)
+               {
+                 printf_filtered ("\
+Cannot enable watchpoint %d because the block in which its expression\n\
+is valid is not currently in scope.\n", bpt->number);
+                 bpt->enable_state = bp_disabled;
+                 return;
+               }
+             select_frame (fr);
+           }
+         
+         value_free (bpt->val);
+         mark = value_mark ();
+         bpt->val = evaluate_expression (bpt->exp);
+         release_value (bpt->val);
+         if (VALUE_LAZY (bpt->val))
+           value_fetch_lazy (bpt->val);
+         
+         if (bpt->type == bp_hardware_watchpoint ||
+             bpt->type == bp_read_watchpoint ||
+             bpt->type == bp_access_watchpoint)
            {
-             printf_filtered ("\
+             int i = hw_watchpoint_used_count (bpt->type, &other_type_used);
+             int mem_cnt = can_use_hardware_watchpoint (bpt->val);
+             
+             /* Hack around 'unused var' error for some targets here */
+             (void) mem_cnt, i;
+             target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT (
+                                                                       bpt->type, i + mem_cnt, other_type_used);
+             /* we can consider of type is bp_hardware_watchpoint, convert to 
+                bp_watchpoint in the following condition */
+             if (target_resources_ok < 0)
+               {
+                 printf_filtered ("\
 Cannot enable watchpoint %d because target watch resources\n\
 have been allocated for other watchpoints.\n", bpt->number);
-             bpt->enable_state = bp_disabled;
-             value_free_to_mark (mark);
-             return;
+                 bpt->enable_state = bp_disabled;
+                 value_free_to_mark (mark);
+                 return;
+               }
            }
+         
+         select_frame (frame_find_by_id (saved_frame_id));
+         value_free_to_mark (mark);
        }
-
-      if (save_selected_frame_level >= 0)
-       select_frame (save_selected_frame);
-      value_free_to_mark (mark);
     }
-  if (modify_breakpoint_hook)
-    modify_breakpoint_hook (bpt);
+
+  if (deprecated_modify_breakpoint_hook)
+    deprecated_modify_breakpoint_hook (bpt);
   breakpoint_modify_event (bpt->number);
 }
 
@@ -7505,6 +7769,16 @@ enable_delete_command (char *args, int from_tty)
   map_breakpoint_numbers (args, enable_delete_breakpoint);
 }
 \f
+static void
+set_breakpoint_cmd (char *args, int from_tty)
+{
+}
+
+static void
+show_breakpoint_cmd (char *args, int from_tty)
+{
+}
+
 /* Use default_breakpoint_'s, or nothing if they aren't valid.  */
 
 struct symtabs_and_lines
@@ -7517,10 +7791,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;
@@ -7529,8 +7803,14 @@ decode_line_spec_1 (char *string, int funfirstline)
 void
 _initialize_breakpoint (void)
 {
+  static struct cmd_list_element *breakpoint_set_cmdlist;
+  static struct cmd_list_element *breakpoint_show_cmdlist;
   struct cmd_list_element *c;
 
+#ifdef SOLIB_ADD
+  observer_attach_solib_unloaded (disable_breakpoints_in_unloaded_shlib);
+#endif
+
   breakpoint_chain = 0;
   /* Don't bother to call set_breakpoint_count.  $bpnum isn't useful
      before a breakpoint is set.  */
@@ -7844,7 +8124,34 @@ such is available.  (However, any hardware watchpoints that were\n\
 created before setting this to nonzero, will continue to use watchpoint\n\
 hardware.)",
                   &setlist);
-  add_show_from_set (c, &showlist);
+  deprecated_add_show_from_set (c, &showlist);
 
   can_use_hw_watchpoints = 1;
+
+  add_prefix_cmd ("breakpoint", class_maintenance, set_breakpoint_cmd, "\
+Breakpoint specific settings\n\
+Configure various breakpoint-specific variables such as\n\
+pending breakpoint behavior",
+                 &breakpoint_set_cmdlist, "set breakpoint ",
+                 0/*allow-unknown*/, &setlist);
+  add_prefix_cmd ("breakpoint", class_maintenance, show_breakpoint_cmd, "\
+Breakpoint specific settings\n\
+Configure various breakpoint-specific variables such as\n\
+pending breakpoint behavior",
+                 &breakpoint_show_cmdlist, "show breakpoint ",
+                 0/*allow-unknown*/, &showlist);
+
+  add_setshow_auto_boolean_cmd ("pending", no_class, &pending_break_support, "\
+Set debugger's behavior regarding pending breakpoints.", "\
+Show debugger's behavior regarding pending breakpoints.", "\
+If on, an unrecognized breakpoint location will cause gdb to create a\n\
+pending breakpoint.  If off, an unrecognized breakpoint location results in\n\
+an error.  If auto, an unrecognized breakpoint location results in a\n\
+user-query to see if a pending breakpoint should be created.", "\
+Debugger's behavior regarding pending breakpoints is %s.",
+                               NULL, NULL,
+                               &breakpoint_set_cmdlist,
+                               &breakpoint_show_cmdlist);
+
+  pending_break_support = AUTO_BOOLEAN_AUTO;
 }
This page took 0.053282 seconds and 4 git commands to generate.