diff -r -u gdb-6.0/gdb/breakpoint.c gdb-6.0.sobreak/gdb/breakpoint.c
--- gdb-6.0/gdb/breakpoint.c	2003-07-02 17:24:30.000000000 +0100
+++ gdb-6.0.sobreak/gdb/breakpoint.c	2003-10-20 13:09:04.000000000 +0100
@@ -210,6 +210,8 @@
    if such is available. */
 static int can_use_hw_watchpoints;
 
+static int hack_allow_future_breaks;
+
 void _initialize_breakpoint (void);
 
 extern int addressprint;	/* Print machine addresses? */
@@ -632,7 +634,7 @@
 	|| b->type == bp_access_watchpoint)
       continue;
     /* bp in memory? */
-    if (!b->inserted)
+    if (!b->inserted || b->address == 0)
       continue;
     /* Addresses and length of the part of the breakpoint that
        we need to copy.  */
@@ -752,6 +754,8 @@
   static char message1[] = "Error inserting catchpoint %d:\n";
   static char message[sizeof (message1) + 30];
 
+  breakpoint_update ();
+
   struct ui_file *tmp_error_stream = mem_fileopen ();
   make_cleanup_ui_file_delete (tmp_error_stream);
 
@@ -854,11 +858,13 @@
 	  {
 	    /* Can't set the breakpoint.  */
 #if defined (DISABLE_UNSETTABLE_BREAK)
-	    if (DISABLE_UNSETTABLE_BREAK (b->address))
+	    if (hack_allow_future_breaks || DISABLE_UNSETTABLE_BREAK (b->address))
 	      {
 		/* See also: disable_breakpoints_in_shlibs. */
 		val = 0;
 		b->enable_state = bp_shlib_disabled;
+		b->address = 0;
+		b->inserted = 0;
 		if (!disabled_breaks)
 		  {
 		    fprintf_unfiltered (tmp_error_stream, 
@@ -1113,6 +1119,10 @@
       target_terminal_ours_for_output ();
       error_stream (tmp_error_stream);
     }
+
+  if (disabled_breaks)
+    printf_filtered ("\n");
+  
   return return_val;
 }
 
@@ -1355,6 +1365,12 @@
     /* Permanent breakpoints cannot be inserted or removed.  */
     return 0;
 
+  if (hack_allow_future_breaks && !b->inserted)
+  {
+   /* don't to try and remove this ? */
+    return 0;
+  }
+
   if (b->type == bp_none)
     warning ("attempted to remove apparently deleted breakpoint #%d?", 
 	     b->number);
@@ -2384,6 +2400,7 @@
 
 #define BP_TEMPFLAG 1
 #define BP_HARDWAREFLAG 2
+#define BP_FUTUREFLAG 4
 
 /* Check watchpoint condition.  */
 
@@ -3416,11 +3433,15 @@
 	    ui_out_text (uiout, ":");
 	    ui_out_field_int (uiout, "line", b->line_number);
 	  }
-	else
+	else if (b->address != 0 || !hack_allow_future_breaks)
 	  {
 	    print_address_symbolic (b->address, stb->stream, demangle, "");
 	    ui_out_field_stream (uiout, "at", stb);
 	  }
+	else
+	  {
+	    ui_out_field_string (uiout, "future-address", b->addr_string);
+	  }
 	break;
       }
 
@@ -4086,6 +4107,8 @@
   struct breakpoint *b;
   int disabled_shlib_breaks = 0;
 
+  silent = 0;
+
   /* See also: insert_breakpoints, under DISABLE_UNSETTABLE_BREAK. */
   ALL_BREAKPOINTS (b)
   {
@@ -4097,19 +4120,23 @@
 	PC_SOLIB (b->address))
       {
 	b->enable_state = bp_shlib_disabled;
+	b->address = 0;
+	b->inserted = 0;
 	if (!silent)
 	  {
 	    if (!disabled_shlib_breaks)
 	      {
 		target_terminal_ours_for_output ();
-		warning ("Temporarily disabling shared library breakpoints:");
+		printf_filtered ("Temporarily disabling shared library breakpoints:");
 	      }
 	    disabled_shlib_breaks = 1;
-	    warning ("breakpoint #%d ", b->number);
+	    printf_filtered (" %d ", b->number);
 	  }
       }
