Phase 1 of the ptid_t changes.
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index e61fab383e9604904236cad1d9debf3a1109655d..805079f2ee78b8d6551d27accc9d79e2b46c5a49 100644 (file)
@@ -1,6 +1,6 @@
 /* Everything about breakpoints, for GDB.
-   Copyright 1986, 87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999
-   Free Software Foundation, Inc.
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "annotate.h"
 #include "symfile.h"
 #include "objfiles.h"
+#include "linespec.h"
+#ifdef UI_OUT
+#include "ui-out.h"
+#endif
 
 #include "gdb-events.h"
 
 /* Prototypes for local functions. */
 
-static void
-catch_command_1 PARAMS ((char *, int, int));
+static void until_break_command_continuation (struct continuation_arg *arg);
 
-static void
-enable_delete_command PARAMS ((char *, int));
+static void catch_command_1 (char *, int, int);
 
-static void
-enable_delete_breakpoint PARAMS ((struct breakpoint *));
+static void enable_delete_command (char *, int);
 
-static void
-enable_once_command PARAMS ((char *, int));
+static void enable_delete_breakpoint (struct breakpoint *);
 
-static void
-enable_once_breakpoint PARAMS ((struct breakpoint *));
+static void enable_once_command (char *, int);
 
-static void
-disable_command PARAMS ((char *, int));
+static void enable_once_breakpoint (struct breakpoint *);
 
-static void
-enable_command PARAMS ((char *, int));
+static void disable_command (char *, int);
 
-static void
-map_breakpoint_numbers PARAMS ((char *, void (*)(struct breakpoint *)));
+static void enable_command (char *, int);
 
-static void
-ignore_command PARAMS ((char *, int));
+static void map_breakpoint_numbers (char *, void (*)(struct breakpoint *));
 
-static int breakpoint_re_set_one PARAMS ((PTR));
+static void ignore_command (char *, int);
 
-static void
-clear_command PARAMS ((char *, int));
+static int breakpoint_re_set_one (PTR);
 
-static void
-catch_command PARAMS ((char *, int));
+static void clear_command (char *, int);
 
-static void
-handle_gnu_4_16_catch_command PARAMS ((char *, int, int));
+static void catch_command (char *, int);
 
-static struct symtabs_and_lines
-get_catch_sals PARAMS ((int));
+static void handle_gnu_4_16_catch_command (char *, int, int);
 
-static void
-watch_command PARAMS ((char *, int));
+static struct symtabs_and_lines get_catch_sals (int);
 
-static int
-can_use_hardware_watchpoint PARAMS ((struct value *));
+static void watch_command (char *, int);
 
-static void break_at_finish_command PARAMS ((char *, int));
-static void break_at_finish_at_depth_command PARAMS ((char *, int));
+static int can_use_hardware_watchpoint (struct value *);
 
-void
-tbreak_command PARAMS ((char *, int));
+static void break_at_finish_command (char *, int);
+static void break_at_finish_at_depth_command (char *, int);
 
-static void tbreak_at_finish_command PARAMS ((char *, int));
+static void tbreak_at_finish_command (char *, int);
 
-static void
-break_command_1 PARAMS ((char *, int, int));
+static void break_command_1 (char *, int, int);
 
-static void
-mention PARAMS ((struct breakpoint *));
+static void mention (struct breakpoint *);
 
-struct breakpoint *
-  set_raw_breakpoint PARAMS ((struct symtab_and_line));
+struct breakpoint *set_raw_breakpoint (struct symtab_and_line);
 
-static void
-check_duplicates PARAMS ((CORE_ADDR, asection *));
+static void check_duplicates (CORE_ADDR, asection *);
 
-static void
-describe_other_breakpoints PARAMS ((CORE_ADDR, asection *));
+static void describe_other_breakpoints (CORE_ADDR, asection *);
 
-static void
-breakpoints_info PARAMS ((char *, int));
+static void breakpoints_info (char *, int);
 
-static void
-breakpoint_1 PARAMS ((int, int));
+static void breakpoint_1 (int, int);
 
-static bpstat
-  bpstat_alloc PARAMS ((struct breakpoint *, bpstat));
+static bpstat bpstat_alloc (struct breakpoint *, bpstat);
 
-static int breakpoint_cond_eval PARAMS ((PTR));
+static int breakpoint_cond_eval (PTR);
 
-static void
-cleanup_executing_breakpoints PARAMS ((PTR));
+static void cleanup_executing_breakpoints (PTR);
 
-static void
-commands_command PARAMS ((char *, int));
+static void commands_command (char *, int);
 
-static void
-condition_command PARAMS ((char *, int));
+static void condition_command (char *, int);
 
-static int
-get_number PARAMS ((char **));
+static int get_number_trailer (char **, int);
 
-void
-set_breakpoint_count PARAMS ((int));
+void set_breakpoint_count (int);
 
 #if 0
-static struct breakpoint *
-  create_temp_exception_breakpoint PARAMS ((CORE_ADDR));
+static struct breakpoint *create_temp_exception_breakpoint (CORE_ADDR);
 #endif
 
 typedef enum
@@ -152,10 +126,11 @@ typedef enum
   }
 insertion_state_t;
 
-static int
-remove_breakpoint PARAMS ((struct breakpoint *, insertion_state_t));
+static int remove_breakpoint (struct breakpoint *, insertion_state_t);
 
-static int print_it_normal PARAMS ((bpstat));
+static enum print_stop_action print_it_typical (bpstat);
+
+static enum print_stop_action print_bp_stop_message (bpstat bs);
 
 typedef struct
   {
@@ -164,105 +139,84 @@ typedef struct
   }
 args_for_catchpoint_enable;
 
-static int watchpoint_check PARAMS ((PTR));
-
-static int cover_target_enable_exception_callback PARAMS ((PTR));
+static int watchpoint_check (PTR);
 
-static int print_it_done PARAMS ((bpstat));
+static int cover_target_enable_exception_callback (PTR);
 
-static int print_it_noop PARAMS ((bpstat));
-
-static void maintenance_info_breakpoints PARAMS ((char *, int));
+static void maintenance_info_breakpoints (char *, int);
 
 #ifdef GET_LONGJMP_TARGET
-static void create_longjmp_breakpoint PARAMS ((char *));
+static void create_longjmp_breakpoint (char *);
 #endif
 
-static int hw_breakpoint_used_count PARAMS ((void));
+static int hw_breakpoint_used_count (void);
 
-static int hw_watchpoint_used_count PARAMS ((enum bptype, int *));
+static int hw_watchpoint_used_count (enum bptype, int *);
 
-static void hbreak_command PARAMS ((char *, int));
+static void hbreak_command (char *, int);
 
-static void thbreak_command PARAMS ((char *, int));
+static void thbreak_command (char *, int);
 
-static void watch_command_1 PARAMS ((char *, int, int));
+static void watch_command_1 (char *, int, int);
 
-static void rwatch_command PARAMS ((char *, int));
+static void rwatch_command (char *, int);
 
-static void awatch_command PARAMS ((char *, int));
+static void awatch_command (char *, int);
 
-static void do_enable_breakpoint PARAMS ((struct breakpoint *, enum bpdisp));
+static void do_enable_breakpoint (struct breakpoint *, enum bpdisp);
 
-static void solib_load_unload_1 PARAMS ((char *hookname,
-                                        int tempflag,
-                                        char *dll_pathname,
-                                        char *cond_string,
-                                        enum bptype bp_kind));
+static void solib_load_unload_1 (char *hookname,
+                                int tempflag,
+                                char *dll_pathname,
+                                char *cond_string, enum bptype bp_kind);
 
-static void create_fork_vfork_event_catchpoint PARAMS ((int tempflag, 
-                                                       char *cond_string,
-                                                       enum bptype bp_kind));
+static void create_fork_vfork_event_catchpoint (int tempflag,
+                                               char *cond_string,
+                                               enum bptype bp_kind);
 
-static void break_at_finish_at_depth_command_1 PARAMS ((char *arg, 
-                                                       int flag, 
-                                                       int from_tty));
+static void break_at_finish_at_depth_command_1 (char *arg,
+                                               int flag, int from_tty);
 
-static void break_at_finish_command_1 PARAMS ((char *arg, 
-                                              int flag, 
-                                              int from_tty));
+static void break_at_finish_command_1 (char *arg, int flag, int from_tty);
 
-static void stop_command PARAMS ((char *arg, int from_tty));
+static void stop_command (char *arg, int from_tty);
 
-static void stopin_command PARAMS ((char *arg, int from_tty));
+static void stopin_command (char *arg, int from_tty);
 
-static void stopat_command PARAMS ((char *arg, int from_tty));
+static void stopat_command (char *arg, int from_tty);
 
-static char *ep_find_event_name_end PARAMS ((char *arg));
+static char *ep_find_event_name_end (char *arg);
 
-static char *ep_parse_optional_if_clause PARAMS ((char **arg));
+static char *ep_parse_optional_if_clause (char **arg);
 
-static char *ep_parse_optional_filename PARAMS ((char **arg));
+static char *ep_parse_optional_filename (char **arg);
 
-static void catch_exec_command_1 PARAMS ((char *arg, int tempflag, 
-                                         int from_tty));
+#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 
-  PARAMS ((int tempflag, char *cond_string,
-          enum exception_event_kind ex_event,
-          struct symtab_and_line * sal));
+static void create_exception_catchpoint (int tempflag, char *cond_string,
+                                        enum exception_event_kind ex_event,
+                                        struct symtab_and_line *sal);
 
-static void catch_exception_command_1 
-  PARAMS ((enum exception_event_kind ex_event,
-          char *arg, int tempflag, int from_tty));
+static void catch_exception_command_1 (enum exception_event_kind ex_event, 
+                                      char *arg, int tempflag, int from_tty);
 
-static void tcatch_command PARAMS ((char *arg, int from_tty));
+static void tcatch_command (char *arg, int from_tty);
 
-static void ep_skip_leading_whitespace PARAMS ((char **s));
+static void ep_skip_leading_whitespace (char **s);
 
 /* Prototypes for exported functions. */
 
-static void
-awatch_command PARAMS ((char *, int));
-
-static void
-do_enable_breakpoint PARAMS ((struct breakpoint *, enum bpdisp));
-
 /* If FALSE, gdb will not use hardware support for watchpoints, even
    if such is available. */
 static int can_use_hw_watchpoints;
 
-void delete_command PARAMS ((char *, int));
-
-void _initialize_breakpoint PARAMS ((void));
-
-void set_breakpoint_count PARAMS ((int));
+void _initialize_breakpoint (void);
 
 extern int addressprint;       /* Print machine addresses? */
 
-#if defined (GET_LONGJMP_TARGET) || defined (SOLIB_ADD)
 static int internal_breakpoint_number = -1;
-#endif
 
 /* Are we executing breakpoint commands?  */
 static int executing_breakpoint_commands;
@@ -271,12 +225,12 @@ static int executing_breakpoint_commands;
    ALL_BREAKPOINTS_SAFE does so even if the statment deletes the current
    breakpoint.  */
 
-#define ALL_BREAKPOINTS(b)  for (b = breakpoint_chain; b; b = b->next)
+#define ALL_BREAKPOINTS(B)  for (B = breakpoint_chain; B; B = B->next)
 
-#define ALL_BREAKPOINTS_SAFE(b,tmp)    \
-       for (b = breakpoint_chain;      \
-            b? (tmp=b->next, 1): 0;    \
-            b = tmp)
+#define ALL_BREAKPOINTS_SAFE(B,TMP)    \
+       for (B = breakpoint_chain;      \
+            B ? (TMP=B->next, 1): 0;   \
+            B = TMP)
 
 /* True if SHIFT_INST_REGS defined, false otherwise.  */
 
@@ -367,8 +321,7 @@ int exception_support_initialized = 0;
 /* Set breakpoint count to NUM.  */
 
 void
