gdb
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 97efc0a46d05e7b5d4a5cd778b48cd9db56b46f6..3dbee8530d9c497c20113c271c709cac6760f94e 100644 (file)
@@ -39,6 +39,7 @@
 #include "language.h"
 #include "gdb_string.h"
 #include "demangle.h"
+#include "filenames.h"
 #include "annotate.h"
 #include "symfile.h"
 #include "objfiles.h"
@@ -62,6 +63,7 @@
 #include "jit.h"
 #include "xml-syscall.h"
 #include "parser-defs.h"
+#include "cli/cli-utils.h"
 
 /* readline include files */
 #include "readline/readline.h"
@@ -71,6 +73,7 @@
 #undef savestring
 
 #include "mi/mi-common.h"
+#include "python/python.h"
 
 /* Arguments to pass as context to some catch command handlers.  */
 #define CATCH_PERMANENT ((void *) (uintptr_t) 0)
@@ -98,7 +101,7 @@ static void clear_command (char *, int);
 
 static void catch_command (char *, int);
 
-static int can_use_hardware_watchpoint (struct value *);
+static int can_use_hardware_watchpoint (struct value *, int);
 
 static void break_command_1 (char *, int, int);
 
@@ -128,11 +131,16 @@ static int breakpoint_address_match (struct address_space *aspace1,
 static int watchpoint_locations_match (struct bp_location *loc1,
                                       struct bp_location *loc2);
 
+static int breakpoint_location_address_match (struct bp_location *bl,
+                                             struct address_space *aspace,
+                                             CORE_ADDR addr);
+
 static void breakpoints_info (char *, int);
 
 static void watchpoints_info (char *, int);
 
-static int breakpoint_1 (int, int, int (*) (const struct breakpoint *));
+static int breakpoint_1 (char *, int, 
+                        int (*) (const struct breakpoint *));
 
 static int breakpoint_cond_eval (void *);
 
@@ -142,8 +150,6 @@ static void commands_command (char *, int);
 
 static void condition_command (char *, int);
 
-static int get_number_trailer (char **, int);
-
 typedef enum
   {
     mark_inserted,
@@ -185,8 +191,6 @@ static void catch_exception_command_1 (enum exception_event_kind ex_event,
 
 static void tcatch_command (char *arg, int from_tty);
 
-static void ep_skip_leading_whitespace (char **s);
-
 static void detach_single_step_breakpoints (void);
 
 static int single_step_breakpoint_inserted_here_p (struct address_space *,
@@ -247,7 +251,7 @@ breakpoint_commands (struct breakpoint *b)
 
 static int breakpoint_proceeded;
 
-static const char *
+const char *
 bpdisp_text (enum bpdisp disp)
 {
   /* NOTE: the following values are a part of MI protocol and
@@ -351,6 +355,9 @@ static int executing_breakpoint_commands;
 /* Are overlay event breakpoints enabled? */
 static int overlay_events_enabled;
 
+/* See description in breakpoint.h. */
+int target_exact_watchpoints = 0;
+
 /* Walk the following statement or block through all breakpoints.
    ALL_BREAKPOINTS_SAFE does so even if the statment deletes the
    current breakpoint.  */
@@ -550,164 +557,6 @@ int default_breakpoint_line;
 struct program_space *default_breakpoint_pspace;
 
 \f
-/* *PP is a string denoting a breakpoint.  Get the number of the
-   breakpoint.  Advance *PP after the string and any trailing
-   whitespace.
-
-   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").
-
-   If the string is a NULL pointer, that denotes the last breakpoint.
-   
-   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_trailer (char **pp, int trailer)
-{
-  int retval = 0;      /* default */
-  char *p = *pp;
-
-  if (p == NULL)
-    /* Empty line means refer to the last breakpoint.  */
-    return breakpoint_count;
-  else if (*p == '$')
-    {
-      /* Make a copy of the name, so we can null-terminate it
-         to pass to lookup_internalvar().  */
-      char *varname;
-      char *start = ++p;
-      LONGEST val;
-
-      while (isalnum (*p) || *p == '_')
-       p++;
-      varname = (char *) alloca (p - start + 1);
-      strncpy (varname, start, p - start);
-      varname[p - start] = '\0';
-      if (get_internalvar_integer (lookup_internalvar (varname), &val))
-       retval = (int) val;
-      else
-       {
-         printf_filtered (_("Convenience variable must "
-                            "have integer value.\n"));
-         retval = 0;
-       }
-    }
-  else
-    {
-      if (*p == '-')
-       ++p;
-      while (*p >= '0' && *p <= '9')
-       ++p;
-      if (p == *pp)
-       /* There is no number here.  (e.g. "cond a == b").  */
-       {
-         /* 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;
-    }
-  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;
-}
-
 /* Return the breakpoint with the specified number, or NULL
    if the number does not refer to an existing breakpoint.  */
 
@@ -800,6 +649,14 @@ condition_command (char *arg, int from_tty)
   ALL_BREAKPOINTS (b)
     if (b->number == bnum)
       {
+       /* Check if this breakpoint has a Python object assigned to
+          it, and if it has a definition of the "stop"
+          method.  This method and conditions entered into GDB from
+          the CLI are mutually exclusive.  */
+       if (b->py_bp_object
+           && gdbpy_breakpoint_has_py_cond (b->py_bp_object))
+         error (_("Cannot set a condition where a Python 'stop' "
+                  "method has been defined in the breakpoint."));
        set_breakpoint_condition (b, p, from_tty);
        return;
       }
@@ -937,6 +794,46 @@ breakpoint_set_commands (struct breakpoint *b,
   observer_notify_breakpoint_modified (b->number);
 }
 
+/* Set the internal `silent' flag on the breakpoint.  Note that this
+   is not the same as the "silent" that may appear in the breakpoint's
+   commands.  */
+
+void
+breakpoint_set_silent (struct breakpoint *b, int silent)
+{
+  int old_silent = b->silent;
+
+  b->silent = silent;
+  if (old_silent != silent)
+    observer_notify_breakpoint_modified (b->number);
+}
+
+/* Set the thread for this breakpoint.  If THREAD is -1, make the
+   breakpoint work for any thread.  */
+
+void
+breakpoint_set_thread (struct breakpoint *b, int thread)
+{
+  int old_thread = b->thread;
+
+  b->thread = thread;
+  if (old_thread != thread)
+    observer_notify_breakpoint_modified (b->number);
+}
+
+/* Set the task for this breakpoint.  If TASK is 0, make the
+   breakpoint work for any task.  */
+
+void
+breakpoint_set_task (struct breakpoint *b, int task)
+{
+  int old_task = b->task;
+
+  b->task = task;
+  if (old_task != task)
+    observer_notify_breakpoint_modified (b->number);
+}
+
 void
 check_tracepoint_command (char *line, void *closure)
 {
@@ -1228,18 +1125,6 @@ breakpoint_restore_shadows (gdb_byte *buf, ULONGEST memaddr, LONGEST len)
 }
 \f
 
-/* A wrapper function for inserting catchpoints.  */
-static void
-insert_catchpoint (struct ui_out *uo, void *args)
-{
-  struct breakpoint *b = (struct breakpoint *) args;
-
-  gdb_assert (b->type == bp_catchpoint);
-  gdb_assert (b->ops != NULL && b->ops->insert != NULL);
-
-  b->ops->insert (b);
-}
-
 /* Return true if BPT is of any hardware watchpoint kind.  */
 
 static int
@@ -1278,6 +1163,25 @@ watchpoint_in_thread_scope (struct breakpoint *b)
              && !is_executing (inferior_ptid)));
 }
 
+/* Set watchpoint B to disp_del_at_next_stop, even including its possible
+   associated bp_watchpoint_scope breakpoint.  */
+
+static void
+watchpoint_del_at_next_stop (struct breakpoint *b)
+{
+  gdb_assert (is_watchpoint (b));
+
+  if (b->related_breakpoint != b)
+    {
+      gdb_assert (b->related_breakpoint->type == bp_watchpoint_scope);
+      gdb_assert (b->related_breakpoint->related_breakpoint == b);
+      b->related_breakpoint->disposition = disp_del_at_next_stop;
+      b->related_breakpoint->related_breakpoint = b->related_breakpoint;
+      b->related_breakpoint = b;
+    }
+  b->disposition = disp_del_at_next_stop;
+}
+
 /* Assuming that B is a watchpoint:
    - Reparse watchpoint expression, if REPARSE is non-zero
    - Evaluate expression and store the result in B->val
@@ -1337,17 +1241,14 @@ update_watchpoint (struct breakpoint *b, int reparse)
   struct frame_id saved_frame_id;
   int frame_saved;
 
+  gdb_assert (is_watchpoint (b));
+
   /* If this is a local watchpoint, we only want to check if the
      watchpoint frame is in scope if the current thread is the thread
      that was used to create the watchpoint.  */
   if (!watchpoint_in_thread_scope (b))
     return;
 
-  /* We don't free locations.  They are stored in bp_location array
-     and update_global_locations will eventually delete them and
-     remove breakpoints if needed.  */
-  b->loc = NULL;
-
   if (b->disposition == disp_del_at_next_stop)
     return;
  
@@ -1358,7 +1259,15 @@ update_watchpoint (struct breakpoint *b, int reparse)
     within_current_scope = 1;
   else
     {
-      struct frame_info *fi;
+      struct frame_info *fi = get_current_frame ();
+      struct gdbarch *frame_arch = get_frame_arch (fi);
+      CORE_ADDR frame_pc = get_frame_pc (fi);
+
+      /* If we're in a function epilogue, unwinding may not work
+        properly, so do not attempt to recreate locations at this
+        point.  See similar comments in watchpoint_check.  */
+      if (gdbarch_in_function_epilogue_p (frame_arch, frame_pc))
+       return;
 
       /* Save the current frame's ID so we can restore it after
          evaluating the watchpoint expression on its own frame.  */
@@ -1374,6 +1283,11 @@ update_watchpoint (struct breakpoint *b, int reparse)
        select_frame (fi);
     }
 
+  /* We don't free locations.  They are stored in the bp_location array
+     and update_global_location_list will eventually delete them and
+     remove breakpoints if needed.  */
+  b->loc = NULL;
+
   if (within_current_scope && reparse)
     {
       char *s;
@@ -1438,43 +1352,10 @@ update_watchpoint (struct breakpoint *b, int reparse)
          b->val_valid = 1;
        }
 
-       /* Change the type of breakpoint between hardware assisted or
-          an ordinary watchpoint depending on the hardware support
-          and free hardware slots.  REPARSE is set when the inferior
-          is started.  */
-       if ((b->type == bp_watchpoint || b->type == bp_hardware_watchpoint)
-           && reparse)
-         {
-           int i, mem_cnt, other_type_used;
-
-           /* We need to determine how many resources are already
-              used for all other hardware watchpoints to see if we
-              still have enough resources to also fit this watchpoint
-              in as well.  To avoid the hw_watchpoint_used_count call
-              below from counting this watchpoint, make sure that it
-              is marked as a software watchpoint.  */
-           b->type = bp_watchpoint;
-           i = hw_watchpoint_used_count (bp_hardware_watchpoint,
-                                         &other_type_used);
-           mem_cnt = can_use_hardware_watchpoint (val_chain);
-
-           if (!mem_cnt)
-             b->type = bp_watchpoint;
-           else
-             {
-               int target_resources_ok = target_can_use_hardware_watchpoint
-                 (bp_hardware_watchpoint, i + mem_cnt, other_type_used);
-               if (target_resources_ok <= 0)
-                 b->type = bp_watchpoint;
-               else
-                 b->type = bp_hardware_watchpoint;
-             }
-         }
-
       frame_pspace = get_frame_program_space (get_selected_frame (NULL));
 
       /* Look at each value on the value chain.  */
-      for (v = val_chain; v; v = next)
+      for (v = val_chain; v; v = value_next (v))
        {
          /* If it's a memory location, and GDB actually needed
             its contents to evaluate the expression, then we
@@ -1517,7 +1398,62 @@ update_watchpoint (struct breakpoint *b, int reparse)
                  loc->watchpoint_type = type;
                }
            }
+       }
+
+      /* Change the type of breakpoint between hardware assisted or
+        an ordinary watchpoint depending on the hardware support
+        and free hardware slots.  REPARSE is set when the inferior
+        is started.  */
+      if ((b->type == bp_watchpoint || b->type == bp_hardware_watchpoint)
+         && reparse)
+       {
+         int reg_cnt;
+         enum bp_loc_type loc_type;
+         struct bp_location *bl;
+
+         reg_cnt = can_use_hardware_watchpoint (val_chain, b->exact);
+
+         if (reg_cnt)
+           {
+             int i, target_resources_ok, other_type_used;
+             enum enable_state orig_enable_state;
+
+             /* We need to determine how many resources are already
+                used for all other hardware watchpoints plus this one
+                to see if we still have enough resources to also fit
+                this watchpoint in as well.  To guarantee the
+                hw_watchpoint_used_count call below counts this
+                watchpoint, make sure that it is marked as a hardware
+                watchpoint.  */
+             b->type = bp_hardware_watchpoint;
+
+             /* hw_watchpoint_used_count ignores disabled watchpoints,
+                and b might be disabled if we're being called from
+                do_enable_breakpoint.  */
+             orig_enable_state = b->enable_state;
+             b->enable_state = bp_enabled;
+
+             i = hw_watchpoint_used_count (bp_hardware_watchpoint,
+                                           &other_type_used);
+
+             b->enable_state = orig_enable_state;
+
+             target_resources_ok = target_can_use_hardware_watchpoint
+                   (bp_hardware_watchpoint, i, other_type_used);
+             if (target_resources_ok <= 0)
+               b->type = bp_watchpoint;
+           }
+         else
+           b->type = bp_watchpoint;
+
+         loc_type = (b->type == bp_watchpoint? bp_loc_other
+                     : bp_loc_hardware_watchpoint);
+         for (bl = b->loc; bl; bl = bl->next)
+           bl->loc_type = loc_type;
+       }
 
+      for (v = val_chain; v; v = next)
+       {
          next = value_next (v);
          if (v != b->val)
            value_free (v);
@@ -1538,17 +1474,11 @@ update_watchpoint (struct breakpoint *b, int reparse)
     }
   else if (!within_current_scope)
     {
-      printf_filtered (_("Watchpoint %d deleted because "
-                        "the program has left the block\n"
-                        "in which its expression is valid.\n"),
+      printf_filtered (_("\
+Watchpoint %d deleted because the program has left the block\n\
+in which its expression is valid.\n"),
                       b->number);
-      if (b->related_breakpoint)
-       {
-         b->related_breakpoint->disposition = disp_del_at_next_stop;
-         b->related_breakpoint->related_breakpoint = NULL;
-         b->related_breakpoint= NULL;
-       }
-      b->disposition = disp_del_at_next_stop;
+      watchpoint_del_at_next_stop (b);
     }
 
   /* Restore the selected frame.  */
@@ -1611,6 +1541,7 @@ insert_bp_location (struct bp_location *bl,
   memset (&bl->target_info, 0, sizeof (bl->target_info));
   bl->target_info.placed_address = bl->address;
   bl->target_info.placed_address_space = bl->pspace->aspace;
+  bl->target_info.length = bl->length;
 
   if (bl->loc_type == bp_loc_software_breakpoint
       || bl->loc_type == bp_loc_hardware_breakpoint)
@@ -1790,10 +1721,10 @@ insert_bp_location (struct bp_location *bl,
              watchpoints.  It's not clear that it's necessary...  */
           && bl->owner->disposition != disp_del_at_next_stop)
     {
-      val = target_insert_watchpoint (bl->address,
-                                     bl->length,
-                                     bl->watchpoint_type,
-                                     bl->owner->cond_exp);
+      gdb_assert (bl->owner->ops != NULL
+                 && bl->owner->ops->insert_location != NULL);
+
+      val = bl->owner->ops->insert_location (bl);
 
       /* If trying to set a read-watchpoint, and it turns out it's not
         supported, try emulating one with an access watchpoint.  */
@@ -1819,12 +1750,12 @@ insert_bp_location (struct bp_location *bl,
 
          if (val == 1)
            {
-             val = target_insert_watchpoint (bl->address,
-                                             bl->length,
-                                             hw_access,
-                                             bl->owner->cond_exp);
-             if (val == 0)
-               bl->watchpoint_type = hw_access;
+             bl->watchpoint_type = hw_access;
+             val = bl->owner->ops->insert_location (bl);
+
+             if (val)
+               /* Back to the original value.  */
+               bl->watchpoint_type = hw_read;
            }
        }
 
@@ -1833,14 +1764,23 @@ insert_bp_location (struct bp_location *bl,
 
   else if (bl->owner->type == bp_catchpoint)
     {
-      struct gdb_exception e = catch_exception (uiout, insert_catchpoint,
-                                               bl->owner, RETURN_MASK_ERROR);
-      exception_fprintf (gdb_stderr, e, "warning: inserting catchpoint %d: ",
-                        bl->owner->number);
-      if (e.reason < 0)
-       bl->owner->enable_state = bp_disabled;
-      else
-       bl->inserted = 1;
+      gdb_assert (bl->owner->ops != NULL
+                 && bl->owner->ops->insert_location != NULL);
+
+      val = bl->owner->ops->insert_location (bl);
+      if (val)
+       {
+         bl->owner->enable_state = bp_disabled;
+
+         if (val == 1)
+           warning (_("\
+Error inserting catchpoint %d: Your system does not support this type\n\
+of catchpoint."), bl->owner->number);
+         else
+           warning (_("Error inserting catchpoint %d."), bl->owner->number);
+       }
+
+      bl->inserted = (val == 0);
 
       /* We've already printed an error message if there was a problem
         inserting this catchpoint, and we've disabled the catchpoint,
@@ -2079,7 +2019,7 @@ reattach_breakpoints (int pid)
   struct cleanup *old_chain;
   struct bp_location *bl, **blp_tmp;
   int val;
-  struct ui_file *tmp_error_stream = mem_fileopen ();
+  struct ui_file *tmp_error_stream;
   int dummy1 = 0, dummy2 = 0;
   struct inferior *inf;
   struct thread_info *tp;
@@ -2093,6 +2033,7 @@ reattach_breakpoints (int pid)
 
   inferior_ptid = tp->ptid;
 
+  tmp_error_stream = mem_fileopen ();
   make_cleanup_ui_file_delete (tmp_error_stream);
 
   ALL_BP_LOCATIONS (bl, blp_tmp)
@@ -2155,22 +2096,94 @@ create_internal_breakpoint (struct gdbarch *gdbarch,
   return b;
 }
 
+static const char *const longjmp_names[] =
+  {
+    "longjmp", "_longjmp", "siglongjmp", "_siglongjmp"
+  };
+#define NUM_LONGJMP_NAMES ARRAY_SIZE(longjmp_names)
+
+/* Per-objfile data private to breakpoint.c.  */
+struct breakpoint_objfile_data
+{
+  /* Minimal symbol for "_ovly_debug_event" (if any).  */
+  struct minimal_symbol *overlay_msym;
+
+  /* Minimal symbol(s) for "longjmp", "siglongjmp", etc. (if any).  */
+  struct minimal_symbol *longjmp_msym[NUM_LONGJMP_NAMES];
+
+  /* Minimal symbol for "std::terminate()" (if any).  */
+  struct minimal_symbol *terminate_msym;
+
+  /* Minimal symbol for "_Unwind_DebugHook" (if any).  */
+  struct minimal_symbol *exception_msym;
+};
+
+static const struct objfile_data *breakpoint_objfile_key;
+
+/* Minimal symbol not found sentinel.  */
+static struct minimal_symbol msym_not_found;
+
+/* Returns TRUE if MSYM point to the "not found" sentinel.  */
+
+static int
+msym_not_found_p (const struct minimal_symbol *msym)
+{
+  return msym == &msym_not_found;
+}
+
+/* Return per-objfile data needed by breakpoint.c.
+   Allocate the data if necessary.  */
+
+static struct breakpoint_objfile_data *
+get_breakpoint_objfile_data (struct objfile *objfile)
+{
+  struct breakpoint_objfile_data *bp_objfile_data;
+
+  bp_objfile_data = objfile_data (objfile, breakpoint_objfile_key);
+  if (bp_objfile_data == NULL)
+    {
+      bp_objfile_data = obstack_alloc (&objfile->objfile_obstack,
+                                      sizeof (*bp_objfile_data));
+
+      memset (bp_objfile_data, 0, sizeof (*bp_objfile_data));
+      set_objfile_data (objfile, breakpoint_objfile_key, bp_objfile_data);
+    }
+  return bp_objfile_data;
+}
+
 static void
-create_overlay_event_breakpoint (char *func_name)
+create_overlay_event_breakpoint (void)
 {
   struct objfile *objfile;
+  const char *const func_name = "_ovly_debug_event";
 
   ALL_OBJFILES (objfile)
     {
       struct breakpoint *b;
-      struct minimal_symbol *m;
+      struct breakpoint_objfile_data *bp_objfile_data;
+      CORE_ADDR addr;
 
-      m = lookup_minimal_symbol_text (func_name, objfile);
-      if (m == NULL)
-        continue;
+      bp_objfile_data = get_breakpoint_objfile_data (objfile);
+
+      if (msym_not_found_p (bp_objfile_data->overlay_msym))
+       continue;
+
+      if (bp_objfile_data->overlay_msym == NULL)
+       {
+         struct minimal_symbol *m;
+
+         m = lookup_minimal_symbol_text (func_name, objfile);
+         if (m == NULL)
+           {
+             /* Avoid future lookups in this objfile.  */
+             bp_objfile_data->overlay_msym = &msym_not_found;
+             continue;
+           }
+         bp_objfile_data->overlay_msym = m;
+       }
 
-      b = create_internal_breakpoint (get_objfile_arch (objfile),
-                                     SYMBOL_VALUE_ADDRESS (m),
+      addr = SYMBOL_VALUE_ADDRESS (bp_objfile_data->overlay_msym);
+      b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
                                       bp_overlay_event);
       b->addr_string = xstrdup (func_name);
 
@@ -2189,70 +2202,117 @@ create_overlay_event_breakpoint (char *func_name)
 }
 
 static void
-create_longjmp_master_breakpoint (char *func_name)
+create_longjmp_master_breakpoint (void)
 {
   struct program_space *pspace;
-  struct objfile *objfile;
   struct cleanup *old_chain;
 
   old_chain = save_current_program_space ();
 
   ALL_PSPACES (pspace)
-  ALL_OBJFILES (objfile)
+  {
+    struct objfile *objfile;
+
+    set_current_program_space (pspace);
+
+    ALL_OBJFILES (objfile)
     {
-      struct breakpoint *b;
-      struct minimal_symbol *m;
+      int i;
+      struct gdbarch *gdbarch;
+      struct breakpoint_objfile_data *bp_objfile_data;
 
-      if (!gdbarch_get_longjmp_target_p (get_objfile_arch (objfile)))
+      gdbarch = get_objfile_arch (objfile);
+      if (!gdbarch_get_longjmp_target_p (gdbarch))
        continue;
 
-      set_current_program_space (pspace);
+      bp_objfile_data = get_breakpoint_objfile_data (objfile);
 
-      m = lookup_minimal_symbol_text (func_name, objfile);
-      if (m == NULL)
-        continue;
+      for (i = 0; i < NUM_LONGJMP_NAMES; i++)
+       {
+         struct breakpoint *b;
+         const char *func_name;
+         CORE_ADDR addr;
 
-      b = create_internal_breakpoint (get_objfile_arch (objfile),
-                                     SYMBOL_VALUE_ADDRESS (m),
-                                      bp_longjmp_master);
-      b->addr_string = xstrdup (func_name);
-      b->enable_state = bp_disabled;
+         if (msym_not_found_p (bp_objfile_data->longjmp_msym[i]))
+           continue;
+
+         func_name = longjmp_names[i];
+         if (bp_objfile_data->longjmp_msym[i] == NULL)
+           {
+             struct minimal_symbol *m;
+
+             m = lookup_minimal_symbol_text (func_name, objfile);
+             if (m == NULL)
+               {
+                 /* Prevent future lookups in this objfile.  */
+                 bp_objfile_data->longjmp_msym[i] = &msym_not_found;
+                 continue;
+               }
+             bp_objfile_data->longjmp_msym[i] = m;
+           }
+
+         addr = SYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]);
+         b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master);
+         b->addr_string = xstrdup (func_name);
+         b->enable_state = bp_disabled;
+       }
     }
+  }
   update_global_location_list (1);
 
   do_cleanups (old_chain);
 }
 
-/* Create a master std::terminate breakpoint.  The actual function
-   looked for is named FUNC_NAME.  */
+/* Create a master std::terminate breakpoint.  */
 static void
-create_std_terminate_master_breakpoint (const char *func_name)
+create_std_terminate_master_breakpoint (void)
 {
   struct program_space *pspace;
-  struct objfile *objfile;
   struct cleanup *old_chain;
+  const char *const func_name = "std::terminate()";
 
   old_chain = save_current_program_space ();
 
   ALL_PSPACES (pspace)
+  {
+    struct objfile *objfile;
+    CORE_ADDR addr;
+
+    set_current_program_space (pspace);
+
     ALL_OBJFILES (objfile)
     {
       struct breakpoint *b;
-      struct minimal_symbol *m;
+      struct breakpoint_objfile_data *bp_objfile_data;
 
-      set_current_program_space (pspace);
+      bp_objfile_data = get_breakpoint_objfile_data (objfile);
 
-      m = lookup_minimal_symbol (func_name, NULL, objfile);
-      if (m == NULL || (MSYMBOL_TYPE (m) != mst_text
-                       && MSYMBOL_TYPE (m) != mst_file_text))
-        continue;
+      if (msym_not_found_p (bp_objfile_data->terminate_msym))
+       continue;
 
-      b = create_internal_breakpoint (get_objfile_arch (objfile),
-                                     SYMBOL_VALUE_ADDRESS (m),
+      if (bp_objfile_data->terminate_msym == NULL)
+       {
+         struct minimal_symbol *m;
+
+         m = lookup_minimal_symbol (func_name, NULL, objfile);
+         if (m == NULL || (MSYMBOL_TYPE (m) != mst_text
+                           && MSYMBOL_TYPE (m) != mst_file_text))
+           {
+             /* Prevent future lookups in this objfile.  */
+             bp_objfile_data->terminate_msym = &msym_not_found;
+             continue;
+           }
+         bp_objfile_data->terminate_msym = m;
+       }
+
+      addr = SYMBOL_VALUE_ADDRESS (bp_objfile_data->terminate_msym);
+      b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
                                       bp_std_terminate_master);
       b->addr_string = xstrdup (func_name);
       b->enable_state = bp_disabled;
     }
+  }
+
   update_global_location_list (1);
 
   do_cleanups (old_chain);
@@ -2264,24 +2324,42 @@ void
 create_exception_master_breakpoint (void)
 {
   struct objfile *objfile;
+  const char *const func_name = "_Unwind_DebugHook";
 
   ALL_OBJFILES (objfile)
     {
-      struct minimal_symbol *debug_hook;
+      struct breakpoint *b;
+      struct gdbarch *gdbarch;
+      struct breakpoint_objfile_data *bp_objfile_data;
+      CORE_ADDR addr;
+
+      bp_objfile_data = get_breakpoint_objfile_data (objfile);
+
+      if (msym_not_found_p (bp_objfile_data->exception_msym))
+       continue;
 
-      debug_hook = lookup_minimal_symbol ("_Unwind_DebugHook", NULL, objfile);
-      if (debug_hook != NULL)
+      gdbarch = get_objfile_arch (objfile);
+
+      if (bp_objfile_data->exception_msym == NULL)
        {
-         struct breakpoint *b;
-         CORE_ADDR addr = SYMBOL_VALUE_ADDRESS (debug_hook);
-         struct gdbarch *gdbarch = get_objfile_arch (objfile);
+         struct minimal_symbol *debug_hook;
 
-         addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
-                                                    &current_target);
-         b = create_internal_breakpoint (gdbarch, addr, bp_exception_master);
-         b->addr_string = xstrdup ("_Unwind_DebugHook");
-         b->enable_state = bp_disabled;
+         debug_hook = lookup_minimal_symbol (func_name, NULL, objfile);
+         if (debug_hook == NULL)
+           {
+             bp_objfile_data->exception_msym = &msym_not_found;
+             continue;
+           }
+
+         bp_objfile_data->exception_msym = debug_hook;
        }
+
+      addr = SYMBOL_VALUE_ADDRESS (bp_objfile_data->exception_msym);
+      addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
+                                                &current_target);
+      b = create_internal_breakpoint (gdbarch, addr, bp_exception_master);
+      b->addr_string = xstrdup (func_name);
+      b->enable_state = bp_disabled;
     }
 
   update_global_location_list (1);
@@ -2400,12 +2478,9 @@ update_breakpoints_after_exec (void)
       }
   }
   /* FIXME what about longjmp breakpoints?  Re-create them here?  */
-  create_overlay_event_breakpoint ("_ovly_debug_event");
-  create_longjmp_master_breakpoint ("longjmp");
-  create_longjmp_master_breakpoint ("_longjmp");
-  create_longjmp_master_breakpoint ("siglongjmp");
-  create_longjmp_master_breakpoint ("_siglongjmp");
-  create_std_terminate_master_breakpoint ("std::terminate()");
+  create_overlay_event_breakpoint ();
+  create_longjmp_master_breakpoint ();
+  create_std_terminate_master_breakpoint ();
   create_exception_master_breakpoint ();
 }
 
@@ -2537,10 +2612,11 @@ remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is)
     }
   else if (bl->loc_type == bp_loc_hardware_watchpoint)
     {
+      gdb_assert (bl->owner->ops != NULL
+                 && bl->owner->ops->remove_location != NULL);
+
       bl->inserted = (is == mark_inserted);
-      val = target_remove_watchpoint (bl->address, bl->length,
-                                     bl->watchpoint_type, 
-                                     bl->owner->cond_exp);
+      bl->owner->ops->remove_location (bl);
 
       /* Failure to remove any of the hardware watchpoints comes here.  */
       if ((is == mark_uninserted) && (bl->inserted))
@@ -2551,11 +2627,13 @@ remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is)
            && breakpoint_enabled (bl->owner)
            && !bl->duplicate)
     {
-      gdb_assert (bl->owner->ops != NULL && bl->owner->ops->remove != NULL);
+      gdb_assert (bl->owner->ops != NULL
+                 && bl->owner->ops->remove_location != NULL);
 
-      val = bl->owner->ops->remove (bl->owner);
+      val = bl->owner->ops->remove_location (bl);
       if (val)
        return val;
+
       bl->inserted = (is == mark_inserted);
     }
 
@@ -2726,11 +2804,10 @@ breakpoint_here_p (struct address_space *aspace, CORE_ADDR pc)
          && bl->loc_type != bp_loc_hardware_breakpoint)
        continue;
 
-      /* ALL_BP_LOCATIONS bp_location has bl->OWNER always non-NULL.  */
+      /* ALL_BP_LOCATIONS bp_location has BL->OWNER always non-NULL.  */
       if ((breakpoint_enabled (bl->owner)
           || bl->owner->enable_state == bp_permanent)
-         && breakpoint_address_match (bl->pspace->aspace, bl->address,
-                                      aspace, pc))
+         && breakpoint_location_address_match (bl, aspace, pc))
        {
          if (overlay_debugging 
              && section_is_overlay (bl->section)
@@ -2755,8 +2832,7 @@ moribund_breakpoint_here_p (struct address_space *aspace, CORE_ADDR pc)
   int ix;
 
   for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
-    if (breakpoint_address_match (loc->pspace->aspace, loc->address,
-                                 aspace,  pc))
+    if (breakpoint_location_address_match (loc, aspace, pc))
       return 1;
 
   return 0;
@@ -2780,8 +2856,7 @@ regular_breakpoint_inserted_here_p (struct address_space *aspace,
        continue;
 
       if (bl->inserted
-         && breakpoint_address_match (bl->pspace->aspace, bl->address,
-                                      aspace, pc))
+         && breakpoint_location_address_match (bl, aspace, pc))
        {
          if (overlay_debugging 
              && section_is_overlay (bl->section)
@@ -2898,8 +2973,7 @@ breakpoint_thread_match (struct address_space *aspace, CORE_ADDR pc,
          && bl->owner->enable_state != bp_permanent)
        continue;
 
-      if (!breakpoint_address_match (bl->pspace->aspace, bl->address,
-                                    aspace, pc))
+      if (!breakpoint_location_address_match (bl, aspace, pc))
        continue;
 
       if (bl->owner->thread != -1)
@@ -3261,11 +3335,6 @@ print_it_typical (bpstat bs)
   int bp_temp = 0;
   enum print_stop_action result;
 
-  /* bs->breakpoint_at can be NULL if it was a momentary breakpoint
-     which has since been deleted.  */
-  if (bs->breakpoint_at == NULL)
-    return PRINT_UNKNOWN;
-
   gdb_assert (bs->bp_location_at != NULL);
 
   bl = bs->bp_location_at;
@@ -3436,6 +3505,8 @@ print_it_typical (bpstat bs)
     case bp_tracepoint:
     case bp_fast_tracepoint:
     case bp_jit_event:
+    case bp_gnu_ifunc_resolver:
+    case bp_gnu_ifunc_resolver_return:
     default:
       result = PRINT_UNKNOWN;
       break;
@@ -3471,10 +3542,14 @@ print_bp_stop_message (bpstat bs)
       {
        struct breakpoint *b = bs->breakpoint_at;
 
+       /* bs->breakpoint_at can be NULL if it was a momentary breakpoint
+          which has since been deleted.  */
+       if (b == NULL)
+         return PRINT_UNKNOWN;
+
        /* Normal case.  Call the breakpoint's print_it method, or
           print_it_typical.  */
-       /* FIXME: how breakpoint can ever be NULL here?  */
-       if (b != NULL && b->ops != NULL && b->ops->print_it != NULL)
+       if (b->ops != NULL && b->ops->print_it != NULL)
          return b->ops->print_it (b);
        else
          return print_it_typical (bs);
@@ -3657,6 +3732,8 @@ watchpoint_check (void *p)
   gdb_assert (bs->breakpoint_at != NULL);
   b = bs->breakpoint_at;
 
+  gdb_assert (is_watchpoint (b));
+
   /* If this is a local watchpoint, we only want to check if the
      watchpoint frame is in scope if the current thread is the thread
      that was used to create the watchpoint.  */
@@ -3766,13 +3843,7 @@ watchpoint_check (void *p)
                   " deleted because the program has left the block in\n\
 which its expression is valid.\n");     
 
-      if (b->related_breakpoint)
-       {
-         b->related_breakpoint->disposition = disp_del_at_next_stop;
-         b->related_breakpoint->related_breakpoint = NULL;
-         b->related_breakpoint = NULL;
-       }
-      b->disposition = disp_del_at_next_stop;
+      watchpoint_del_at_next_stop (b);
 
       return WP_DELETED;
     }
@@ -3790,6 +3861,9 @@ bpstat_check_location (const struct bp_location *bl,
   /* BL is from existing struct breakpoint.  */
   gdb_assert (b != NULL);
 
+  if (b->ops && b->ops->breakpoint_hit)
+    return b->ops->breakpoint_hit (bl, aspace, bp_addr);
+
   /* By definition, the inferior does not report stops at
      tracepoints.  */
   if (is_tracepoint (b))
@@ -3818,7 +3892,7 @@ bpstat_check_location (const struct bp_location *bl,
   if (is_hardware_watchpoint (b)
       && b->watchpoint_triggered == watch_triggered_no)
     return 0;
-  
+
   if (b->type == bp_hardware_breakpoint)
     {
       if (bl->address != bp_addr)
@@ -3829,13 +3903,6 @@ bpstat_check_location (const struct bp_location *bl,
        return 0;
     }
 
-  if (b->type == bp_catchpoint)
-    {
-      gdb_assert (b->ops != NULL && b->ops->breakpoint_hit != NULL);
-      if (!b->ops->breakpoint_hit (b))
-        return 0;
-    }
-     
   return 1;
 }
 
@@ -3977,9 +4044,7 @@ bpstat_check_watchpoint (bpstat bs)
            case 0:
              /* Error from catch_errors.  */
              printf_filtered (_("Watchpoint %d deleted.\n"), b->number);
-             if (b->related_breakpoint)
-               b->related_breakpoint->disposition = disp_del_at_next_stop;
-             b->disposition = disp_del_at_next_stop;
+             watchpoint_del_at_next_stop (b);
              /* We've already printed what needs to be printed.  */
              bs->print_it = print_it_done;
              break;
@@ -4023,6 +4088,11 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
       int value_is_zero = 0;
       struct expression *cond;
 
+      /* Evaluate Python breakpoints that have a "stop"
+        method implemented.  */
+      if (b->py_bp_object)
+       bs->stop = gdbpy_should_stop (b->py_bp_object);
+
       if (is_watchpoint (b))
        cond = b->cond_exp;
       else
@@ -4185,15 +4255,14 @@ bpstat_stop_status (struct address_space *aspace,
             watchpoint as triggered so that we will handle the
             out-of-scope event.  We'll get to the watchpoint next
             iteration.  */
-         if (b->type == bp_watchpoint_scope)
+         if (b->type == bp_watchpoint_scope && b->related_breakpoint != b)
            b->related_breakpoint->watchpoint_triggered = watch_triggered_yes;
        }
     }
 
   for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
     {
-      if (breakpoint_address_match (loc->pspace->aspace, loc->address,
-                                   aspace, bp_addr))
+      if (breakpoint_location_address_match (loc, aspace, bp_addr))
        {
          bs = bpstat_alloc (loc, &bs_link);
          /* For hits of moribund locations, we should just proceed.  */
@@ -4307,7 +4376,7 @@ handle_jit_event (void)
 /* Decide what infrun needs to do with this bpstat.  */
 
 struct bpstat_what
-bpstat_what (bpstat bs)
+bpstat_what (bpstat bs_head)
 {
   struct bpstat_what retval;
   /* We need to defer calling `solib_add', as adding new symbols
@@ -4315,12 +4384,13 @@ bpstat_what (bpstat bs)
      and hence may clear unprocessed entries in the BS chain.  */
   int shlib_event = 0;
   int jit_event = 0;
+  bpstat bs;
 
   retval.main_action = BPSTAT_WHAT_KEEP_CHECKING;
   retval.call_dummy = STOP_NONE;
   retval.is_longjmp = 0;
 
-  for (; bs != NULL; bs = bs->next)
+  for (bs = bs_head; bs != NULL; bs = bs->next)
     {
       /* Extract this BS's action.  After processing each BS, we check
         if its action overrides all we've seem so far.  */
@@ -4450,6 +4520,16 @@ bpstat_what (bpstat bs)
             out already.  */
          internal_error (__FILE__, __LINE__,
                          _("bpstat_what: tracepoint encountered"));
+         break;
+       case bp_gnu_ifunc_resolver:
+         /* Step over it (and insert bp_gnu_ifunc_resolver_return).  */
+         this_action = BPSTAT_WHAT_SINGLE;
+         break;
+       case bp_gnu_ifunc_resolver_return:
+         /* The breakpoint will be removed, execution will restart from the
+            PC of the former breakpoint.  */
+         this_action = BPSTAT_WHAT_KEEP_CHECKING;
+         break;
        default:
          internal_error (__FILE__, __LINE__,
                          _("bpstat_what: unhandled bptype %d"), (int) bptype);
@@ -4458,6 +4538,9 @@ bpstat_what (bpstat bs)
       retval.main_action = max (retval.main_action, this_action);
     }
 
+  /* These operations may affect the bs->breakpoint_at state so they are
+     delayed after MAIN_ACTION is decided above.  */
+
   if (shlib_event)
     {
       if (debug_infrun)
@@ -4487,12 +4570,29 @@ bpstat_what (bpstat bs)
       handle_jit_event ();
     }
 
-  return retval;
-}
+  for (bs = bs_head; bs != NULL; bs = bs->next)
+    {
+      struct breakpoint *b = bs->breakpoint_at;
 
-/* Nonzero if we should step constantly (e.g. watchpoints on machines
-   without hardware support).  This isn't related to a specific bpstat,
-   just to things like whether watchpoints are set.  */
+      if (b == NULL)
+       continue;
+      switch (b->type)
+       {
+       case bp_gnu_ifunc_resolver:
+         gnu_ifunc_resolver_stop (b);
+         break;
+       case bp_gnu_ifunc_resolver_return:
+         gnu_ifunc_resolver_return_stop (b);
+         break;
+       }
+    }
+
+  return retval;
+}
+
+/* Nonzero if we should step constantly (e.g. watchpoints on machines
+   without hardware support).  This isn't related to a specific bpstat,
+   just to things like whether watchpoints are set.  */
 
 int
 bpstat_should_step (void)
@@ -4517,12 +4617,40 @@ bpstat_causes_stop (bpstat bs)
 
 \f
 
+/* Compute a string of spaces suitable to indent the next line
+   so it starts at the position corresponding to the table column
+   named COL_NAME in the currently active table of UIOUT.  */
+
+static char *
+wrap_indent_at_field (struct ui_out *uiout, const char *col_name)
+{
+  static char wrap_indent[80];
+  int i, total_width, width, align;
+  char *text;
+
+  total_width = 0;
+  for (i = 1; ui_out_query_field (uiout, i, &width, &align, &text); i++)
+    {
+      if (strcmp (text, col_name) == 0)
+       {
+         gdb_assert (total_width < sizeof wrap_indent);
+         memset (wrap_indent, ' ', total_width);
+         wrap_indent[total_width] = 0;
+
+         return wrap_indent;
+       }
+
+      total_width += width + 1;
+    }
+
+  return NULL;
+}
+
 /* Print the LOC location out of the list of B->LOC locations.  */
 
-static void print_breakpoint_location (struct breakpoint *b,
-                                      struct bp_location *loc,
-                                      char *wrap_indent,
-                                      struct ui_stream *stb)
+static void
+print_breakpoint_location (struct breakpoint *b,
+                          struct bp_location *loc)
 {
   struct cleanup *old_chain = save_current_program_space ();
 
@@ -4532,7 +4660,9 @@ static void print_breakpoint_location (struct breakpoint *b,
   if (loc != NULL)
     set_current_program_space (loc->pspace);
 
-  if (b->source_file && loc)
+  if (b->display_canonical)
+    ui_out_field_string (uiout, "what", b->addr_string);
+  else if (b->source_file && loc)
     {
       struct symbol *sym 
        = find_pc_sect_function (loc->address, loc->section);
@@ -4541,8 +4671,9 @@ static void print_breakpoint_location (struct breakpoint *b,
          ui_out_text (uiout, "in ");
          ui_out_field_string (uiout, "func",
                               SYMBOL_PRINT_NAME (sym));
-         ui_out_wrap_hint (uiout, wrap_indent);
-         ui_out_text (uiout, " at ");
+         ui_out_text (uiout, " ");
+         ui_out_wrap_hint (uiout, wrap_indent_at_field (uiout, "what"));
+         ui_out_text (uiout, "at ");
        }
       ui_out_field_string (uiout, "file", b->source_file);
       ui_out_text (uiout, ":");
@@ -4560,9 +4691,14 @@ static void print_breakpoint_location (struct breakpoint *b,
     }
   else if (loc)
     {
+      struct ui_stream *stb = ui_out_stream_new (uiout);
+      struct cleanup *stb_chain = make_cleanup_ui_out_stream_delete (stb);
+
       print_address_symbolic (loc->gdbarch, loc->address, stb->stream,
                              demangle, "");
       ui_out_field_stream (uiout, "at", stb);
+
+      do_cleanups (stb_chain);
     }
   else
     ui_out_field_string (uiout, "pending", b->addr_string);
@@ -4608,6 +4744,8 @@ bptype_string (enum bptype type)
     {bp_fast_tracepoint, "fast tracepoint"},
     {bp_static_tracepoint, "static tracepoint"},
     {bp_jit_event, "jit events"},
+    {bp_gnu_ifunc_resolver, "STT_GNU_IFUNC resolver"},
+    {bp_gnu_ifunc_resolver_return, "STT_GNU_IFUNC resolver return"},
   };
 
   if (((int) type >= (sizeof (bptypes) / sizeof (bptypes[0])))
@@ -4626,14 +4764,10 @@ print_one_breakpoint_location (struct breakpoint *b,
                               struct bp_location *loc,
                               int loc_number,
                               struct bp_location **last_loc,
-                              int print_address_bits,
                               int allflag)
 {
   struct command_line *l;
   static char bpenables[] = "nynny";
-  char wrap_indent[80];
-  struct ui_stream *stb = ui_out_stream_new (uiout);
-  struct cleanup *old_chain = make_cleanup_ui_out_stream_delete (stb);
   struct cleanup *bkpt_chain;
 
   int header_of_multiple = 0;
@@ -4695,15 +4829,6 @@ print_one_breakpoint_location (struct breakpoint *b,
 
   
   /* 5 and 6 */
-  strcpy (wrap_indent, "                           ");
-  if (opts.addressprint)
-    {
-      if (print_address_bits <= 32)
-       strcat (wrap_indent, "           ");
-      else
-       strcat (wrap_indent, "                   ");
-    }
-
   if (b->ops != NULL && b->ops->print_one != NULL)
     {
       /* Although the print_one can possibly print all locations,
@@ -4755,6 +4880,8 @@ print_one_breakpoint_location (struct breakpoint *b,
       case bp_fast_tracepoint:
       case bp_static_tracepoint:
       case bp_jit_event:
+      case bp_gnu_ifunc_resolver:
+      case bp_gnu_ifunc_resolver_return:
        if (opts.addressprint)
          {
            annotate_field (4);
@@ -4768,7 +4895,7 @@ print_one_breakpoint_location (struct breakpoint *b,
          }
        annotate_field (5);
        if (!header_of_multiple)
-         print_breakpoint_location (b, loc, wrap_indent, stb);
+         print_breakpoint_location (b, loc);
        if (b->loc)
          *last_loc = b->loc;
        break;
@@ -4821,9 +4948,12 @@ print_one_breakpoint_location (struct breakpoint *b,
          ui_out_field_int (uiout, "task", b->task);
        }
     }
-  
+
   ui_out_text (uiout, "\n");
-  
+
+  if (!part_of_multiple && b->ops && b->ops->print_one_detail)
+    b->ops->print_one_detail (b, uiout);
+
   if (!part_of_multiple && b->static_trace_marker_id)
     {
       gdb_assert (b->type == bp_static_tracepoint);
@@ -4924,17 +5054,14 @@ print_one_breakpoint_location (struct breakpoint *b,
     }
        
   do_cleanups (bkpt_chain);
-  do_cleanups (old_chain);
 }
 
 static void
 print_one_breakpoint (struct breakpoint *b,
                      struct bp_location **last_loc, 
-                     int print_address_bits,
                      int allflag)
 {
-  print_one_breakpoint_location (b, NULL, 0, last_loc,
-                                print_address_bits, allflag);
+  print_one_breakpoint_location (b, NULL, 0, last_loc, allflag);
 
   /* If this breakpoint has custom print function,
      it's already printed.  Otherwise, print individual
@@ -4947,7 +5074,7 @@ print_one_breakpoint (struct breakpoint *b,
         situation.
 
         Note that while hardware watchpoints have several locations
-        internally, that's no a property exposed to user.  */
+        internally, that's not a property exposed to user.  */
       if (b->loc 
          && !is_hardware_watchpoint (b)
          && (b->loc->next || !b->loc->enabled)
@@ -4956,8 +5083,7 @@ print_one_breakpoint (struct breakpoint *b,
          struct bp_location *loc;
          int n = 1;
          for (loc = b->loc; loc; loc = loc->next, ++n)
-           print_one_breakpoint_location (b, loc, n, last_loc,
-                                          print_address_bits, allflag);
+           print_one_breakpoint_location (b, loc, n, last_loc, allflag);
        }
     }
 }
@@ -5001,9 +5127,7 @@ do_captured_breakpoint_query (struct ui_out *uiout, void *data)
     {
       if (args->bnum == b->number)
        {
-         int print_address_bits = breakpoint_address_bits (b);
-
-         print_one_breakpoint (b, &dummy_loc, print_address_bits, 0);
+         print_one_breakpoint (b, &dummy_loc, 0);
          return GDB_RC_OK;
        }
     }
@@ -5036,7 +5160,17 @@ user_settable_breakpoint (const struct breakpoint *b)
          || b->type == bp_catchpoint
          || b->type == bp_hardware_breakpoint
          || is_tracepoint (b)
-         || is_watchpoint (b));
+         || is_watchpoint (b)
+         || b->type == bp_gnu_ifunc_resolver);
+}
+
+/* Return true if this breakpoint was set by the user, false if it is
+   internal or momentary.  */
+
+int
+user_breakpoint_p (struct breakpoint *b)
+{
+  return user_settable_breakpoint (b) && b->number > 0;
 }
 
 /* Print information on user settable breakpoint (watchpoint, etc)
@@ -5047,7 +5181,7 @@ user_settable_breakpoint (const struct breakpoint *b)
    breakpoints listed.  */
 
 static int
-breakpoint_1 (int bnum, int allflag, 
+breakpoint_1 (char *args, int allflag, 
              int (*filter) (const struct breakpoint *))
 {
   struct breakpoint *b;
@@ -5064,29 +5198,36 @@ breakpoint_1 (int bnum, int allflag,
      required for address fields.  */
   nr_printable_breakpoints = 0;
   ALL_BREAKPOINTS (b)
-    if (bnum == -1
-       || bnum == b->number)
-      {
-       /* If we have a filter, only list the breakpoints it accepts.  */
-       if (filter && !filter (b))
-         continue;
-       
-       if (allflag || (user_settable_breakpoint (b)
-                       && b->number > 0))
-         {
-           int addr_bit, type_len;
+    {
+      /* If we have a filter, only list the breakpoints it accepts.  */
+      if (filter && !filter (b))
+       continue;
 
-           addr_bit = breakpoint_address_bits (b);
-           if (addr_bit > print_address_bits)
-             print_address_bits = addr_bit;
+      /* If we have an "args" string, it is a list of breakpoints to 
+        accept.  Skip the others.  */
+      if (args != NULL && *args != '\0')
+       {
+         if (allflag && parse_and_eval_long (args) != b->number)
+           continue;
+         if (!allflag && !number_is_in_list (args, b->number))
+           continue;
+       }
 
-           type_len = strlen (bptype_string (b->type));
-           if (type_len > print_type_col_width)
-             print_type_col_width = type_len;
+      if (allflag || user_breakpoint_p (b))
+       {
+         int addr_bit, type_len;
 
-           nr_printable_breakpoints++;
-         }
-      }
+         addr_bit = breakpoint_address_bits (b);
+         if (addr_bit > print_address_bits)
+           print_address_bits = addr_bit;
+
+         type_len = strlen (bptype_string (b->type));
+         if (type_len > print_type_col_width)
+           print_type_col_width = type_len;
+
+         nr_printable_breakpoints++;
+       }
+    }
 
   if (opts.addressprint)
     bkpttbl_chain 
@@ -5115,16 +5256,16 @@ breakpoint_1 (int bnum, int allflag,
     annotate_field (3);
   ui_out_table_header (uiout, 3, ui_left, "enabled", "Enb");   /* 4 */
   if (opts.addressprint)
-       {
-         if (nr_printable_breakpoints > 0)
-           annotate_field (4);
-         if (print_address_bits <= 32)
-           ui_out_table_header (uiout, 10, ui_left, 
-                                "addr", "Address");            /* 5 */
-         else
-           ui_out_table_header (uiout, 18, ui_left, 
-                                "addr", "Address");            /* 5 */
-       }
+    {
+      if (nr_printable_breakpoints > 0)
+       annotate_field (4);
+      if (print_address_bits <= 32)
+       ui_out_table_header (uiout, 10, ui_left, 
+                            "addr", "Address");                /* 5 */
+      else
+       ui_out_table_header (uiout, 18, ui_left, 
+                            "addr", "Address");                /* 5 */
+    }
   if (nr_printable_breakpoints > 0)
     annotate_field (5);
   ui_out_table_header (uiout, 40, ui_noalign, "what", "What"); /* 6 */
@@ -5133,23 +5274,34 @@ breakpoint_1 (int bnum, int allflag,
     annotate_breakpoints_table ();
 
   ALL_BREAKPOINTS (b)
-  {
-    QUIT;
-    if (bnum == -1
-       || bnum == b->number)
-      {
-       /* If we have a filter, only list the breakpoints it accepts.  */
-       if (filter && !filter (b))
-         continue;
-       
-       /* We only print out user settable breakpoints unless the
-          allflag is set.  */
-       if (allflag || (user_settable_breakpoint (b)
-                       && b->number > 0))
-         print_one_breakpoint (b, &last_loc, print_address_bits, allflag);
-      }
-  }
-  
+    {
+      QUIT;
+      /* If we have a filter, only list the breakpoints it accepts.  */
+      if (filter && !filter (b))
+       continue;
+
+      /* If we have an "args" string, it is a list of breakpoints to 
+        accept.  Skip the others.  */
+
+      if (args != NULL && *args != '\0')
+       {
+         if (allflag)  /* maintenance info breakpoint */
+           {
+             if (parse_and_eval_long (args) != b->number)
+               continue;
+           }
+         else          /* all others */
+           {
+             if (!number_is_in_list (args, b->number))
+               continue;
+           }
+       }
+      /* We only print out user settable breakpoints unless the
+        allflag is set.  */
+      if (allflag || user_breakpoint_p (b))
+       print_one_breakpoint (b, &last_loc, allflag);
+    }
+
   do_cleanups (bkpttbl_chain);
 
   if (nr_printable_breakpoints == 0)
@@ -5158,12 +5310,12 @@ breakpoint_1 (int bnum, int allflag,
         empty list.  */
       if (!filter)
        {
-         if (bnum == -1)
+         if (args == NULL || *args == '\0')
            ui_out_message (uiout, 0, "No breakpoints or watchpoints.\n");
          else
            ui_out_message (uiout, 0, 
-                           "No breakpoint or watchpoint number %d.\n",
-                           bnum);
+                           "No breakpoint or watchpoint matching '%s'.\n",
+                           args);
        }
     }
   else
@@ -5199,46 +5351,31 @@ default_collect_info (void)
 }
   
 static void
-breakpoints_info (char *bnum_exp, int from_tty)
+breakpoints_info (char *args, int from_tty)
 {
-  int bnum = -1;
-
-  if (bnum_exp)
-    bnum = parse_and_eval_long (bnum_exp);
-
-  breakpoint_1 (bnum, 0, NULL);
+  breakpoint_1 (args, 0, NULL);
 
   default_collect_info ();
 }
 
 static void
-watchpoints_info (char *wpnum_exp, int from_tty)
+watchpoints_info (char *args, int from_tty)
 {
-  int wpnum = -1, num_printed;
-
-  if (wpnum_exp)
-    wpnum = parse_and_eval_long (wpnum_exp);
-
-  num_printed = breakpoint_1 (wpnum, 0, is_watchpoint);
+  int num_printed = breakpoint_1 (args, 0, is_watchpoint);
 
   if (num_printed == 0)
     {
-      if (wpnum == -1)
+      if (args == NULL || *args == '\0')
        ui_out_message (uiout, 0, "No watchpoints.\n");
       else
-       ui_out_message (uiout, 0, "No watchpoint number %d.\n", wpnum);
+       ui_out_message (uiout, 0, "No watchpoint matching '%s'.\n", args);
     }
 }
 
 static void
-maintenance_info_breakpoints (char *bnum_exp, int from_tty)
+maintenance_info_breakpoints (char *args, int from_tty)
 {
-  int bnum = -1;
-
-  if (bnum_exp)
-    bnum = parse_and_eval_long (bnum_exp);
-
-  breakpoint_1 (bnum, 1, NULL);
+  breakpoint_1 (args, 1, NULL);
 
   default_collect_info ();
 }
@@ -5399,6 +5536,39 @@ breakpoint_address_match (struct address_space *aspace1, CORE_ADDR addr1,
          && addr1 == addr2);
 }
 
+/* Returns true if {ASPACE2,ADDR2} falls within the range determined by
+   {ASPACE1,ADDR1,LEN1}.  In most targets, this can only be true if ASPACE1
+   matches ASPACE2.  On targets that have global breakpoints, the address
+   space doesn't really matter.  */
+
+static int
+breakpoint_address_match_range (struct address_space *aspace1, CORE_ADDR addr1,
+                               int len1, struct address_space *aspace2,
+                               CORE_ADDR addr2)
+{
+  return ((gdbarch_has_global_breakpoints (target_gdbarch)
+          || aspace1 == aspace2)
+         && addr2 >= addr1 && addr2 < addr1 + len1);
+}
+
+/* Returns true if {ASPACE,ADDR} matches the breakpoint BL.  BL may be
+   a ranged breakpoint.  In most targets, a match happens only if ASPACE
+   matches the breakpoint's address space.  On targets that have global
+   breakpoints, the address space doesn't really matter.  */
+
+static int
+breakpoint_location_address_match (struct bp_location *bl,
+                                  struct address_space *aspace,
+                                  CORE_ADDR addr)
+{
+  return (breakpoint_address_match (bl->pspace->aspace, bl->address,
+                                   aspace, addr)
+         || (bl->length
+             && breakpoint_address_match_range (bl->pspace->aspace,
+                                                bl->address, bl->length,
+                                                aspace, addr)));
+}
+
 /* Assuming LOC1 and LOC2's types' have meaningful target addresses
    (breakpoint_address_is_meaningful), returns true if LOC1 and LOC2
    represent the same location.  */
@@ -5421,16 +5591,20 @@ breakpoint_locations_match (struct bp_location *loc1,
   else if (hw_point1)
     return watchpoint_locations_match (loc1, loc2);
   else
-    return breakpoint_address_match (loc1->pspace->aspace, loc1->address,
-                                    loc2->pspace->aspace, loc2->address);
+    /* We compare bp_location.length in order to cover ranged breakpoints.  */
+    return (breakpoint_address_match (loc1->pspace->aspace, loc1->address,
+                                    loc2->pspace->aspace, loc2->address)
+           && loc1->length == loc2->length);
 }
 
 static void
 breakpoint_adjustment_warning (CORE_ADDR from_addr, CORE_ADDR to_addr,
                                int bnum, int have_bnum)
 {
-  char astr1[40];
-  char astr2[40];
+  /* The longest string possibly returned by hex_string_custom
+     is 50 chars.  These must be at least that big for safety.  */
+  char astr1[64];
+  char astr2[64];
 
   strcpy (astr1, hex_string_custom ((unsigned long) from_addr, 8));
   strcpy (astr2, hex_string_custom ((unsigned long) to_addr, 8));
@@ -5518,6 +5692,8 @@ allocate_bp_location (struct breakpoint *bpt)
     case bp_longjmp_master:
     case bp_std_terminate_master:
     case bp_exception_master:
+    case bp_gnu_ifunc_resolver:
+    case bp_gnu_ifunc_resolver_return:
       loc->loc_type = bp_loc_software_breakpoint;
       break;
     case bp_hardware_breakpoint:
@@ -5607,6 +5783,7 @@ set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
   b->ops = NULL;
   b->condition_not_parsed = 0;
   b->py_bp_object = NULL;
+  b->related_breakpoint = b;
 
   /* Add this breakpoint to the end of the chain so that a list of
      breakpoints will come out in order of increasing numbers.  */
@@ -5623,9 +5800,12 @@ set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
   return b;
 }
 
-/* Initialize loc->function_name.  */
+/* Initialize loc->function_name.  EXPLICIT_LOC says no indirect function
+   resolutions should be made as the user specified the location explicitly
+   enough.  */
+
 static void
-set_breakpoint_location_function (struct bp_location *loc)
+set_breakpoint_location_function (struct bp_location *loc, int explicit_loc)
 {
   gdb_assert (loc->owner != NULL);
 
@@ -5633,8 +5813,33 @@ set_breakpoint_location_function (struct bp_location *loc)
       || loc->owner->type == bp_hardware_breakpoint
       || is_tracepoint (loc->owner))
     {
-      find_pc_partial_function (loc->address, &(loc->function_name), 
-                               NULL, NULL);
+      int is_gnu_ifunc;
+
+      find_pc_partial_function_gnu_ifunc (loc->address, &loc->function_name,
+                                         NULL, NULL, &is_gnu_ifunc);
+
+      if (is_gnu_ifunc && !explicit_loc)
+       {
+         struct breakpoint *b = loc->owner;
+
+         gdb_assert (loc->pspace == current_program_space);
+         if (gnu_ifunc_resolve_name (loc->function_name,
+                                     &loc->requested_address))
+           {
+             /* Recalculate ADDRESS based on new REQUESTED_ADDRESS.  */
+             loc->address = adjust_breakpoint_address (loc->gdbarch,
+                                                       loc->requested_address,
+                                                       b->type);
+           }
+         else if (b->type == bp_breakpoint && b->loc == loc
+                  && loc->next == NULL && b->related_breakpoint == b)
+           {
+             /* Create only the whole new breakpoint of this type but do not
+                mess more complicated breakpoints with multiple locations.  */
+             b->type = bp_gnu_ifunc_resolver;
+           }
+       }
+
       if (loc->function_name)
        loc->function_name = xstrdup (loc->function_name);
     }
@@ -5709,7 +5914,8 @@ set_raw_breakpoint (struct gdbarch *gdbarch,
   b->loc->section = sal.section;
   b->line_number = sal.line;
 
-  set_breakpoint_location_function (b->loc);
+  set_breakpoint_location_function (b->loc,
+                                   sal.explicit_pc || sal.explicit_line);
 
   breakpoints_changed ();
 
@@ -5860,14 +6066,6 @@ remove_thread_event_breakpoints (void)
       delete_breakpoint (b);
 }
 
-struct captured_parse_breakpoint_args
-  {
-    char **arg_p;
-    struct symtabs_and_lines *sals_p;
-    char ***addr_string_p;
-    int *not_found_ptr;
-  };
-
 struct lang_and_radix
   {
     enum language lang;
@@ -5886,6 +6084,19 @@ create_jit_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
   return b;
 }
 
+/* Remove JIT code registration and unregistration breakpoint(s).  */
+
+void
+remove_jit_event_breakpoints (void)
+{
+  struct breakpoint *b, *b_tmp;
+
+  ALL_BREAKPOINTS_SAFE (b, b_tmp)
+    if (b->type == bp_jit_event
+       && b->loc->pspace == current_program_space)
+      delete_breakpoint (b);
+}
+
 void
 remove_solib_event_breakpoints (void)
 {
@@ -5943,7 +6154,7 @@ disable_breakpoints_in_shlibs (void)
   }
 }
 
-/* Disable any breakpoints that are in in an unloaded shared library.
+/* Disable any breakpoints that are in an unloaded shared library.
    Only apply to enabled breakpoints, disabled ones can just stay
    disabled.  */
 
@@ -5997,17 +6208,17 @@ disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
 /* Implement the "insert" breakpoint_ops method for fork
    catchpoints.  */
 
-static void
-insert_catch_fork (struct breakpoint *b)
+static int
+insert_catch_fork (struct bp_location *bl)
 {
-  target_insert_fork_catchpoint (PIDGET (inferior_ptid));
+  return target_insert_fork_catchpoint (PIDGET (inferior_ptid));
 }
 
 /* Implement the "remove" breakpoint_ops method for fork
    catchpoints.  */
 
 static int
-remove_catch_fork (struct breakpoint *b)
+remove_catch_fork (struct bp_location *bl)
 {
   return target_remove_fork_catchpoint (PIDGET (inferior_ptid));
 }
@@ -6016,9 +6227,10 @@ remove_catch_fork (struct breakpoint *b)
    catchpoints.  */
 
 static int
-breakpoint_hit_catch_fork (struct breakpoint *b)
+breakpoint_hit_catch_fork (const struct bp_location *bl,
+                          struct address_space *aspace, CORE_ADDR bp_addr)
 {
-  return inferior_has_forked (inferior_ptid, &b->forked_inferior_pid);
+  return inferior_has_forked (inferior_ptid, &bl->owner->forked_inferior_pid);
 }
 
 /* Implement the "print_it" breakpoint_ops method for fork
@@ -6084,8 +6296,10 @@ static struct breakpoint_ops catch_fork_breakpoint_ops =
   insert_catch_fork,
   remove_catch_fork,
   breakpoint_hit_catch_fork,
+  NULL, /* resources_needed */
   print_it_catch_fork,
   print_one_catch_fork,
+  NULL, /* print_one_detail */
   print_mention_catch_fork,
   print_recreate_catch_fork
 };
@@ -6093,17 +6307,17 @@ static struct breakpoint_ops catch_fork_breakpoint_ops =
 /* Implement the "insert" breakpoint_ops method for vfork
    catchpoints.  */
 
-static void
-insert_catch_vfork (struct breakpoint *b)
+static int
+insert_catch_vfork (struct bp_location *bl)
 {
-  target_insert_vfork_catchpoint (PIDGET (inferior_ptid));
+  return target_insert_vfork_catchpoint (PIDGET (inferior_ptid));
 }
 
 /* Implement the "remove" breakpoint_ops method for vfork
    catchpoints.  */
 
 static int
-remove_catch_vfork (struct breakpoint *b)
+remove_catch_vfork (struct bp_location *bl)
 {
   return target_remove_vfork_catchpoint (PIDGET (inferior_ptid));
 }
@@ -6112,9 +6326,10 @@ remove_catch_vfork (struct breakpoint *b)
    catchpoints.  */
 
 static int
-breakpoint_hit_catch_vfork (struct breakpoint *b)
+breakpoint_hit_catch_vfork (const struct bp_location *bl,
+                           struct address_space *aspace, CORE_ADDR bp_addr)
 {
-  return inferior_has_vforked (inferior_ptid, &b->forked_inferior_pid);
+  return inferior_has_vforked (inferior_ptid, &bl->owner->forked_inferior_pid);
 }
 
 /* Implement the "print_it" breakpoint_ops method for vfork
@@ -6179,8 +6394,10 @@ static struct breakpoint_ops catch_vfork_breakpoint_ops =
   insert_catch_vfork,
   remove_catch_vfork,
   breakpoint_hit_catch_vfork,
+  NULL, /* resources_needed */
   print_it_catch_vfork,
   print_one_catch_vfork,
+  NULL, /* print_one_detail */
   print_mention_catch_vfork,
   print_recreate_catch_vfork
 };
@@ -6188,20 +6405,20 @@ static struct breakpoint_ops catch_vfork_breakpoint_ops =
 /* Implement the "insert" breakpoint_ops method for syscall
    catchpoints.  */
 
-static void
-insert_catch_syscall (struct breakpoint *b)
+static int
+insert_catch_syscall (struct bp_location *bl)
 {
   struct inferior *inf = current_inferior ();
 
   ++inf->total_syscalls_count;
-  if (!b->syscalls_to_be_caught)
+  if (!bl->owner->syscalls_to_be_caught)
     ++inf->any_syscall_count;
   else
     {
       int i, iter;
 
       for (i = 0;
-           VEC_iterate (int, b->syscalls_to_be_caught, i, iter);
+           VEC_iterate (int, bl->owner->syscalls_to_be_caught, i, iter);
            i++)
        {
           int elem;
@@ -6223,30 +6440,30 @@ insert_catch_syscall (struct breakpoint *b)
        }
     }
 
-  target_set_syscall_catchpoint (PIDGET (inferior_ptid),
-                                inf->total_syscalls_count != 0,
-                                inf->any_syscall_count,
-                                VEC_length (int, inf->syscalls_counts),
-                                VEC_address (int, inf->syscalls_counts));
+  return target_set_syscall_catchpoint (PIDGET (inferior_ptid),
+                                       inf->total_syscalls_count != 0,
+                                       inf->any_syscall_count,
+                                       VEC_length (int, inf->syscalls_counts),
+                                       VEC_address (int, inf->syscalls_counts));
 }
 
 /* Implement the "remove" breakpoint_ops method for syscall
    catchpoints.  */
 
 static int
-remove_catch_syscall (struct breakpoint *b)
+remove_catch_syscall (struct bp_location *bl)
 {
   struct inferior *inf = current_inferior ();
 
   --inf->total_syscalls_count;
-  if (!b->syscalls_to_be_caught)
+  if (!bl->owner->syscalls_to_be_caught)
     --inf->any_syscall_count;
   else
     {
       int i, iter;
 
       for (i = 0;
-           VEC_iterate (int, b->syscalls_to_be_caught, i, iter);
+           VEC_iterate (int, bl->owner->syscalls_to_be_caught, i, iter);
            i++)
        {
           int elem;
@@ -6270,12 +6487,14 @@ remove_catch_syscall (struct breakpoint *b)
    catchpoints.  */
 
 static int
-breakpoint_hit_catch_syscall (struct breakpoint *b)
+breakpoint_hit_catch_syscall (const struct bp_location *bl,
+                             struct address_space *aspace, CORE_ADDR bp_addr)
 {
   /* We must check if we are catching specific syscalls in this
      breakpoint.  If we are, then we must guarantee that the called
      syscall is the same syscall we are catching.  */
   int syscall_number = 0;
+  const struct breakpoint *b = bl->owner;
 
   if (!inferior_has_called_syscall (inferior_ptid, &syscall_number))
     return 0;
@@ -6344,7 +6563,7 @@ print_it_catch_syscall (struct breakpoint *b)
 
 static void
 print_one_catch_syscall (struct breakpoint *b,
-                         struct bp_location **last_loc)
+                        struct bp_location **last_loc)
 {
   struct value_print_options opts;
 
@@ -6462,8 +6681,10 @@ static struct breakpoint_ops catch_syscall_breakpoint_ops =
   insert_catch_syscall,
   remove_catch_syscall,
   breakpoint_hit_catch_syscall,
+  NULL, /* resources_needed */
   print_it_catch_syscall,
   print_one_catch_syscall,
+  NULL, /* print_one_detail */
   print_mention_catch_syscall,
   print_recreate_catch_syscall
 };
@@ -6546,22 +6767,23 @@ create_fork_vfork_event_catchpoint (struct gdbarch *gdbarch,
 
 /* Exec catchpoints.  */
 
-static void
-insert_catch_exec (struct breakpoint *b)
+static int
+insert_catch_exec (struct bp_location *bl)
 {
-  target_insert_exec_catchpoint (PIDGET (inferior_ptid));
+  return target_insert_exec_catchpoint (PIDGET (inferior_ptid));
 }
 
 static int
-remove_catch_exec (struct breakpoint *b)
+remove_catch_exec (struct bp_location *bl)
 {
   return target_remove_exec_catchpoint (PIDGET (inferior_ptid));
 }
 
 static int
-breakpoint_hit_catch_exec (struct breakpoint *b)
+breakpoint_hit_catch_exec (const struct bp_location *bl,
+                          struct address_space *aspace, CORE_ADDR bp_addr)
 {
-  return inferior_has_execd (inferior_ptid, &b->exec_pathname);
+  return inferior_has_execd (inferior_ptid, &bl->owner->exec_pathname);
 }
 
 static enum print_stop_action
@@ -6615,8 +6837,10 @@ static struct breakpoint_ops catch_exec_breakpoint_ops =
   insert_catch_exec,
   remove_catch_exec,
   breakpoint_hit_catch_exec,
+  NULL, /* resources_needed */
   print_it_catch_exec,
   print_one_catch_exec,
+  NULL, /* print_one_detail */
   print_mention_catch_exec,
   print_recreate_catch_exec
 };
@@ -6640,13 +6864,22 @@ create_syscall_event_catchpoint (int tempflag, VEC(int) *filter,
 static int
 hw_breakpoint_used_count (void)
 {
-  struct breakpoint *b;
   int i = 0;
+  struct breakpoint *b;
+  struct bp_location *bl;
 
   ALL_BREAKPOINTS (b)
   {
     if (b->type == bp_hardware_breakpoint && breakpoint_enabled (b))
-      i++;
+      for (bl = b->loc; bl; bl = bl->next)
+       {
+         /* Special types of hardware breakpoints may use more than
+            one register.  */
+         if (b->ops && b->ops->resources_needed)
+           i += b->ops->resources_needed (bl);
+         else
+           i++;
+       }
   }
 
   return i;
@@ -6655,20 +6888,30 @@ hw_breakpoint_used_count (void)
 static int
 hw_watchpoint_used_count (enum bptype type, int *other_type_used)
 {
-  struct breakpoint *b;
   int i = 0;
+  struct breakpoint *b;
+  struct bp_location *bl;
 
   *other_type_used = 0;
   ALL_BREAKPOINTS (b)
-  {
-    if (breakpoint_enabled (b))
-      {
+    {
+      if (!breakpoint_enabled (b))
+       continue;
+
        if (b->type == type)
-         i++;
+         for (bl = b->loc; bl; bl = bl->next)
+           {
+             /* Special types of hardware watchpoints may use more than
+                one register.  */
+             if (b->ops && b->ops->resources_needed)
+               i += b->ops->resources_needed (bl);
+             else
+               i++;
+           }
        else if (is_hardware_watchpoint (b))
          *other_type_used = 1;
-      }
-  }
+    }
+
   return i;
 }
 
@@ -6799,7 +7042,7 @@ clone_momentary_breakpoint (struct breakpoint *orig)
 
   copy = set_raw_breakpoint_without_location (orig->gdbarch, orig->type);
   copy->loc = allocate_bp_location (copy);
-  set_breakpoint_location_function (copy->loc);
+  set_breakpoint_location_function (copy->loc, 1);
 
   copy->loc->gdbarch = orig->loc->gdbarch;
   copy->loc->requested_address = orig->loc->requested_address;
@@ -6899,6 +7142,7 @@ mention (struct breakpoint *b)
        do_cleanups (ui_out_chain);
        break;
       case bp_breakpoint:
+      case bp_gnu_ifunc_resolver:
        if (ui_out_is_mi_like_p (uiout))
          {
            say_where = 0;
@@ -6909,6 +7153,8 @@ mention (struct breakpoint *b)
        else
          printf_filtered (_("Breakpoint"));
        printf_filtered (_(" %d"), b->number);
+       if (b->type == bp_gnu_ifunc_resolver)
+         printf_filtered (_(" at gnu-indirect-function resolver"));
        say_where = 1;
        break;
       case bp_hardware_breakpoint:
@@ -6968,6 +7214,7 @@ mention (struct breakpoint *b)
       case bp_longjmp_master:
       case bp_std_terminate_master:
       case bp_exception_master:
+      case bp_gnu_ifunc_resolver_return:
        break;
       }
 
@@ -7028,7 +7275,8 @@ add_location_to_breakpoint (struct breakpoint *b,
   gdb_assert (loc->pspace != NULL);
   loc->section = sal->section;
 
-  set_breakpoint_location_function (loc);
+  set_breakpoint_location_function (loc,
+                                   sal->explicit_pc || sal->explicit_line);
   return loc;
 }
 \f
@@ -7087,7 +7335,7 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
                       enum bptype type, enum bpdisp disposition,
                       int thread, int task, int ignore_count,
                       struct breakpoint_ops *ops, int from_tty,
-                      int enabled, int internal)
+                      int enabled, int internal, int display_canonical)
 {
   struct breakpoint *b = NULL;
   int i;
@@ -7147,12 +7395,9 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
                  char *marker_str;
                  int i;
 
-                 while (*p == ' ' || *p == '\t')
-                   p++;
+                 p = skip_spaces (p);
 
-                 endp = p;
-                 while (*endp != ' ' && *endp != '\t' && *endp != '\0')
-                   endp++;
+                 endp = skip_to_space (p);
 
                  marker_str = savestring (p, endp - p);
                  b->static_trace_marker_id = marker_str;
@@ -7199,6 +7444,7 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
        }
     }   
 
+  b->display_canonical = display_canonical;
   if (addr_string)
     b->addr_string = addr_string;
   else
@@ -7365,7 +7611,8 @@ expand_line_sal_maybe (struct symtab_and_line sal)
 
 static void
 create_breakpoints_sal (struct gdbarch *gdbarch,
-                       struct symtabs_and_lines sals, char **addr_string,
+                       struct symtabs_and_lines sals,
+                       struct linespec_result *canonical,
                        char *cond_string,
                        enum bptype type, enum bpdisp disposition,
                        int thread, int task, int ignore_count,
@@ -7379,27 +7626,29 @@ create_breakpoints_sal (struct gdbarch *gdbarch,
       struct symtabs_and_lines expanded = 
        expand_line_sal_maybe (sals.sals[i]);
 
-      create_breakpoint_sal (gdbarch, expanded, addr_string[i],
+      create_breakpoint_sal (gdbarch, expanded, canonical->canonical[i],
                             cond_string, type, disposition,
                             thread, task, ignore_count, ops,
-                            from_tty, enabled, internal);
+                            from_tty, enabled, internal,
+                            canonical->special_display);
     }
 }
 
-/* Parse ARG which is assumed to be a SAL specification possibly
+/* Parse ADDRESS 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.  */
+   address strings.  ADDRESS points to the end of the SAL.
+
+   The array and the line spec strings are allocated on the heap, it is
+   the caller's responsibility to free them.  */
 
 static void
 parse_breakpoint_sals (char **address,
                       struct symtabs_and_lines *sals,
-                      char ***addr_string,
-                      int *not_found_ptr)
+                      struct linespec_result *canonical)
 {
   char *addr_start = *address;
 
-  *addr_string = NULL;
   /* If no arg given, or if first arg is 'if ', use the default
      breakpoint.  */
   if ((*address) == NULL
@@ -7448,15 +7697,14 @@ parse_breakpoint_sals (char **address,
              || ((strchr ("+-", (*address)[0]) != NULL)
                  && ((*address)[1] != '['))))
        *sals = decode_line_1 (address, 1, default_breakpoint_symtab,
-                              default_breakpoint_line, addr_string, 
-                              not_found_ptr);
+                              default_breakpoint_line, canonical);
       else
        *sals = decode_line_1 (address, 1, (struct symtab *) NULL, 0,
-                              addr_string, not_found_ptr);
+                              canonical);
     }
   /* 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 (sals->nelts > 0 && canonical->canonical == NULL)
+    canonical->canonical = xcalloc (sals->nelts, sizeof (char **));
   if (addr_start != (*address))
     {
       int i;
@@ -7464,9 +7712,9 @@ parse_breakpoint_sals (char **address,
       for (i = 0; i < sals->nelts; i++)
        {
          /* Add the string if not present.  */
-         if ((*addr_string)[i] == NULL)
-           (*addr_string)[i] = savestring (addr_start, 
-                                           (*address) - addr_start);
+         if (canonical->canonical[i] == NULL)
+           canonical->canonical[i] = savestring (addr_start, 
+                                                 (*address) - addr_start);
        }
     }
 }
@@ -7516,15 +7764,6 @@ check_fast_tracepoint_sals (struct gdbarch *gdbarch,
     }
 }
 
-static void
-do_captured_parse_breakpoint (struct ui_out *ui, void *data)
-{
-  struct captured_parse_breakpoint_args *args = data;
-  
-  parse_breakpoint_sals (args->arg_p, args->sals_p, args->addr_string_p, 
-                        args->not_found_ptr);
-}
-
 /* Given TOK, a string specification of condition and thread, as
    accepted by the 'break' command, extract the condition
    string and thread number and set *COND_STRING and *THREAD.
@@ -7544,13 +7783,9 @@ find_condition_and_thread (char *tok, CORE_ADDR pc,
       char *cond_start = NULL;
       char *cond_end = NULL;
 
-      while (*tok == ' ' || *tok == '\t')
-       tok++;
+      tok = skip_spaces (tok);
       
-      end_tok = tok;
-      
-      while (*end_tok != ' ' && *end_tok != '\t' && *end_tok != '\000')
-       end_tok++;
+      end_tok = skip_to_space (tok);
       
       toklen = end_tok - tok;
       
@@ -7609,12 +7844,9 @@ decode_static_tracepoint_spec (char **arg_p)
   char *marker_str;
   int i;
 
-  while (*p == ' ' || *p == '\t')
-    p++;
+  p = skip_spaces (p);
 
-  endp = p;
-  while (*endp != ' ' && *endp != '\t' && *endp != '\0')
-    endp++;
+  endp = skip_to_space (p);
 
   marker_str = savestring (p, endp - p);
   old_chain = make_cleanup (xfree, marker_str);
@@ -7667,29 +7899,22 @@ create_breakpoint (struct gdbarch *gdbarch,
                   struct breakpoint_ops *ops,
                   int from_tty, int enabled, int internal)
 {
-  struct gdb_exception e;
+  volatile struct gdb_exception e;
   struct symtabs_and_lines sals;
   struct symtab_and_line pending_sal;
   char *copy_arg;
   char *addr_start = arg;
-  char **addr_string;
+  struct linespec_result canonical;
   struct cleanup *old_chain;
   struct cleanup *bkpt_chain = NULL;
-  struct captured_parse_breakpoint_args parse_args;
   int i;
   int pending = 0;
-  int not_found = 0;
   int task = 0;
   int prev_bkpt_count = breakpoint_count;
 
   sals.sals = NULL;
   sals.nelts = 0;
-  addr_string = NULL;
-
-  parse_args.arg_p = &arg;
-  parse_args.sals_p = &sals;
-  parse_args.addr_string_p = &addr_string;
-  parse_args.not_found_ptr = &not_found;
+  init_linespec_result (&canonical);
 
   if (type_wanted == bp_static_tracepoint && is_marker_spec (arg))
     {
@@ -7698,14 +7923,16 @@ create_breakpoint (struct gdbarch *gdbarch,
       sals = decode_static_tracepoint_spec (&arg);
 
       copy_arg = savestring (addr_start, arg - addr_start);
-      addr_string = xcalloc (sals.nelts, sizeof (char **));
+      canonical.canonical = xcalloc (sals.nelts, sizeof (char **));
       for (i = 0; i < sals.nelts; i++)
-       addr_string[i] = xstrdup (copy_arg);
+       canonical.canonical[i] = xstrdup (copy_arg);
       goto done;
     }
 
-  e = catch_exception (uiout, do_captured_parse_breakpoint, 
-                      &parse_args, RETURN_MASK_ALL);
+  TRY_CATCH (e, RETURN_MASK_ALL)
+    {
+      parse_breakpoint_sals (&arg, &sals, &canonical);
+    }
 
   /* If caller is interested in rc value from parse, set value.  */
   switch (e.reason)
@@ -7737,7 +7964,7 @@ create_breakpoint (struct gdbarch *gdbarch,
             breakpoint behavior is on and thus a pending breakpoint
             is defaulted on behalf of the user.  */
          copy_arg = xstrdup (addr_start);
-         addr_string = &copy_arg;
+         canonical.canonical = &copy_arg;
          sals.nelts = 1;
          sals.sals = &pending_sal;
          pending_sal.pc = 0;
@@ -7746,6 +7973,7 @@ create_breakpoint (struct gdbarch *gdbarch,
        default:
          throw_exception (e);
        }
+      break;
     default:
       if (!sals.nelts)
        return 0;
@@ -7761,8 +7989,8 @@ create_breakpoint (struct gdbarch *gdbarch,
       /* 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);
+      /* Cleanup the canonical array but not its contents.  */
+      make_cleanup (xfree, canonical.canonical);
     }
 
   /* ----------------------------- SNIP -----------------------------
@@ -7771,12 +7999,12 @@ create_breakpoint (struct gdbarch *gdbarch,
      then the memory is not reclaimed.  */
   bkpt_chain = make_cleanup (null_cleanup, 0);
 
-  /* Mark the contents of the addr_string for cleanup.  These go on
+  /* Mark the contents of the canonical for cleanup.  These go on
      the bkpt_chain and only occur if the breakpoint create fails.  */
   for (i = 0; i < sals.nelts; i++)
     {
-      if (addr_string[i] != NULL)
-       make_cleanup (xfree, addr_string[i]);
+      if (canonical.canonical[i] != NULL)
+       make_cleanup (xfree, canonical.canonical[i]);
     }
 
   /* Resolve all line numbers to PC's and verify that the addresses
@@ -7823,7 +8051,7 @@ create_breakpoint (struct gdbarch *gdbarch,
         expand multiple locations for each sal, given than SALS
         already should contain all sals for MARKER_ID.  */
       if (type_wanted == bp_static_tracepoint
-         && is_marker_spec (addr_string[0]))
+         && is_marker_spec (canonical.canonical[0]))
        {
          int i;
 
@@ -7838,11 +8066,12 @@ create_breakpoint (struct gdbarch *gdbarch,
              expanded.sals[0] = sals.sals[i];
              old_chain = make_cleanup (xfree, expanded.sals);
 
-             create_breakpoint_sal (gdbarch, expanded, addr_string[i],
+             create_breakpoint_sal (gdbarch, expanded, canonical.canonical[i],
                                     cond_string, type_wanted,
                                     tempflag ? disp_del : disp_donttouch,
                                     thread, task, ignore_count, ops,
-                                    from_tty, enabled, internal);
+                                    from_tty, enabled, internal,
+                                    canonical.special_display);
 
              do_cleanups (old_chain);
 
@@ -7863,7 +8092,7 @@ create_breakpoint (struct gdbarch *gdbarch,
            }
        }
       else
-       create_breakpoints_sal (gdbarch, sals, addr_string, cond_string,
+       create_breakpoints_sal (gdbarch, sals, &canonical, cond_string,
                                type_wanted,
                                tempflag ? disp_del : disp_donttouch,
                                thread, task, ignore_count, ops, from_tty,
@@ -7878,7 +8107,7 @@ create_breakpoint (struct gdbarch *gdbarch,
       b = set_raw_breakpoint_without_location (gdbarch, type_wanted);
       set_breakpoint_number (internal, b);
       b->thread = -1;
-      b->addr_string = addr_string[0];
+      b->addr_string = canonical.canonical[0];
       b->cond_string = NULL;
       b->ignore_count = ignore_count;
       b->disposition = tempflag ? disp_del : disp_donttouch;
@@ -8030,76 +8259,379 @@ thbreak_command (char *arg, int from_tty)
 }
 
 static void
-stop_command (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\
+       stop at <line>\n"));
+}
+
+static void
+stopin_command (char *arg, int from_tty)
+{
+  int badInput = 0;
+
+  if (arg == (char *) NULL)
+    badInput = 1;
+  else if (*arg != '*')
+    {
+      char *argptr = arg;
+      int hasColon = 0;
+
+      /* Look for a ':'.  If this is a line number specification, then
+         say it is bad, otherwise, it should be an address or
+         function/method name.  */
+      while (*argptr && !hasColon)
+       {
+         hasColon = (*argptr == ':');
+         argptr++;
+       }
+
+      if (hasColon)
+       badInput = (*argptr != ':');    /* Not a class::method */
+      else
+       badInput = isdigit (*arg);      /* a simple line number */
+    }
+
+  if (badInput)
+    printf_filtered (_("Usage: stop in <function | address>\n"));
+  else
+    break_command_1 (arg, 0, from_tty);
+}
+
+static void
+stopat_command (char *arg, int from_tty)
+{
+  int badInput = 0;
+
+  if (arg == (char *) NULL || *arg == '*')     /* no line number */
+    badInput = 1;
+  else
+    {
+      char *argptr = arg;
+      int hasColon = 0;
+
+      /* Look for a ':'.  If there is a '::' then get out, otherwise
+         it is probably a line number.  */
+      while (*argptr && !hasColon)
+       {
+         hasColon = (*argptr == ':');
+         argptr++;
+       }
+
+      if (hasColon)
+       badInput = (*argptr == ':');    /* we have class::method */
+      else
+       badInput = !isdigit (*arg);     /* not a line number */
+    }
+
+  if (badInput)
+    printf_filtered (_("Usage: stop at <line>\n"));
+  else
+    break_command_1 (arg, 0, from_tty);
+}
+
+/* Implement the "breakpoint_hit" breakpoint_ops method for
+   ranged breakpoints.  */
+
+static int
+breakpoint_hit_ranged_breakpoint (const struct bp_location *bl,
+                                 struct address_space *aspace,
+                                 CORE_ADDR bp_addr)
+{
+  return breakpoint_address_match_range (bl->pspace->aspace, bl->address,
+                                        bl->length, aspace, bp_addr);
+}
+
+/* Implement the "resources_needed" breakpoint_ops method for
+   ranged breakpoints.  */
+
+static int
+resources_needed_ranged_breakpoint (const struct bp_location *bl)
+{
+  return target_ranged_break_num_registers ();
+}
+
+/* Implement the "print_it" breakpoint_ops method for
+   ranged breakpoints.  */
+
+static enum print_stop_action
+print_it_ranged_breakpoint (struct breakpoint *b)
+{
+  struct bp_location *bl = b->loc;
+
+  gdb_assert (b->type == bp_hardware_breakpoint);
+
+  /* Ranged breakpoints have only one location.  */
+  gdb_assert (bl && bl->next == NULL);
+
+  annotate_breakpoint (b->number);
+  if (b->disposition == disp_del)
+    ui_out_text (uiout, "\nTemporary ranged breakpoint ");
+  else
+    ui_out_text (uiout, "\nRanged breakpoint ");
+  if (ui_out_is_mi_like_p (uiout))
+    {
+      ui_out_field_string (uiout, "reason",
+                     async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
+      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+    }
+  ui_out_field_int (uiout, "bkptno", b->number);
+  ui_out_text (uiout, ", ");
+
+  return PRINT_SRC_AND_LOC;
+}
+
+/* Implement the "print_one" breakpoint_ops method for
+   ranged breakpoints.  */
+
+static void
+print_one_ranged_breakpoint (struct breakpoint *b,
+                            struct bp_location **last_loc)
+{
+  struct bp_location *bl = b->loc;
+  struct value_print_options opts;
+
+  /* Ranged breakpoints have only one location.  */
+  gdb_assert (bl && bl->next == NULL);
+
+  get_user_print_options (&opts);
+
+  if (opts.addressprint)
+    /* We don't print the address range here, it will be printed later
+       by print_one_detail_ranged_breakpoint.  */
+    ui_out_field_skip (uiout, "addr");
+  annotate_field (5);
+  print_breakpoint_location (b, bl);
+  *last_loc = bl;
+}
+
+/* Implement the "print_one_detail" breakpoint_ops method for
+   ranged breakpoints.  */
+
+static void
+print_one_detail_ranged_breakpoint (const struct breakpoint *b,
+                                   struct ui_out *uiout)
+{
+  CORE_ADDR address_start, address_end;
+  struct bp_location *bl = b->loc;
+  struct ui_stream *stb = ui_out_stream_new (uiout);
+  struct cleanup *cleanup = make_cleanup_ui_out_stream_delete (stb);
+
+  gdb_assert (bl);
+
+  address_start = bl->address;
+  address_end = address_start + bl->length - 1;
+
+  ui_out_text (uiout, "\taddress range: ");
+  fprintf_unfiltered (stb->stream, "[%s, %s]",
+                     print_core_address (bl->gdbarch, address_start),
+                     print_core_address (bl->gdbarch, address_end));
+  ui_out_field_stream (uiout, "addr", stb);
+  ui_out_text (uiout, "\n");
+
+  do_cleanups (cleanup);
+}
+
+/* Implement the "print_mention" breakpoint_ops method for
+   ranged breakpoints.  */
+
+static void
+print_mention_ranged_breakpoint (struct breakpoint *b)
+{
+  struct bp_location *bl = b->loc;
+
+  gdb_assert (bl);
+  gdb_assert (b->type == bp_hardware_breakpoint);
+
+  if (ui_out_is_mi_like_p (uiout))
+    return;
+
+  printf_filtered (_("Hardware assisted ranged breakpoint %d from %s to %s."),
+                  b->number, paddress (bl->gdbarch, bl->address),
+                  paddress (bl->gdbarch, bl->address + bl->length - 1));
+}
+
+/* Implement the "print_recreate" breakpoint_ops method for
+   ranged breakpoints.  */
+
+static void
+print_recreate_ranged_breakpoint (struct breakpoint *b, struct ui_file *fp)
 {
-  printf_filtered (_("Specify the type of breakpoint to set.\n\
-Usage: stop in <function | address>\n\
-       stop at <line>\n"));
+  fprintf_unfiltered (fp, "break-range %s, %s", b->addr_string,
+                     b->addr_string_range_end);
 }
 
-static void
-stopin_command (char *arg, int from_tty)
+/* The breakpoint_ops structure to be used in ranged breakpoints.  */
+
+static struct breakpoint_ops ranged_breakpoint_ops =
 {
-  int badInput = 0;
+  NULL, /* insert */
+  NULL, /* remove */
+  breakpoint_hit_ranged_breakpoint,
+  resources_needed_ranged_breakpoint,
+  print_it_ranged_breakpoint,
+  print_one_ranged_breakpoint,
+  print_one_detail_ranged_breakpoint,
+  print_mention_ranged_breakpoint,
+  print_recreate_ranged_breakpoint
+};
 
-  if (arg == (char *) NULL)
-    badInput = 1;
-  else if (*arg != '*')
+/* Find the address where the end of the breakpoint range should be
+   placed, given the SAL of the end of the range.  This is so that if
+   the user provides a line number, the end of the range is set to the
+   last instruction of the given line.  */
+
+static CORE_ADDR
+find_breakpoint_range_end (struct symtab_and_line sal)
+{
+  CORE_ADDR end;
+
+  /* If the user provided a PC value, use it.  Otherwise,
+     find the address of the end of the given location.  */
+  if (sal.explicit_pc)
+    end = sal.pc;
+  else
     {
-      char *argptr = arg;
-      int hasColon = 0;
+      int ret;
+      CORE_ADDR start;
 
-      /* Look for a ':'.  If this is a line number specification, then
-         say it is bad, otherwise, it should be an address or
-         function/method name.  */
-      while (*argptr && !hasColon)
-       {
-         hasColon = (*argptr == ':');
-         argptr++;
-       }
+      ret = find_line_pc_range (sal, &start, &end);
+      if (!ret)
+       error (_("Could not find location of the end of the range."));
 
-      if (hasColon)
-       badInput = (*argptr != ':');    /* Not a class::method */
-      else
-       badInput = isdigit (*arg);      /* a simple line number */
+      /* find_line_pc_range returns the start of the next line.  */
+      end--;
     }
 
-  if (badInput)
-    printf_filtered (_("Usage: stop in <function | address>\n"));
-  else
-    break_command_1 (arg, 0, from_tty);
+  return end;
 }
 
+/* Implement the "break-range" CLI command.  */
+
 static void
-stopat_command (char *arg, int from_tty)
+break_range_command (char *arg, int from_tty)
 {
-  int badInput = 0;
+  char *arg_start, *addr_string_start, *addr_string_end;
+  struct linespec_result canonical_start, canonical_end;
+  int bp_count, can_use_bp, length;
+  CORE_ADDR end;
+  struct breakpoint *b;
+  struct symtab_and_line sal_start, sal_end;
+  struct symtabs_and_lines sals_start, sals_end;
+  struct cleanup *cleanup_bkpt;
+
+  /* We don't support software ranged breakpoints.  */
+  if (target_ranged_break_num_registers () < 0)
+    error (_("This target does not support hardware ranged breakpoints."));
+
+  bp_count = hw_breakpoint_used_count ();
+  bp_count += target_ranged_break_num_registers ();
+  can_use_bp = target_can_use_hardware_watchpoint (bp_hardware_breakpoint,
+                                                  bp_count, 0);
+  if (can_use_bp < 0)
+    error (_("Hardware breakpoints used exceeds limit."));
+
+  if (arg == NULL || arg[0] == '\0')
+    error(_("No address range specified."));
+
+  sals_start.sals = NULL;
+  sals_start.nelts = 0;
+  init_linespec_result (&canonical_start);
+
+  while (*arg == ' ' || *arg == '\t')
+    arg++;
+
+  parse_breakpoint_sals (&arg, &sals_start, &canonical_start);
+
+  sal_start = sals_start.sals[0];
+  addr_string_start = canonical_start.canonical[0];
+  cleanup_bkpt = make_cleanup (xfree, addr_string_start);
+  xfree (sals_start.sals);
+  xfree (canonical_start.canonical);
+
+  if (arg[0] != ',')
+    error (_("Too few arguments."));
+  else if (sals_start.nelts == 0)
+    error (_("Could not find location of the beginning of the range."));
+  else if (sals_start.nelts != 1)
+    error (_("Cannot create a ranged breakpoint with multiple locations."));
+
+  resolve_sal_pc (&sal_start);
+
+  arg++;       /* Skip the comma.  */
+  while (*arg == ' ' || *arg == '\t')
+    arg++;
+
+  /* Parse the end location.  */
+
+  sals_end.sals = NULL;
+  sals_end.nelts = 0;
+  init_linespec_result (&canonical_end);
+  arg_start = arg;
+
+  /* We call decode_line_1 directly here instead of using
+     parse_breakpoint_sals because we need to specify the start location's
+     symtab and line as the default symtab and line for the end of the
+     range.  This makes it possible to have ranges like "foo.c:27, +14",
+     where +14 means 14 lines from the start location.  */
+  sals_end = decode_line_1 (&arg, 1, sal_start.symtab, sal_start.line,
+                           &canonical_end);
+
+  /* canonical_end can be NULL if it was of the form "*0xdeadbeef".  */
+  if (canonical_end.canonical == NULL)
+    canonical_end.canonical = xcalloc (1, sizeof (char **));
+  /* Add the string if not present.  */
+  if (arg_start != arg && canonical_end.canonical[0] == NULL)
+    canonical_end.canonical[0] = savestring (arg_start, arg - arg_start);
+
+  sal_end = sals_end.sals[0];
+  addr_string_end = canonical_end.canonical[0];
+  make_cleanup (xfree, addr_string_end);
+  xfree (sals_end.sals);
+  xfree (canonical_end.canonical);
+
+  if (sals_end.nelts == 0)
+    error (_("Could not find location of the end of the range."));
+  else if (sals_end.nelts != 1)
+    error (_("Cannot create a ranged breakpoint with multiple locations."));
+
+  resolve_sal_pc (&sal_end);
+
+  end = find_breakpoint_range_end (sal_end);
+  if (sal_start.pc > end)
+    error (_("Invalid address range, end preceeds start."));
+
+  length = end - sal_start.pc + 1;
+  if (length < 0)
+    /* Length overflowed.  */
+    error (_("Address range too large."));
+  else if (length == 1)
+    {
+      /* This range is simple enough to be handled by
+        the `hbreak' command.  */
+      hbreak_command (addr_string_start, 1);
+
+      do_cleanups (cleanup_bkpt);
 
-  if (arg == (char *) NULL || *arg == '*')     /* no line number */
-    badInput = 1;
-  else
-    {
-      char *argptr = arg;
-      int hasColon = 0;
+      return;
+    }
 
-      /* Look for a ':'.  If there is a '::' then get out, otherwise
-         it is probably a line number.  */
-      while (*argptr && !hasColon)
-       {
-         hasColon = (*argptr == ':');
-         argptr++;
-       }
+  /* Now set up the breakpoint.  */
+  b = set_raw_breakpoint (get_current_arch (), sal_start,
+                         bp_hardware_breakpoint);
+  set_breakpoint_count (breakpoint_count + 1);
+  b->number = breakpoint_count;
+  b->disposition = disp_donttouch;
+  b->addr_string = addr_string_start;
+  b->addr_string_range_end = addr_string_end;
+  b->ops = &ranged_breakpoint_ops;
+  b->loc->length = length;
 
-      if (hasColon)
-       badInput = (*argptr == ':');    /* we have class::method */
-      else
-       badInput = !isdigit (*arg);     /* not a line number */
-    }
+  discard_cleanups (cleanup_bkpt);
 
-  if (badInput)
-    printf_filtered (_("Usage: stop at <line>\n"));
-  else
-    break_command_1 (arg, 0, from_tty);
+  mention (b);
+  update_global_location_list (1);
 }
 
 /*  Return non-zero if EXP is verified as constant.  Returned zero
@@ -8211,6 +8743,54 @@ watchpoint_exp_is_const (const struct expression *exp)
   return 1;
 }
 
+/* Implement the "insert" breakpoint_ops method for hardware watchpoints.  */
+
+static int
+insert_watchpoint (struct bp_location *bl)
+{
+  int length = bl->owner->exact? 1 : bl->length;
+
+  return target_insert_watchpoint (bl->address, length, bl->watchpoint_type,
+                                  bl->owner->cond_exp);
+}
+
+/* Implement the "remove" breakpoint_ops method for hardware watchpoints.  */
+
+static int
+remove_watchpoint (struct bp_location *bl)
+{
+  int length = bl->owner->exact? 1 : bl->length;
+
+  return target_remove_watchpoint (bl->address, length, bl->watchpoint_type,
+                                  bl->owner->cond_exp);
+}
+
+/* Implement the "resources_needed" breakpoint_ops method for
+   hardware watchpoints.  */
+
+static int
+resources_needed_watchpoint (const struct bp_location *bl)
+{
+  int length = bl->owner->exact? 1 : bl->length;
+
+  return target_region_ok_for_hw_watchpoint (bl->address, length);
+}
+
+/* The breakpoint_ops structure to be used in hardware watchpoints.  */
+
+static struct breakpoint_ops watchpoint_breakpoint_ops =
+{
+  insert_watchpoint,
+  remove_watchpoint,
+  NULL, /* breakpoint_hit */
+  resources_needed_watchpoint,
+  NULL, /* print_it */
+  NULL, /* print_one */
+  NULL, /* print_one_detail */
+  NULL, /* print_mention */
+  NULL  /* print_recreate */
+};
+
 /* accessflag:  hw_write:  watch write, 
                 hw_read:   watch read, 
                hw_access: watch access (read or write) */
@@ -8231,7 +8811,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty,
   char *cond_end = NULL;
   int i, other_type_used, target_resources_ok = 0;
   enum bptype bp_type;
-  int mem_cnt = 0;
+  int reg_cnt = 0;
   int thread = -1;
   int pc = 0;
 
@@ -8332,13 +8912,8 @@ watch_command_1 (char *arg, int accessflag, int from_tty,
   else if (val != NULL)
     release_value (val);
 
-  tok = arg;
-  while (*tok == ' ' || *tok == '\t')
-    tok++;
-  end_tok = tok;
-
-  while (*end_tok != ' ' && *end_tok != '\t' && *end_tok != '\000')
-    end_tok++;
+  tok = skip_spaces (arg);
+  end_tok = skip_to_space (tok);
 
   toklen = end_tok - tok;
   if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
@@ -8366,14 +8941,14 @@ watch_command_1 (char *arg, int accessflag, int from_tty,
   else
     bp_type = bp_hardware_watchpoint;
 
-  mem_cnt = can_use_hardware_watchpoint (val);
-  if (mem_cnt == 0 && bp_type != bp_hardware_watchpoint)
+  reg_cnt = can_use_hardware_watchpoint (val, target_exact_watchpoints);
+  if (reg_cnt == 0 && bp_type != bp_hardware_watchpoint)
     error (_("Expression cannot be implemented with read/access watchpoint."));
-  if (mem_cnt != 0)
+  if (reg_cnt != 0)
     {
       i = hw_watchpoint_used_count (bp_type, &other_type_used);
       target_resources_ok = 
-       target_can_use_hardware_watchpoint (bp_type, i + mem_cnt, 
+       target_can_use_hardware_watchpoint (bp_type, i + reg_cnt,
                                            other_type_used);
       if (target_resources_ok == 0 && bp_type != bp_hardware_watchpoint)
        error (_("Target does not support this type of hardware watchpoint."));
@@ -8385,7 +8960,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty,
 
   /* Change the type of breakpoint to an ordinary watchpoint if a
      hardware watchpoint could not be set.  */
-  if (!mem_cnt || target_resources_ok <= 0)
+  if (!reg_cnt || target_resources_ok <= 0)
     bp_type = bp_watchpoint;
 
   frame = block_innermost_frame (exp_valid_block);
@@ -8444,7 +9019,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty,
                                          core_addr_to_string (addr));
       xfree (name);
 
-      b->exp_string = xstrprintf ("-location: %.*s",
+      b->exp_string = xstrprintf ("-location %.*s",
                                  (int) (exp_end - exp_start), exp_start);
 
       /* The above expression is in C.  */
@@ -8454,6 +9029,12 @@ watch_command_1 (char *arg, int accessflag, int from_tty,
     b->exp_string = savestring (exp_start, exp_end - exp_start);
   b->val = val;
   b->val_valid = 1;
+  b->ops = &watchpoint_breakpoint_ops;
+
+  /* Use an exact watchpoint when there's only one memory region to be
+     watched, and only one debug register is needed to watch it.  */
+  b->exact = target_exact_watchpoints && reg_cnt == 1;
+
   if (cond_start)
     b->cond_string = savestring (cond_start, cond_end - cond_start);
   else
@@ -8493,12 +9074,15 @@ watch_command_1 (char *arg, int accessflag, int from_tty,
   update_global_location_list (1);
 }
 
-/* Return count of locations need to be watched and can be handled in
-   hardware.  If the watchpoint can not be handled in hardware return
-   zero.  */
+/* Return count of debug registers needed to watch the given expression.
+   If EXACT_WATCHPOINTS is 1, then consider that only the address of
+   the start of the watched region will be monitored (i.e., all accesses
+   will be aligned).  This uses less debug registers on some targets.
+
+   If the watchpoint cannot be handled in hardware return zero.  */
 
 static int
-can_use_hardware_watchpoint (struct value *v)
+can_use_hardware_watchpoint (struct value *v, int exact_watchpoints)
 {
   int found_memory_cnt = 0;
   struct value *head = v;
@@ -8551,12 +9135,18 @@ can_use_hardware_watchpoint (struct value *v)
                      && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
                {
                  CORE_ADDR vaddr = value_address (v);
-                 int       len   = TYPE_LENGTH (value_type (v));
+                 int len;
+                 int num_regs;
+
+                 len = (exact_watchpoints
+                        && is_scalar_type_recursive (vtype))?
+                   1 : TYPE_LENGTH (value_type (v));
 
-                 if (!target_region_ok_for_hw_watchpoint (vaddr, len))
+                 num_regs = target_region_ok_for_hw_watchpoint (vaddr, len);
+                 if (!num_regs)
                    return 0;
                  else
-                   found_memory_cnt++;
+                   found_memory_cnt += num_regs;
                }
            }
        }
@@ -8607,7 +9197,7 @@ watch_maybe_just_location (char *arg, int accessflag, int from_tty)
       && (check_for_argument (&arg, "-location", sizeof ("-location") - 1)
          || check_for_argument (&arg, "-l", sizeof ("-l") - 1)))
     {
-      ep_skip_leading_whitespace (&arg);
+      arg = skip_spaces (arg);
       just_location = 1;
     }
 
@@ -8689,10 +9279,9 @@ until_break_command (char *arg, int from_tty, int anywhere)
 
   if (default_breakpoint_valid)
     sals = decode_line_1 (&arg, 1, default_breakpoint_symtab,
-                         default_breakpoint_line, (char ***) NULL, NULL);
+                         default_breakpoint_line, NULL);
   else
-    sals = decode_line_1 (&arg, 1, (struct symtab *) NULL, 
-                         0, (char ***) NULL, NULL);
+    sals = decode_line_1 (&arg, 1, (struct symtab *) NULL, 0, NULL);
 
   if (sals.nelts != 1)
     error (_("Couldn't get information on specified line."));
@@ -8764,15 +9353,6 @@ until_break_command (char *arg, int from_tty, int anywhere)
     do_cleanups (old_chain);
 }
 
-static void
-ep_skip_leading_whitespace (char **s)
-{
-  if ((s == NULL) || (*s == NULL))
-    return;
-  while (isspace (**s))
-    *s += 1;
-}
-
 /* This function attempts to parse an optional "if <cond>" clause
    from the arg string.  If one is not found, it returns NULL.
 
@@ -8794,7 +9374,7 @@ ep_parse_optional_if_clause (char **arg)
 
   /* Skip any extra leading whitespace, and record the start of the
      condition string.  */
-  ep_skip_leading_whitespace (arg);
+  *arg = skip_spaces (*arg);
   cond_string = *arg;
 
   /* Assume that the condition occupies the remainder of the arg
@@ -8829,7 +9409,7 @@ catch_fork_command_1 (char *arg, int from_tty,
 
   if (!arg)
     arg = "";
-  ep_skip_leading_whitespace (&arg);
+  arg = skip_spaces (arg);
 
   /* The allowed syntax is:
      catch [v]fork
@@ -8873,7 +9453,7 @@ catch_exec_command_1 (char *arg, int from_tty,
 
   if (!arg)
     arg = "";
-  ep_skip_leading_whitespace (&arg);
+  arg = skip_spaces (arg);
 
   /* The allowed syntax is:
      catch exec
@@ -8892,7 +9472,7 @@ catch_exec_command_1 (char *arg, int from_tty,
 }
 
 static enum print_stop_action
-print_exception_catchpoint (struct breakpoint *b)
+print_it_exception_catchpoint (struct breakpoint *b)
 {
   int bp_temp, bp_throw;
 
@@ -8982,8 +9562,10 @@ static struct breakpoint_ops gnu_v3_exception_catchpoint_ops = {
   NULL, /* insert */
   NULL, /* remove */
   NULL, /* breakpoint_hit */
-  print_exception_catchpoint,
+  NULL, /* resources_needed */
+  print_it_exception_catchpoint,
   print_one_exception_catchpoint,
+  NULL, /* print_one_detail */
   print_mention_exception_catchpoint,
   print_recreate_exception_catchpoint
 };
@@ -9022,7 +9604,7 @@ catch_exception_command_1 (enum exception_event_kind ex_event, char *arg,
 
   if (!arg)
     arg = "";
-  ep_skip_leading_whitespace (&arg);
+  arg = skip_spaces (arg);
 
   cond_string = ep_parse_optional_if_clause (&arg);
 
@@ -9208,11 +9790,11 @@ catch_syscall_command_1 (char *arg, int from_tty,
   /* Checking if the feature if supported.  */
   if (gdbarch_get_syscall_number_p (gdbarch) == 0)
     error (_("The feature 'catch syscall' is not supported on \
-this architeture yet."));
+this architecture yet."));
 
   tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
 
-  ep_skip_leading_whitespace (&arg);
+  arg = skip_spaces (arg);
 
   /* We need to do this first "dummy" translation in order
      to get the syscall XML file loaded or, most important,
@@ -9364,8 +9946,8 @@ clear_command (char *arg, int from_tty)
                                    && b->source_file != NULL
                                    && sal.symtab != NULL
                                    && sal.pspace == loc->pspace
-                                   && strcmp (b->source_file,
-                                              sal.symtab->filename) == 0
+                                   && filename_cmp (b->source_file,
+                                                    sal.symtab->filename) == 0
                                    && b->line_number == sal.line);
                  if (pc_match || line_match)
                    {
@@ -9898,12 +10480,20 @@ delete_breakpoint (struct breakpoint *bpt)
 
   /* At least avoid this stale reference until the reference counting
      of breakpoints gets resolved.  */
-  if (bpt->related_breakpoint != NULL)
+  if (bpt->related_breakpoint != bpt)
     {
-      gdb_assert (bpt->related_breakpoint->related_breakpoint == bpt);
-      bpt->related_breakpoint->disposition = disp_del_at_next_stop;
-      bpt->related_breakpoint->related_breakpoint = NULL;
-      bpt->related_breakpoint = NULL;
+      struct breakpoint *related;
+
+      if (bpt->type == bp_watchpoint_scope)
+       watchpoint_del_at_next_stop (bpt->related_breakpoint);
+      else if (bpt->related_breakpoint->type == bp_watchpoint_scope)
+       watchpoint_del_at_next_stop (bpt);
+
+      /* Unlink bpt from the bpt->related_breakpoint ring.  */
+      for (related = bpt; related->related_breakpoint != bpt;
+          related = related->related_breakpoint);
+      related->related_breakpoint = bpt->related_breakpoint;
+      bpt->related_breakpoint = bpt;
     }
 
   observer_notify_breakpoint_deleted (bpt->number);
@@ -9922,6 +10512,7 @@ delete_breakpoint (struct breakpoint *bpt)
   xfree (bpt->cond_string);
   xfree (bpt->cond_exp);
   xfree (bpt->addr_string);
+  xfree (bpt->addr_string_range_end);
   xfree (bpt->exp);
   xfree (bpt->exp_string);
   xfree (bpt->exp_string_reparse);
@@ -10216,14 +10807,21 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
   return sal;
 }
 
-static void
+/* Create new breakpoint locations for B (a hardware or software breakpoint)
+   based on SALS and SALS_END.  If SALS_END.NELTS is not zero, then B is
+   a ranged breakpoint.  */
+
+void
 update_breakpoint_locations (struct breakpoint *b,
-                            struct symtabs_and_lines sals)
+                            struct symtabs_and_lines sals,
+                            struct symtabs_and_lines sals_end)
 {
   int i;
-  char *s;
   struct bp_location *existing_locations = b->loc;
 
+  /* Ranged breakpoints have only one start location and one end location.  */
+  gdb_assert (sals_end.nelts == 0 || (sals.nelts == 1 && sals_end.nelts == 1));
+
   /* If there's no new locations, and all existing locations are
      pending, don't do anything.  This optimizes the common case where
      all locations are in the same shared library, that was unloaded.
@@ -10244,6 +10842,7 @@ update_breakpoint_locations (struct breakpoint *b,
         old symtab.  */
       if (b->cond_string != NULL)
        {
+         char *s;
          struct gdb_exception e;
 
          s = b->cond_string;
@@ -10270,6 +10869,13 @@ update_breakpoint_locations (struct breakpoint *b,
 
       if (b->line_number == 0)
        b->line_number = sals.sals[i].line;
+
+      if (sals_end.nelts)
+       {
+         CORE_ADDR end = find_breakpoint_range_end (sals_end.sals[0]);
+
+         new_loc->length = end - sals.sals[0].pc + 1;
+       }
     }
 
   /* Update locations of permanent breakpoints.  */
@@ -10295,8 +10901,7 @@ update_breakpoint_locations (struct breakpoint *b,
            if (have_ambiguous_names)
              {
                for (; l; l = l->next)
-                 if (breakpoint_address_match (e->pspace->aspace, e->address,
-                                               l->pspace->aspace, l->address))
+                 if (breakpoint_locations_match (e, l))
                    {
                      l->enabled = 0;
                      break;
@@ -10319,6 +10924,135 @@ update_breakpoint_locations (struct breakpoint *b,
   update_global_location_list (1);
 }
 
+/* Find the SaL locations corresponding to the given ADDR_STRING.
+   On return, FOUND will be 1 if any SaL was found, zero otherwise.  */
+
+static struct symtabs_and_lines
+addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
+{
+  char *s;
+  int marker_spec;
+  struct symtabs_and_lines sals = {0};
+  struct gdb_exception e;
+
+  s = addr_string;
+  marker_spec = b->type == bp_static_tracepoint && is_marker_spec (s);
+
+  TRY_CATCH (e, RETURN_MASK_ERROR)
+    {
+      if (marker_spec)
+       {
+         sals = decode_static_tracepoint_spec (&s);
+         if (sals.nelts > b->static_trace_marker_id_idx)
+           {
+             sals.sals[0] = sals.sals[b->static_trace_marker_id_idx];
+             sals.nelts = 1;
+           }
+         else
+           error (_("marker %s not found"), b->static_trace_marker_id);
+       }
+      else
+       sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, NULL);
+    }
+  if (e.reason < 0)
+    {
+      int not_found_and_ok = 0;
+      /* For pending breakpoints, it's expected that parsing will
+        fail until the right shared library is loaded.  User has
+        already told to create pending breakpoints and don't need
+        extra messages.  If breakpoint is in bp_shlib_disabled
+        state, then user already saw the message about that
+        breakpoint being disabled, and don't want to see more
+        errors.  */
+      if (e.error == NOT_FOUND_ERROR
+         && (b->condition_not_parsed 
+             || (b->loc && b->loc->shlib_disabled)
+             || b->enable_state == bp_disabled))
+       not_found_and_ok = 1;
+
+      if (!not_found_and_ok)
+       {
+         /* We surely don't want to warn about the same breakpoint
+            10 times.  One solution, implemented here, is disable
+            the breakpoint on error.  Another solution would be to
+            have separate 'warning emitted' flag.  Since this
+            happens only when a binary has changed, I don't know
+            which approach is better.  */
+         b->enable_state = bp_disabled;
+         throw_exception (e);
+       }
+    }
+
+  if (e.reason == 0 || e.error != NOT_FOUND_ERROR)
+    {
+      gdb_assert (sals.nelts == 1);
+
+      resolve_sal_pc (&sals.sals[0]);
+      if (b->condition_not_parsed && s && s[0])
+       {
+         char *cond_string = 0;
+         int thread = -1;
+         int task = 0;
+
+         find_condition_and_thread (s, sals.sals[0].pc,
+                                    &cond_string, &thread, &task);
+         if (cond_string)
+           b->cond_string = cond_string;
+         b->thread = thread;
+         b->task = task;
+         b->condition_not_parsed = 0;
+       }
+
+      if (b->type == bp_static_tracepoint && !marker_spec)
+       sals.sals[0] = update_static_tracepoint (b, sals.sals[0]);
+
+      *found = 1;
+    }
+  else
+    *found = 0;
+
+  return sals;
+}
+
+/* Reevaluate a hardware or software breakpoint and recreate its locations.
+   This is necessary after symbols are read (e.g., an executable or DSO
+   was loaded, or the inferior just started).  */
+
+static void
+re_set_breakpoint (struct breakpoint *b)
+{
+  int found;
+  struct symtabs_and_lines sals, sals_end;
+  struct symtabs_and_lines expanded = {0};
+  struct symtabs_and_lines expanded_end = {0};
+  struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
+
+  input_radix = b->input_radix;
+  save_current_space_and_thread ();
+  switch_to_program_space_and_thread (b->pspace);
+  set_language (b->language);
+
+  sals = addr_string_to_sals (b, b->addr_string, &found);
+  if (found)
+    {
+      make_cleanup (xfree, sals.sals);
+      expanded = expand_line_sal_maybe (sals.sals[0]);
+    }
+
+  if (b->addr_string_range_end)
+    {
+      sals_end = addr_string_to_sals (b, b->addr_string_range_end, &found);
+      if (found)
+       {
+         make_cleanup (xfree, sals_end.sals);
+         expanded_end = expand_line_sal_maybe (sals_end.sals[0]);
+       }
+    }
+
+  update_breakpoint_locations (b, expanded, expanded_end);
+  do_cleanups (cleanups);
+}
+
 /* Reset a breakpoint given it's struct breakpoint * BINT.
    The value we return ends up being the return value from catch_errors.
    Unused in this case.  */
@@ -10328,14 +11062,6 @@ breakpoint_re_set_one (void *bint)
 {
   /* Get past catch_errs.  */
   struct breakpoint *b = (struct breakpoint *) bint;
-  int not_found = 0;
-  int *not_found_ptr = &not_found;
-  struct symtabs_and_lines sals = {0};
-  struct symtabs_and_lines expanded = {0};
-  char *s;
-  struct gdb_exception e;
-  struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
-  int marker_spec = 0;
 
   switch (b->type)
     {
@@ -10348,6 +11074,7 @@ breakpoint_re_set_one (void *bint)
     case bp_tracepoint:
     case bp_fast_tracepoint:
     case bp_static_tracepoint:
+    case bp_gnu_ifunc_resolver:
       /* Do not attempt to re-set breakpoints disabled during startup.  */
       if (b->enable_state == bp_startup_disabled)
        return 0;
@@ -10359,89 +11086,7 @@ breakpoint_re_set_one (void *bint)
          return 0;
        }
 
-      input_radix = b->input_radix;
-      s = b->addr_string;
-
-      save_current_space_and_thread ();
-      switch_to_program_space_and_thread (b->pspace);
-
-      marker_spec = b->type == bp_static_tracepoint && is_marker_spec (s);
-
-      set_language (b->language);
-      TRY_CATCH (e, RETURN_MASK_ERROR)
-       {
-         if (marker_spec)
-           {
-             sals = decode_static_tracepoint_spec (&s);
-             if (sals.nelts > b->static_trace_marker_id_idx)
-               {
-                 sals.sals[0] = sals.sals[b->static_trace_marker_id_idx];
-                 sals.nelts = 1;
-               }
-             else
-               error (_("marker %s not found"), b->static_trace_marker_id);
-           }
-         else
-           sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0,
-                                 (char ***) NULL, not_found_ptr);
-       }
-      if (e.reason < 0)
-       {
-         int not_found_and_ok = 0;
-         /* For pending breakpoints, it's expected that parsing will
-            fail until the right shared library is loaded.  User has
-            already told to create pending breakpoints and don't need
-            extra messages.  If breakpoint is in bp_shlib_disabled
-            state, then user already saw the message about that
-            breakpoint being disabled, and don't want to see more
-            errors.  */
-         if (not_found 
-             && (b->condition_not_parsed 
-                 || (b->loc && b->loc->shlib_disabled)
-                 || b->enable_state == bp_disabled))
-           not_found_and_ok = 1;
-
-         if (!not_found_and_ok)
-           {
-             /* We surely don't want to warn about the same breakpoint
-                10 times.  One solution, implemented here, is disable
-                the breakpoint on error.  Another solution would be to
-                have separate 'warning emitted' flag.  Since this
-                happens only when a binary has changed, I don't know
-                which approach is better.  */
-             b->enable_state = bp_disabled;
-             throw_exception (e);
-           }
-       }
-
-      if (!not_found)
-       {
-         gdb_assert (sals.nelts == 1);
-
-         resolve_sal_pc (&sals.sals[0]);
-         if (b->condition_not_parsed && s && s[0])
-           {
-             char *cond_string = 0;
-             int thread = -1;
-             int task = 0;
-
-             find_condition_and_thread (s, sals.sals[0].pc,
-                                        &cond_string, &thread, &task);
-             if (cond_string)
-               b->cond_string = cond_string;
-             b->thread = thread;
-             b->task = task;
-             b->condition_not_parsed = 0;
-           }
-
-         if (b->type == bp_static_tracepoint && !marker_spec)
-           sals.sals[0] = update_static_tracepoint (b, sals.sals[0]);
-
-         expanded = expand_line_sal_maybe (sals.sals[0]);
-       }
-
-      make_cleanup (xfree, sals.sals);
-      update_breakpoint_locations (b, expanded);
+      re_set_breakpoint (b);
       break;
 
     case bp_watchpoint:
@@ -10518,10 +11163,10 @@ breakpoint_re_set_one (void *bint)
     case bp_exception:
     case bp_exception_resume:
     case bp_jit_event:
+    case bp_gnu_ifunc_resolver_return:
       break;
     }
 
-  do_cleanups (cleanups);
   return 0;
 }
 
@@ -10554,12 +11199,9 @@ breakpoint_re_set (void)
 
   do_cleanups (old_chain);
 
-  create_overlay_event_breakpoint ("_ovly_debug_event");
-  create_longjmp_master_breakpoint ("longjmp");
-  create_longjmp_master_breakpoint ("_longjmp");
-  create_longjmp_master_breakpoint ("siglongjmp");
-  create_longjmp_master_breakpoint ("_siglongjmp");
-  create_std_terminate_master_breakpoint ("std::terminate()");
+  create_overlay_event_breakpoint ();
+  create_longjmp_master_breakpoint ();
+  create_std_terminate_master_breakpoint ();
   create_exception_master_breakpoint ();
 }
 \f
@@ -10629,13 +11271,6 @@ set_ignore_count (int bptnum, int count, int from_tty)
   error (_("No breakpoint number %d."), bptnum);
 }
 
-void
-make_breakpoint_silent (struct breakpoint *b)
-{
-  /* Silence the breakpoint.  */
-  b->silent = 1;
-}
-
 /* Command to set ignore-count of breakpoint N to COUNT.  */
 
 static void
@@ -10668,21 +11303,23 @@ map_breakpoint_numbers (char *args, void (*function) (struct breakpoint *,
                                                      void *),
                        void *data)
 {
-  char *p = args;
-  char *p1;
   int num;
   struct breakpoint *b, *tmp;
   int match;
+  struct get_number_or_range_state state;
 
-  if (p == 0)
+  if (args == 0)
     error_no_arg (_("one or more breakpoint numbers"));
 
-  while (*p)
+  init_number_or_range (&state, args);
+
+  while (!state.finished)
     {
+      char *p = state.string;
+
       match = 0;
-      p1 = p;
 
-      num = get_number_or_range (&p1);
+      num = get_number_or_range (&state);
       if (num == 0)
        {
          warning (_("bad breakpoint number at or near '%s'"), p);
@@ -10692,17 +11329,30 @@ map_breakpoint_numbers (char *args, void (*function) (struct breakpoint *,
          ALL_BREAKPOINTS_SAFE (b, tmp)
            if (b->number == num)
              {
-               struct breakpoint *related_breakpoint = b->related_breakpoint;
+               struct breakpoint *related_breakpoint;
+
                match = 1;
-               function (b, data);
-               if (related_breakpoint)
-                 function (related_breakpoint, data);
+               related_breakpoint = b;
+               do
+                 {
+                   struct breakpoint *next_related_b;
+
+                   /* FUNCTION can be also delete_breakpoint.  */
+                   next_related_b = related_breakpoint->related_breakpoint;
+                   function (related_breakpoint, data);
+
+                   /* For delete_breakpoint of the last entry of the ring we
+                      were traversing we would never get back to B.  */
+                   if (next_related_b == related_breakpoint)
+                     break;
+                   related_breakpoint = next_related_b;
+                 }
+               while (related_breakpoint != b);
                break;
              }
          if (match == 0)
            printf_unfiltered (_("No breakpoint number %d.\n"), num);
        }
-      p = p1;
     }
 }
 
@@ -10719,7 +11369,7 @@ find_location_by_number (char *number)
   *dot = '\0';
 
   p1 = number;
-  bp_num = get_number_or_range (&p1);
+  bp_num = get_number (&p1);
   if (bp_num == 0)
     error (_("Bad breakpoint number '%s'"), number);
 
@@ -10733,7 +11383,7 @@ find_location_by_number (char *number)
     error (_("Bad breakpoint number '%s'"), number);
   
   p1 = dot+1;
-  loc_num = get_number_or_range (&p1);
+  loc_num = get_number (&p1);
   if (loc_num == 0)
     error (_("Bad breakpoint location number '%s'"), number);
 
@@ -10793,7 +11443,7 @@ disable_command (char *args, int from_tty)
       case bp_none:
        warning (_("attempted to disable apparently deleted breakpoint #%d?"),
                 bpt->number);
-       continue;
+       break;
       case bp_breakpoint:
       case bp_tracepoint:
       case bp_fast_tracepoint:
@@ -10805,8 +11455,9 @@ disable_command (char *args, int from_tty)
       case bp_read_watchpoint:
       case bp_access_watchpoint:
        disable_breakpoint (bpt);
+       break;
       default:
-       continue;
+       break;
       }
   else if (strchr (args, '.'))
     {
@@ -10894,7 +11545,7 @@ enable_command (char *args, int from_tty)
       case bp_none:
        warning (_("attempted to enable apparently deleted breakpoint #%d?"),
                 bpt->number);
-       continue;
+       break;
       case bp_breakpoint:
       case bp_tracepoint:
       case bp_fast_tracepoint:
@@ -10906,8 +11557,9 @@ enable_command (char *args, int from_tty)
       case bp_read_watchpoint:
       case bp_access_watchpoint:
        enable_breakpoint (bpt);
+       break;
       default:
-       continue;
+       break;
       }
   else if (strchr (args, '.'))
     {
@@ -10996,10 +11648,10 @@ decode_line_spec_1 (char *string, int funfirstline)
     sals = decode_line_1 (&string, funfirstline,
                          default_breakpoint_symtab,
                          default_breakpoint_line,
-                         (char ***) NULL, NULL);
+                         NULL);
   else
     sals = decode_line_1 (&string, funfirstline,
-                         (struct symtab *) NULL, 0, (char ***) NULL, NULL);
+                         (struct symtab *) NULL, 0, NULL);
   if (*string)
     error (_("Junk at end of line specification: %s"), string);
   return sals;
@@ -11226,8 +11878,11 @@ catch_syscall_completer (struct cmd_list_element *cmd,
                          char *text, char *word)
 {
   const char **list = get_syscall_names ();
+  char **retlist
+    = (list == NULL) ? NULL : complete_on_enum (list, text, word);
 
-  return (list == NULL) ? NULL : complete_on_enum (list, text, word);
+  xfree (list);
+  return retlist;
 }
 
 /* Tracepoint-specific operations.  */
@@ -11398,21 +12053,18 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
    omitted.  */
 
 static void
-tracepoints_info (char *tpnum_exp, int from_tty)
+tracepoints_info (char *args, int from_tty)
 {
-  int tpnum = -1, num_printed;
+  int num_printed;
 
-  if (tpnum_exp)
-    tpnum = parse_and_eval_long (tpnum_exp);
-
-  num_printed = breakpoint_1 (tpnum, 0, is_tracepoint);
+  num_printed = breakpoint_1 (args, 0, is_tracepoint);
 
   if (num_printed == 0)
     {
-      if (tpnum == -1)
+      if (args == NULL || *args == '\0')
        ui_out_message (uiout, 0, "No tracepoints.\n");
       else
-       ui_out_message (uiout, 0, "No tracepoint number %d.\n", tpnum);
+       ui_out_message (uiout, 0, "No tracepoint matching '%s'.\n", args);
     }
 
   default_collect_info ();
@@ -11475,6 +12127,18 @@ delete_trace_command (char *arg, int from_tty)
     map_breakpoint_numbers (arg, do_delete_breakpoint, NULL);
 }
 
+/* Helper function for trace_pass_command.  */
+
+static void
+trace_pass_set_count (struct breakpoint *bp, int count, int from_tty)
+{
+  bp->pass_count = count;
+  observer_notify_tracepoint_modified (bp->number);
+  if (from_tty)
+    printf_filtered (_("Setting tracepoint %d's passcount to %d\n"),
+                    bp->number, count);
+}
+
 /* Set passcount for tracepoint.
 
    First command argument is passcount, second is tracepoint number.
@@ -11484,9 +12148,8 @@ delete_trace_command (char *arg, int from_tty)
 static void
 trace_pass_command (char *args, int from_tty)
 {
-  struct breakpoint *t1 = (struct breakpoint *) -1, *t2;
+  struct breakpoint *t1;
   unsigned int count;
-  int all = 0;
 
   if (args == 0 || *args == 0)
     error (_("passcount command requires an "
@@ -11500,32 +12163,32 @@ trace_pass_command (char *args, int from_tty)
   if (*args && strncasecmp (args, "all", 3) == 0)
     {
       args += 3;                       /* Skip special argument "all".  */
-      all = 1;
       if (*args)
        error (_("Junk at end of arguments."));
-    }
-  else
-    t1 = get_tracepoint_by_number (&args, 1, 1);
 
-  do
+      ALL_TRACEPOINTS (t1)
+      {
+       trace_pass_set_count (t1, count, from_tty);
+      }
+    }
+  else if (*args == '\0')
     {
+      t1 = get_tracepoint_by_number (&args, NULL, 1);
       if (t1)
+       trace_pass_set_count (t1, count, from_tty);
+    }
+  else
+    {
+      struct get_number_or_range_state state;
+
+      init_number_or_range (&state, args);
+      while (!state.finished)
        {
-         ALL_TRACEPOINTS (t2)
-           if (t1 == (struct breakpoint *) -1 || t1 == t2)
-             {
-               t2->pass_count = count;
-               observer_notify_tracepoint_modified (t2->number);
-               if (from_tty)
-                 printf_filtered (_("Setting tracepoint %d's "
-                                    "passcount to %d\n"),
-                                  t2->number, count);
-             }
-         if (! all && *args)
-           t1 = get_tracepoint_by_number (&args, 1, 0);
+         t1 = get_tracepoint_by_number (&args, &state, 1);
+         if (t1)
+           trace_pass_set_count (t1, count, from_tty);
        }
     }
-  while (*args);
 }
 
 struct breakpoint *
@@ -11557,18 +12220,25 @@ get_tracepoint_by_number_on_target (int num)
 }
 
 /* Utility: parse a tracepoint number and look it up in the list.
-   If MULTI_P is true, there might be a range of tracepoints in ARG.
-   if OPTIONAL_P is true, then if the argument is missing, the most
+   If STATE is not NULL, use, get_number_or_range_state and ignore ARG.
+   If OPTIONAL_P is true, then if the argument is missing, the most
    recent tracepoint (tracepoint_count) is returned.  */
 struct breakpoint *
-get_tracepoint_by_number (char **arg, int multi_p, int optional_p)
+get_tracepoint_by_number (char **arg,
+                         struct get_number_or_range_state *state,
+                         int optional_p)
 {
   extern int tracepoint_count;
   struct breakpoint *t;
   int tpnum;
   char *instring = arg == NULL ? NULL : *arg;
 
-  if (arg == NULL || *arg == NULL || ! **arg)
+  if (state)
+    {
+      gdb_assert (!state->finished);
+      tpnum = get_number_or_range (state);
+    }
+  else if (arg == NULL || *arg == NULL || ! **arg)
     {
       if (optional_p)
        tpnum = tracepoint_count;
@@ -11576,7 +12246,7 @@ get_tracepoint_by_number (char **arg, int multi_p, int optional_p)
        error_no_arg (_("tracepoint number"));
     }
   else
-    tpnum = multi_p ? get_number_or_range (arg) : get_number (arg);
+    tpnum = get_number (arg);
 
   if (tpnum <= 0)
     {
@@ -11595,9 +12265,6 @@ get_tracepoint_by_number (char **arg, int multi_p, int optional_p)
       return t;
     }
 
-  /* FIXME: if we are in the middle of a range we don't want to give
-     a message.  The current interface to get_number_or_range doesn't
-     allow us to discover this.  */
   printf_unfiltered ("No tracepoint number %d.\n", tpnum);
   return NULL;
 }
@@ -11625,7 +12292,7 @@ save_breakpoints (char *filename, int from_tty,
   ALL_BREAKPOINTS (tp)
   {
     /* Skip internal and momentary breakpoints.  */
-    if (!user_settable_breakpoint (tp) || tp->number < 0)
+    if (!user_breakpoint_p (tp))
       continue;
 
     /* If we have a filter, only save the breakpoints it accepts.  */
@@ -11663,14 +12330,14 @@ save_breakpoints (char *filename, int from_tty,
   ALL_BREAKPOINTS (tp)
   {
     /* Skip internal and momentary breakpoints.  */
-    if (!user_settable_breakpoint (tp) || tp->number < 0)
+    if (!user_breakpoint_p (tp))
       continue;
 
     /* If we have a filter, only save the breakpoints it accepts.  */
     if (filter && !filter (tp))
       continue;
 
-    if (tp->ops != NULL)
+    if (tp->ops != NULL && tp->ops->print_recreate != NULL)
       (tp->ops->print_recreate) (tp, fp);
     else
       {
@@ -11798,7 +12465,7 @@ save_tracepoints_command (char *args, int from_tty)
 /* Create a vector of all tracepoints.  */
 
 VEC(breakpoint_p) *
-all_tracepoints ()
+all_tracepoints (void)
 {
   VEC(breakpoint_p) *tp_vec = 0;
   struct breakpoint *tp;
@@ -11905,6 +12572,8 @@ _initialize_breakpoint (void)
   observer_attach_inferior_exit (clear_syscall_counts);
   observer_attach_memory_changed (invalidate_bp_value_on_memory_change);
 
+  breakpoint_objfile_key = register_objfile_data ();
+
   breakpoint_chain = 0;
   /* Don't bother to call set_breakpoint_count.  $bpnum isn't useful
      before a breakpoint is set.  */
@@ -11942,7 +12611,7 @@ BREAK_ARGS_HELP ("tbreak")));
   set_cmd_completer (c, location_completer);
 
   c = add_com ("hbreak", class_breakpoint, hbreak_command, _("\
-Set a hardware assisted  breakpoint.\n\
+Set a hardware assisted breakpoint.\n\
 Like \"break\" except the breakpoint requires hardware support,\n\
 some target hardware may not have this support.\n\
 \n"
@@ -12100,7 +12769,7 @@ breakpoint set."));
     }
 
   add_info ("breakpoints", breakpoints_info, _("\
-Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
+Status of specified breakpoints (all user-settable breakpoints if no argument).\n\
 The \"Type\" column indicates one of:\n\
 \tbreakpoint     - normal breakpoint\n\
 \twatchpoint     - watchpoint\n\
@@ -12248,9 +12917,7 @@ the memory to which it refers."));
   set_cmd_completer (c, expression_completer);
 
   add_info ("watchpoints", watchpoints_info, _("\
-Status of watchpoints, or watchpoint number NUMBER."));
-
-
+Status of specified watchpoints (all watchpoints if no argument)."));
 
   /* XXX: cagney/2005-02-23: This should be a boolean, and should
      respond to changes - contrary to the description.  */
@@ -12316,7 +12983,7 @@ Do \"help tracepoints\" for info on other tracepoint commands."));
   set_cmd_completer (c, location_completer);
 
   add_info ("tracepoints", tracepoints_info, _("\
-Status of tracepoints, or tracepoint number NUMBER.\n\
+Status of specified tracepoints (all tracepoints if no argument).\n\
 Convenience variable \"$tpnum\" contains the number of the\n\
 last tracepoint set."));
 
@@ -12426,7 +13093,23 @@ inferior in all-stop mode, gdb behaves as if always-inserted mode is off."),
                           &show_always_inserted_mode,
                           &breakpoint_set_cmdlist,
                           &breakpoint_show_cmdlist);
-  
+
+  add_com ("break-range", class_breakpoint, break_range_command, _("\
+Set a breakpoint for an address range.\n\
+break-range START-LOCATION, END-LOCATION\n\
+where START-LOCATION and END-LOCATION can be one of the following:\n\
+  LINENUM, for that line in the current file,\n\
+  FILE:LINENUM, for that line in that file,\n\
+  +OFFSET, for that number of lines after the current line\n\
+           or the start of the range\n\
+  FUNCTION, for the first line in that function,\n\
+  FILE:FUNCTION, to distinguish among like-named static functions.\n\
+  *ADDRESS, for the instruction at that address.\n\
+\n\
+The breakpoint will stop execution of the inferior whenever it executes\n\
+an instruction at any address within the [START-LOCATION, END-LOCATION]\n\
+range (including START-LOCATION and END-LOCATION)."));
+
   automatic_hardware_breakpoints = 1;
 
   observer_attach_about_to_proceed (breakpoint_about_to_proceed);
This page took 0.075245 seconds and 4 git commands to generate.