-#endif
   }
+#endif
+  if (!silent && disabled_shlib_breaks)
+    printf_filtered ("\n");
 }
 
 /* Try to reenable any breakpoints in shared libraries.  */
@@ -4117,18 +4144,35 @@
 re_enable_breakpoints_in_shlibs (void)
 {
   struct breakpoint *b;
+  int enabled_shlib_breaks = 0;
+  int silent = 0;
 
   ALL_BREAKPOINTS (b)
     if (b->enable_state == bp_shlib_disabled)
-    {
-      char buf[1];
+      {
+	char buf[1];
 
-      /* Do not reenable the breakpoint if the shared library
-         is still not mapped in.  */
-      if (target_read_memory (b->address, buf, 1) == 0)
-	b->enable_state = bp_enabled;
-    }
-}
+	/* Do not reenable the breakpoint if the shared library
+	   is still not mapped in.  */
+	if (target_read_memory (b->address, buf, 1) == 0) 
+	  { 
+	    b->enable_state = bp_enabled; 
+	    if (!silent)  
+	      {  
+		if (!enabled_shlib_breaks)  
+		  {  
+		    target_terminal_ours_for_output ();  
+		    printf_filtered ("Re-enabling shared library breakpoints:");  
+		  }  
+		enabled_shlib_breaks = 1;  
+		printf_filtered (" %d", b->number);  
+	      }  
+	  } 
+      } 
+ 
+  if (!silent && enabled_shlib_breaks)  
+    printf_filtered ("\n");  
+} 
 
 #endif
 
@@ -4569,7 +4613,8 @@
 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 origflags, int thread, int ignore_count,
+		    int from_tty)
 {
   if (type == bp_hardware_breakpoint)
     {
@@ -4634,6 +4679,7 @@
       if (default_breakpoint_valid)
 	{
 	  struct symtab_and_line sal;
+      char *s;
 	  init_sal (&sal);		/* initialize to zeroes */
 	  sals->sals = (struct symtab_and_line *)
 	    xmalloc (sizeof (struct symtab_and_line));
@@ -4643,6 +4689,11 @@
 	  sal.section = find_pc_overlay (sal.pc);
 	  sals->sals[0] = sal;
 	  sals->nelts = 1;
+	  /* Supply a "*ADDR" for default case (ADDR is pc value).  */
+	  s = paddr_u (sal.pc);
+	  *addr_string = (char **) xmalloc (sizeof (char **));
+	  **addr_string = (char *) xmalloc (strlen (s) + 2);
+	  sprintf (**addr_string, "*%s", s);
 	}
       else
 	error ("No default breakpoint address now.");
@@ -4719,140 +4770,6 @@
     }
 }
 