-set_breakpoint_count (num)
-     int num;
+set_breakpoint_count (int num)
 {
   breakpoint_count = num;
   set_internalvar (lookup_internalvar ("bpnum"),
@@ -378,7 +331,7 @@ set_breakpoint_count (num)
 /* Used in run_command to zero the hit count when a new run starts. */
 
 void
-clear_breakpoint_hit_counts ()
+clear_breakpoint_hit_counts (void)
 {
   struct breakpoint *b;
 
@@ -403,12 +356,14 @@ int default_breakpoint_line;
 
    Currently the string can either be a number or "$" followed by the name
    of a convenience variable.  Making it an expression wouldn't work well
-   for map_breakpoint_numbers (e.g. "4 + 5 + 6").  */
+   for map_breakpoint_numbers (e.g. "4 + 5 + 6").
+   
+   TRAILER is a character which can be found after the number; most
+   commonly this is `-'.  If you don't want a trailer, use \0.  */ 
 static int
-get_number (pp)
-     char **pp;
+get_number_trailer (char **pp, int trailer)
 {
-  int retval;
+  int retval = 0;      /* default */
   char *p = *pp;
 
   if (p == NULL)
@@ -428,11 +383,13 @@ get_number (pp)
       strncpy (varname, start, p - start);
       varname[p - start] = '\0';
       val = value_of_internalvar (lookup_internalvar (varname));
-      if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_INT)
-       error (
- "Convenience variables used to specify breakpoints must have integer values."
-         );
-      retval = (int) value_as_long (val);
+      if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT)
+       retval = (int) value_as_long (val);
+      else
+       {
+         printf_filtered ("Convenience variable must have integer value.\n");
+         retval = 0;
+       }
     }
   else
     {
@@ -442,23 +399,119 @@ get_number (pp)
        ++p;
       if (p == *pp)
        /* There is no number here.  (e.g. "cond a == b").  */
-       error_no_arg ("breakpoint number");
-      retval = atoi (*pp);
+       {
+         /* Skip non-numeric token */
+         while (*p && !isspace((int) *p))
+           ++p;
+         /* Return zero, which caller must interpret as error. */
+         retval = 0;
+       }
+      else
+       retval = atoi (*pp);
+    }
+  if (!(isspace (*p) || *p == '\0' || *p == trailer))
+    {
+      /* Trailing junk: return 0 and let caller print error msg. */
+      while (!(isspace (*p) || *p == '\0' || *p == trailer))
+       ++p;
+      retval = 0;
     }
-  if (!(isspace (*p) || *p == '\0'))
-    error ("breakpoint number expected");
   while (isspace (*p))
     p++;
   *pp = p;
   return retval;
 }
+
+
+/* Like get_number_trailer, but don't allow a trailer.  */
+int
+get_number (char **pp)
+{
+  return get_number_trailer (pp, '\0');
+}
+
+/* Parse a number or a range.
+ * A number will be of the form handled by get_number.
+ * A range will be of the form <number1> - <number2>, and 
+ * will represent all the integers between number1 and number2,
+ * inclusive.
+ *
+ * While processing a range, this fuction is called iteratively;
+ * At each call it will return the next value in the range.
+ *
+ * At the beginning of parsing a range, the char pointer PP will
+ * be advanced past <number1> and left pointing at the '-' token.
+ * Subsequent calls will not advance the pointer until the range
+ * is completed.  The call that completes the range will advance
+ * pointer PP past <number2>.
+ */
+
+int 
+get_number_or_range (char **pp)
+{
+  static int last_retval, end_value;
+  static char *end_ptr;
+  static int in_range = 0;
+
+  if (**pp != '-')
+    {
+      /* Default case: pp is pointing either to a solo number, 
+        or to the first number of a range.  */
+      last_retval = get_number_trailer (pp, '-');
+      if (**pp == '-')
+       {
+         char **temp;
+
+         /* This is the start of a range (<number1> - <number2>).
+            Skip the '-', parse and remember the second number,
+            and also remember the end of the final token.  */
+
+         temp = &end_ptr; 
+         end_ptr = *pp + 1; 
+         while (isspace ((int) *end_ptr))
+           end_ptr++;  /* skip white space */
+         end_value = get_number (temp);
+         if (end_value < last_retval) 
+           {
+             error ("inverted range");
+           }
+         else if (end_value == last_retval)
+           {
+             /* degenerate range (number1 == number2).  Advance the
+                token pointer so that the range will be treated as a
+                single number.  */ 
+             *pp = end_ptr;
+           }
+         else
+           in_range = 1;
+       }
+    }
+  else if (! in_range)
+    error ("negative value");
+  else
+    {
+      /* pp points to the '-' that betokens a range.  All
+        number-parsing has already been done.  Return the next
+        integer value (one greater than the saved previous value).
+        Do not advance the token pointer 'pp' until the end of range
+        is reached.  */
+
+      if (++last_retval == end_value)
+       {
+         /* End of range reached; advance token pointer.  */
+         *pp = end_ptr;
+         in_range = 0;
+       }
+    }
+  return last_retval;
+}
+
+
 \f
 /* condition N EXP -- set break condition of breakpoint N to EXP.  */
 
 static void
-condition_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+condition_command (char *arg, int from_tty)
 {
   register struct breakpoint *b;
   char *p;
@@ -469,17 +522,19 @@ condition_command (arg, from_tty)
 
   p = arg;
   bnum = get_number (&p);
+  if (bnum == 0)
+    error ("Bad breakpoint argument: '%s'", arg);
 
   ALL_BREAKPOINTS (b)
     if (b->number == bnum)
     {
       if (b->cond)
        {
-         free ((PTR) b->cond);
+         xfree (b->cond);
          b->cond = 0;
        }
       if (b->cond_string != NULL)
-       free ((PTR) b->cond_string);
+       xfree (b->cond_string);
 
       if (*p == 0)
        {
@@ -507,9 +562,7 @@ condition_command (arg, from_tty)
 
 /* ARGSUSED */
 static void
-commands_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+commands_command (char *arg, int from_tty)
 {
   register struct breakpoint *b;
   char *p;
@@ -525,6 +578,7 @@ commands_command (arg, from_tty)
 
   p = arg;
   bnum = get_number (&p);
+
   if (p && *p)
     error ("Unexpected extra arguments following breakpoint number.");
 
@@ -553,10 +607,7 @@ commands_command (arg, from_tty)
    shadow contents, not the breakpoints themselves.  From breakpoint.c.  */
 
 int
-read_memory_nobpt (memaddr, myaddr, len)
-     CORE_ADDR memaddr;
-     char *myaddr;
-     unsigned len;
+read_memory_nobpt (CORE_ADDR memaddr, char *myaddr, unsigned len)
 {
   int status;
   struct breakpoint *b;
@@ -637,10 +688,9 @@ read_memory_nobpt (memaddr, myaddr, len)
       if (bp_addr + bp_size < memaddr + len)
        {
          /* Copy the section of memory after the breakpoint.  */
-         status = read_memory_nobpt
-           (bp_addr + bp_size,
-            myaddr + bp_addr + bp_size - memaddr,
-            memaddr + len - (bp_addr + bp_size));
+         status = read_memory_nobpt (bp_addr + bp_size,
+                                     myaddr + bp_addr + bp_size - memaddr,
+                                     memaddr + len - (bp_addr + bp_size));
          if (status != 0)
            return status;
        }
@@ -658,7 +708,7 @@ read_memory_nobpt (memaddr, myaddr, len)
    or an `errno' value if could not write the inferior.  */
 
 int
-insert_breakpoints ()
+insert_breakpoints (void)
 {
   register struct breakpoint *b, *temp;
   int return_val = 0;  /* return success code. */
@@ -671,7 +721,10 @@ insert_breakpoints ()
 
   ALL_BREAKPOINTS_SAFE (b, temp)
   {
-    if (b->type != bp_watchpoint
+    if (b->enable == permanent)
+      /* Permanent breakpoints cannot be inserted or removed.  */
+      continue;
+    else if (b->type != bp_watchpoint
        && b->type != bp_hardware_watchpoint
        && b->type != bp_read_watchpoint
        && b->type != bp_access_watchpoint
@@ -805,6 +858,7 @@ insert_breakpoints ()
              b->type == bp_read_watchpoint ||
              b->type == bp_access_watchpoint)
             && b->enable == enabled
+            && b->disposition != del_at_next_stop
             && !b->inserted
             && !b->duplicate)
       {
@@ -839,8 +893,13 @@ insert_breakpoints ()
        if (within_current_scope)
          {
            /* Evaluate the expression and cut the chain of values
-              produced off from the value chain.  */
+              produced off from the value chain.
+
+              Make sure the value returned isn't lazy; we use
+              laziness to determine what memory GDB actually needed
+              in order to compute the value of the expression.  */
            v = evaluate_expression (b->exp);
+           VALUE_CONTENTS(v);
            value_release_to_mark (mark);
 
            b->val_chain = v;
@@ -849,26 +908,45 @@ insert_breakpoints ()
            /* Look at each value on the value chain.  */
            for (; v; v = v->next)
              {
-               /* If it's a memory location, then we must watch it.  */
-               if (v->lval == lval_memory)
+               /* If it's a memory location, and GDB actually needed
+                   its contents to evaluate the expression, then we
+                   must watch it.  */
+               if (VALUE_LVAL (v) == lval_memory
+                   && ! VALUE_LAZY (v))
                  {
-                   int addr, len, type;
-
-                   addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
-                   len = TYPE_LENGTH (VALUE_TYPE (v));
-                   type   = hw_write;
-                   if (b->type == bp_read_watchpoint)
-                     type = hw_read;
-                   else if (b->type == bp_access_watchpoint)
-                     type = hw_access;
-
-                   val = target_insert_watchpoint (addr, len, type);
-                   if (val == -1)
+                   struct type *vtype = check_typedef (VALUE_TYPE (v));
+
+                   /* We only watch structs and arrays if user asked
+                      for it explicitly, never if they just happen to
+                      appear in the middle of some value chain.  */
+                   if (v == b->val_chain
+                       || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+                           && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
                      {
-                       b->inserted = 0;
-                       break;
+                       CORE_ADDR addr;
+                       int len, type;
+
+                       addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+                       len = TYPE_LENGTH (VALUE_TYPE (v));
+                       type   = hw_write;
+                       if (b->type == bp_read_watchpoint)
+                         type = hw_read;
+                       else if (b->type == bp_access_watchpoint)
+                         type = hw_access;
+
+                       val = target_insert_watchpoint (addr, len, type);
+                       if (val == -1)
+                         {
+                           /* Don't exit the loop, try to insert
+                              every value on the value chain.  That's
+                              because we will be removing all the
+                              watches below, and removing a
+                              watchpoint we didn't insert could have
+                              adverse effects.  */
+                           b->inserted = 0;
+                         }
+                       val = 0;
                      }
-                   val = 0;
                  }
              }
            /* Failure to insert a watchpoint on any memory value in the
@@ -883,7 +961,7 @@ insert_breakpoints ()
          }
        else
          {
-           printf_filtered ("Hardware watchpoint %d deleted", b->number);
+           printf_filtered ("Hardware watchpoint %d deleted ", b->number);
            printf_filtered ("because the program has left the block \n");
            printf_filtered ("in which its expression is valid.\n");
            if (b->related_breakpoint)
@@ -894,7 +972,7 @@ insert_breakpoints ()
        /* Restore the frame and level.  */
        if ((saved_frame != selected_frame) ||
            (saved_level != selected_frame_level))
-         select_and_print_frame (saved_frame, saved_level);
+         select_frame (saved_frame, saved_level);
 
        if (val)
          return_val = val;     /* remember failure */
@@ -910,13 +988,13 @@ insert_breakpoints ()
        switch (b->type)
          {
          case bp_catch_fork:
-           val = target_insert_fork_catchpoint (inferior_pid);
+           val = target_insert_fork_catchpoint (PIDGET (inferior_ptid));
            break;
          case bp_catch_vfork:
-           val = target_insert_vfork_catchpoint (inferior_pid);
+           val = target_insert_vfork_catchpoint (PIDGET (inferior_ptid));
            break;
          case bp_catch_exec:
-           val = target_insert_exec_catchpoint (inferior_pid);
+           val = target_insert_exec_catchpoint (PIDGET (inferior_ptid));
            break;
          default:
            warning ("Internal error, %s line %d.", __FILE__, __LINE__);
@@ -940,7 +1018,7 @@ insert_breakpoints ()
 
 
 int
-remove_breakpoints ()
+remove_breakpoints (void)
 {
   register struct breakpoint *b;
   int val;
@@ -958,15 +1036,35 @@ remove_breakpoints ()
 }
 
 int
-reattach_breakpoints (pid)
-     int pid;
+remove_hw_watchpoints (void)
+{
+  register struct breakpoint *b;
+  int val;
+
+  ALL_BREAKPOINTS (b)
+  {
+    if (b->inserted
+       && (b->type == bp_hardware_watchpoint
+           || b->type == bp_read_watchpoint
+           || b->type == bp_access_watchpoint))
+      {
+       val = remove_breakpoint (b, mark_uninserted);
+       if (val != 0)
+         return val;
+      }
+  }
+  return 0;
+}
+
+int
+reattach_breakpoints (int pid)
 {
   register struct breakpoint *b;
   int val;
-  int saved_inferior_pid = inferior_pid;
+  ptid_t saved_inferior_ptid = inferior_ptid;
 
-  /* FIXME: use a cleanup, to insure that inferior_pid gets replaced! */
-  inferior_pid = pid;  /* Because remove_breakpoint will use this global. */
+  /* FIXME: use a cleanup, to insure that inferior_ptid gets replaced! */
+  inferior_ptid = pid_to_ptid (pid);   /* Because remove_breakpoint will use this global. */
   ALL_BREAKPOINTS (b)
   {
     if (b->inserted)
@@ -978,17 +1076,17 @@ reattach_breakpoints (pid)
          val = target_insert_breakpoint (b->address, b->shadow_contents);
        if (val != 0)
          {
-           inferior_pid = saved_inferior_pid;
+           inferior_ptid = saved_inferior_ptid;
            return val;
          }
       }
   }
-  inferior_pid = saved_inferior_pid;
+  inferior_ptid = saved_inferior_ptid;
   return 0;
 }
 
 void
-update_breakpoints_after_exec ()
+update_breakpoints_after_exec (void)
 {
   struct breakpoint *b;
   struct breakpoint *temp;
@@ -1007,6 +1105,13 @@ update_breakpoints_after_exec ()
        continue;
       }
 
+    /* Thread event breakpoints must be set anew after an exec().  */
+    if (b->type == bp_thread_event)
+      {
+       delete_breakpoint (b);
+       continue;
+      }
+
     /* Step-resume breakpoints are meaningless after an exec(). */
     if (b->type == bp_step_resume)
       {
@@ -1096,18 +1201,17 @@ update_breakpoints_after_exec ()
 }
 
 int
-detach_breakpoints (pid)
-     int pid;
+detach_breakpoints (int pid)
 {
   register struct breakpoint *b;
   int val;
-  int saved_inferior_pid = inferior_pid;
+  ptid_t saved_inferior_ptid = inferior_ptid;
 
-  if (pid == inferior_pid)
-    error ("Cannot detach breakpoints of inferior_pid");
+  if (pid == PIDGET (inferior_ptid))
+    error ("Cannot detach breakpoints of inferior_ptid");
 
-  /* FIXME: use a cleanup, to insure that inferior_pid gets replaced! */
-  inferior_pid = pid;  /* Because remove_breakpoint will use this global. */
+  /* FIXME: use a cleanup, to insure that inferior_ptid gets replaced! */
+  inferior_ptid = pid_to_ptid (pid);   /* Because remove_breakpoint will use this global. */
   ALL_BREAKPOINTS (b)
   {
     if (b->inserted)
@@ -1115,22 +1219,24 @@ detach_breakpoints (pid)
        val = remove_breakpoint (b, mark_inserted);
        if (val != 0)
          {
-           inferior_pid = saved_inferior_pid;
+           inferior_ptid = saved_inferior_ptid;
            return val;
          }
       }
   }
-  inferior_pid = saved_inferior_pid;
+  inferior_ptid = saved_inferior_ptid;
   return 0;
 }
 
 static int
-remove_breakpoint (b, is)
-     struct breakpoint *b;
-     insertion_state_t is;
+remove_breakpoint (struct breakpoint *b, insertion_state_t is)
 {
   int val;
 
+  if (b->enable == permanent)
+    /* Permanent breakpoints cannot be inserted or removed.  */
+    return 0;
+
   if (b->type == bp_none)
     warning ("attempted to remove apparently deleted breakpoint #%d?", 
             b->number);
@@ -1144,7 +1250,6 @@ remove_breakpoint (b, is)
       && b->type != bp_catch_exec
       && b->type != bp_catch_catch
       && b->type != bp_catch_throw)
-
     {
       if (b->type == bp_hardware_breakpoint)
        val = target_remove_hw_breakpoint (b->address, b->shadow_contents);
@@ -1153,7 +1258,7 @@ remove_breakpoint (b, is)
          /* Check to see if breakpoint is in an overlay section;
             if so, we should remove the breakpoint at the LMA address.
             If that is not equal to the raw address, then we should 
-            presumable remove the breakpoint there as well.  */
+            presumably remove the breakpoint there as well.  */
          if (overlay_debugging && b->section &&
              section_is_overlay (b->section))
            {
@@ -1191,22 +1296,31 @@ remove_breakpoint (b, is)
        {
          /* For each memory reference remove the watchpoint
             at that address.  */
-         if (v->lval == lval_memory)
+         if (VALUE_LVAL (v) == lval_memory
+             && ! VALUE_LAZY (v))
            {
-             int addr, len, type;
-
-             addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
-             len = TYPE_LENGTH (VALUE_TYPE (v));
-             type   = hw_write;
-             if (b->type == bp_read_watchpoint)
-               type = hw_read;
-             else if (b->type == bp_access_watchpoint)
-               type = hw_access;
+             struct type *vtype = check_typedef (VALUE_TYPE (v));
 
-             val = target_remove_watchpoint (addr, len, type);
-             if (val == -1)
-               b->inserted = 1;
-             val = 0;
+             if (v == b->val_chain
+                 || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+                     && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
+               {
+                 CORE_ADDR addr;
+                 int len, type;
+
+                 addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+                 len = TYPE_LENGTH (VALUE_TYPE (v));
+                 type   = hw_write;
+                 if (b->type == bp_read_watchpoint)
+                   type = hw_read;
+                 else if (b->type == bp_access_watchpoint)
+                   type = hw_access;
+
+                 val = target_remove_watchpoint (addr, len, type);
+                 if (val == -1)
+                   b->inserted = 1;
+                 val = 0;
+               }
            }
        }
       /* Failure to remove any of the hardware watchpoints comes here.  */
@@ -1233,13 +1347,13 @@ remove_breakpoint (b, is)
       switch (b->type)
        {
        case bp_catch_fork:
-         val = target_remove_fork_catchpoint (inferior_pid);
+         val = target_remove_fork_catchpoint (PIDGET (inferior_ptid));
          break;
        case bp_catch_vfork:
-         val = target_remove_vfork_catchpoint (inferior_pid);
+         val = target_remove_vfork_catchpoint (PIDGET (inferior_ptid));
          break;
        case bp_catch_exec:
-         val = target_remove_exec_catchpoint (inferior_pid);
+         val = target_remove_exec_catchpoint (PIDGET (inferior_ptid));
          break;
        default:
          warning ("Internal error, %s line %d.", __FILE__, __LINE__);
@@ -1279,7 +1393,7 @@ remove_breakpoint (b, is)
 /* Clear the "inserted" flag in all breakpoints.  */
 
 void
-mark_breakpoints_out ()
+mark_breakpoints_out (void)
 {
   register struct breakpoint *b;
 
@@ -1300,8 +1414,7 @@ mark_breakpoints_out ()
 
 
 void
-breakpoint_init_inferior (context)
-     enum inf_context context;
+breakpoint_init_inferior (enum inf_context context)
 {
   register struct breakpoint *b, *temp;
   static int warning_needed = 0;
@@ -1357,40 +1470,47 @@ breakpoint_init_inferior (context)
     }
 }
 
-/* breakpoint_here_p (PC) returns 1 if an enabled breakpoint exists at
-   PC.  When continuing from a location with a breakpoint, we actually
-   single step once before calling insert_breakpoints.  */
+/* breakpoint_here_p (PC) returns non-zero if an enabled breakpoint
+   exists at PC.  It returns ordinary_breakpoint_here if it's an
+   ordinary breakpoint, or permanent_breakpoint_here if it's a
+   permanent breakpoint.
+   - When continuing from a location with an ordinary breakpoint, we
+     actually single step once before calling insert_breakpoints.
+   - When continuing from a localion with a permanent breakpoint, we
+     need to use the `SKIP_PERMANENT_BREAKPOINT' macro, provided by
+     the target, to advance the PC past the breakpoint.  */
 
-int
-breakpoint_here_p (pc)
-     CORE_ADDR pc;
+enum breakpoint_here
+breakpoint_here_p (CORE_ADDR pc)
 {
   register struct breakpoint *b;
+  int any_breakpoint_here = 0;
 
   ALL_BREAKPOINTS (b)
-    if (b->enable == enabled
-       && b->enable != shlib_disabled
-       && b->enable != call_disabled
+    if ((b->enable == enabled
+        || b->enable == permanent)
        && b->address == pc)    /* bp is enabled and matches pc */
-    {
-      if (overlay_debugging &&
-         section_is_overlay (b->section) &&
-         !section_is_mapped (b->section))
-       continue;               /* unmapped overlay -- can't be a match */
-      else
-       return 1;
-    }
+      {
+       if (overlay_debugging &&
+           section_is_overlay (b->section) &&
+           !section_is_mapped (b->section))
+         continue;             /* unmapped overlay -- can't be a match */
+       else if (b->enable == permanent)
+         return permanent_breakpoint_here;
+       else
+         any_breakpoint_here = 1;
+      }
 
-  return 0;
+  return any_breakpoint_here ? ordinary_breakpoint_here : 0;
 }
 
+
 /* breakpoint_inserted_here_p (PC) is just like breakpoint_here_p(),
    but it only returns true if there is actually a breakpoint inserted
    at PC.  */
 
 int
-breakpoint_inserted_here_p (pc)
-     CORE_ADDR pc;
+breakpoint_inserted_here_p (CORE_ADDR pc)
 {
   register struct breakpoint *b;
 
@@ -1416,8 +1536,7 @@ breakpoint_inserted_here_p (pc)
    bp_call_dummy breakpoint.  */
 
 int
-frame_in_dummy (frame)
-     struct frame_info *frame;
+frame_in_dummy (struct frame_info *frame)
 {
   struct breakpoint *b;
 
@@ -1442,18 +1561,16 @@ frame_in_dummy (frame)
   return 0;
 }
 
-/* breakpoint_match_thread (PC, PID) returns true if the breakpoint at PC
-   is valid for process/thread PID.  */
+/* breakpoint_thread_match (PC, PID) returns true if the breakpoint at
+   PC is valid for process/thread PID.  */
 
 int
-breakpoint_thread_match (pc, pid)
-     CORE_ADDR pc;
-     int pid;
+breakpoint_thread_match (CORE_ADDR pc, ptid_t ptid)
 {
   struct breakpoint *b;
   int thread;
 
-  thread = pid_to_thread_id (pid);
+  thread = pid_to_thread_id (ptid);
 
   ALL_BREAKPOINTS (b)
     if (b->enable != disabled
@@ -1478,8 +1595,7 @@ breakpoint_thread_match (pc, pid)
    in breakpoint.h.  */
 
 int
-ep_is_catchpoint (ep)
-     struct breakpoint *ep;
+ep_is_catchpoint (struct breakpoint *ep)
 {
   return
     (ep->type == bp_catch_load)
@@ -1488,39 +1604,32 @@ ep_is_catchpoint (ep)
     || (ep->type == bp_catch_vfork)
     || (ep->type == bp_catch_exec)
     || (ep->type == bp_catch_catch)
-    || (ep->type == bp_catch_throw)
-
+    || (ep->type == bp_catch_throw);
 
   /* ??rehrauer: Add more kinds here, as are implemented... */
-    ;
 }
 
 int
-ep_is_shlib_catchpoint (ep)
-     struct breakpoint *ep;
+ep_is_shlib_catchpoint (struct breakpoint *ep)
 {
   return
     (ep->type == bp_catch_load)
-    || (ep->type == bp_catch_unload)
-    ;
+    || (ep->type == bp_catch_unload);
 }
 
 int
-ep_is_exception_catchpoint (ep)
-     struct breakpoint *ep;
+ep_is_exception_catchpoint (struct breakpoint *ep)
 {
   return
     (ep->type == bp_catch_catch)
-    || (ep->type == bp_catch_throw)
-    ;
+    || (ep->type == bp_catch_throw);
 }
 
 /* Clear a bpstat so that it says we are not at any breakpoint.
    Also free any storage that is part of a bpstat.  */
 
 void
-bpstat_clear (bsp)
-     bpstat *bsp;
+bpstat_clear (bpstat *bsp)
 {
   bpstat p;
   bpstat q;
@@ -1533,7 +1642,7 @@ bpstat_clear (bsp)
       q = p->next;
       if (p->old_val != NULL)
        value_free (p->old_val);
-      free ((PTR) p);
+      xfree (p);
       p = q;
     }
   *bsp = NULL;
@@ -1543,8 +1652,7 @@ bpstat_clear (bsp)
    is part of the bpstat is copied as well.  */
 
 bpstat
-bpstat_copy (bs)
-     bpstat bs;
+bpstat_copy (bpstat bs)
 {
   bpstat p = NULL;
   bpstat tmp;
@@ -1571,9 +1679,7 @@ bpstat_copy (bs)
 /* Find the bpstat associated with this breakpoint */
 
 bpstat
-bpstat_find_breakpoint (bsp, breakpoint)
-     bpstat bsp;
-     struct breakpoint *breakpoint;
+bpstat_find_breakpoint (bpstat bsp, struct breakpoint *breakpoint)
 {
   if (bsp == NULL)
     return NULL;
@@ -1595,8 +1701,7 @@ bpstat_find_breakpoint (bsp, breakpoint)
 
    See wait_for_inferior's use of this function.  */
 struct breakpoint *
-bpstat_find_step_resume_breakpoint (bsp)
-     bpstat bsp;
+bpstat_find_step_resume_breakpoint (bpstat bsp)
 {
   if (bsp == NULL)
     error ("Internal error (bpstat_find_step_resume_breakpoint)");
@@ -1619,8 +1724,7 @@ bpstat_find_step_resume_breakpoint (bsp)
    Return 0 if passed a bpstat which does not indicate any breakpoints.  */
 
 int
-bpstat_num (bsp)
-     bpstat *bsp;
+bpstat_num (bpstat *bsp)
 {
   struct breakpoint *b;
 
@@ -1640,8 +1744,7 @@ bpstat_num (bsp)
 /* Modify BS so that the actions will not be performed.  */
 
 void
-bpstat_clear_actions (bs)
-     bpstat bs;
+bpstat_clear_actions (bpstat bs)
 {
   for (; bs != NULL; bs = bs->next)
     {
@@ -1657,8 +1760,7 @@ bpstat_clear_actions (bs)
 /* Stub for cleaning up our state if we error-out of a breakpoint command */
 /* ARGSUSED */
 static void
-cleanup_executing_breakpoints (ignore)
-     PTR ignore;
+cleanup_executing_breakpoints (PTR ignore)
 {
   executing_breakpoint_commands = 0;
 }
@@ -1669,8 +1771,7 @@ cleanup_executing_breakpoints (ignore)
    the global "breakpoint_proceeded" after each command.  */
 
 void
-bpstat_do_actions (bsp)
-     bpstat *bsp;
+bpstat_do_actions (bpstat *bsp)
 {
   bpstat bs;
   struct cleanup *old_chain;
@@ -1723,80 +1824,120 @@ top:
   discard_cleanups (old_chain);
 }
 
-/* This is the normal print_it function for a bpstat.  In the future,
+/* This is the normal print function for a bpstat.  In the future,
    much of this logic could (should?) be moved to bpstat_stop_status,
-   by having it set different print_it functions.
-
-   Current scheme: When we stop, bpstat_print() is called.
-   It loops through the bpstat list of things causing this stop,
-   calling the print_it function for each one. The default
-   print_it function, used for breakpoints, is print_it_normal().
-   (Also see print_it_noop() and print_it_done()).
-
-   Return values from this routine (used by bpstat_print() to
-   decide what to do):
-   1: Means we printed something, and we do *not* desire that
-   something to be followed by a location.
-   0: Means we printed something, and we *do*  desire that
-   something to be followed by a location.
-   -1: Means we printed nothing.  */
-
-static int
-print_it_normal (bs)
-     bpstat bs;
-{
+   by having it set different print_it values.
+
+   Current scheme: When we stop, bpstat_print() is called.  It loops
+   through the bpstat list of things causing this stop, calling the
+   print_bp_stop_message function on each one. The behavior of the
+   print_bp_stop_message function depends on the print_it field of
+   bpstat. If such field so indicates, call this function here.
+
+   Return values from this routine (ultimately used by bpstat_print()
+   and normal_stop() to decide what to do): 
+   PRINT_NOTHING: Means we already printed all we needed to print,
+   don't print anything else.
+   PRINT_SRC_ONLY: Means we printed something, and we do *not* desire
+   that something to be followed by a location.
+   PRINT_SCR_AND_LOC: Means we printed something, and we *do* desire
+   that something to be followed by a location.
+   PRINT_UNKNOWN: Means we printed nothing or we need to do some more
+   analysis.  */
+
+static enum print_stop_action
+print_it_typical (bpstat bs)
+{
+#ifdef UI_OUT
+  struct cleanup *old_chain;
+  struct ui_stream *stb;
+  stb = ui_out_stream_new (uiout);
+  old_chain = make_cleanup_ui_out_stream_delete (stb);
+#endif /* UI_OUT */
   /* bs->breakpoint_at can be NULL if it was a momentary breakpoint
      which has since been deleted.  */
-  if (bs->breakpoint_at == NULL
-      || (bs->breakpoint_at->type != bp_breakpoint
-         && bs->breakpoint_at->type != bp_catch_load
-         && bs->breakpoint_at->type != bp_catch_unload
-         && bs->breakpoint_at->type != bp_catch_fork
-         && bs->breakpoint_at->type != bp_catch_vfork
-         && bs->breakpoint_at->type != bp_catch_exec
-         && bs->breakpoint_at->type != bp_catch_catch
-         && bs->breakpoint_at->type != bp_catch_throw
-         && bs->breakpoint_at->type != bp_hardware_breakpoint
-         && bs->breakpoint_at->type != bp_watchpoint
-         && bs->breakpoint_at->type != bp_read_watchpoint
-         && bs->breakpoint_at->type != bp_access_watchpoint
-         && bs->breakpoint_at->type != bp_hardware_watchpoint))
-    return -1;
+  if (bs->breakpoint_at == NULL)
+    return PRINT_UNKNOWN;
 
-  if (ep_is_shlib_catchpoint (bs->breakpoint_at))
+  switch (bs->breakpoint_at->type)
     {
+    case bp_breakpoint:
+    case bp_hardware_breakpoint:
+#ifdef UI_OUT
+      annotate_breakpoint (bs->breakpoint_at->number);
+      ui_out_text (uiout, "\nBreakpoint ");
+      if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+       ui_out_field_string (uiout, "reason", "breakpoint-hit");
+      ui_out_field_int (uiout, "bkptno", bs->breakpoint_at->number);
+      ui_out_text (uiout, ", ");
+      return PRINT_SRC_AND_LOC;
+#else
+      /* I think the user probably only wants to see one breakpoint
+         number, not all of them.  */
+      annotate_breakpoint (bs->breakpoint_at->number);
+      printf_filtered ("\nBreakpoint %d, ", bs->breakpoint_at->number);
+      return PRINT_SRC_AND_LOC;
+#endif
+      break;
+
+    case bp_shlib_event:
+      /* Did we stop because the user set the stop_on_solib_events
+        variable?  (If so, we report this as a generic, "Stopped due
+        to shlib event" message.) */
+      printf_filtered ("Stopped due to shared library event\n");
+      return PRINT_NOTHING;
+      break;
+
+    case bp_thread_event:
+      /* Not sure how we will get here. 
+        GDB should not stop for these breakpoints.  */
+      printf_filtered ("Thread Event Breakpoint: gdb should not stop!\n");
+      return PRINT_NOTHING;
+      break;
+
+    case bp_catch_load:
       annotate_catchpoint (bs->breakpoint_at->number);
       printf_filtered ("\nCatchpoint %d (", bs->breakpoint_at->number);
-      if (bs->breakpoint_at->type == bp_catch_load)
-       printf_filtered ("loaded");
-      else if (bs->breakpoint_at->type == bp_catch_unload)
-       printf_filtered ("unloaded");
+      printf_filtered ("loaded");
       printf_filtered (" %s), ", bs->breakpoint_at->triggered_dll_pathname);
-      return 0;
-    }
-  else if (bs->breakpoint_at->type == bp_catch_fork ||
-          bs->breakpoint_at->type == bp_catch_vfork)
-    {
+      return PRINT_SRC_AND_LOC;
+      break;
+
+    case bp_catch_unload:
+      annotate_catchpoint (bs->breakpoint_at->number);
+      printf_filtered ("\nCatchpoint %d (", bs->breakpoint_at->number);
+      printf_filtered ("unloaded");
+      printf_filtered (" %s), ", bs->breakpoint_at->triggered_dll_pathname);
+      return PRINT_SRC_AND_LOC;
+      break;
+
+    case bp_catch_fork:
       annotate_catchpoint (bs->breakpoint_at->number);
       printf_filtered ("\nCatchpoint %d (", bs->breakpoint_at->number);
-      if (bs->breakpoint_at->type == bp_catch_fork)
-       printf_filtered ("forked");
-      else if (bs->breakpoint_at->type == bp_catch_vfork)
-       printf_filtered ("vforked");
+      printf_filtered ("forked");
       printf_filtered (" process %d), ", 
                       bs->breakpoint_at->forked_inferior_pid);
-      return 0;
-    }
-  else if (bs->breakpoint_at->type == bp_catch_exec)
-    {
+      return PRINT_SRC_AND_LOC;
+      break;
+
+    case bp_catch_vfork:
+      annotate_catchpoint (bs->breakpoint_at->number);
+      printf_filtered ("\nCatchpoint %d (", bs->breakpoint_at->number);
+      printf_filtered ("vforked");
+      printf_filtered (" process %d), ", 
+                      bs->breakpoint_at->forked_inferior_pid);
+      return PRINT_SRC_AND_LOC;
+      break;
+
+    case bp_catch_exec:
       annotate_catchpoint (bs->breakpoint_at->number);
       printf_filtered ("\nCatchpoint %d (exec'd %s), ",
                       bs->breakpoint_at->number,
                       bs->breakpoint_at->exec_pathname);
-      return 0;
-    }
-  else if (bs->breakpoint_at->type == bp_catch_catch)
-    {
+      return PRINT_SRC_AND_LOC;
+      break;
+
+    case bp_catch_catch:
       if (current_exception_event && 
          (CURRENT_EXCEPTION_KIND == EX_EVENT_CATCH))
        {
@@ -1820,15 +1961,17 @@ print_it_normal (bs)
            printf_filtered ("unknown");
 
          printf_filtered ("\n");
-         return 1;     /* don't bother to print location frame info */
+         /* don't bother to print location frame info */
+         return PRINT_SRC_ONLY;
        }
       else
        {
-         return -1;    /* really throw, some other bpstat will handle it */
+         /* really throw, some other bpstat will handle it */
+         return PRINT_UNKNOWN; 
        }
-    }
-  else if (bs->breakpoint_at->type == bp_catch_throw)
-    {
+      break;
+
+    case bp_catch_throw:
       if (current_exception_event && 
          (CURRENT_EXCEPTION_KIND == EX_EVENT_THROW))
        {
@@ -1852,97 +1995,227 @@ print_it_normal (bs)
            printf_filtered ("unknown");
 
          printf_filtered ("\n");
-         return 1;     /* don't bother to print location frame info */
+         /* don't bother to print location frame info */
+         return PRINT_SRC_ONLY; 
        }
       else
        {
-         return -1;    /* really catch, some other bpstat willhandle it */
+         /* really catch, some other bpstat will handle it */
+         return PRINT_UNKNOWN; 
        }
-    }
+      break;
 
-  else if (bs->breakpoint_at->type == bp_breakpoint ||
-          bs->breakpoint_at->type == bp_hardware_breakpoint)
-    {
-      /* I think the user probably only wants to see one breakpoint
-         number, not all of them.  */
-      annotate_breakpoint (bs->breakpoint_at->number);
-      printf_filtered ("\nBreakpoint %d, ", bs->breakpoint_at->number);
-      return 0;
-    }
-  else if ((bs->old_val != NULL) &&
-          (bs->breakpoint_at->type == bp_watchpoint ||
-           bs->breakpoint_at->type == bp_access_watchpoint ||
-           bs->breakpoint_at->type == bp_hardware_watchpoint))
-    {
-      annotate_watchpoint (bs->breakpoint_at->number);
-      mention (bs->breakpoint_at);
-      printf_filtered ("\nOld value = ");
-      value_print (bs->old_val, gdb_stdout, 0, Val_pretty_default);
-      printf_filtered ("\nNew value = ");
-      value_print (bs->breakpoint_at->val, gdb_stdout, 0,
-                  Val_pretty_default);
-      printf_filtered ("\n");
-      value_free (bs->old_val);
-      bs->old_val = NULL;
+    case bp_watchpoint:
+    case bp_hardware_watchpoint:
+      if (bs->old_val != NULL)
+       {
+         annotate_watchpoint (bs->breakpoint_at->number);
+#ifdef UI_OUT
+         if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+           ui_out_field_string (uiout, "reason", "watchpoint-trigger");
+         mention (bs->breakpoint_at);
+         ui_out_list_begin (uiout, "value");
+         ui_out_text (uiout, "\nOld value = ");
+         value_print (bs->old_val, stb->stream, 0, Val_pretty_default);
+         ui_out_field_stream (uiout, "old", stb);
+         ui_out_text (uiout, "\nNew value = ");
+         value_print (bs->breakpoint_at->val, stb->stream, 0, Val_pretty_default);
+         ui_out_field_stream (uiout, "new", stb);
+         ui_out_list_end (uiout);
+         ui_out_text (uiout, "\n");
+#else
+         mention (bs->breakpoint_at);
+         printf_filtered ("\nOld value = ");
+         value_print (bs->old_val, gdb_stdout, 0, Val_pretty_default);
+         printf_filtered ("\nNew value = ");
+         value_print (bs->breakpoint_at->val, gdb_stdout, 0,
+                      Val_pretty_default);
+         printf_filtered ("\n");
+#endif
+         value_free (bs->old_val);
+         bs->old_val = NULL;
+       }
       /* More than one watchpoint may have been triggered.  */
-      return -1;
-    }
-  else if (bs->breakpoint_at->type == bp_access_watchpoint ||
-          bs->breakpoint_at->type == bp_read_watchpoint)
-    {
+      return PRINT_UNKNOWN;
+      break;
+
+    case bp_read_watchpoint:
+#ifdef UI_OUT
+      if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+       ui_out_field_string (uiout, "reason", "read-watchpoint-trigger");
+      mention (bs->breakpoint_at);
+      ui_out_list_begin (uiout, "value");
+      ui_out_text (uiout, "\nValue = ");
+      value_print (bs->breakpoint_at->val, stb->stream, 0, Val_pretty_default);
+      ui_out_field_stream (uiout, "value", stb);
+      ui_out_list_end (uiout);
+      ui_out_text (uiout, "\n");
+#else
       mention (bs->breakpoint_at);
       printf_filtered ("\nValue = ");
       value_print (bs->breakpoint_at->val, gdb_stdout, 0,
                   Val_pretty_default);
       printf_filtered ("\n");
-      return -1;
-    }
-  /* We can't deal with it.  
-     Maybe another member of the bpstat chain can.  */
-  return -1;
-}
-
-/* Print a message indicating what happened.
-   This is called from normal_stop().
-   The input to this routine is the head of the bpstat list - a list
-   of the eventpoints that caused this stop.
-   This routine calls the "print_it" routine(s) associated
-   with these eventpoints. This will print (for example)
-   the "Breakpoint n," part of the output.
-   The return value of this routine is one of:
+#endif
+      return PRINT_UNKNOWN;
+      break;
 
-   -1: Means we printed nothing
-   0: Means we printed something, and expect subsequent
-   code to print the location. An example is 
-   "Breakpoint 1, " which should be followed by
-   the location.
-   1 : Means we printed something, but there is no need
-   to also print the location part of the message.
-   An example is the catch/throw messages, which
-   don't require a location appended to the end.  */
+    case bp_access_watchpoint:
+#ifdef UI_OUT
+      if (bs->old_val != NULL)     
+       {
+         annotate_watchpoint (bs->breakpoint_at->number);
+         if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+           ui_out_field_string (uiout, "reason", "access-watchpoint-trigger");
+         mention (bs->breakpoint_at);
+         ui_out_list_begin (uiout, "value");
+         ui_out_text (uiout, "\nOld value = ");
+         value_print (bs->old_val, stb->stream, 0, Val_pretty_default);
+         ui_out_field_stream (uiout, "old", stb);
+         value_free (bs->old_val);
+         bs->old_val = NULL;
+         ui_out_text (uiout, "\nNew value = ");
+       }
+      else 
+       {
+         mention (bs->breakpoint_at);
+         if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+           ui_out_field_string (uiout, "reason", "access-watchpoint-trigger");
+         ui_out_list_begin (uiout, "value");
+         ui_out_text (uiout, "\nValue = ");
+       }
+      value_print (bs->breakpoint_at->val, stb->stream, 0,Val_pretty_default);
+      ui_out_field_stream (uiout, "new", stb);
+      ui_out_list_end (uiout);
+      ui_out_text (uiout, "\n");
+#else
+      if (bs->old_val != NULL)     
+       {
+         annotate_watchpoint (bs->breakpoint_at->number);
+         mention (bs->breakpoint_at);
+         printf_filtered ("\nOld value = ");
+         value_print (bs->old_val, gdb_stdout, 0, Val_pretty_default);
+         value_free (bs->old_val);
+         bs->old_val = NULL;
+         printf_filtered ("\nNew value = ");
+       }
+      else 
+       {
+         mention (bs->breakpoint_at);
+         printf_filtered ("\nValue = ");
+       }
+      value_print (bs->breakpoint_at->val, gdb_stdout, 0,
+                  Val_pretty_default);
+      printf_filtered ("\n");
+#endif
+      return PRINT_UNKNOWN;
+      break;
 
-int
-bpstat_print (bs)
-     bpstat bs;
-{
-  int val;
+    /* Fall through, we don't deal with these types of breakpoints
+       here. */
 
-  if (bs == NULL)
-    return -1;
+    case bp_finish:
+#ifdef UI_OUT
+      if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+       ui_out_field_string (uiout, "reason", "function-finished");
+#endif
+      return PRINT_UNKNOWN;
+      break;
 
-  val = (*bs->print_it) (bs);
-  if (val >= 0)
-    return val;
+    case bp_until:
+#ifdef UI_OUT
+      if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+       ui_out_field_string (uiout, "reason", "location-reached");
+#endif
+      return PRINT_UNKNOWN;
+      break;
 
-  /* Maybe another breakpoint in the chain caused us to stop.
-     (Currently all watchpoints go on the bpstat whether hit or not.
+    case bp_none:
+    case bp_longjmp:
+    case bp_longjmp_resume:
+    case bp_step_resume:
+    case bp_through_sigtramp:
+    case bp_watchpoint_scope:
+    case bp_call_dummy:
+    default:
+      return PRINT_UNKNOWN;
+    }
+}
+
+/* Generic routine for printing messages indicating why we
+   stopped. The behavior of this function depends on the value
+   'print_it' in the bpstat structure.  Under some circumstances we
+   may decide not to print anything here and delegate the task to
+   normal_stop(). */
+
+static enum print_stop_action
+print_bp_stop_message (bpstat bs)
+{
+  switch (bs->print_it)
+    {
+    case print_it_noop:
+      /* Nothing should be printed for this bpstat entry. */
+      return PRINT_UNKNOWN;
+      break;
+
+    case print_it_done:
+      /* We still want to print the frame, but we already printed the
+         relevant messages. */
+      return PRINT_SRC_AND_LOC;
+      break;
+
+    case print_it_normal:
+      /* Normal case, we handle everything in print_it_typical. */
+      return print_it_typical (bs);
+      break;
+    default:
+      internal_error (__FILE__, __LINE__,
+                     "print_bp_stop_message: unrecognized enum value");
+      break;
+    }
+}
+
+/* Print a message indicating what happened.  This is called from
+   normal_stop().  The input to this routine is the head of the bpstat
+   list - a list of the eventpoints that caused this stop.  This
+   routine calls the generic print routine for printing a message
+   about reasons for stopping.  This will print (for example) the
+   "Breakpoint n," part of the output.  The return value of this
+   routine is one of:
+
+   PRINT_UNKNOWN: Means we printed nothing
+   PRINT_SRC_AND_LOC: Means we printed something, and expect subsequent
+   code to print the location. An example is 
+   "Breakpoint 1, " which should be followed by
+   the location.
+   PRINT_SRC_ONLY: Means we printed something, but there is no need
+   to also print the location part of the message.
+   An example is the catch/throw messages, which
+   don't require a location appended to the end.  
+   PRINT_NOTHING: We have done some printing and we don't need any 
+   further info to be printed.*/
+
+enum print_stop_action
+bpstat_print (bpstat bs)
+{
+  int val;
+
+  /* Maybe another breakpoint in the chain caused us to stop.
+     (Currently all watchpoints go on the bpstat whether hit or not.
      That probably could (should) be changed, provided care is taken
      with respect to bpstat_explains_signal).  */
-  if (bs->next)
-    return bpstat_print (bs->next);
+  for (; bs; bs = bs->next)
+    {
+      val = print_bp_stop_message (bs);
+      if (val == PRINT_SRC_ONLY 
+         || val == PRINT_SRC_AND_LOC 
+         || val == PRINT_NOTHING)
+       return val;
+    }
 
-  /* We reached the end of the chain without printing anything.  */
-  return -1;
+  /* We reached the end of the chain, or we got a null BS to start
+     with and nothing was printed. */
+  return PRINT_UNKNOWN;
 }
 
 /* Evaluate the expression EXP and return 1 if value is zero.
@@ -1951,8 +2224,7 @@ bpstat_print (bs)
    make it pass through catch_errors.  */
 
 static int
-breakpoint_cond_eval (exp)
-     PTR exp;
+breakpoint_cond_eval (PTR exp)
 {
   value_ptr mark = value_mark ();
   int i = !value_true (evaluate_expression ((struct expression *) exp));
@@ -1963,9 +2235,7 @@ breakpoint_cond_eval (exp)
 /* Allocate a new bpstat and chain it to the current one.  */
 
 static bpstat
-bpstat_alloc (b, cbs)
-     register struct breakpoint *b;
-     bpstat cbs;               /* Current "bs" value */
+bpstat_alloc (struct breakpoint *b, bpstat cbs /* Current "bs" value */ )
 {
   bpstat bs;
 
@@ -1994,8 +2264,7 @@ bpstat_alloc (b, cbs)
 /* Check watchpoint condition.  */
 
 static int
-watchpoint_check (p)
-     PTR p;
+watchpoint_check (PTR p)
 {
   bpstat bs = (bpstat) p;
   struct breakpoint *b;
@@ -2057,9 +2326,23 @@ watchpoint_check (p)
          So we can't even detect the first assignment to it and
          watch after that (since the garbage may or may not equal
          the first value assigned).  */
+      /* We print all the stop information in print_it_typical(), but
+        in this case, by the time we call print_it_typical() this bp
+        will be deleted already. So we have no choice but print the
+        information here. */
+#ifdef UI_OUT
+      if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+       ui_out_field_string (uiout, "reason", "watchpoint-scope");
+      ui_out_text (uiout, "\nWatchpoint ");
+      ui_out_field_int (uiout, "wpnum", bs->breakpoint_at->number);
+      ui_out_text (uiout, " deleted because the program has left the block in\n\
+which its expression is valid.\n");     
+#else
       printf_filtered ("\
 Watchpoint %d deleted because the program has left the block in\n\
 which its expression is valid.\n", bs->breakpoint_at->number);
+#endif 
+
       if (b->related_breakpoint)
        b->related_breakpoint->disposition = del_at_next_stop;
       b->disposition = del_at_next_stop;
@@ -2068,40 +2351,6 @@ which its expression is valid.\n", bs->breakpoint_at->number);
     }
 }
 
-/* This is used when everything which needs to be printed has
-   already been printed.  But we still want to print the frame.  */
-
-/* Background: When we stop, bpstat_print() is called.
-   It loops through the bpstat list of things causing this stop,
-   calling the print_it function for each one. The default
-   print_it function, used for breakpoints, is print_it_normal().
-   Also see print_it_noop() and print_it_done() are the other 
-   two possibilities. See comments in bpstat_print() and
-   in header of print_it_normal() for more detail.  */
-
-static int
-print_it_done (bs)
-     bpstat bs;
-{
-  return 0;
-}
-
-/* This is used when nothing should be printed for this bpstat entry.  */
-/* Background: When we stop, bpstat_print() is called.
-   It loops through the bpstat list of things causing this stop,
-   calling the print_it function for each one. The default
-   print_it function, used for breakpoints, is print_it_normal().
-   Also see print_it_noop() and print_it_done() are the other 
-   two possibilities. See comments in bpstat_print() and
-   in header of print_it_normal() for more detail.  */
-
-static int
-print_it_noop (bs)
-     bpstat bs;
-{
-  return -1;
-}
-
 /* 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_BREAKPOINT is nonzero
@@ -2123,9 +2372,7 @@ print_it_noop (bs)
    commands, FIXME??? fields.  */
 
 bpstat
-bpstat_stop_status (pc, not_a_breakpoint)
-     CORE_ADDR *pc;
-     int not_a_breakpoint;
+bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint)
 {
   register struct breakpoint *b, *temp;
   CORE_ADDR bp_addr;
@@ -2140,7 +2387,8 @@ bpstat_stop_status (pc, not_a_breakpoint)
   char message[sizeof (message1) + 30 /* slop */ ];
 
   /* Get the address where the breakpoint would have been.  */
-  bp_addr = *pc - DECR_PC_AFTER_BREAK;
+  bp_addr = *pc - (not_a_breakpoint && !SOFTWARE_SINGLE_STEP_P () ? 
+                   0 : DECR_PC_AFTER_BREAK);
 
   ALL_BREAKPOINTS_SAFE (b, temp)
   {
@@ -2169,22 +2417,16 @@ bpstat_stop_status (pc, not_a_breakpoint)
        && b->address != (*pc - DECR_PC_AFTER_HW_BREAK))
       continue;
 
-    if (b->type != bp_watchpoint
-       && b->type != bp_hardware_watchpoint
-       && b->type != bp_read_watchpoint
-       && b->type != bp_access_watchpoint
-       && not_a_breakpoint)
-      continue;
-
     /* Is this a catchpoint of a load or unload?  If so, did we
        get a load or unload of the specified library?  If not,
        ignore it. */
     if ((b->type == bp_catch_load)
 #if defined(SOLIB_HAVE_LOAD_EVENT)
-       && (!SOLIB_HAVE_LOAD_EVENT (inferior_pid)
+       && (!SOLIB_HAVE_LOAD_EVENT (PIDGET (inferior_ptid))
            || ((b->dll_pathname != NULL)
                && (strcmp (b->dll_pathname, 
-                           SOLIB_LOADED_LIBRARY_PATHNAME (inferior_pid)) 
+                           SOLIB_LOADED_LIBRARY_PATHNAME (
+                             PIDGET (inferior_ptid)))
                    != 0)))
 #endif
       )
@@ -2192,25 +2434,28 @@ bpstat_stop_status (pc, not_a_breakpoint)
 
     if ((b->type == bp_catch_unload)
 #if defined(SOLIB_HAVE_UNLOAD_EVENT)
-       && (!SOLIB_HAVE_UNLOAD_EVENT (inferior_pid)
+       && (!SOLIB_HAVE_UNLOAD_EVENT (PIDGET (inferior_ptid))
            || ((b->dll_pathname != NULL)
                && (strcmp (b->dll_pathname, 
-                           SOLIB_UNLOADED_LIBRARY_PATHNAME (inferior_pid)) 
+                           SOLIB_UNLOADED_LIBRARY_PATHNAME (
+                             PIDGET (inferior_ptid)))
                    != 0)))
 #endif
       )
       continue;
 
     if ((b->type == bp_catch_fork)
-       && !target_has_forked (inferior_pid, &b->forked_inferior_pid))
+       && !target_has_forked (PIDGET (inferior_ptid),
+                              &b->forked_inferior_pid))
       continue;
 
     if ((b->type == bp_catch_vfork)
-       && !target_has_vforked (inferior_pid, &b->forked_inferior_pid))
+       && !target_has_vforked (PIDGET (inferior_ptid),
+                               &b->forked_inferior_pid))
       continue;
 
     if ((b->type == bp_catch_exec)
-       && !target_has_execd (inferior_pid, &b->exec_pathname))
+       && !target_has_execd (PIDGET (inferior_ptid), &b->exec_pathname))
       continue;
 
     if (ep_is_exception_catchpoint (b) &&
@@ -2234,6 +2479,9 @@ bpstat_stop_status (pc, not_a_breakpoint)
          {
          case WP_DELETED:
            /* We've already printed what needs to be printed.  */
+           /* Actually this is superfluous, because by the time we
+               call print_it_typical() the wp will be already deleted,
+               and the function will return immediately. */
            bs->print_it = print_it_done;
            /* Stop.  */
            break;
@@ -2245,8 +2493,6 @@ bpstat_stop_status (pc, not_a_breakpoint)
            /* Don't stop.  */
            bs->print_it = print_it_noop;
            bs->stop = 0;
-           /* Don't consider this a hit.  */
-           --(b->hit_count);
            continue;
          default:
            /* Can't happen.  */
@@ -2276,16 +2522,24 @@ bpstat_stop_status (pc, not_a_breakpoint)
          continue;
        for (v = b->val_chain; v; v = v->next)
          {
-           if (v->lval == lval_memory)
+           if (VALUE_LVAL (v) == lval_memory
+               && ! VALUE_LAZY (v))
              {
-               CORE_ADDR vaddr;
-
-               vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
-               /* Exact match not required.  Within range is sufficient.  
-                */
-               if (addr >= vaddr &&
-                   addr < vaddr + TYPE_LENGTH (VALUE_TYPE (v)))
-                 found = 1;
+               struct type *vtype = check_typedef (VALUE_TYPE (v));
+
+               if (v == b->val_chain
+                   || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+                       && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
+                 {
+                   CORE_ADDR vaddr;
+
+                   vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+                   /* Exact match not required.  Within range is
+                       sufficient.  */
+                   if (addr >= vaddr &&
+                       addr < vaddr + TYPE_LENGTH (VALUE_TYPE (v)))
+                     found = 1;
+                 }
              }
          }
        if (found)
@@ -2298,6 +2552,17 @@ bpstat_stop_status (pc, not_a_breakpoint)
              /* Stop.  */
              break;
            case WP_VALUE_CHANGED:
+             if (b->type == bp_read_watchpoint)
+               {
+                 /* Don't stop: read watchpoints shouldn't fire if
+                    the value has changed.  This is for targets which
+                    cannot set read-only watchpoints.  */
+                 bs->print_it = print_it_noop;
+                 bs->stop = 0;
+                 continue;
+               }
+             ++(b->hit_count);
+             break;
            case WP_VALUE_NOT_CHANGED:
              /* Stop.  */
              ++(b->hit_count);
@@ -2334,9 +2599,8 @@ bpstat_stop_status (pc, not_a_breakpoint)
        real_breakpoint = 1;
       }
 
-    if (b->frame && b->frame != (get_current_frame ())->frame &&
-       (b->type == bp_step_resume &&
-        (INNER_THAN (get_current_frame ()->frame, b->frame))))
+    if (b->frame &&
+       b->frame != (get_current_frame ())->frame)
       bs->stop = 0;
     else
       {
@@ -2363,6 +2627,7 @@ bpstat_stop_status (pc, not_a_breakpoint)
        else if (b->ignore_count > 0)
          {
            b->ignore_count--;
+           annotate_ignore_count_change ();
            bs->stop = 0;
          }
        else
@@ -2429,8 +2694,7 @@ bpstat_stop_status (pc, not_a_breakpoint)
 \f
 /* Tell what to do about this bpstat.  */
 struct bpstat_what
-bpstat_what (bs)
-     bpstat bs;
+bpstat_what (bpstat bs)
 {
   /* Classify each bpstat as one of the following.  */
   enum class
@@ -2509,7 +2773,7 @@ bpstat_what (bs)
      back and decide something of a lower priority is better.  The
      ordering is:
 
-     kc   < clr sgl shl slr sn sr ss ts
+     kc   < clr sgl shl shlr slr sn sr ss ts
      sgl  < clrs shl shlr slr sn sr ss ts
      slr  < err shl shlr sn sr ss ts
      clr  < clrs err shl shlr sn sr ss ts
@@ -2554,7 +2818,7 @@ bpstat_what (bs)
 /*bp_noisy */
     {sn, sn, sn, sn, sn, sn, sn, sr, ts, shl, shlr},
 /*long_jump */
-    {slr, ss, sn, slr, err, err, err, sr, ts, shl, shlr},
+    {slr, ss, sn, slr, slr, err, err, sr, ts, shl, shlr},
 /*long_resume */
     {clr, ss, sn, clrs, err, err, err, sr, ts, shl, shlr},
 /*step_resume */
@@ -2649,6 +2913,9 @@ bpstat_what (bs)
        case bp_shlib_event:
          bs_class = shlib_event;
          break;
+       case bp_thread_event:
+         bs_class = bp_nostop;
+         break;
        case bp_catch_load:
        case bp_catch_unload:
          /* Only if this catchpoint triggered should we cause the
@@ -2704,18 +2971,18 @@ bpstat_what (bs)
    just to things like whether watchpoints are set.  */
 
 int
-bpstat_should_step ()
+bpstat_should_step (void)
 {
   struct breakpoint *b;
   ALL_BREAKPOINTS (b)
     if (b->enable == enabled && b->type == bp_watchpoint)
-    return 1;
+      return 1;
   return 0;
 }
 
 /* Nonzero if there are enabled hardware watchpoints. */
 int
-bpstat_have_active_hw_watchpoints ()
+bpstat_have_active_hw_watchpoints (void)
 {
   struct breakpoint *b;
   ALL_BREAKPOINTS (b)
@@ -2724,7 +2991,7 @@ bpstat_have_active_hw_watchpoints ()
        ((b->type == bp_hardware_watchpoint) ||
         (b->type == bp_read_watchpoint) ||
         (b->type == bp_access_watchpoint)))
-    return 1;
+      return 1;
   return 0;
 }
 \f
@@ -2733,9 +3000,7 @@ bpstat_have_active_hw_watchpoints ()
    function returns another bpstat which contains only the catchpoints
    on that first list, if any. */
 void
-bpstat_get_triggered_catchpoints (ep_list, cp_list)
-     bpstat ep_list;
-     bpstat *cp_list;
+bpstat_get_triggered_catchpoints (bpstat ep_list, bpstat *cp_list)
 {
   struct bpstats root_bs[1];
   bpstat bs = root_bs;
@@ -2771,11 +3036,13 @@ bpstat_get_triggered_catchpoints (ep_list, cp_list)
          catchpoint triggers.  Clients who may wish to know the name
          later must get it from the catchpoint itself.) */
       if (ep->triggered_dll_pathname != NULL)
-       free (ep->triggered_dll_pathname);
+       xfree (ep->triggered_dll_pathname);
       if (ep->type == bp_catch_load)
-       dll_pathname = SOLIB_LOADED_LIBRARY_PATHNAME (inferior_pid);
+       dll_pathname = SOLIB_LOADED_LIBRARY_PATHNAME (
+                        PIDGET (inferior_ptid));
       else
-       dll_pathname = SOLIB_UNLOADED_LIBRARY_PATHNAME (inferior_pid);
+       dll_pathname = SOLIB_UNLOADED_LIBRARY_PATHNAME (
+                        PIDGET (inferior_ptid));
 #else
       dll_pathname = NULL;
 #endif
@@ -2792,28 +3059,19 @@ bpstat_get_triggered_catchpoints (ep_list, cp_list)
   *cp_list = bs;
 }
 
-/* Print information on breakpoint number BNUM, or -1 if all.
-   If WATCHPOINTS is zero, process only breakpoints; if WATCHPOINTS
-   is nonzero, process only watchpoints.  */
-
-typedef struct
-{
-  enum bptype type;
-  char *description;
-}
-ep_type_description_t;
-
+/* Print B to gdb_stdout. */
 static void
-breakpoint_1 (bnum, allflag)
-     int bnum;
-     int allflag;
+print_one_breakpoint (struct breakpoint *b,
+                     CORE_ADDR *last_addr)
 {
-  register struct breakpoint *b;
   register struct command_line *l;
   register struct symbol *sym;
-  CORE_ADDR last_addr = (CORE_ADDR) - 1;
-  int found_a_breakpoint = 0;
-  static ep_type_description_t bptypes[] =
+  struct ep_type_description
+    {
+      enum bptype type;
+      char *description;
+    };
+  static struct ep_type_description bptypes[] =
   {
     {bp_none, "?deleted?"},
     {bp_breakpoint, "breakpoint"},
@@ -2831,6 +3089,7 @@ breakpoint_1 (bnum, allflag)
     {bp_watchpoint_scope, "watchpoint scope"},
     {bp_call_dummy, "call dummy"},
     {bp_shlib_event, "shlib events"},
+    {bp_thread_event, "thread events"},
     {bp_catch_load, "catch load"},
     {bp_catch_unload, "catch unload"},
     {bp_catch_fork, "catch fork"},
@@ -2839,275 +3098,572 @@ breakpoint_1 (bnum, allflag)
     {bp_catch_catch, "catch catch"},
     {bp_catch_throw, "catch throw"}
   };
-
+  
   static char *bpdisps[] =
   {"del", "dstp", "dis", "keep"};
-  static char bpenables[] = "nyn";
+  static char bpenables[] = "nynny";
   char wrap_indent[80];
+#ifdef UI_OUT
+  struct ui_stream *stb = ui_out_stream_new (uiout);
+  struct cleanup *old_chain = make_cleanup_ui_out_stream_delete (stb);
+#endif
 
+  annotate_record ();
+#ifdef UI_OUT
+  ui_out_list_begin (uiout, "bkpt");
+#endif
 
+  /* 1 */
+  annotate_field (0);
+#ifdef UI_OUT
+  ui_out_field_int (uiout, "number", b->number);
+#else
+  printf_filtered ("%-3d ", b->number);
+#endif
 
-  ALL_BREAKPOINTS (b)
-    if (bnum == -1
-       || bnum == b->number)
+  /* 2 */
+  annotate_field (1);
+  if (((int) b->type > (sizeof (bptypes) / sizeof (bptypes[0])))
+      || ((int) b->type != bptypes[(int) b->type].type))
+    internal_error (__FILE__, __LINE__,
+                   "bptypes table does not describe type #%d.",
+                   (int) b->type);
+#ifdef UI_OUT
+  ui_out_field_string (uiout, "type", bptypes[(int) b->type].description);
+#else
+  printf_filtered ("%-14s ", bptypes[(int) b->type].description);
+#endif
+
+  /* 3 */
+  annotate_field (2);
+#ifdef UI_OUT
+  ui_out_field_string (uiout, "disp", bpdisps[(int) b->disposition]);
+#else
+  printf_filtered ("%-4s ", bpdisps[(int) b->disposition]);
+#endif
+
+  /* 4 */
+  annotate_field (3);
+#ifdef UI_OUT
+  ui_out_field_fmt (uiout, "enabled", "%c", bpenables[(int) b->enable]);
+  ui_out_spaces (uiout, 2);
+#else
+  printf_filtered ("%-3c ", bpenables[(int) b->enable]);
+#endif
+  
+  /* 5 and 6 */
+  strcpy (wrap_indent, "                           ");
+  if (addressprint)
     {
-/*  We only print out user settable breakpoints unless the allflag is set. */
-      if (!allflag
-         && b->type != bp_breakpoint
-         && b->type != bp_catch_load
-         && b->type != bp_catch_unload
-         && 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->type != bp_hardware_breakpoint
-         && b->type != bp_watchpoint
-         && b->type != bp_read_watchpoint
-         && b->type != bp_access_watchpoint
-         && b->type != bp_hardware_watchpoint)
-       continue;
+      if (TARGET_ADDR_BIT <= 32)
+       strcat (wrap_indent, "           ");
+      else
+       strcat (wrap_indent, "                   ");
+    }
+  switch (b->type)
+    {
+    case bp_none:
+      internal_error (__FILE__, __LINE__,
+                     "print_one_breakpoint: bp_none encountered\n");
+      break;
 
-      if (!found_a_breakpoint++)
+    case bp_watchpoint:
+    case bp_hardware_watchpoint:
+    case bp_read_watchpoint:
+    case bp_access_watchpoint:
+      /* Field 4, the address, is omitted (which makes the columns
+        not line up too nicely with the headers, but the effect
+        is relatively readable).  */
+#ifdef UI_OUT
+      if (addressprint)
+       ui_out_field_skip (uiout, "addr");
+      annotate_field (5);
+      print_expression (b->exp, stb->stream);
+      ui_out_field_stream (uiout, "what", stb);
+#else
+      annotate_field (5);
+      print_expression (b->exp, gdb_stdout);
+#endif
+      break;
+      
+    case bp_catch_load:
+    case bp_catch_unload:
+      /* Field 4, the address, is omitted (which makes the columns
+        not line up too nicely with the headers, but the effect
+        is relatively readable).  */
+#ifdef UI_OUT
+      if (addressprint)
+       ui_out_field_skip (uiout, "addr");
+      annotate_field (5);
+      if (b->dll_pathname == NULL)
        {
-         annotate_breakpoints_headers ();
-
-         annotate_field (0);
-         printf_filtered ("Num ");
-         annotate_field (1);
-         printf_filtered ("Type           ");
-         annotate_field (2);
-         printf_filtered ("Disp ");
-         annotate_field (3);
-         printf_filtered ("Enb ");
-         if (addressprint)
-           {
-             annotate_field (4);
-             printf_filtered ("Address    ");
-           }
-         annotate_field (5);
-         printf_filtered ("What\n");
-
-         annotate_breakpoints_table ();
+         ui_out_field_string (uiout, "what", "<any library>");
+         ui_out_spaces (uiout, 1);
        }
-
-      annotate_record ();
-      annotate_field (0);
-      printf_filtered ("%-3d ", b->number);
-      annotate_field (1);
-      if ((int) b->type > (sizeof (bptypes) / sizeof (bptypes[0])))
-       error ("bptypes table does not describe type #%d.", (int) b->type);
-      if ((int) b->type != bptypes[(int) b->type].type)
-       error ("bptypes table does not describe type #%d?", (int) b->type);
-      printf_filtered ("%-14s ", bptypes[(int) b->type].description);
-      annotate_field (2);
-      printf_filtered ("%-4s ", bpdisps[(int) b->disposition]);
-      annotate_field (3);
-      printf_filtered ("%-3c ", bpenables[(int) b->enable]);
-
-      strcpy (wrap_indent, "                           ");
+      else
+       {
+         ui_out_text (uiout, "library \"");
+         ui_out_field_string (uiout, "what", b->dll_pathname);
+         ui_out_text (uiout, "\" ");
+       }
+#else
+      annotate_field (5);
+      if (b->dll_pathname == NULL)
+       printf_filtered ("<any library> ");
+      else
+       printf_filtered ("library \"%s\" ", b->dll_pathname);
+#endif
+      break;
+      
+    case bp_catch_fork:
+    case bp_catch_vfork:
+      /* Field 4, the address, is omitted (which makes the columns
+        not line up too nicely with the headers, but the effect
+        is relatively readable).  */
+#ifdef UI_OUT
       if (addressprint)
-       strcat (wrap_indent, "           ");
-      switch (b->type)
+       ui_out_field_skip (uiout, "addr");
+      annotate_field (5);
+      if (b->forked_inferior_pid != 0)
        {
-       case bp_watchpoint:
-       case bp_hardware_watchpoint:
-       case bp_read_watchpoint:
-       case bp_access_watchpoint:
-         /* Field 4, the address, is omitted (which makes the columns
-            not line up too nicely with the headers, but the effect
-            is relatively readable).  */
-         annotate_field (5);
-         print_expression (b->exp, gdb_stdout);
-         break;
-
-       case bp_catch_load:
-       case bp_catch_unload:
-         /* Field 4, the address, is omitted (which makes the columns
-            not line up too nicely with the headers, but the effect
-            is relatively readable).  */
-         annotate_field (5);
-         if (b->dll_pathname == NULL)
-           printf_filtered ("<any library> ");
-         else
-           printf_filtered ("library \"%s\" ", b->dll_pathname);
-         break;
-
-       case bp_catch_fork:
-       case bp_catch_vfork:
-         /* Field 4, the address, is omitted (which makes the columns
-            not line up too nicely with the headers, but the effect
-            is relatively readable).  */
-         annotate_field (5);
-         if (b->forked_inferior_pid != 0)
-           printf_filtered ("process %d ", b->forked_inferior_pid);
-         break;
-
-       case bp_catch_exec:
-         /* Field 4, the address, is omitted (which makes the columns
-            not line up too nicely with the headers, but the effect
-            is relatively readable).  */
-         annotate_field (5);
-         if (b->exec_pathname != NULL)
-           printf_filtered ("program \"%s\" ", b->exec_pathname);
-         break;
-       case bp_catch_catch:
-         /* Field 4, the address, is omitted (which makes the columns
-            not line up too nicely with the headers, but the effect
-            is relatively readable).  */
-         annotate_field (5);
-         printf_filtered ("exception catch ");
-         break;
-       case bp_catch_throw:
-         /* Field 4, the address, is omitted (which makes the columns
-            not line up too nicely with the headers, but the effect
-            is relatively readable).  */
-         annotate_field (5);
-         printf_filtered ("exception throw ");
-         break;
-
-       case bp_breakpoint:
-       case bp_hardware_breakpoint:
-       case bp_until:
-       case bp_finish:
-       case bp_longjmp:
-       case bp_longjmp_resume:
-       case bp_step_resume:
-       case bp_through_sigtramp:
-       case bp_watchpoint_scope:
-       case bp_call_dummy:
-       case bp_shlib_event:
-         if (addressprint)
-           {
-             annotate_field (4);
-             /* FIXME-32x64: need a print_address_numeric with
-                field width */
-             printf_filtered
-               ("%s ",
-                local_hex_string_custom
-                ((unsigned long) b->address, "08l"));
-           }
+         ui_out_text (uiout, "process ");
+         ui_out_field_int (uiout, "what", b->forked_inferior_pid);
+         ui_out_spaces (uiout, 1);
+       }
+#else
+      annotate_field (5);
+      if (b->forked_inferior_pid != 0)
+       printf_filtered ("process %d ", b->forked_inferior_pid);
+      break;
+#endif
+      
+    case bp_catch_exec:
+      /* Field 4, the address, is omitted (which makes the columns
+        not line up too nicely with the headers, but the effect
+        is relatively readable).  */
+#ifdef UI_OUT
+      if (addressprint)
+       ui_out_field_skip (uiout, "addr");
+      annotate_field (5);
+      if (b->exec_pathname != NULL)
+       {
+         ui_out_text (uiout, "program \"");
+         ui_out_field_string (uiout, "what", b->exec_pathname);
+         ui_out_text (uiout, "\" ");
+       }
+#else
+      annotate_field (5);
+      if (b->exec_pathname != NULL)
+       printf_filtered ("program \"%s\" ", b->exec_pathname);
+#endif
+      break;
 
-         annotate_field (5);
+    case bp_catch_catch:
+      /* Field 4, the address, is omitted (which makes the columns
+        not line up too nicely with the headers, but the effect
+        is relatively readable).  */
+#ifdef UI_OUT
+      if (addressprint)
+       ui_out_field_skip (uiout, "addr");
+      annotate_field (5);
+      ui_out_field_string (uiout, "what", "exception catch");
+      ui_out_spaces (uiout, 1);
+#else
+      annotate_field (5);
+      printf_filtered ("exception catch ");
+#endif
+      break;
 
-         last_addr = b->address;
-         if (b->source_file)
+    case bp_catch_throw:
+      /* Field 4, the address, is omitted (which makes the columns
+        not line up too nicely with the headers, but the effect
+        is relatively readable).  */
+#ifdef UI_OUT
+      if (addressprint)
+       ui_out_field_skip (uiout, "addr");
+      annotate_field (5);
+      ui_out_field_string (uiout, "what", "exception throw");
+      ui_out_spaces (uiout, 1);
+#else
+      annotate_field (5);
+      printf_filtered ("exception throw ");
+#endif
+      break;
+      
+    case bp_breakpoint:
+    case bp_hardware_breakpoint:
+    case bp_until:
+    case bp_finish:
+    case bp_longjmp:
+    case bp_longjmp_resume:
+    case bp_step_resume:
+    case bp_through_sigtramp:
+    case bp_watchpoint_scope:
+    case bp_call_dummy:
+    case bp_shlib_event:
+    case bp_thread_event:
+#ifdef UI_OUT
+      if (addressprint)
+       {
+         annotate_field (4);
+         ui_out_field_core_addr (uiout, "addr", b->address);
+       }
+      annotate_field (5);
+      *last_addr = b->address;
+      if (b->source_file)
+       {
+         sym = find_pc_sect_function (b->address, b->section);
+         if (sym)
            {
-             sym = find_pc_sect_function (b->address, b->section);
-             if (sym)
-               {
-                 fputs_filtered ("in ", gdb_stdout);
-                 fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
-                 wrap_here (wrap_indent);
-                 fputs_filtered (" at ", gdb_stdout);
-               }
-             fputs_filtered (b->source_file, gdb_stdout);
-             printf_filtered (":%d", b->line_number);
+             ui_out_text (uiout, "in ");
+             ui_out_field_string (uiout, "func",
+                                  SYMBOL_SOURCE_NAME (sym));
+             ui_out_wrap_hint (uiout, wrap_indent);
+             ui_out_text (uiout, " at ");
            }
-         else
-           print_address_symbolic (b->address, gdb_stdout, demangle, " ");
-         break;
+         ui_out_field_string (uiout, "file", b->source_file);
+         ui_out_text (uiout, ":");
+         ui_out_field_int (uiout, "line", b->line_number);
        }
-
-      if (b->thread != -1)
-       printf_filtered (" thread %d", b->thread);
-
-      printf_filtered ("\n");
-
-      if (b->frame)
+      else
        {
-         annotate_field (6);
-
-         printf_filtered ("\tstop only in stack frame at ");
-         print_address_numeric (b->frame, 1, gdb_stdout);
-         printf_filtered ("\n");
+         print_address_symbolic (b->address, stb->stream, demangle, "");
+         ui_out_field_stream (uiout, "at", stb);
        }
-
-      if (b->cond)
+#else
+      if (addressprint)
        {
-         annotate_field (7);
+         char *tmp;
 
-         printf_filtered ("\tstop only if ");
-         print_expression (b->cond, gdb_stdout);
-         printf_filtered ("\n");
-       }
+         annotate_field (4);
 
-      if (b->thread != -1)
-       {
-         /* FIXME should make an annotation for this */
-         printf_filtered ("\tstop only in thread %d\n", b->thread);
-       }
+         if (TARGET_ADDR_BIT <= 32)
+           tmp = longest_local_hex_string_custom (b->address
+                                                  & (CORE_ADDR) 0xffffffff, 
+                                                  "08l");
+         else
+           tmp = longest_local_hex_string_custom (b->address, "016l");
 
-      if (show_breakpoint_hit_counts && b->hit_count)
+         printf_filtered ("%s ", tmp);
+       }
+      annotate_field (5);
+      *last_addr = b->address;
+      if (b->source_file)
        {
-         /* FIXME should make an annotation for this */
-         if (ep_is_catchpoint (b))
-           printf_filtered ("\tcatchpoint");
-         else
-           printf_filtered ("\tbreakpoint");
-         printf_filtered (" already hit %d time%s\n",
-                          b->hit_count, (b->hit_count == 1 ? "" : "s"));
+         sym = find_pc_sect_function (b->address, b->section);
+         if (sym)
+           {
+             fputs_filtered ("in ", gdb_stdout);
+             fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
+             wrap_here (wrap_indent);
+             fputs_filtered (" at ", gdb_stdout);
+           }
+         fputs_filtered (b->source_file, gdb_stdout);
+         printf_filtered (":%d", b->line_number);
        }
+      else
+       print_address_symbolic (b->address, gdb_stdout, demangle, " ");
+#endif
+      break;
+    }
+  
+  if (b->thread != -1)
+    {
+#ifdef UI_OUT
+      /* FIXME: This seems to be redundant and lost here; see the
+        "stop only in" line a little further down. */
+      ui_out_text (uiout, " thread ");
+      ui_out_field_int (uiout, "thread", b->thread);
+#else
+      printf_filtered (" thread %d", b->thread);
+#endif
+    }
+  
+#ifdef UI_OUT
+  ui_out_text (uiout, "\n");
+#else
+  printf_filtered ("\n");
+#endif
+  
+  if (b->frame)
+    {
+      annotate_field (6);
+#ifdef UI_OUT
+      ui_out_text (uiout, "\tstop only in stack frame at ");
+      ui_out_field_core_addr (uiout, "frame", b->frame);
+      ui_out_text (uiout, "\n");
+#else
+      printf_filtered ("\tstop only in stack frame at ");
+      print_address_numeric (b->frame, 1, gdb_stdout);
+      printf_filtered ("\n");
+#endif
+    }
+  
+  if (b->cond)
+    {
+      annotate_field (7);
+#ifdef UI_OUT
+      ui_out_text (uiout, "\tstop only if ");
+      print_expression (b->cond, stb->stream);
+      ui_out_field_stream (uiout, "cond", stb);
+      ui_out_text (uiout, "\n");
+#else
+      printf_filtered ("\tstop only if ");
+      print_expression (b->cond, gdb_stdout);
+      printf_filtered ("\n");
+#endif
+    }
+  
+  if (b->thread != -1)
+    {
+      /* FIXME should make an annotation for this */
+#ifdef UI_OUT
+      ui_out_text (uiout, "\tstop only in thread ");
+      ui_out_field_int (uiout, "thread", b->thread);
+      ui_out_text (uiout, "\n");
+#else
+      printf_filtered ("\tstop only in thread %d\n", b->thread);
+#endif
+    }
+  
+  if (show_breakpoint_hit_counts && b->hit_count)
+    {
+      /* FIXME should make an annotation for this */
+#ifdef UI_OUT
+      if (ep_is_catchpoint (b))
+       ui_out_text (uiout, "\tcatchpoint");
+      else
+       ui_out_text (uiout, "\tbreakpoint");
+      ui_out_text (uiout, " already hit ");
+      ui_out_field_int (uiout, "times", b->hit_count);
+      if (b->hit_count == 1)
+       ui_out_text (uiout, " time\n");
+      else
+       ui_out_text (uiout, " times\n");
+#else
+      if (ep_is_catchpoint (b))
+       printf_filtered ("\tcatchpoint");
+      else
+       printf_filtered ("\tbreakpoint");
+      printf_filtered (" already hit %d time%s\n",
+                      b->hit_count, (b->hit_count == 1 ? "" : "s"));
+#endif
+    }
+  
+#ifdef UI_OUT
+  /* Output the count also if it is zero, but only if this is
+     mi. FIXME: Should have a better test for this. */
+  if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+    if (show_breakpoint_hit_counts && b->hit_count == 0)
+      ui_out_field_int (uiout, "times", b->hit_count);
+#endif
 
-      if (b->ignore_count)
+  if (b->ignore_count)
+    {
+      annotate_field (8);
+#ifdef UI_OUT
+      ui_out_text (uiout, "\tignore next ");
+      ui_out_field_int (uiout, "ignore", b->ignore_count);
+      ui_out_text (uiout, " hits\n");
+#else
+      printf_filtered ("\tignore next %d hits\n", b->ignore_count);
+#endif
+    }
+  
+  if ((l = b->commands))
+    {
+      annotate_field (9);
+#ifdef UI_OUT
+      ui_out_list_begin (uiout, "script");
+      print_command_lines (uiout, l, 4);
+      ui_out_list_end (uiout);
+#else
+      while (l)
        {
-         annotate_field (8);
-
-         printf_filtered ("\tignore next %d hits\n", b->ignore_count);
+         print_command_line (l, 4, gdb_stdout);
+         l = l->next;
        }
+#endif
+    }
+#ifdef UI_OUT
+  ui_out_list_end (uiout);
+  do_cleanups (old_chain);
+#endif
+}
 
-      if ((l = b->commands))
-       {
-         annotate_field (9);
+struct captured_breakpoint_query_args
+  {
+    int bnum;
+  };
 
-         while (l)
-           {
-             print_command_line (l, 4, gdb_stdout);
-             l = l->next;
-           }
+static int
+do_captured_breakpoint_query (void *data)
+{
+  struct captured_breakpoint_query_args *args = data;
+  register struct breakpoint *b;
+  CORE_ADDR dummy_addr = 0;
+  ALL_BREAKPOINTS (b)
+    {
+      if (args->bnum == b->number)
+       {
+         print_one_breakpoint (b, &dummy_addr);
+         return GDB_RC_OK;
        }
     }
+  return GDB_RC_NONE;
+}
+
+enum gdb_rc
+gdb_breakpoint_query (/* output object, */ int bnum)
+{
+  struct captured_breakpoint_query_args args;
+  args.bnum = bnum;
+  /* For the moment we don't trust print_one_breakpoint() to not throw
+     an error. */
+  return catch_errors (do_captured_breakpoint_query, &args,
+                      NULL, RETURN_MASK_ALL);
+}
+
+/* Print information on breakpoint number BNUM, or -1 if all.
+   If WATCHPOINTS is zero, process only breakpoints; if WATCHPOINTS
+   is nonzero, process only watchpoints.  */
 
+static void
+breakpoint_1 (int bnum, int allflag)
+{
+  register struct breakpoint *b;
+  CORE_ADDR last_addr = (CORE_ADDR) -1;
+  int found_a_breakpoint = 0;
+  
+#ifdef UI_OUT
+  if (addressprint)
+    ui_out_table_begin (uiout, 6, "BreakpointTable");
+  else
+    ui_out_table_begin (uiout, 5, "BreakpointTable");
+#endif /* UI_OUT */
+
+  ALL_BREAKPOINTS (b)
+    if (bnum == -1
+       || bnum == b->number)
+      {
+       /* We only print out user settable breakpoints unless the
+          allflag is set. */
+       if (!allflag
+           && b->type != bp_breakpoint
+           && b->type != bp_catch_load
+           && b->type != bp_catch_unload
+           && 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->type != bp_hardware_breakpoint
+           && b->type != bp_watchpoint
+           && b->type != bp_read_watchpoint
+           && b->type != bp_access_watchpoint
+           && b->type != bp_hardware_watchpoint)
+         continue;
+       
+       if (!found_a_breakpoint++)
+         {
+           annotate_breakpoints_headers ();
+#ifdef UI_OUT
+           annotate_field (0);
+           ui_out_table_header (uiout, 3, ui_left, "Num");     /* 1 */
+           annotate_field (1);
+           ui_out_table_header (uiout, 14, ui_left, "Type");   /* 2 */
+           annotate_field (2);
+           ui_out_table_header (uiout, 4, ui_left, "Disp");    /* 3 */
+           annotate_field (3);
+           ui_out_table_header (uiout, 3, ui_left, "Enb");     /* 4 */
+           if (addressprint)
+             {
+               annotate_field (4);
+               if (TARGET_ADDR_BIT <= 32)
+                 ui_out_table_header (uiout, 10, ui_left, "Address");  /* 5 */
+               else
+                 ui_out_table_header (uiout, 18, ui_left, "Address");  /* 5 */
+             }
+           annotate_field (5);
+           ui_out_table_header (uiout, 40, ui_noalign, "What");        /* 6 */
+           ui_out_table_body (uiout);
+#else
+           annotate_field (0);
+           printf_filtered ("Num ");
+           annotate_field (1);
+           printf_filtered ("Type           ");
+           annotate_field (2);
+           printf_filtered ("Disp ");
+           annotate_field (3);
+           printf_filtered ("Enb ");
+           if (addressprint)
+             {
+               annotate_field (4);
+               if (TARGET_ADDR_BIT <= 32)
+                 printf_filtered ("Address    ");
+               else
+                 printf_filtered ("Address            ");
+             }
+           annotate_field (5);
+           printf_filtered ("What\n");
+#endif /* UI_OUT */
+           annotate_breakpoints_table ();
+         }
+       
+       print_one_breakpoint (b, &last_addr);
+      }
+  
   if (!found_a_breakpoint)
     {
+#ifdef UI_OUT
+      if (bnum == -1)
+       ui_out_message (uiout, 0, "No breakpoints or watchpoints.\n");
+      else
+       ui_out_message (uiout, 0, "No breakpoint or watchpoint number %d.\n",
+                       bnum);
+#else
       if (bnum == -1)
        printf_filtered ("No breakpoints or watchpoints.\n");
       else
        printf_filtered ("No breakpoint or watchpoint number %d.\n", bnum);
+#endif /* UI_OUT */
     }
   else
-    /* Compare against (CORE_ADDR)-1 in case some compiler decides
-       that a comparison of an unsigned with -1 is always false.  */
-  if (last_addr != (CORE_ADDR) - 1)
-    set_next_address (last_addr);
+    {
+      /* Compare against (CORE_ADDR)-1 in case some compiler decides
+        that a comparison of an unsigned with -1 is always false.  */
+      if (last_addr != (CORE_ADDR) -1)
+       set_next_address (last_addr);
+    }
 
+#ifdef UI_OUT
+  ui_out_table_end (uiout);
+#endif /* UI_OUT */
+  /* FIXME? Should this be moved up so that it is only called when
+     there have been breakpoints? */
   annotate_breakpoints_table_end ();
 }
 
 /* ARGSUSED */
 static void
-breakpoints_info (bnum_exp, from_tty)
-     char *bnum_exp;
-     int from_tty;
+breakpoints_info (char *bnum_exp, int from_tty)
 {
   int bnum = -1;
 
   if (bnum_exp)
-    bnum = parse_and_eval_address (bnum_exp);
+    bnum = parse_and_eval_long (bnum_exp);
 
   breakpoint_1 (bnum, 0);
 }
 
 /* ARGSUSED */
 static void
-maintenance_info_breakpoints (bnum_exp, from_tty)
-     char *bnum_exp;
-     int from_tty;
+maintenance_info_breakpoints (char *bnum_exp, int from_tty)
 {
   int bnum = -1;
 
   if (bnum_exp)
-    bnum = parse_and_eval_address (bnum_exp);
+    bnum = parse_and_eval_long (bnum_exp);
 
   breakpoint_1 (bnum, 1);
 }
@@ -3115,9 +3671,7 @@ maintenance_info_breakpoints (bnum_exp, from_tty)
 /* Print a message describing any breakpoints set at PC.  */
 
 static void
-describe_other_breakpoints (pc, section)
-     CORE_ADDR pc;
-     asection *section;
+describe_other_breakpoints (CORE_ADDR pc, asection *section)
 {
   register int others = 0;
   register struct breakpoint *b;
@@ -3136,14 +3690,15 @@ describe_other_breakpoints (pc, section)
            b->section == section)
          {
            others--;
-           printf_filtered
-             ("%d%s%s ",
-              b->number,
-              ((b->enable == disabled || 
-                b->enable == shlib_disabled || 
-                b->enable == call_disabled)
-               ? " (disabled)" : ""),
-              (others > 1) ? "," : ((others == 1) ? " and" : ""));
+           printf_filtered ("%d%s%s ",
+                            b->number,
+                            ((b->enable == disabled || 
+                              b->enable == shlib_disabled || 
+                              b->enable == call_disabled) ? " (disabled)" 
+                             : b->enable == permanent ? " (permanent)"
+                             : ""),
+                            (others > 1) ? "," 
+                            : ((others == 1) ? " and" : ""));
          }
       printf_filtered ("also set at pc ");
       print_address_numeric (pc, 1, gdb_stdout);
@@ -3155,11 +3710,8 @@ describe_other_breakpoints (pc, section)
    for the `break' command with no arguments.  */
 
 void
-set_default_breakpoint (valid, addr, symtab, line)
-     int valid;
-     CORE_ADDR addr;
-     struct symtab *symtab;
-     int line;
+set_default_breakpoint (int valid, CORE_ADDR addr, struct symtab *symtab,
+                       int line)
 {
   default_breakpoint_valid = valid;
   default_breakpoint_address = addr;
@@ -3169,15 +3721,16 @@ set_default_breakpoint (valid, addr, symtab, line)
 
 /* Rescan breakpoints at address ADDRESS,
    marking the first one as "first" and any others as "duplicates".
-   This is so that the bpt instruction is only inserted once.  */
+   This is so that the bpt instruction is only inserted once.
+   If we have a permanent breakpoint at ADDRESS, make that one
+   the official one, and the rest as duplicates.  */
 
 static void
-check_duplicates (address, section)
-     CORE_ADDR address;
-     asection *section;
+check_duplicates (CORE_ADDR address, asection *section)
 {
   register struct breakpoint *b;
   register int count = 0;
+  struct breakpoint *perm_bp = 0;
 
   if (address == 0)            /* Watchpoints are uninteresting */
     return;
@@ -3189,9 +3742,46 @@ check_duplicates (address, section)
        && b->address == address
        && (overlay_debugging == 0 || b->section == section))
     {
+      /* Have we found a permanent breakpoint?  */
+      if (b->enable == permanent)
+       {
+         perm_bp = b;
+         break;
+       }
+       
       count++;
       b->duplicate = count > 1;
     }
+
+  /* If we found a permanent breakpoint at this address, go over the
+     list again and declare all the other breakpoints there to be the
+     duplicates.  */
+  if (perm_bp)
+    {
+      perm_bp->duplicate = 0;
+
+      /* Permanent breakpoint should always be inserted.  */
+      if (! perm_bp->inserted)
+       internal_error (__FILE__, __LINE__,
+                       "allegedly permanent breakpoint is not "
+                       "actually inserted");
+
+      ALL_BREAKPOINTS (b)
+       if (b != perm_bp)
+         {
+           if (b->inserted)
+             internal_error (__FILE__, __LINE__,
+                             "another breakpoint was inserted on top of "
+                             "a permanent breakpoint");
+
+           if (b->enable != disabled
+               && b->enable != shlib_disabled
+               && b->enable != call_disabled
+               && b->address == address
+               && (overlay_debugging == 0 || b->section == section))
+             b->duplicate = 1;
+         }
+    }
 }
 
 /* Low level routine to set a breakpoint.
@@ -3205,8 +3795,7 @@ check_duplicates (address, section)
    your arguments BEFORE calling this routine!  */
 
 struct breakpoint *
-set_raw_breakpoint (sal)
-     struct symtab_and_line sal;
+set_raw_breakpoint (struct symtab_and_line sal)
 {
   register struct breakpoint *b, *b1;
 
@@ -3254,11 +3843,22 @@ set_raw_breakpoint (sal)
   return b;
 }
 
+
+/* Note that the breakpoint object B describes a permanent breakpoint
+   instruction, hard-wired into the inferior's code.  */
+void
+make_breakpoint_permanent (struct breakpoint *b)
+{
+  b->enable = permanent;
+
+  /* By definition, permanent breakpoints are already present in the code.  */
+  b->inserted = 1;
+}
+
 #ifdef GET_LONGJMP_TARGET
 
 static void
-create_longjmp_breakpoint (func_name)
-     char *func_name;
+create_longjmp_breakpoint (char *func_name)
 {
   struct symtab_and_line sal;
   struct breakpoint *b;
@@ -3285,7 +3885,7 @@ create_longjmp_breakpoint (func_name)
   b->enable = disabled;
   b->silent = 1;
   if (func_name)
-    b->addr_string = strsave (func_name);
+    b->addr_string = xstrdup (func_name);
   b->number = internal_breakpoint_number--;
 }
 
@@ -3296,7 +3896,7 @@ create_longjmp_breakpoint (func_name)
    set_longjmp_resume_breakpoint() to figure out where we are going. */
 
 void
-enable_longjmp_breakpoint ()
+enable_longjmp_breakpoint (void)
 {
   register struct breakpoint *b;
 
@@ -3309,33 +3909,67 @@ enable_longjmp_breakpoint ()
 }
 
 void
-disable_longjmp_breakpoint ()
+disable_longjmp_breakpoint (void)
 {
   register struct breakpoint *b;
 
-  ALL_BREAKPOINTS (b)
-    if (b->type == bp_longjmp
-       || b->type == bp_longjmp_resume)
-    {
-      b->enable = disabled;
-      check_duplicates (b->address, b->section);
-    }
+  ALL_BREAKPOINTS (b)
+    if (b->type == bp_longjmp
+       || b->type == bp_longjmp_resume)
+    {
+      b->enable = disabled;
+      check_duplicates (b->address, b->section);
+    }
+}
+
+struct breakpoint *
+create_thread_event_breakpoint (CORE_ADDR address)
+{
+  struct breakpoint *b;
+  struct symtab_and_line sal;
+  char addr_string[80];                /* Surely an addr can't be longer than that. */
+
+  INIT_SAL (&sal);             /* initialize to zeroes */
+  sal.pc = address;
+  sal.section = find_pc_overlay (sal.pc);
+  if ((b = set_raw_breakpoint (sal)) == NULL)
+    return NULL;
+  
+  b->number = internal_breakpoint_number--;
+  b->disposition = donttouch;
+  b->type = bp_thread_event;   /* XXX: do we need a new type? 
+                                  bp_thread_event */
+  b->enable = enabled;
+  /* addr_string has to be used or breakpoint_re_set will delete me.  */
+  sprintf (addr_string, "*0x%s", paddr (b->address));
+  b->addr_string = xstrdup (addr_string);
+
+  return b;
+}
+
+void
+remove_thread_event_breakpoints (void)
+{
+  struct breakpoint *b, *temp;
+
+  ALL_BREAKPOINTS_SAFE (b, temp)
+    if (b->type == bp_thread_event)
+      delete_breakpoint (b);
 }
 
 #ifdef SOLIB_ADD
 void
-remove_solib_event_breakpoints ()
+remove_solib_event_breakpoints (void)
 {
   register struct breakpoint *b, *temp;
 
   ALL_BREAKPOINTS_SAFE (b, temp)
     if (b->type == bp_shlib_event)
-    delete_breakpoint (b);
+      delete_breakpoint (b);
 }
 
-void
-create_solib_event_breakpoint (address)
-     CORE_ADDR address;
+struct breakpoint *
+create_solib_event_breakpoint (CORE_ADDR address)
 {
   struct breakpoint *b;
   struct symtab_and_line sal;
@@ -3347,14 +3981,15 @@ create_solib_event_breakpoint (address)
   b->number = internal_breakpoint_number--;
   b->disposition = donttouch;
   b->type = bp_shlib_event;
+
+  return b;
 }
 
 /* Disable any breakpoints that are on code in shared libraries.  Only
    apply to enabled breakpoints, disabled ones can just stay disabled.  */
 
 void
-disable_breakpoints_in_shlibs (silent)
-     int silent;
+disable_breakpoints_in_shlibs (int silent)
 {
   struct breakpoint *b;
   int disabled_shlib_breaks = 0;
@@ -3387,7 +4022,7 @@ disable_breakpoints_in_shlibs (silent)
 
 /* Try to reenable any breakpoints in shared libraries.  */
 void
-re_enable_breakpoints_in_shlibs ()
+re_enable_breakpoints_in_shlibs (void)
 {
   struct breakpoint *b;
 
@@ -3406,12 +4041,8 @@ re_enable_breakpoints_in_shlibs ()
 #endif
 
 static void
-solib_load_unload_1 (hookname, tempflag, dll_pathname, cond_string, bp_kind)
-     char *hookname;
-     int tempflag;
-     char *dll_pathname;
-     char *cond_string;
-     enum bptype bp_kind;
+solib_load_unload_1 (char *hookname, int tempflag, char *dll_pathname,
+                    char *cond_string, enum bptype bp_kind)
 {
   struct breakpoint *b;
   struct symtabs_and_lines sals;
@@ -3442,13 +4073,13 @@ solib_load_unload_1 (hookname, tempflag, dll_pathname, cond_string, bp_kind)
 
   /* Make sure that all storage allocated in decode_line_1 gets freed
      in case the following errors out.  */
-  old_chain = make_cleanup (free, sals.sals);
+  old_chain = make_cleanup (xfree, sals.sals);
   if (canonical != (char **) NULL)
     {
-      make_cleanup (free, canonical);
+      make_cleanup (xfree, canonical);
       canonical_strings_chain = make_cleanup (null_cleanup, 0);
       if (canonical[0] != NULL)
-       make_cleanup (free, canonical[0]);
+       make_cleanup (xfree, canonical[0]);
     }
 
   resolve_sal_pc (&sals.sals[0]);
@@ -3487,34 +4118,24 @@ solib_load_unload_1 (hookname, tempflag, dll_pathname, cond_string, bp_kind)
 }
 
 void
-create_solib_load_event_breakpoint (hookname, tempflag, 
-                                   dll_pathname, cond_string)
-     char *hookname;
-     int tempflag;
-     char *dll_pathname;
-     char *cond_string;
+create_solib_load_event_breakpoint (char *hookname, int tempflag,
+                                   char *dll_pathname, char *cond_string)
 {
   solib_load_unload_1 (hookname, tempflag, dll_pathname, 
                       cond_string, bp_catch_load);
 }
 
 void
-create_solib_unload_event_breakpoint (hookname, tempflag, 
-                                     dll_pathname, cond_string)
-     char *hookname;
-     int tempflag;
-     char *dll_pathname;
-     char *cond_string;
+create_solib_unload_event_breakpoint (char *hookname, int tempflag,
+                                     char *dll_pathname, char *cond_string)
 {
   solib_load_unload_1 (hookname,tempflag, dll_pathname, 
                       cond_string, bp_catch_unload);
 }
 
 static void
-create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_kind)
-     int tempflag;
-     char *cond_string;
-     enum bptype bp_kind;
+create_fork_vfork_event_catchpoint (int tempflag, char *cond_string,
+                                   enum bptype bp_kind)
 {
   struct symtab_and_line sal;
   struct breakpoint *b;
@@ -3543,25 +4164,19 @@ create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_kind)
 }
 
 void
-create_fork_event_catchpoint (tempflag, cond_string)
-     int tempflag;
-     char *cond_string;
+create_fork_event_catchpoint (int tempflag, char *cond_string)
 {
   create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_catch_fork);
 }
 
 void
-create_vfork_event_catchpoint (tempflag, cond_string)
-     int tempflag;
-     char *cond_string;
+create_vfork_event_catchpoint (int tempflag, char *cond_string)
 {
   create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_catch_vfork);
 }
 
 void
-create_exec_event_catchpoint (tempflag, cond_string)
-     int tempflag;
-     char *cond_string;
+create_exec_event_catchpoint (int tempflag, char *cond_string)
 {
   struct symtab_and_line sal;
   struct breakpoint *b;
@@ -3589,7 +4204,7 @@ create_exec_event_catchpoint (tempflag, cond_string)
 }
 
 static int
-hw_breakpoint_used_count ()
+hw_breakpoint_used_count (void)
 {
   register struct breakpoint *b;
   int i = 0;
@@ -3604,9 +4219,7 @@ hw_breakpoint_used_count ()
 }
 
 static int
-hw_watchpoint_used_count (type, other_type_used)
-     enum bptype type;
-     int *other_type_used;
+hw_watchpoint_used_count (enum bptype type, int *other_type_used)
 {
   register struct breakpoint *b;
   int i = 0;
@@ -3635,9 +4248,7 @@ hw_watchpoint_used_count (type, other_type_used)
    that gets deleted automatically... */
 
 void
-set_longjmp_resume_breakpoint (pc, frame)
-     CORE_ADDR pc;
-     struct frame_info *frame;
+set_longjmp_resume_breakpoint (CORE_ADDR pc, struct frame_info *frame)
 {
   register struct breakpoint *b;
 
@@ -3656,7 +4267,7 @@ set_longjmp_resume_breakpoint (pc, frame)
 }
 
 void
-disable_watchpoints_before_interactive_call_start ()
+disable_watchpoints_before_interactive_call_start (void)
 {
   struct breakpoint *b;
 
@@ -3676,7 +4287,7 @@ disable_watchpoints_before_interactive_call_start ()
 }
 
 void
-enable_watchpoints_after_interactive_call_stop ()
+enable_watchpoints_after_interactive_call_stop (void)
 {
   struct breakpoint *b;
 
@@ -3701,10 +4312,8 @@ enable_watchpoints_after_interactive_call_stop ()
    Restrict it to frame FRAME if FRAME is nonzero.  */
 
 struct breakpoint *
-set_momentary_breakpoint (sal, frame, type)
-     struct symtab_and_line sal;
-     struct frame_info *frame;
-     enum bptype type;
+set_momentary_breakpoint (struct symtab_and_line sal, struct frame_info *frame,
+                         enum bptype type)
 {
   register struct breakpoint *b;
   b = set_raw_breakpoint (sal);
@@ -3716,8 +4325,8 @@ set_momentary_breakpoint (sal, frame, type)
   /* If we're debugging a multi-threaded program, then we
      want momentary breakpoints to be active in only a 
      single thread of control.  */
-  if (in_thread_list (inferior_pid))
-    b->thread = pid_to_thread_id (inferior_pid);
+  if (in_thread_list (inferior_ptid))
+    b->thread = pid_to_thread_id (inferior_ptid);
 
   return b;
 }
@@ -3726,10 +4335,16 @@ set_momentary_breakpoint (sal, frame, type)
 /* Tell the user we have just set a breakpoint B.  */
 
 static void
-mention (b)
-     struct breakpoint *b;
+mention (struct breakpoint *b)
 {
   int say_where = 0;
+#ifdef UI_OUT
+  struct cleanup *old_chain;
+  struct ui_stream *stb;
+
+  stb = ui_out_stream_new (uiout);
+  old_chain = make_cleanup_ui_out_stream_delete (stb);
+#endif /* UI_OUT */
 
   /* FIXME: This is misplaced; mention() is called by things (like hitting a
      watchpoint) other than breakpoint creation.  It should be possible to
@@ -3745,6 +4360,26 @@ mention (b)
     case bp_none:
       printf_filtered ("(apparently deleted?) Eventpoint %d: ", b->number);
       break;
+#ifdef UI_OUT
+    case bp_watchpoint:
+      ui_out_text (uiout, "Watchpoint ");
+      ui_out_list_begin (uiout, "wpt");
+      ui_out_field_int (uiout, "number", b->number);
+      ui_out_text (uiout, ": ");
+      print_expression (b->exp, stb->stream);
+      ui_out_field_stream (uiout, "exp", stb);
+      ui_out_list_end (uiout);
+      break;
+    case bp_hardware_watchpoint:
+      ui_out_text (uiout, "Hardware watchpoint ");
+      ui_out_list_begin (uiout, "wpt");
+      ui_out_field_int (uiout, "number", b->number);
+      ui_out_text (uiout, ": ");
+      print_expression (b->exp, stb->stream);
+      ui_out_field_stream (uiout, "exp", stb);
+      ui_out_list_end (uiout);
+      break;
+#else
     case bp_watchpoint:
       printf_filtered ("Watchpoint %d: ", b->number);
       print_expression (b->exp, gdb_stdout);
@@ -3753,6 +4388,27 @@ mention (b)
       printf_filtered ("Hardware watchpoint %d: ", b->number);
       print_expression (b->exp, gdb_stdout);
       break;
+#endif
+#ifdef UI_OUT
+    case bp_read_watchpoint:
+      ui_out_text (uiout, "Hardware read watchpoint ");
+      ui_out_list_begin (uiout, "hw-rwpt");
+      ui_out_field_int (uiout, "number", b->number);
+      ui_out_text (uiout, ": ");
+      print_expression (b->exp, stb->stream);
+      ui_out_field_stream (uiout, "exp", stb);
+      ui_out_list_end (uiout);
+      break;
+    case bp_access_watchpoint:
+      ui_out_text (uiout, "Hardware access (read/write) watchpoint ");
+      ui_out_list_begin (uiout, "hw-awpt");
+      ui_out_field_int (uiout, "number", b->number);
+      ui_out_text (uiout, ": ");
+      print_expression (b->exp, stb->stream);
+      ui_out_field_stream (uiout, "exp", stb);
+      ui_out_list_end (uiout);
+      break;
+#else
     case bp_read_watchpoint:
       printf_filtered ("Hardware read watchpoint %d: ", b->number);
       print_expression (b->exp, gdb_stdout);
@@ -3762,11 +4418,26 @@ mention (b)
                       b->number);
       print_expression (b->exp, gdb_stdout);
       break;
+#endif
     case bp_breakpoint:
+#ifdef UI_OUT
+      if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+       {
+         say_where = 0;
+         break;
+       }
+#endif
       printf_filtered ("Breakpoint %d", b->number);
       say_where = 1;
       break;
     case bp_hardware_breakpoint:
+#ifdef UI_OUT
+      if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+       {
+         say_where = 0;
+         break;
+       }
+#endif
       printf_filtered ("Hardware assisted breakpoint %d", b->number);
       say_where = 1;
       break;
@@ -3804,6 +4475,7 @@ mention (b)
     case bp_call_dummy:
     case bp_watchpoint_scope:
     case bp_shlib_event:
+    case bp_thread_event:
       break;
     }
   if (say_where)
@@ -3819,111 +4491,146 @@ mention (b)
       TUIDO (((TuiOpaqueFuncPtr) tui_vAllSetHasBreakAt, b, 1));
       TUIDO (((TuiOpaqueFuncPtr) tuiUpdateAllExecInfos));
     }
+#ifdef UI_OUT
+  do_cleanups (old_chain);
+#endif
+#ifdef UI_OUT
+  if (interpreter_p && strcmp (interpreter_p, "mi") == 0)
+    return;
+#endif
   printf_filtered ("\n");
 }
 \f
 
-/* 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. */
+/* Add SALS.nelts breakpoints to the breakpoint table.  For each
+   SALS.sal[i] breakpoint, include the corresponding ADDR_STRING[i],
+   COND[i] and COND_STRING[i] values.
+
+   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
+   caller is expected to cleanups both the ADDR_STRING, COND_STRING,
+   COND and SALS arrays and each of those arrays contents. */
 
 static void
-break_command_1 (arg, flag, from_tty)
-     char *arg;
-     int flag, from_tty;
+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 tempflag, hardwareflag;
-  struct symtabs_and_lines sals;
-  struct symtab_and_line sal;
-  register struct expression *cond = 0;
-  register struct breakpoint *b;
-
-  /* Pointers in arg to the start, and one past the end, of the condition.  */
-  char *cond_start = NULL;
-  char *cond_end = NULL;
-  /* Pointers in arg to the start, and one past the end,
-     of the address part.  */
-  char *addr_start = NULL;
-  char *addr_end = NULL;
-  struct cleanup *old_chain;
-  struct cleanup *canonical_strings_chain = NULL;
-  char **canonical = (char **) NULL;
-  int i;
-  int thread;
-
-  hardwareflag = flag & BP_HARDWAREFLAG;
-  tempflag = flag & BP_TEMPFLAG;
-
-  sals.sals = NULL;
-  sals.nelts = 0;
+  if (type == bp_hardware_breakpoint)
+    {
+      int i = hw_breakpoint_used_count ();
+      int target_resources_ok = 
+       TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_hardware_breakpoint, 
+                                           i + sals.nelts, 0);
+      if (target_resources_ok == 0)
+       error ("No hardware breakpoint support in the target.");
+      else if (target_resources_ok < 0)
+       error ("Hardware breakpoints used exceeds limit.");
+    }
 
-  INIT_SAL (&sal);             /* initialize to zeroes */
+  /* Now set all the breakpoints.  */
+  {
+    int i;
+    for (i = 0; i < sals.nelts; i++)
+      {
+       struct breakpoint *b;
+       struct symtab_and_line sal = sals.sals[i];
+
+       if (from_tty)
+         describe_other_breakpoints (sal.pc, sal.section);
+       
+       b = set_raw_breakpoint (sal);
+       set_breakpoint_count (breakpoint_count + 1);
+       b->number = breakpoint_count;
+       b->type = type;
+       b->cond = cond[i];
+       b->thread = thread;
+       b->addr_string = addr_string[i];
+       b->cond_string = cond_string[i];
+       b->ignore_count = ignore_count;
+       b->enable = enabled;
+       b->disposition = disposition;
+       mention (b);
+      }
+  }    
+}
 
-  /* If no arg given, or if first arg is 'if ', use the default breakpoint. */
+/* Parse ARG which is assumed to be a SAL specification possibly
+   followed by conditionals.  On return, SALS contains an array of SAL
+   addresses found. ADDR_STRING contains a vector of (canonical)
+   address strings. ARG points to the end of the SAL. */
 
-  if (!arg || (arg[0] == 'i' && arg[1] == 'f'
-              && (arg[2] == ' ' || arg[2] == '\t')))
+void
+parse_breakpoint_sals (char **address,
+                      struct symtabs_and_lines *sals,
+                      char ***addr_string)
+{
+  char *addr_start = *address;
+  *addr_string = NULL;
+  /* If no arg given, or if first arg is 'if ', use the default
+     breakpoint. */
+  if ((*address) == NULL
+      || (strncmp ((*address), "if", 2) == 0 && isspace ((*address)[2])))
     {
       if (default_breakpoint_valid)
        {
-         sals.sals = (struct symtab_and_line *)
+         struct symtab_and_line sal;
+         INIT_SAL (&sal);              /* initialize to zeroes */
+         sals->sals = (struct symtab_and_line *)
            xmalloc (sizeof (struct symtab_and_line));
          sal.pc = default_breakpoint_address;
          sal.line = default_breakpoint_line;
          sal.symtab = default_breakpoint_symtab;
          sal.section = find_pc_overlay (sal.pc);
-         sals.sals[0] = sal;
-         sals.nelts = 1;
+         sals->sals[0] = sal;
+         sals->nelts = 1;
        }
       else
        error ("No default breakpoint address now.");
     }
   else
     {
-      addr_start = arg;
-
       /* Force almost all breakpoints to be in terms of the
          current_source_symtab (which is decode_line_1's default).  This
          should produce the results we want almost all of the time while
          leaving default_breakpoint_* alone.  */
       if (default_breakpoint_valid
          && (!current_source_symtab
-             || (arg && (*arg == '+' || *arg == '-'))))
-       sals = decode_line_1 (&arg, 1, default_breakpoint_symtab,
-                             default_breakpoint_line, &canonical);
+             || (strchr ("+-", (*address)[0]) != NULL)))
+       *sals = decode_line_1 (address, 1, default_breakpoint_symtab,
+                              default_breakpoint_line, addr_string);
       else
-       sals = decode_line_1 (&arg, 1, (struct symtab *) NULL, 0, &canonical);
-
-      addr_end = arg;
+       *sals = decode_line_1 (address, 1, (struct symtab *) NULL, 0, addr_string);
     }
-
-  if (!sals.nelts)
-    return;
-
-  /* Make sure that all storage allocated in decode_line_1 gets freed
-     in case the following `for' loop errors out.  */
-  old_chain = make_cleanup (free, sals.sals);
-  if (canonical != (char **) NULL)
+  /* For any SAL that didn't have a canonical string, fill one in. */
+  if (sals->nelts > 0 && *addr_string == NULL)
+    *addr_string = xcalloc (sals->nelts, sizeof (char **));
+  if (addr_start != (*address))
     {
-      make_cleanup (free, canonical);
-      canonical_strings_chain = make_cleanup (null_cleanup, 0);
-      for (i = 0; i < sals.nelts; i++)
+      int i;
+      for (i = 0; i < sals->nelts; i++)
        {
-         if (canonical[i] != NULL)
-           make_cleanup (free, canonical[i]);
+         /* Add the string if not present. */
+         if ((*addr_string)[i] == NULL)
+           (*addr_string)[i] = savestring (addr_start, (*address) - addr_start);
        }
     }
+}
 
-  thread = -1;                 /* No specific thread yet */
 
-  /* Resolve all line numbers to PC's, and verify that conditions
-     can be parsed, before setting any breakpoints.  */
-  for (i = 0; i < sals.nelts; i++)
-    {
-      char *tok, *end_tok;
-      int toklen;
+/* Convert each SAL into a real PC.  Verify that the PC can be
+   inserted as a breakpoint.  If it can't throw an error. */
 
-      resolve_sal_pc (&sals.sals[i]);
+void
+breakpoint_sals_to_pc (struct symtabs_and_lines *sals,
+                      char *address)
+{    
+  int i;
+  for (i = 0; i < sals->nelts; i++)
+    {
+      resolve_sal_pc (&sals->sals[i]);
 
       /* It's possible for the PC to be nonzero, but still an illegal
          value on some targets.
@@ -3938,16 +4645,98 @@ break_command_1 (arg, flag, from_tty)
 
          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))
+      if (PC_REQUIRES_RUN_BEFORE_USE (sals->sals[i].pc))
        {
-         error ("Cannot break on %s without a running program.", 
-                addr_start);
+         if (address == NULL)
+           error ("Cannot break without a running program.");
+         else
+           error ("Cannot break on %s without a running program.", 
+                  address);
        }
+    }
+}
+
+/* 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);
 
-      tok = arg;
+  /* 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++;
 
@@ -3961,8 +4750,11 @@ break_command_1 (arg, flag, from_tty)
          if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
            {
              tok = cond_start = end_tok + 1;
-             cond = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), 0);
+             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)
            {
@@ -3980,70 +4772,157 @@ break_command_1 (arg, flag, from_tty)
            error ("Junk at end of arguments.");
        }
     }
-  if (hardwareflag)
-    {
-      int i, target_resources_ok;
 
-      i = hw_breakpoint_used_count ();
-      target_resources_ok = 
-       TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_hardware_breakpoint, 
-                                           i + sals.nelts, 0);
-      if (target_resources_ok == 0)
-       error ("No hardware breakpoint support in the target.");
-      else if (target_resources_ok < 0)
-       error ("Hardware breakpoints used exceeds limit.");
+  create_breakpoints (sals, addr_string, cond, cond_string,
+                     hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
+                     tempflag ? del : 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);
+}
 
-  /* Remove the canonical strings from the cleanup, they are needed below.  */
-  if (canonical != (char **) NULL)
-    discard_cleanups (canonical_strings_chain);
+/* Set a breakpoint of TYPE/DISPOSITION according to ARG (function,
+   linenum or *address) with COND and IGNORE_COUNT. */
 
-  /* Now set all the breakpoints.  */
-  for (i = 0; i < sals.nelts; i++)
-    {
-      sal = sals.sals[i];
+struct captured_breakpoint_args
+  {
+    char *address;
+    char *condition;
+    int hardwareflag;
+    int tempflag;
+    int thread;
+    int ignore_count;
+  };
 
-      if (from_tty)
-       describe_other_breakpoints (sal.pc, sal.section);
+static int
+do_captured_breakpoint (void *data)
+{
+  struct captured_breakpoint_args *args = data;
+  struct symtabs_and_lines sals;
+  register struct expression **cond;
+  struct cleanup *old_chain;
+  struct cleanup *breakpoint_chain = NULL;
+  int i;
+  char **addr_string;
+  char **cond_string;
 
-      b = set_raw_breakpoint (sal);
-      set_breakpoint_count (breakpoint_count + 1);
-      b->number = breakpoint_count;
-      b->type = hardwareflag ? bp_hardware_breakpoint : bp_breakpoint;
-      b->cond = cond;
-      b->thread = thread;
+  char *address_end;
 
-      /* If a canonical line spec is needed use that instead of the
-         command string.  */
-      if (canonical != (char **) NULL && canonical[i] != NULL)
-       b->addr_string = canonical[i];
-      else if (addr_start)
-       b->addr_string = savestring (addr_start, addr_end - addr_start);
-      if (cond_start)
-       b->cond_string = savestring (cond_start, cond_end - cond_start);
+  /* Parse the source and lines spec.  Delay check that the expression
+     didn't contain trailing garbage until after cleanups are in
+     place. */
+  sals.sals = NULL;
+  sals.nelts = 0;
+  address_end = args->address;
+  addr_string = NULL;
+  parse_breakpoint_sals (&address_end, &sals, &addr_string);
 
-      b->enable = enabled;
-      b->disposition = tempflag ? del : donttouch;
-      mention (b);
+  if (!sals.nelts)
+    return GDB_RC_NONE;
+
+  /* Create a chain of things at always need to be cleaned up. */
+  old_chain = make_cleanup (null_cleanup, 0);
+
+  /* Always have a addr_string array, even if it is empty. */
+  make_cleanup (xfree, addr_string);
+
+  /* Make sure that all storage allocated to SALS gets freed.  */
+  make_cleanup (xfree, sals.sals);
+
+  /* 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 goes
+     through then that memory is not cleaned up. */
+  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]);
     }
 
-  if (sals.nelts > 1)
+  /* 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);
+
+  /* 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++)
     {
-      warning ("Multiple breakpoints were set.");
-      warning ("Use the \"delete\" command to delete unwanted breakpoints.");
+      if (args->condition != NULL)
+       {
+         char *tok = args->condition;
+         cond[i] = parse_exp_1 (&tok, block_for_pc (sals.sals[i].pc), 0);
+         if (*tok != '\0')
+           error ("Garbage %s follows condition", tok);
+         make_cleanup (xfree, cond[i]);
+         cond_string[i] = xstrdup (args->condition);
+       }
     }
+
+  create_breakpoints (sals, addr_string, cond, cond_string,
+                     args->hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
+                     args->tempflag ? del : donttouch,
+                     args->thread, args->ignore_count, 0/*from-tty*/);
+
+  /* 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;
+}
+
+enum gdb_rc
+gdb_breakpoint (char *address, char *condition,
+               int hardwareflag, int tempflag,
+               int thread, int ignore_count)
+{
+  struct captured_breakpoint_args args;
+  args.address = address;
+  args.condition = condition;
+  args.hardwareflag = hardwareflag;
+  args.tempflag = tempflag;
+  args.thread = thread;
+  args.ignore_count = ignore_count;
+  return catch_errors (do_captured_breakpoint, &args,
+                      NULL, RETURN_MASK_ALL);
 }
 
+
 static void
-break_at_finish_at_depth_command_1 (arg, flag, from_tty)
-     char *arg;
-     int flag;
-     int from_tty;
+break_at_finish_at_depth_command_1 (char *arg, int flag, int from_tty)
 {
   struct frame_info *frame;
   CORE_ADDR low, high, selected_pc = 0;
-  char *extra_args, *level_arg, *addr_string;
+  char *extra_args = NULL;
+  char *level_arg;
+  char *addr_string;
   int extra_args_len = 0, if_arg = 0;
 
   if (!arg ||
@@ -4103,7 +4982,7 @@ break_at_finish_at_depth_command_1 (arg, flag, from_tty)
          else
            sprintf (addr_string, "*0x%s", paddr_nz (high));
          break_command_1 (addr_string, flag, from_tty);
-         free (addr_string);
+         xfree (addr_string);
        }
       else
        error ("No function contains the specified address");
@@ -4114,17 +4993,14 @@ break_at_finish_at_depth_command_1 (arg, flag, from_tty)
 
 
 static void
-break_at_finish_command_1 (arg, flag, from_tty)
-     char *arg;
-     int flag;
-     int from_tty;
+break_at_finish_command_1 (char *arg, int flag, int from_tty)
 {
   char *addr_string, *break_string, *beg_addr_string;
   CORE_ADDR low, high;
   struct symtabs_and_lines sals;
   struct symtab_and_line sal;
   struct cleanup *old_chain;
-  char *extra_args;
+  char *extra_args = NULL;
   int extra_args_len = 0;
   int i, if_arg = 0;
 
@@ -4175,8 +5051,8 @@ break_at_finish_command_1 (arg, flag, from_tty)
   sals = decode_line_1 (&addr_string, 1, (struct symtab *) NULL, 0,
                        (char ***) NULL);
 
-  free (beg_addr_string);
-  old_chain = make_cleanup (free, sals.sals);
+  xfree (beg_addr_string);
+  old_chain = make_cleanup (xfree, sals.sals);
   for (i = 0; (i < sals.nelts); i++)
     {
       sal = sals.sals[i];
@@ -4188,7 +5064,7 @@ break_at_finish_command_1 (arg, flag, from_tty)
          else
            sprintf (break_string, "*0x%s", paddr_nz (high));
          break_command_1 (break_string, flag, from_tty);
-         free (break_string);
+         xfree (break_string);
        }
       else
        error ("No function contains the specified address");
@@ -4205,8 +5081,7 @@ break_at_finish_command_1 (arg, flag, from_tty)
 /* Helper function for break_command_1 and disassemble_command.  */
 
 void
-resolve_sal_pc (sal)
-     struct symtab_and_line *sal;
+resolve_sal_pc (struct symtab_and_line *sal)
 {
   CORE_ADDR pc;
 
@@ -4253,65 +5128,49 @@ resolve_sal_pc (sal)
 }
 
 void
-break_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+break_command (char *arg, int from_tty)
 {
   break_command_1 (arg, 0, from_tty);
 }
 
 static void
-break_at_finish_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+break_at_finish_command (char *arg, int from_tty)
 {
   break_at_finish_command_1 (arg, 0, from_tty);
 }
 
 static void
-break_at_finish_at_depth_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+break_at_finish_at_depth_command (char *arg, int from_tty)
 {
   break_at_finish_at_depth_command_1 (arg, 0, from_tty);
 }
 
 void
-tbreak_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+tbreak_command (char *arg, int from_tty)
 {
   break_command_1 (arg, BP_TEMPFLAG, from_tty);
 }
 
 static void
-tbreak_at_finish_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+tbreak_at_finish_command (char *arg, int from_tty)
 {
   break_at_finish_command_1 (arg, BP_TEMPFLAG, from_tty);
 }
 
 static void
-hbreak_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+hbreak_command (char *arg, int from_tty)
 {
   break_command_1 (arg, BP_HARDWAREFLAG, from_tty);
 }
 
 static void
-thbreak_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+thbreak_command (char *arg, int from_tty)
 {
   break_command_1 (arg, (BP_TEMPFLAG | BP_HARDWAREFLAG), from_tty);
 }
 
 static void
-stop_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+stop_command (char *arg, int from_tty)
 {
   printf_filtered ("Specify the type of breakpoint to set.\n\
 Usage: stop in <function | address>\n\
@@ -4319,9 +5178,7 @@ Usage: stop in <function | address>\n\
 }
 
 static void
-stopin_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+stopin_command (char *arg, int from_tty)
 {
   int badInput = 0;
 
@@ -4354,9 +5211,7 @@ stopin_command (arg, from_tty)
 }
 
 static void
-stopat_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+stopat_command (char *arg, int from_tty)
 {
   int badInput = 0;
 
@@ -4392,10 +5247,7 @@ stopat_command (arg, from_tty)
                 hw_read:   watch read, 
                hw_access: watch access (read or write) */
 static void
-watch_command_1 (arg, accessflag, from_tty)
-     char *arg;
-     int accessflag;
-     int from_tty;
+watch_command_1 (char *arg, int accessflag, int from_tty)
 {
   struct breakpoint *b;
   struct symtab_and_line sal;
@@ -4478,7 +5330,7 @@ watch_command_1 (arg, accessflag, from_tty)
      startup sequence by the dynamic linker.
 
      However, I tried avoiding that by having HP-UX's implementation of
-     TARGET_CAN_USE_HW_WATCHPOINT return FALSE if there was no inferior_pid
+     TARGET_CAN_USE_HW_WATCHPOINT return FALSE if there was no inferior_ptid
      yet, which forced slow watches before a "run" or "attach", and it
      still fails somewhere in the startup code.
 
@@ -4571,34 +5423,69 @@ watch_command_1 (arg, accessflag, from_tty)
 
 #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)
+     (TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(LEN))
 #endif
 
 static int
-can_use_hardware_watchpoint (v)
-     struct value *v;
+can_use_hardware_watchpoint (struct value *v)
 {
   int found_memory_cnt = 0;
+  struct value *head = v;
 
   /* Did the user specifically forbid us to use hardware watchpoints? */
   if (!can_use_hw_watchpoints)
     return 0;
 
-  /* Make sure all the intermediate values are in memory.  Also make sure
-     we found at least one memory expression.  Guards against watch 0x12345,
-     which is meaningless, but could cause errors if one tries to insert a 
-     hardware watchpoint for the constant expression.  */
+  /* Make sure that the value of the expression depends only upon
+     memory contents, and values computed from them within GDB.  If we
+     find any register references or function calls, we can't use a
+     hardware watchpoint.
+
+     The idea here is that evaluating an expression generates a series
+     of values, one holding the value of every subexpression.  (The
+     expression a*b+c has five subexpressions: a, b, a*b, c, and
+     a*b+c.)  GDB's values hold almost enough information to establish
+     the criteria given above --- they identify memory lvalues,
+     register lvalues, computed values, etcetera.  So we can evaluate
+     the expression, and then scan the chain of values that leaves
+     behind to decide whether we can detect any possible change to the
+     expression's final value using only hardware watchpoints.
+
+     However, I don't think that the values returned by inferior
+     function calls are special in any way.  So this function may not
+     notice that an expression involving an inferior function call
+     can't be watched with hardware watchpoints.  FIXME.  */
   for (; v; v = v->next)
     {
-      if (v->lval == lval_memory)
+      if (VALUE_LVAL (v) == lval_memory)
        {
-         CORE_ADDR vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
-         int       len   = TYPE_LENGTH (VALUE_TYPE (v));
-
-         if (!TARGET_REGION_OK_FOR_HW_WATCHPOINT (vaddr, len))
-           return 0;
+         if (VALUE_LAZY (v))
+           /* A lazy memory lvalue is one that GDB never needed to fetch;
+              we either just used its address (e.g., `a' in `a.b') or
+              we never needed it at all (e.g., `a' in `a,b').  */
+           ;
          else
-           found_memory_cnt++;
+           {
+             /* Ahh, memory we actually used!  Check if we can cover
+                 it with hardware watchpoints.  */
+             struct type *vtype = check_typedef (VALUE_TYPE (v));
+
+             /* We only watch structs and arrays if user asked for it
+                explicitly, never if they just happen to appear in a
+                middle of some value chain.  */
+             if (v == head
+                 || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+                     && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
+               {
+                 CORE_ADDR vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+                 int       len   = TYPE_LENGTH (VALUE_TYPE (v));
+
+                 if (!TARGET_REGION_OK_FOR_HW_WATCHPOINT (vaddr, len))
+                   return 0;
+                 else
+                   found_memory_cnt++;
+               }
+           }
        }
       else if (v->lval != not_lval && v->modifiable == 0)
        return 0;       /* ??? What does this represent? */
@@ -4611,26 +5498,41 @@ can_use_hardware_watchpoint (v)
   return found_memory_cnt;
 }
 
+#ifdef UI_OUT
+void
+watch_command_wrapper (char *arg, int from_tty)
+{
+  watch_command (arg, from_tty);
+}
+#endif
 static void
-watch_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+watch_command (char *arg, int from_tty)
 {
   watch_command_1 (arg, hw_write, from_tty);
 }
 
+#ifdef UI_OUT
+void
+rwatch_command_wrapper (char *arg, int from_tty)
+{
+  rwatch_command (arg, from_tty);
+}
+#endif
 static void
-rwatch_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+rwatch_command (char *arg, int from_tty)
 {
   watch_command_1 (arg, hw_read, from_tty);
 }
 
+#ifdef UI_OUT
+void
+awatch_command_wrapper (char *arg, int from_tty)
+{
+  awatch_command (arg, from_tty);
+}
+#endif
 static void
-awatch_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+awatch_command (char *arg, int from_tty)
 {
   watch_command_1 (arg, hw_access, from_tty);
 }
@@ -4643,27 +5545,26 @@ awatch_command (arg, from_tty)
    cmd_continuation pointer, to complete the until command. It takes
    care of cleaning up the temporary breakpoints set up by the until
    command. */
-void
-until_break_command_continuation (arg)
-     struct continuation_arg *arg;
+static void
+until_break_command_continuation (struct continuation_arg *arg)
 {
-  /* Do all the exec cleanups, which at this point should only be the
-     one set up in the first part of the until_break_command
-     function. */
-  do_exec_cleanups (ALL_CLEANUPS);
+  struct cleanup *cleanups;
+
+  cleanups = (struct cleanup *) arg->data.pointer;
+  do_exec_cleanups (cleanups);
 }
 
 /* ARGSUSED */
 void
-until_break_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+until_break_command (char *arg, int from_tty)
 {
   struct symtabs_and_lines sals;
   struct symtab_and_line sal;
   struct frame_info *prev_frame = get_prev_frame (selected_frame);
   struct breakpoint *breakpoint;
   struct cleanup *old_chain;
+  struct continuation_arg *arg1;
+
 
   clear_proceed_status ();
 
@@ -4681,7 +5582,7 @@ until_break_command (arg, from_tty)
     error ("Couldn't get information on specified line.");
 
   sal = sals.sals[0];
-  free ((PTR) sals.sals);      /* malloc'd, so freed */
+  xfree (sals.sals);   /* malloc'd, so freed */
 
   if (*arg)
     error ("Junk at end of arguments.");
@@ -4690,11 +5591,10 @@ until_break_command (arg, from_tty)
 
   breakpoint = set_momentary_breakpoint (sal, selected_frame, bp_until);
 
-  if (!async_p || !target_has_async)
-    old_chain = make_cleanup ((make_cleanup_func) delete_breakpoint, 
-                             breakpoint);
+  if (!event_loop_p || !target_can_async_p ())
+    old_chain = make_cleanup_delete_breakpoint (breakpoint);
   else
-    make_exec_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
+    old_chain = make_exec_cleanup_delete_breakpoint (breakpoint);
 
   /* If we are running asynchronously, and the target supports async
      execution, we are not waiting for the target to stop, in the call
@@ -4703,13 +5603,18 @@ until_break_command (arg, from_tty)
      where we get a chance to do that is in fetch_inferior_event, so
      we must set things up for that. */
 
-  if (async_p && target_has_async)
+  if (event_loop_p && target_can_async_p ())
     {
-      /* In this case we don't need args for the continuation, because
-         all it needs to do is do the cleanups in the
-         exec_cleanup_chain, which will be only those inserted by this
-         function. We can get away by using ALL_CLEANUPS. */
-      add_continuation (until_break_command_continuation, NULL);
+      /* In this case the arg for the continuation is just the point
+         in the exec_cleanups chain from where to start doing
+         cleanups, because all the continuation does is the cleanups in
+         the exec_cleanup_chain. */
+      arg1 =
+       (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+      arg1->next         = NULL;
+      arg1->data.pointer = old_chain;
+
+      add_continuation (until_break_command_continuation, arg1);
     }
 
   /* Keep within the current frame */
@@ -4719,16 +5624,16 @@ until_break_command (arg, from_tty)
       sal = find_pc_line (prev_frame->pc, 0);
       sal.pc = prev_frame->pc;
       breakpoint = set_momentary_breakpoint (sal, prev_frame, bp_until);
-      if (!async_p || !target_has_async)
-       make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
+      if (!event_loop_p || !target_can_async_p ())
+       make_cleanup_delete_breakpoint (breakpoint);
       else
-       make_exec_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
+       make_exec_cleanup_delete_breakpoint (breakpoint);
     }
 
   proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
   /* Do the cleanups now, anly if we are not running asynchronously,
      of if we are, but the target is still synchronous. */
-  if (!async_p || !target_has_async)
+  if (!event_loop_p || !target_can_async_p ())
     do_cleanups (old_chain);
 }
 \f
@@ -4736,23 +5641,22 @@ until_break_command (arg, from_tty)
 /* 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 (name)
-     char *name;
+catch_breakpoint (char *name)
 {
 }
 
 static int
-disable_catch_breakpoint ()
+disable_catch_breakpoint (void)
 {
 }
 
 static int
-delete_catch_breakpoint ()
+delete_catch_breakpoint (void)
 {
 }
 
 static int
-enable_catch_breakpoint ()
+enable_catch_breakpoint (void)
 {
 }
 #endif /* 0 */
@@ -4772,9 +5676,7 @@ struct sal_chain
 /* For each catch clause identified in ARGS, run FUNCTION
    with that clause as an argument.  */
 static struct symtabs_and_lines
-map_catch_names (args, function)
-     char *args;
-     int (*function) ();
+map_catch_names (char *args, int (*function) ())
 {
   register char *p = args;
   register char *p1;
@@ -4833,8 +5735,7 @@ map_catch_names (args, function)
 /* This shares a lot of code with `print_frame_label_vars' from stack.c.  */
 
 static struct symtabs_and_lines
-get_catch_sals (this_level_only)
-     int this_level_only;
+get_catch_sals (int this_level_only)
 {
   register struct blockvector *bl;
   register struct block *block;
@@ -4946,8 +5847,7 @@ get_catch_sals (this_level_only)
 }
 
 static void
-ep_skip_leading_whitespace (s)
-     char **s;
+ep_skip_leading_whitespace (char **s)
 {
   if ((s == NULL) || (*s == NULL))
     return;
@@ -4961,8 +5861,7 @@ ep_skip_leading_whitespace (s)
    the token is returned.  Else, NULL is returned. */
 
 static char *
-ep_find_event_name_end (arg)
-     char *arg;
+ep_find_event_name_end (char *arg)
 {
   char *s = arg;
   char *event_name_end = NULL;
@@ -4995,8 +5894,7 @@ ep_find_event_name_end (arg)
    if clause in the arg string. */
 
 static char *
-ep_parse_optional_if_clause (arg)
-     char **arg;
+ep_parse_optional_if_clause (char **arg)
 {
   char *cond_string;
 
@@ -5028,8 +5926,7 @@ ep_parse_optional_if_clause (arg)
    Note that clients needing to preserve the returned filename for
    future access should copy it to their own buffers. */
 static char *
-ep_parse_optional_filename (arg)
-     char **arg;
+ep_parse_optional_filename (char **arg)
 {
   static char filename[1024];
   char *arg_p = *arg;
@@ -5063,17 +5960,13 @@ typedef enum
 }
 catch_fork_kind;
 
-static void catch_fork_command_1 PARAMS ((catch_fork_kind fork_kind, 
-                                         char *arg, 
-                                         int tempflag, 
-                                         int from_tty));
+#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 (fork_kind, arg, tempflag, from_tty)
-     catch_fork_kind fork_kind;
-     char *arg;
-     int tempflag;
-     int from_tty;
+catch_fork_command_1 (catch_fork_kind fork_kind, char *arg, int tempflag,
+                     int from_tty)
 {
   char *cond_string = NULL;
 
@@ -5104,12 +5997,11 @@ catch_fork_command_1 (fork_kind, arg, tempflag, from_tty)
       break;
     }
 }
+#endif
 
+#if defined(CHILD_INSERT_EXEC_CATCHPOINT)
 static void
-catch_exec_command_1 (arg, tempflag, from_tty)
-     char *arg;
-     int tempflag;
-     int from_tty;
+catch_exec_command_1 (char *arg, int tempflag, int from_tty)
 {
   char *cond_string = NULL;
 
@@ -5129,13 +6021,11 @@ catch_exec_command_1 (arg, tempflag, 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 (arg, tempflag, from_tty)
-     char *arg;
-     int tempflag;
-     int from_tty;
+catch_load_command_1 (char *arg, int tempflag, int from_tty)
 {
   char *dll_pathname = NULL;
   char *cond_string = NULL;
@@ -5172,15 +6062,12 @@ catch_load_command_1 (arg, tempflag, from_tty)
   /* Create a load breakpoint that only triggers when a load of
      the specified dll (or any dll, if no pathname was specified)
      occurs. */
-  SOLIB_CREATE_CATCH_LOAD_HOOK (inferior_pid, tempflag, 
+  SOLIB_CREATE_CATCH_LOAD_HOOK (PIDGET (inferior_ptid), tempflag, 
                                dll_pathname, cond_string);
 }
 
 static void
-catch_unload_command_1 (arg, tempflag, from_tty)
-     char *arg;
-     int tempflag;
-     int from_tty;
+catch_unload_command_1 (char *arg, int tempflag, int from_tty)
 {
   char *dll_pathname = NULL;
   char *cond_string = NULL;
@@ -5217,7 +6104,7 @@ catch_unload_command_1 (arg, tempflag, from_tty)
   /* Create an unload breakpoint that only triggers when an unload of
      the specified dll (or any dll, if no pathname was specified)
      occurs. */
-  SOLIB_CREATE_CATCH_UNLOAD_HOOK (inferior_pid, tempflag, 
+  SOLIB_CREATE_CATCH_UNLOAD_HOOK (PIDGET (inferior_ptid), tempflag, 
                                  dll_pathname, cond_string);
 }
 #endif /* SOLIB_ADD */
@@ -5228,11 +6115,9 @@ catch_unload_command_1 (arg, tempflag, from_tty)
    exception event callback */
 
 static void
-create_exception_catchpoint (tempflag, cond_string, ex_event, sal)
-     int tempflag;
-     char *cond_string;
-     enum exception_event_kind ex_event;
-     struct symtab_and_line *sal;
+create_exception_catchpoint (int tempflag, char *cond_string,
+                            enum exception_event_kind ex_event,
+                            struct symtab_and_line *sal)
 {
   struct breakpoint *b;
   int thread = -1;             /* All threads. */
@@ -5269,11 +6154,8 @@ create_exception_catchpoint (tempflag, cond_string, ex_event, sal)
 /* Deal with "catch catch" and "catch throw" commands */
 
 static void
-catch_exception_command_1 (ex_event, arg, tempflag, from_tty)
-     enum exception_event_kind ex_event;
-     char *arg;
-     int tempflag;
-     int from_tty;
+catch_exception_command_1 (enum exception_event_kind ex_event, char *arg,
+                          int tempflag, int from_tty)
 {
   char *cond_string = NULL;
   struct symtab_and_line *sal = NULL;
@@ -5324,8 +6206,7 @@ catch_exception_command_1 (ex_event, arg, tempflag, from_tty)
    inside a catch_errors */
 
 static int
-cover_target_enable_exception_callback (arg)
-     PTR arg;
+cover_target_enable_exception_callback (PTR arg)
 {
   args_for_catchpoint_enable *args = arg;
   struct symtab_and_line *sal;
@@ -5353,10 +6234,7 @@ cover_target_enable_exception_callback (arg)
 
 
 static void
-handle_gnu_4_16_catch_command (arg, tempflag, from_tty)
-     char *arg;
-     int tempflag;
-     int from_tty;
+handle_gnu_4_16_catch_command (char *arg, int tempflag, int from_tty)
 {
   /* First, translate ARG into something we can deal with in terms
      of breakpoints.  */
@@ -5445,15 +6323,14 @@ handle_gnu_4_16_catch_command (arg, tempflag, from_tty)
       warning ("Multiple breakpoints were set.");
       warning ("Use the \"delete\" command to delete unwanted breakpoints.");
     }
-  free ((PTR) sals.sals);
+  xfree (sals.sals);
 }
 
 #if 0
 /* This creates a temporary internal breakpoint
    just to placate infrun */
 static struct breakpoint *
-create_temp_exception_breakpoint (pc)
-     CORE_ADDR pc;
+create_temp_exception_breakpoint (CORE_ADDR pc)
 {
   struct symtab_and_line sal;
   struct breakpoint *b;
@@ -5477,10 +6354,7 @@ create_temp_exception_breakpoint (pc)
 #endif
 
 static void
-catch_command_1 (arg, tempflag, from_tty)
-     char *arg;
-     int tempflag;
-     int from_tty;
+catch_command_1 (char *arg, int tempflag, int from_tty)
 {
 
   /* The first argument may be an event name, such as "start" or "load".
@@ -5603,8 +6477,7 @@ catch_command_1 (arg, tempflag, from_tty)
 /* Used by the gui, could be made a worker for other things. */
 
 struct breakpoint *
-set_breakpoint_sal (sal)
-     struct symtab_and_line sal;
+set_breakpoint_sal (struct symtab_and_line sal)
 {
   struct breakpoint *b;
   b = set_raw_breakpoint (sal);
@@ -5620,51 +6493,42 @@ set_breakpoint_sal (sal)
 /* 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 (args)
-     char *args;
+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 (args)
-     char *args;
+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 (args)
-     char *args;
+delete_catch (char *args)
 {
   /* Map the delete command to catch clauses described in ARGS.  */
 }
 #endif /* 0 */
 
 static void
-catch_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+catch_command (char *arg, int from_tty)
 {
   catch_command_1 (arg, 0, from_tty);
 }
 \f
 
 static void
-tcatch_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+tcatch_command (char *arg, int from_tty)
 {
   catch_command_1 (arg, 1, from_tty);
 }
 
 
 static void
-clear_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+clear_command (char *arg, int from_tty)
 {
   register struct breakpoint *b, *b1;
   int default_match;
@@ -5794,7 +6658,7 @@ clear_command (arg, from_tty)
       if (from_tty)
        putchar_unfiltered ('\n');
     }
-  free ((PTR) sals.sals);
+  xfree (sals.sals);
 }
 \f
 /* Delete breakpoint in BS if they are `delete' breakpoints and
@@ -5802,8 +6666,7 @@ clear_command (arg, from_tty)
    This is called after any breakpoint is hit, or after errors.  */
 
 void
-breakpoint_auto_delete (bs)
-     bpstat bs;
+breakpoint_auto_delete (bpstat bs)
 {
   struct breakpoint *b, *temp;
 
@@ -5823,8 +6686,7 @@ breakpoint_auto_delete (bs)
    structures. */
 
 void
-delete_breakpoint (bpt)
-     struct breakpoint *bpt;
+delete_breakpoint (struct breakpoint *bpt)
 {
   register struct breakpoint *b;
   register bpstat bs;
@@ -5929,6 +6791,15 @@ delete_breakpoint (bpt)
        {
          int val;
 
+         /* We should never reach this point if there is a permanent
+            breakpoint at the same address as the one being deleted.
+            If there is a permanent breakpoint somewhere, it should
+            always be the only one inserted.  */
+         if (b->enable == permanent)
+           internal_error (__FILE__, __LINE__,
+                           "another breakpoint was inserted on top of "
+                           "a permanent breakpoint");
+
          if (b->type == bp_hardware_breakpoint)
            val = target_insert_hw_breakpoint (b->address, b->shadow_contents);
          else
@@ -5947,25 +6818,25 @@ delete_breakpoint (bpt)
 
   free_command_lines (&bpt->commands);
   if (bpt->cond)
-    free (bpt->cond);
+    xfree (bpt->cond);
   if (bpt->cond_string != NULL)
-    free (bpt->cond_string);
+    xfree (bpt->cond_string);
   if (bpt->addr_string != NULL)
-    free (bpt->addr_string);
+    xfree (bpt->addr_string);
   if (bpt->exp != NULL)
-    free (bpt->exp);
+    xfree (bpt->exp);
   if (bpt->exp_string != NULL)
-    free (bpt->exp_string);
+    xfree (bpt->exp_string);
   if (bpt->val != NULL)
     value_free (bpt->val);
   if (bpt->source_file != NULL)
-    free (bpt->source_file);
+    xfree (bpt->source_file);
   if (bpt->dll_pathname != NULL)
-    free (bpt->dll_pathname);
+    xfree (bpt->dll_pathname);
   if (bpt->triggered_dll_pathname != NULL)
-    free (bpt->triggered_dll_pathname);
+    xfree (bpt->triggered_dll_pathname);
   if (bpt->exec_pathname != NULL)
-    free (bpt->exec_pathname);
+    xfree (bpt->exec_pathname);
 
   /* Be sure no bpstat's are pointing at it after it's been freed.  */
   /* FIXME, how can we find all bpstat's?
@@ -5987,13 +6858,29 @@ delete_breakpoint (bpt)
      bp, we mark it as deleted before freeing its storage. */
   bpt->type = bp_none;
 
-  free ((PTR) bpt);
+  xfree (bpt);
+}
+
+static void
+do_delete_breakpoint_cleanup (void *b)
+{
+  delete_breakpoint (b);
+}
+
+struct cleanup *
+make_cleanup_delete_breakpoint (struct breakpoint *b)
+{
+  return make_cleanup (do_delete_breakpoint_cleanup, b);
+}
+
+struct cleanup *
+make_exec_cleanup_delete_breakpoint (struct breakpoint *b)
+{
+  return make_exec_cleanup (do_delete_breakpoint_cleanup, b);
 }
 
 void
-delete_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+delete_command (char *arg, int from_tty)
 {
   struct breakpoint *b, *temp;
 
@@ -6008,6 +6895,7 @@ delete_command (arg, from_tty)
       {
        if (b->type != bp_call_dummy &&
            b->type != bp_shlib_event &&
+           b->type != bp_thread_event &&
            b->number >= 0)
          breaks_to_delete = 1;
       }
@@ -6020,6 +6908,7 @@ delete_command (arg, from_tty)
          {
            if (b->type != bp_call_dummy &&
                b->type != bp_shlib_event &&
+               b->type != bp_thread_event &&
                b->number >= 0)
              delete_breakpoint (b);
          }
@@ -6034,8 +6923,7 @@ delete_command (arg, from_tty)
    Unused in this case.  */
 
 static int
-breakpoint_re_set_one (bint)
-     PTR bint;
+breakpoint_re_set_one (PTR bint)
 {
   /* get past catch_errs */
   struct breakpoint *b = (struct breakpoint *) bint;
@@ -6080,7 +6968,7 @@ breakpoint_re_set_one (bint)
            {
              s = b->cond_string;
              if (b->cond)
-               free ((PTR) b->cond);
+               xfree (b->cond);
              b->cond = parse_exp_1 (&s, block_for_pc (sals.sals[i].pc), 0);
            }
 
@@ -6099,7 +6987,7 @@ breakpoint_re_set_one (bint)
            )
            {
              if (b->source_file != NULL)
-               free (b->source_file);
+               xfree (b->source_file);
              if (sals.sals[i].symtab == NULL)
                b->source_file = NULL;
              else
@@ -6128,7 +7016,7 @@ breakpoint_re_set_one (bint)
          check_duplicates (b->address, b->section);
 
        }
-      free ((PTR) sals.sals);
+      xfree (sals.sals);
       break;
 
     case bp_watchpoint:
@@ -6146,7 +7034,7 @@ breakpoint_re_set_one (bint)
 
       /* So for now, just use a global context.  */
       if (b->exp)
-       free ((PTR) b->exp);
+       xfree (b->exp);
       b->exp = parse_expression (b->exp_string);
       b->exp_valid_block = innermost_block;
       mark = value_mark ();
@@ -6161,7 +7049,7 @@ breakpoint_re_set_one (bint)
        {
          s = b->cond_string;
          if (b->cond)
-           free ((PTR) b->cond);
+           xfree (b->cond);
          b->cond = parse_exp_1 (&s, (struct block *) 0, 0);
        }
       if (b->enable == enabled)
@@ -6193,6 +7081,10 @@ breakpoint_re_set_one (bint)
          starts and we really don't want to touch it.  */
     case bp_shlib_event:
 
+      /* Like bp_shlib_event, this breakpoint type is special.
+        Once it is set up, we do not want to touch it.  */
+    case bp_thread_event:
+
       /* Keep temporary breakpoints, which can be encountered when we step
          over a dlopen call and SOLIB_ADD is resetting the breakpoints.
          Otherwise these should have been blown away via the cleanup chain
@@ -6210,7 +7102,7 @@ breakpoint_re_set_one (bint)
 
 /* Re-set all breakpoints after symbols have been re-loaded.  */
 void
-breakpoint_re_set ()
+breakpoint_re_set (void)
 {
   struct breakpoint *b, *temp;
   enum language save_language;
@@ -6252,21 +7144,19 @@ breakpoint_re_set ()
 /* Reset the thread number of this breakpoint:
 
    - If the breakpoint is for all threads, leave it as-is.
-   - Else, reset it to the current thread for inferior_pid. */
+   - Else, reset it to the current thread for inferior_ptid. */
 void
-breakpoint_re_set_thread (b)
-     struct breakpoint *b;
+breakpoint_re_set_thread (struct breakpoint *b)
 {
   if (b->thread != -1)
     {
-      if (in_thread_list (inferior_pid))
-       b->thread = pid_to_thread_id (inferior_pid);
+      if (in_thread_list (inferior_ptid))
+       b->thread = pid_to_thread_id (inferior_ptid);
     }
 }
 
 void
-set_ignore_count (bptnum, count, from_tty)
-     int bptnum, count, from_tty;
+set_ignore_count (int bptnum, int count, int from_tty)
 {
   register struct breakpoint *b;
 
@@ -6297,7 +7187,7 @@ set_ignore_count (bptnum, count, from_tty)
 
 /* Clear the ignore counts of all breakpoints.  */
 void
-breakpoint_clear_ignore_counts ()
+breakpoint_clear_ignore_counts (void)
 {
   struct breakpoint *b;
 
@@ -6308,9 +7198,7 @@ breakpoint_clear_ignore_counts ()
 /* Command to set ignore-count of breakpoint N to COUNT.  */
 
 static void
-ignore_command (args, from_tty)
-     char *args;
-     int from_tty;
+ignore_command (char *args, int from_tty)
 {
   char *p = args;
   register int num;
@@ -6319,7 +7207,8 @@ ignore_command (args, from_tty)
     error_no_arg ("a breakpoint number");
 
   num = get_number (&p);
-
+  if (num == 0)
+    error ("bad breakpoint number: '%s'", args);
   if (*p == 0)
     error ("Second argument (specified ignore-count) is missing.");
 
@@ -6334,42 +7223,48 @@ ignore_command (args, from_tty)
    whose numbers are given in ARGS.  */
 
 static void
-map_breakpoint_numbers (args, function)
-     char *args;
-     void (*function) PARAMS ((struct breakpoint *));
+map_breakpoint_numbers (char *args, void (*function) (struct breakpoint *))
 {
   register char *p = args;
   char *p1;
   register int num;
-  register struct breakpoint *b;
+  register struct breakpoint *b, *tmp;
+  int match;
 
   if (p == 0)
     error_no_arg ("one or more breakpoint numbers");
 
   while (*p)
     {
+      match = 0;
       p1 = p;
 
-      num = get_number (&p1);
-
-      ALL_BREAKPOINTS (b)
-       if (b->number == num)
+      num = get_number_or_range (&p1);
+      if (num == 0)
        {
-         struct breakpoint *related_breakpoint = b->related_breakpoint;
-         function (b);
-         if (related_breakpoint)
-           function (related_breakpoint);
-         goto win;
+         warning ("bad breakpoint number at or near '%s'", p);
+       }
+      else
+       {
+         ALL_BREAKPOINTS_SAFE (b, tmp)
+           if (b->number == num)
+             {
+               struct breakpoint *related_breakpoint = b->related_breakpoint;
+               match = 1;
+               function (b);
+               if (related_breakpoint)
+                 function (related_breakpoint);
+               break;
+             }
+         if (match == 0)
+           printf_unfiltered ("No breakpoint number %d.\n", num);
        }
-      printf_unfiltered ("No breakpoint number %d.\n", num);
-    win:
       p = p1;
     }
 }
 
 void
-disable_breakpoint (bpt)
-     struct breakpoint *bpt;
+disable_breakpoint (struct breakpoint *bpt)
 {
   /* Never disable a watchpoint scope breakpoint; we want to
      hit them when we leave scope so we can delete both the
@@ -6377,6 +7272,10 @@ disable_breakpoint (bpt)
   if (bpt->type == bp_watchpoint_scope)
     return;
 
+  /* You can't disable permanent breakpoints.  */
+  if (bpt->enable == permanent)
+    return;
+
   bpt->enable = disabled;
 
   check_duplicates (bpt->address, bpt->section);
@@ -6388,9 +7287,7 @@ disable_breakpoint (bpt)
 
 /* ARGSUSED */
 static void
-disable_command (args, from_tty)
-     char *args;
-     int from_tty;
+disable_command (char *args, int from_tty)
 {
   register struct breakpoint *bpt;
   if (args == 0)
@@ -6423,9 +7320,7 @@ disable_command (args, from_tty)
 }
 
 static void
-do_enable_breakpoint (bpt, disposition)
-     struct breakpoint *bpt;
-     enum bpdisp disposition;
+do_enable_breakpoint (struct breakpoint *bpt, enum bpdisp disposition)
 {
   struct frame_info *save_selected_frame = NULL;
   int save_selected_frame_level = -1;
@@ -6445,7 +7340,8 @@ do_enable_breakpoint (bpt, disposition)
        error ("Hardware breakpoints used exceeds limit.");
     }
 
-  bpt->enable = enabled;
+  if (bpt->enable != permanent)
+    bpt->enable = enabled;
   bpt->disposition = disposition;
   check_duplicates (bpt->address, bpt->section);
   breakpoints_changed ();
@@ -6510,8 +7406,7 @@ have been allocated for other watchpoints.\n", bpt->number);
        }
 
       if (save_selected_frame_level >= 0)
-       select_and_print_frame (save_selected_frame,
-                               save_selected_frame_level);
+       select_frame (save_selected_frame, save_selected_frame_level);
       value_free_to_mark (mark);
     }
   if (modify_breakpoint_hook)
@@ -6520,8 +7415,7 @@ have been allocated for other watchpoints.\n", bpt->number);
 }
 
 void
-enable_breakpoint (bpt)
-     struct breakpoint *bpt;
+enable_breakpoint (struct breakpoint *bpt)
 {
   do_enable_breakpoint (bpt, bpt->disposition);
 }
@@ -6532,9 +7426,7 @@ enable_breakpoint (bpt)
 
 /* ARGSUSED */
 static void
-enable_command (args, from_tty)
-     char *args;
-     int from_tty;
+enable_command (char *args, int from_tty)
 {
   register struct breakpoint *bpt;
   if (args == 0)
@@ -6567,33 +7459,27 @@ enable_command (args, from_tty)
 }
 
 static void
-enable_once_breakpoint (bpt)
-     struct breakpoint *bpt;
+enable_once_breakpoint (struct breakpoint *bpt)
 {
   do_enable_breakpoint (bpt, disable);
 }
 
 /* ARGSUSED */
 static void
-enable_once_command (args, from_tty)
-     char *args;
-     int from_tty;
+enable_once_command (char *args, int from_tty)
 {
   map_breakpoint_numbers (args, enable_once_breakpoint);
 }
 
 static void
-enable_delete_breakpoint (bpt)
-     struct breakpoint *bpt;
+enable_delete_breakpoint (struct breakpoint *bpt)
 {
   do_enable_breakpoint (bpt, del);
 }
 
 /* ARGSUSED */
 static void
-enable_delete_command (args, from_tty)
-     char *args;
-     int from_tty;
+enable_delete_command (char *args, int from_tty)
 {
   map_breakpoint_numbers (args, enable_delete_breakpoint);
 }
@@ -6601,9 +7487,7 @@ enable_delete_command (args, from_tty)
 /* Use default_breakpoint_'s, or nothing if they aren't valid.  */
 
 struct symtabs_and_lines
-decode_line_spec_1 (string, funfirstline)
-     char *string;
-     int funfirstline;
+decode_line_spec_1 (char *string, int funfirstline)
 {
   struct symtabs_and_lines sals;
   if (string == 0)
@@ -6622,7 +7506,7 @@ decode_line_spec_1 (string, funfirstline)
 }
 \f
 void
-_initialize_breakpoint ()
+_initialize_breakpoint (void)
 {
   struct cmd_list_element *c;
 
This page took 0.106382 seconds and 4 git commands to generate.