-/* 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. */
-
-static void
-break_command_1 (char *arg, int flag, int from_tty)
-{
-  int tempflag, hardwareflag;
-  struct symtabs_and_lines sals;
-  register struct expression **cond = 0;
-  /* Pointers in arg to the start, and one past the end, of the
-     condition.  */
-  char **cond_string = (char **) NULL;
-  char *addr_start = arg;
-  char **addr_string;
-  struct cleanup *old_chain;
-  struct cleanup *breakpoint_chain = NULL;
-  int i;
-  int thread = -1;
-  int ignore_count = 0;
-
-  hardwareflag = flag & BP_HARDWAREFLAG;
-  tempflag = flag & BP_TEMPFLAG;
-
-  sals.sals = NULL;
-  sals.nelts = 0;
-  addr_string = NULL;
-  parse_breakpoint_sals (&arg, &sals, &addr_string);
-
-  if (!sals.nelts)
-    return;
-
-  /* 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);
-
-  /* Allocate space for all the cond expressions. */
-  cond = xcalloc (sals.nelts, sizeof (struct expression *));
-  make_cleanup (xfree, cond);
-
-  /* Allocate space for all the cond strings. */
-  cond_string = xcalloc (sals.nelts, sizeof (char **));
-  make_cleanup (xfree, cond_string);
-
-  /* ----------------------------- SNIP -----------------------------
-     Anything added to the cleanup chain beyond this point is assumed
-     to be part of a breakpoint.  If the breakpoint create succeeds
-     then the memory is not reclaimed. */
-  breakpoint_chain = make_cleanup (null_cleanup, 0);
-
-  /* Mark the contents of the addr_string for cleanup.  These go on
-     the breakpoint_chain and only occure if the breakpoint create
-     fails. */
-  for (i = 0; i < sals.nelts; i++)
-    {
-      if (addr_string[i] != NULL)
-	make_cleanup (xfree, addr_string[i]);
-    }
-
-  /* Resolve all line numbers to PC's and verify that the addresses
-     are ok for the target.  */
-  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++)
-    {
-      char *tok = arg;
-      while (tok && *tok)
-	{
-	  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.");
-	}
-    }
-
-  create_breakpoints (sals, addr_string, cond, cond_string,
-		      hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
-		      tempflag ? disp_del : disp_donttouch,
-		      thread, ignore_count, from_tty);
-
-  if (sals.nelts > 1)
-    {
-      warning ("Multiple breakpoints were set.");
-      warning ("Use the \"delete\" command to delete unwanted breakpoints.");
-    }
-  /* That's it. Discard the cleanups for data inserted into the
-     breakpoint. */
-  discard_cleanups (breakpoint_chain);
-  /* But cleanup everything else. */
-  do_cleanups (old_chain);
-}
-
 /* Set a breakpoint of TYPE/DISPOSITION according to ARG (function,
    linenum or *address) with COND and IGNORE_COUNT. */
 
@@ -4862,11 +4779,30 @@
     char *condition;
     int hardwareflag;
     int tempflag;
+    int futureflag;
     int thread;
     int ignore_count;
+    int from_tty;
+  };
+
+struct captured_parse_breakpoint_sals_args
+  {
+    char **address;
+    struct symtabs_and_lines *sals;
+    char ***addr_string;
   };
 
 static int
+captured_parse_breakpoint_sals (void *data)
+{
+  struct captured_parse_breakpoint_sals_args *args
+    = (struct captured_parse_breakpoint_sals_args *) data;
+
+  parse_breakpoint_sals (args->address, args->sals, args->addr_string);
+  return (int) GDB_RC_OK;
+}
+
+static int
 do_captured_breakpoint (void *data)
 {
   struct captured_breakpoint_args *args = data;
@@ -4877,8 +4813,14 @@
   int i;
   char **addr_string;
   char **cond_string;
-
   char *address_end;
+  int orig_flags;
+  int rc = GDB_RC_OK;
+
+  orig_flags =
+    (args->hardwareflag ? BP_HARDWAREFLAG : 0)
+    | (args->tempflag ? BP_TEMPFLAG : 0)
+    | (args->futureflag ? BP_FUTUREFLAG : 0);
 
   /* Parse the source and lines spec.  Delay check that the expression
      didn't contain trailing garbage until after cleanups are in
@@ -4887,9 +4829,56 @@
   sals.nelts = 0;
   address_end = args->address;
   addr_string = NULL;
-  parse_breakpoint_sals (&address_end, &sals, &addr_string);
 
-  if (!sals.nelts)
+  if (args->futureflag) 
+    {
+      /* This is gross, but we need to catch errors here, since
+	 that is how we are going to find out that this function
+	 could not be found...  But we don't want to change the
+	 error behavior in the case where we are directly trying
+	 to set a breakpoint.  If only gdb had a reasonable error
+	 handling scheme, rather than this stupid longjmp foolishness!
+      */
+      struct captured_parse_breakpoint_sals_args parse_args;
+      parse_args.address = &address_end;
+      parse_args.sals = &sals;
+      parse_args.addr_string = &addr_string;
+
+      rc = catch_errors (captured_parse_breakpoint_sals, &parse_args,
+		    NULL, RETURN_MASK_ALL);
+    }
+  else
+    {
+      parse_breakpoint_sals (&address_end, &sals, &addr_string);
+    }
+
+  if (args->futureflag && rc != GDB_RC_OK)
+    {
+      if (args->futureflag)
+	{
+	  struct symtab_and_line sal = {0, 0};
+	  struct breakpoint *b = set_raw_breakpoint (sal, bp_breakpoint);
+	  
+	  b->number = ++breakpoint_count;
+	  b->addr_string = savestring (args->address, strlen (args->address));
+	  b->enable_state = bp_shlib_disabled;
+          b->address = 0;
+	  b->inserted = 0;
+	  b->ignore_count = args->ignore_count;
+	  b->disposition = args->tempflag ? disp_del : disp_donttouch;
+	  if (args->condition != NULL)
+	    {
+	      b->cond_string = savestring (args->condition, 
+					   strlen (args->condition));
+	    }
+	  b->thread = args->thread;
+	  mention (b);
+	  return GDB_RC_OK;
+	}
+      else
+	return GDB_RC_NONE;
+    }
+  else if (!sals.nelts)
     return GDB_RC_NONE;
 
   /* Create a chain of things at always need to be cleaned up. */
@@ -4909,8 +4898,7 @@
   cond_string = xcalloc (sals.nelts, sizeof (char **));
   make_cleanup (xfree, cond_string);
 
-  /* ----------------------------- SNIP -----------------------------
-     Anything added to the cleanup chain beyond this point is assumed
+  /* Anything added to the cleanup chain beyond this point is assumed
      to be part of a breakpoint.  If the breakpoint create goes
      through then that memory is not cleaned up. */
   breakpoint_chain = make_cleanup (null_cleanup, 0);
@@ -4927,12 +4915,53 @@
   /* Wait until now before checking for garbage at the end of the
      address. That way cleanups can take care of freeing any
      memory. */
-  if (*address_end != '\0')
-    error ("Garbage %s following breakpoint address", address_end);
+  {
+    char *tok = address_end;
+    while (tok && *tok)
+      {
+	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_end = cond_start;
+	    while (*cond_end != '\000')
+	      cond_end++;
+	    args->condition = tok;
+	    tok = cond_end;
+	  }
+	else if (toklen >= 1 && strncmp (tok, "thread", toklen) == 0)
+	  {
+	    char *tmptok;
+	    
+	    tok = end_tok + 1;
+	    tmptok = tok;
+	    args->thread = strtol (tok, &tok, 0);
+	    if (tok == tmptok)
+	      error ("Junk after thread keyword.");
+	    if (! valid_thread_id (args->thread))
+	      error ("Unknown thread %d\n", args->thread);
+	  }
+	else
+	  error ("Junk at end of arguments.");
+      }
+  }
+  
   /* Resolve all line numbers to PC's.  */
   breakpoint_sals_to_pc (&sals, args->address);
-
+  
   /* Verify that conditions can be parsed, before setting any
      breakpoints.  */
   for (i = 0; i < sals.nelts; i++)
@@ -4950,15 +4979,75 @@
 
   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->tempflag ? disp_del : disp_donttouch, orig_flags,
+		      args->thread, args->ignore_count, args->from_tty);
 
+  if (args->from_tty && (sals.nelts > 1))
+    {
+      warning ("Multiple breakpoints were set.");
+      warning ("Use the \"delete\" command to delete unwanted breakpoints.");
+    }
+  
   /* That's it. Discard the cleanups for data inserted into the
      breakpoint. */
   discard_cleanups (breakpoint_chain);
+  
   /* But cleanup everything else. */
   do_cleanups (old_chain);
+  
   return GDB_RC_OK;
+}    
+
+static void break_command_1 (char *arg, int flags, int from_tty)
+{
+  struct captured_breakpoint_args args;
+  args.address = arg;
+  args.condition = NULL;
+  args.hardwareflag = flags & BP_HARDWAREFLAG;
+  args.tempflag = flags & BP_TEMPFLAG;
+
+  args.futureflag = hack_allow_future_breaks && (
+	  !((flags & BP_HARDWAREFLAG) || (flags & BP_TEMPFLAG)));
+
+  args.thread = -1;
+  args.ignore_count = 0;
+  args.from_tty = from_tty;
+
+  if (args.futureflag)
+    {
+      if (args.tempflag)
+	error ("Future breakpoints may not be specified as temporary.");
+      if (args.hardwareflag)
+	error ("Future breakpoints may not be specified as hardware.");
+    }
+  
+  if (args.futureflag)
+    {
+      enum gdb_rc ret = catch_errors (do_captured_breakpoint,
+				      &args, NULL, RETURN_MASK_ALL);
+      if (ret != GDB_RC_OK)
+	{
+	  struct symtab_and_line sal =
+	    {0, 0};
+	  struct breakpoint *b = set_raw_breakpoint (sal, bp_breakpoint);
+
+	  printf_unfiltered
+	    ("Will attempt to resolve \"%s\" on future dynamic loads.\n", args.address);
+
+	  b->number = ++breakpoint_count;
+	  b->addr_string = savestring (args.address, strlen (args.address));
+	  b->enable_state = bp_shlib_disabled;
+          b->address = 0;
+	  b->inserted = 0;
+	  b->disposition = disp_donttouch;
+	  if (modify_breakpoint_hook)
+	    modify_breakpoint_hook (b);
+	}
+    }
+  else
+    {
+      do_captured_breakpoint (&args);
+    }
 }
 
 enum gdb_rc
@@ -4971,6 +5060,11 @@
   args.condition = condition;
   args.hardwareflag = hardwareflag;
   args.tempflag = tempflag;
+
+  args.futureflag = hack_allow_future_breaks && (
+	  !(hardwareflag || tempflag));
+
+  
   args.thread = thread;
   args.ignore_count = ignore_count;
   return catch_errors (do_captured_breakpoint, &args,
@@ -6930,10 +7024,27 @@
   return 0;
 }
 
-/* Re-set all breakpoints after symbols have been re-loaded.  */
+unsigned int symbol_generation = 1;
+unsigned int breakpoint_generation  = 0;
+
+void breakpoint_update ()
+{
+  if (breakpoint_generation != symbol_generation) {
+    breakpoint_re_set_all ();
+    breakpoint_generation = symbol_generation;
+  }
+}
+
 void
 breakpoint_re_set (void)
 {
+  symbol_generation++;
+}
+
+/* Re-set all breakpoints after symbols have been re-loaded.  */
+void
+breakpoint_re_set_all (void)
+{
   struct breakpoint *b, *temp;
   enum language save_language;
   int save_input_radix;
@@ -7652,5 +7763,9 @@
 		   &setlist);
   add_show_from_set (c, &showlist);
 
+  c = add_set_cmd ("hack-allow-future-breaks", class_support, var_zinteger,
+                  (char *) &hack_allow_future_breaks,
+                  "Allow breakpoints in unseen .sos to be set\n", &setlist);
+
   can_use_hw_watchpoints = 1;
 }
diff -r -u gdb-6.0/gdb/infrun.c gdb-6.0.sobreak/gdb/infrun.c
--- gdb-6.0/gdb/infrun.c	2003-06-19 16:04:57.000000000 +0100
+++ gdb-6.0.sobreak/gdb/infrun.c	2003-10-20 10:10:58.000000000 +0100
@@ -2182,7 +2182,10 @@
 	     shlib event breakpoint, and SOLIB_ADD might adjust
 	     breakpoint addresses via breakpoint_re_set.  */
 	  if (breakpoints_inserted)
+      {
+        disable_breakpoints_in_shlibs(0);
 	    remove_breakpoints ();
+      }
 	  breakpoints_inserted = 0;
 
 	  /* Check for any newly added shared libraries if we're
@@ -2195,7 +2198,7 @@
 
 	  /* Try to reenable shared library breakpoints, additional
 	     code segments in shared libraries might be mapped in now. */
-	  re_enable_breakpoints_in_shlibs ();
+	  re_enable_breakpoints_in_shlibs();
 
 	  /* If requested, stop when the dynamic linker notifies
 	     gdb of events.  This allows the user to get control

