Get rid of VEC(static_tracepoint_marker_p)
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index adc89505917fc9cef2bad44a59309916db3007ed..9de0e6330c553f4dccfcd05fe20de8102472e2b0 100644 (file)
@@ -1,6 +1,6 @@
 /* Everything about breakpoints, for GDB.
 
-   Copyright (C) 1986-2017 Free Software Foundation, Inc.
+   Copyright (C) 1986-2018 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -49,7 +49,7 @@
 #include "block.h"
 #include "solib.h"
 #include "solist.h"
-#include "observer.h"
+#include "observable.h"
 #include "memattr.h"
 #include "ada-lang.h"
 #include "top.h"
@@ -96,8 +96,6 @@ enum exception_event_kind
 static void map_breakpoint_numbers (const char *,
                                    gdb::function_view<void (breakpoint *)>);
 
-static void ignore_command (char *, int);
-
 static void breakpoint_re_set_default (struct breakpoint *);
 
 static void
@@ -119,8 +117,6 @@ static std::vector<symtab_and_line> decode_location_default
   (struct breakpoint *b, const struct event_location *location,
    struct program_space *search_pspace);
 
-static void clear_command (char *, int);
-
 static int can_use_hardware_watchpoint (struct value *);
 
 static void mention (struct breakpoint *);
@@ -165,14 +161,6 @@ static int breakpoint_location_address_range_overlap (struct bp_location *,
                                                      const address_space *,
                                                      CORE_ADDR, int);
 
-static void info_breakpoints_command (char *, int);
-
-static void info_watchpoints_command (char *, int);
-
-static void commands_command (char *, int);
-
-static void condition_command (char *, int);
-
 static int remove_breakpoint (struct bp_location *);
 static int remove_breakpoint_1 (struct bp_location *, enum remove_bp_reason);
 
@@ -186,15 +174,9 @@ static int hw_watchpoint_used_count_others (struct breakpoint *except,
                                            enum bptype type,
                                            int *other_type_used);
 
-static void hbreak_command (char *, int);
-
-static void thbreak_command (char *, int);
-
 static void enable_breakpoint_disp (struct breakpoint *, enum bpdisp,
                                    int count);
 
-static void stop_command (char *arg, int from_tty);
-
 static void free_bp_location (struct bp_location *loc);
 static void incref_bp_location (struct bp_location *loc);
 static void decref_bp_location (struct bp_location **loc);
@@ -244,13 +226,7 @@ static int is_hardware_watchpoint (const struct breakpoint *bpt);
 
 static void insert_breakpoint_locations (void);
 
-static void info_tracepoints_command (char *, int);
-
-static void enable_trace_command (char *, int);
-
-static void disable_trace_command (char *, int);
-
-static void trace_pass_command (char *, int);
+static void trace_pass_command (const char *, int);
 
 static void set_tracepoint_count (int num);
 
@@ -734,7 +710,7 @@ mark_breakpoint_location_modified (struct bp_location *loc)
    condition_evaluation_mode.  */
 
 static void
-set_condition_evaluation_mode (char *args, int from_tty,
+set_condition_evaluation_mode (const char *args, int from_tty,
                               struct cmd_list_element *c)
 {
   const char *old_mode, *new_mode;
@@ -903,12 +879,12 @@ set_breakpoint_condition (struct breakpoint *b, const char *exp,
        {
          struct watchpoint *w = (struct watchpoint *) b;
 
-         innermost_block = NULL;
+         innermost_block.reset ();
          arg = exp;
          w->cond_exp = parse_exp_1 (&arg, 0, 0, 0);
          if (*arg)
            error (_("Junk at end of expression"));
-         w->cond_exp_valid_block = innermost_block;
+         w->cond_exp_valid_block = innermost_block.block ();
        }
       else
        {
@@ -927,7 +903,7 @@ set_breakpoint_condition (struct breakpoint *b, const char *exp,
     }
   mark_breakpoint_modified (b);
 
-  observer_notify_breakpoint_modified (b);
+  gdb::observers::breakpoint_modified.notify (b);
 }
 
 /* Completion for the "condition" command.  */
@@ -945,7 +921,6 @@ condition_completer (struct cmd_list_element *cmd,
     {
       int len;
       struct breakpoint *b;
-      VEC (char_ptr) *result = NULL;
 
       if (text[0] == '$')
        {
@@ -982,10 +957,10 @@ condition_completer (struct cmd_list_element *cmd,
 /* condition N EXP -- set break condition of breakpoint N to EXP.  */
 
 static void
-condition_command (char *arg, int from_tty)
+condition_command (const char *arg, int from_tty)
 {
   struct breakpoint *b;
-  char *p;
+  const char *p;
   int bnum;
 
   if (arg == 0)
@@ -1197,7 +1172,7 @@ breakpoint_set_commands (struct breakpoint *b,
   validate_commands_for_breakpoint (b, commands.get ());
 
   b->commands = std::move (commands);
-  observer_notify_breakpoint_modified (b);
+  gdb::observers::breakpoint_modified.notify (b);
 }
 
 /* Set the internal `silent' flag on the breakpoint.  Note that this
@@ -1211,7 +1186,7 @@ breakpoint_set_silent (struct breakpoint *b, int silent)
 
   b->silent = silent;
   if (old_silent != silent)
-    observer_notify_breakpoint_modified (b);
+    gdb::observers::breakpoint_modified.notify (b);
 }
 
 /* Set the thread for this breakpoint.  If THREAD is -1, make the
@@ -1224,7 +1199,7 @@ breakpoint_set_thread (struct breakpoint *b, int thread)
 
   b->thread = thread;
   if (old_thread != thread)
-    observer_notify_breakpoint_modified (b);
+    gdb::observers::breakpoint_modified.notify (b);
 }
 
 /* Set the task for this breakpoint.  If TASK is 0, make the
@@ -1237,7 +1212,7 @@ breakpoint_set_task (struct breakpoint *b, int task)
 
   b->task = task;
   if (old_task != task)
-    observer_notify_breakpoint_modified (b);
+    gdb::observers::breakpoint_modified.notify (b);
 }
 
 void
@@ -1294,16 +1269,13 @@ commands_command_1 (const char *arg, int from_tty,
         {
           validate_commands_for_breakpoint (b, cmd.get ());
           b->commands = cmd;
-          observer_notify_breakpoint_modified (b);
+          gdb::observers::breakpoint_modified.notify (b);
         }
      });
-
-  if (cmd == NULL)
-    error (_("No breakpoints specified."));
 }
 
 static void
-commands_command (char *arg, int from_tty)
+commands_command (const char *arg, int from_tty)
 {
   commands_command_1 (arg, from_tty, NULL);
 }
@@ -1892,7 +1864,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
                  loc->gdbarch = get_type_arch (value_type (v));
 
                  loc->pspace = frame_pspace;
-                 loc->address = addr;
+                 loc->address = address_significant (loc->gdbarch, addr);
 
                  if (bitsize != 0)
                    {
@@ -2254,12 +2226,8 @@ build_target_condition_list (struct bp_location *bl)
 static agent_expr_up
 parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
 {
-  struct cleanup *old_cleanups = 0;
-  struct expression **argvec;
   const char *cmdrest;
   const char *format_start, *format_end;
-  struct format_piece *fpieces;
-  int nargs;
   struct gdbarch *gdbarch = get_current_arch ();
 
   if (cmd == NULL)
@@ -2276,9 +2244,7 @@ parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
 
   format_start = cmdrest;
 
-  fpieces = parse_format_string (&cmdrest);
-
-  old_cleanups = make_cleanup (free_format_pieces_cleanup, &fpieces);
+  format_pieces fpieces (&cmdrest);
 
   format_end = cmdrest;
 
@@ -2296,17 +2262,14 @@ parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
 
   /* For each argument, make an expression.  */
 
-  argvec = (struct expression **) alloca (strlen (cmd)
-                                        * sizeof (struct expression *));
-
-  nargs = 0;
+  std::vector<struct expression *> argvec;
   while (*cmdrest != '\0')
     {
       const char *cmd1;
 
       cmd1 = cmdrest;
       expression_up expr = parse_exp_1 (&cmd1, scope, block_for_pc (scope), 1);
-      argvec[nargs++] = expr.release ();
+      argvec.push_back (expr.release ());
       cmdrest = cmd1;
       if (*cmdrest == ',')
        ++cmdrest;
@@ -2320,7 +2283,7 @@ parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
     {
       aexpr = gen_printf (scope, gdbarch, 0, 0,
                          format_start, format_end - format_start,
-                         fpieces, nargs, argvec);
+                         argvec.size (), argvec.data ());
     }
   CATCH (ex, RETURN_MASK_ERROR)
     {
@@ -2330,8 +2293,6 @@ parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
     }
   END_CATCH
 
-  do_cleanups (old_cleanups);
-
   /* We have a valid agent expression, return it.  */
   return aexpr;
 }
@@ -2482,8 +2443,7 @@ insert_bp_location (struct bp_location *bl,
                    int *hw_breakpoint_error,
                    int *hw_bp_error_explained_already)
 {
-  enum errors bp_err = GDB_NO_ERROR;
-  const char *bp_err_message = NULL;
+  gdb_exception bp_excpt = exception_none;
 
   if (!should_be_inserted (bl) || (bl->inserted && !bl->needs_update))
     return 0;
@@ -2592,12 +2552,11 @@ insert_bp_location (struct bp_location *bl,
 
              val = bl->owner->ops->insert_location (bl);
              if (val)
-               bp_err = GENERIC_ERROR;
+               bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
            }
          CATCH (e, RETURN_MASK_ALL)
            {
-             bp_err = e.error;
-             bp_err_message = e.message;
+             bp_excpt = e;
            }
          END_CATCH
        }
@@ -2632,16 +2591,16 @@ insert_bp_location (struct bp_location *bl,
                      val = target_insert_breakpoint (bl->gdbarch,
                                                      &bl->overlay_target_info);
                      if (val)
-                       bp_err = GENERIC_ERROR;
+                       bp_excpt
+                         = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
                    }
                  CATCH (e, RETURN_MASK_ALL)
                    {
-                     bp_err = e.error;
-                     bp_err_message = e.message;
+                     bp_excpt = e;
                    }
                  END_CATCH
 
-                 if (bp_err != GDB_NO_ERROR)
+                 if (bp_excpt.reason != 0)
                    fprintf_unfiltered (tmp_error_stream,
                                        "Overlay breakpoint %d "
                                        "failed: in ROM?\n",
@@ -2658,12 +2617,11 @@ insert_bp_location (struct bp_location *bl,
 
                  val = bl->owner->ops->insert_location (bl);
                  if (val)
-                   bp_err = GENERIC_ERROR;
+                   bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
                }
              CATCH (e, RETURN_MASK_ALL)
                {
-                 bp_err = e.error;
-                 bp_err_message = e.message;
+                 bp_excpt = e;
                }
              END_CATCH
            }
@@ -2675,7 +2633,7 @@ insert_bp_location (struct bp_location *bl,
            }
        }
 
-      if (bp_err != GDB_NO_ERROR)
+      if (bp_excpt.reason != 0)
        {
          /* Can't set the breakpoint.  */
 
@@ -2687,7 +2645,9 @@ insert_bp_location (struct bp_location *bl,
             breakpoint insertion failed (e.g., the remote target
             doesn't define error codes), so we must treat generic
             errors as memory errors.  */
-         if ((bp_err == GENERIC_ERROR || bp_err == MEMORY_ERROR)
+         if (bp_excpt.reason == RETURN_ERROR
+             && (bp_excpt.error == GENERIC_ERROR
+                 || bp_excpt.error == MEMORY_ERROR)
              && bl->loc_type == bp_loc_software_breakpoint
              && (solib_name_from_address (bl->pspace, bl->address)
                  || shared_objfile_contains_address_p (bl->pspace,
@@ -2695,7 +2655,7 @@ insert_bp_location (struct bp_location *bl,
            {
              /* See also: disable_breakpoints_in_shlibs.  */
              bl->shlib_disabled = 1;
-             observer_notify_breakpoint_modified (bl->owner);
+             gdb::observers::breakpoint_modified.notify (bl->owner);
              if (!*disabled_breaks)
                {
                  fprintf_unfiltered (tmp_error_stream, 
@@ -2715,16 +2675,18 @@ insert_bp_location (struct bp_location *bl,
              if (bl->loc_type == bp_loc_hardware_breakpoint)
                {
                  *hw_breakpoint_error = 1;
-                 *hw_bp_error_explained_already = bp_err_message != NULL;
+                 *hw_bp_error_explained_already = bp_excpt.message != NULL;
                   fprintf_unfiltered (tmp_error_stream,
                                       "Cannot insert hardware breakpoint %d%s",
-                                      bl->owner->number, bp_err_message ? ":" : ".\n");
-                  if (bp_err_message != NULL)
-                    fprintf_unfiltered (tmp_error_stream, "%s.\n", bp_err_message);
+                                      bl->owner->number,
+                                     bp_excpt.message ? ":" : ".\n");
+                  if (bp_excpt.message != NULL)
+                    fprintf_unfiltered (tmp_error_stream, "%s.\n",
+                                       bp_excpt.message);
                }
              else
                {
-                 if (bp_err_message == NULL)
+                 if (bp_excpt.message == NULL)
                    {
                      std::string message
                        = memory_error_message (TARGET_XFER_E_IO,
@@ -2740,7 +2702,7 @@ insert_bp_location (struct bp_location *bl,
                      fprintf_unfiltered (tmp_error_stream,
                                          "Cannot insert breakpoint %d: %s\n",
                                          bl->owner->number,
-                                         bp_err_message);
+                                         bp_excpt.message);
                    }
                }
              return 1;
@@ -3333,7 +3295,7 @@ create_longjmp_master_breakpoint (void)
              /* We are only interested in checking one element.  */
              probe *p = ret[0];
 
-             if (!can_evaluate_probe_arguments (p))
+             if (!p->can_evaluate_arguments ())
                {
                  /* We cannot use the probe interface here, because it does
                     not know how to evaluate arguments.  */
@@ -3353,7 +3315,7 @@ create_longjmp_master_breakpoint (void)
              struct breakpoint *b;
 
              b = create_internal_breakpoint (gdbarch,
-                                             get_probe_address (p, objfile),
+                                             p->get_relocated_address (objfile),
                                              bp_longjmp_master,
                                              &internal_breakpoint_ops);
              b->location = new_probe_location ("-probe-stap libc:longjmp");
@@ -3486,7 +3448,7 @@ create_exception_master_breakpoint (void)
              /* We are only interested in checking one element.  */
              probe *p = ret[0];
 
-             if (!can_evaluate_probe_arguments (p))
+             if (!p->can_evaluate_arguments ())
                {
                  /* We cannot use the probe interface here, because it does
                     not know how to evaluate arguments.  */
@@ -3506,7 +3468,7 @@ create_exception_master_breakpoint (void)
              struct breakpoint *b;
 
              b = create_internal_breakpoint (gdbarch,
-                                             get_probe_address (p, objfile),
+                                             p->get_relocated_address (objfile),
                                              bp_exception_master,
                                              &internal_breakpoint_ops);
              b->location = new_probe_location ("-probe-stap libgcc:unwind");
@@ -4642,8 +4604,7 @@ print_bp_stop_message (bpstat bs)
 static void
 print_solib_event (int is_catchpoint)
 {
-  int any_deleted
-    = !VEC_empty (char_ptr, current_program_space->deleted_solibs);
+  bool any_deleted = !current_program_space->deleted_solibs.empty ();
   int any_added
     = !VEC_empty (so_list_ptr, current_program_space->added_solibs);
 
@@ -4662,16 +4623,12 @@ print_solib_event (int is_catchpoint)
 
   if (any_deleted)
     {
-      char *name;
-      int ix;
-
       current_uiout->text (_("  Inferior unloaded "));
       ui_out_emit_list list_emitter (current_uiout, "removed");
-      for (ix = 0;
-          VEC_iterate (char_ptr, current_program_space->deleted_solibs,
-                       ix, name);
-          ++ix)
+      for (int ix = 0; ix < current_program_space->deleted_solibs.size (); ix++)
        {
+         const std::string &name = current_program_space->deleted_solibs[ix];
+
          if (ix > 0)
            current_uiout->text ("    ");
          current_uiout->field_string ("library", name);
@@ -5364,7 +5321,7 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
       bs->stop = 0;
       /* Increase the hit count even though we don't stop.  */
       ++(b->hit_count);
-      observer_notify_breakpoint_modified (b);
+      gdb::observers::breakpoint_modified.notify (b);
     }  
 }
 
@@ -5519,7 +5476,7 @@ bpstat_stop_status (const address_space *aspace,
          if (bs->stop)
            {
              ++(b->hit_count);
-             observer_notify_breakpoint_modified (b);
+             gdb::observers::breakpoint_modified.notify (b);
 
              /* We will stop here.  */
              if (b->disposition == disp_disable)
@@ -6054,12 +6011,10 @@ bptype_string (enum bptype type)
 static void
 output_thread_groups (struct ui_out *uiout,
                      const char *field_name,
-                     VEC(int) *inf_num,
+                     const std::vector<int> &inf_nums,
                      int mi_only)
 {
   int is_mi = uiout->is_mi_like_p ();
-  int inf;
-  int i;
 
   /* For backward compatibility, don't display inferiors in CLI unless
      there are several.  Always display them for MI. */
@@ -6068,13 +6023,13 @@ output_thread_groups (struct ui_out *uiout,
 
   ui_out_emit_list list_emitter (uiout, field_name);
 
-  for (i = 0; VEC_iterate (int, inf_num, i, inf); ++i)
+  for (size_t i = 0; i < inf_nums.size (); i++)
     {
       if (is_mi)
        {
          char mi_group[10];
 
-         xsnprintf (mi_group, sizeof (mi_group), "i%d", inf);
+         xsnprintf (mi_group, sizeof (mi_group), "i%d", inf_nums[i]);
          uiout->field_string (NULL, mi_group);
        }
       else
@@ -6084,7 +6039,7 @@ output_thread_groups (struct ui_out *uiout,
          else
            uiout->text (", ");
        
-         uiout->text (plongest (inf));
+         uiout->text (plongest (inf_nums[i]));
        }
     }
 }
@@ -6243,13 +6198,13 @@ print_one_breakpoint_location (struct breakpoint *b,
   if (loc != NULL && !header_of_multiple)
     {
       struct inferior *inf;
-      VEC(int) *inf_num = NULL;
+      std::vector<int> inf_nums;
       int mi_only = 1;
 
       ALL_INFERIORS (inf)
        {
          if (inf->pspace == loc->pspace)
-           VEC_safe_push (int, inf_num, inf->num);
+           inf_nums.push_back (inf->num);
        }
 
         /* For backward compatibility, don't display inferiors in CLI unless
@@ -6262,8 +6217,7 @@ print_one_breakpoint_location (struct breakpoint *b,
                   moribund_locations and thus having NULL OWNER.  */
                && loc->owner->type != bp_catchpoint))
        mi_only = 0;
-      output_thread_groups (uiout, "thread-groups", inf_num, mi_only);
-      VEC_free (int, inf_num);
+      output_thread_groups (uiout, "thread-groups", inf_nums, mi_only);
     }
 
   if (!part_of_multiple)
@@ -6714,7 +6668,7 @@ default_collect_info (void)
 }
   
 static void
-info_breakpoints_command (char *args, int from_tty)
+info_breakpoints_command (const char *args, int from_tty)
 {
   breakpoint_1 (args, 0, NULL);
 
@@ -6722,7 +6676,7 @@ info_breakpoints_command (char *args, int from_tty)
 }
 
 static void
-info_watchpoints_command (char *args, int from_tty)
+info_watchpoints_command (const char *args, int from_tty)
 {
   int num_printed = breakpoint_1 (args, 0, is_watchpoint);
   struct ui_out *uiout = current_uiout;
@@ -7014,16 +6968,11 @@ static CORE_ADDR
 adjust_breakpoint_address (struct gdbarch *gdbarch,
                           CORE_ADDR bpaddr, enum bptype bptype)
 {
-  if (!gdbarch_adjust_breakpoint_address_p (gdbarch))
-    {
-      /* Very few targets need any kind of breakpoint adjustment.  */
-      return bpaddr;
-    }
-  else if (bptype == bp_watchpoint
-           || bptype == bp_hardware_watchpoint
-           || bptype == bp_read_watchpoint
-           || bptype == bp_access_watchpoint
-           || bptype == bp_catchpoint)
+  if (bptype == bp_watchpoint
+      || bptype == bp_hardware_watchpoint
+      || bptype == bp_read_watchpoint
+      || bptype == bp_access_watchpoint
+      || bptype == bp_catchpoint)
     {
       /* Watchpoints and the various bp_catch_* eventpoints should not
          have their addresses modified.  */
@@ -7041,11 +6990,16 @@ adjust_breakpoint_address (struct gdbarch *gdbarch,
     }
   else
     {
-      CORE_ADDR adjusted_bpaddr;
+      CORE_ADDR adjusted_bpaddr = bpaddr;
 
-      /* Some targets have architectural constraints on the placement
-         of breakpoint instructions.  Obtain the adjusted address.  */
-      adjusted_bpaddr = gdbarch_adjust_breakpoint_address (gdbarch, bpaddr);
+      if (gdbarch_adjust_breakpoint_address_p (gdbarch))
+       {
+         /* Some targets have architectural constraints on the placement
+            of breakpoint instructions.  Obtain the adjusted address.  */
+         adjusted_bpaddr = gdbarch_adjust_breakpoint_address (gdbarch, bpaddr);
+       }
+
+      adjusted_bpaddr = address_significant (gdbarch, adjusted_bpaddr);
 
       /* An adjusted breakpoint address can significantly alter
          a user's expectations.  Print a warning if an adjustment
@@ -7685,7 +7639,7 @@ disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
        loc->inserted = 0;
 
        /* This may cause duplicate notifications for the same breakpoint.  */
-       observer_notify_breakpoint_modified (b);
+       gdb::observers::breakpoint_modified.notify (b);
 
        if (!disabled_shlib_breaks)
          {
@@ -7768,7 +7722,7 @@ disable_breakpoints_in_freed_objfile (struct objfile *objfile)
        }
 
       if (bp_modified)
-       observer_notify_breakpoint_modified (b);
+       gdb::observers::breakpoint_modified.notify (b);
     }
 }
 
@@ -8091,13 +8045,12 @@ check_status_catch_solib (struct bpstats *bs)
 {
   struct solib_catchpoint *self
     = (struct solib_catchpoint *) bs->breakpoint_at;
-  int ix;
 
   if (self->is_load)
     {
       struct so_list *iter;
 
-      for (ix = 0;
+      for (int ix = 0;
           VEC_iterate (so_list_ptr, current_program_space->added_solibs,
                        ix, iter);
           ++ix)
@@ -8109,15 +8062,10 @@ check_status_catch_solib (struct bpstats *bs)
     }
   else
     {
-      char *iter;
-
-      for (ix = 0;
-          VEC_iterate (char_ptr, current_program_space->deleted_solibs,
-                       ix, iter);
-          ++ix)
+      for (const std::string &iter : current_program_space->deleted_solibs)
        {
          if (!self->regex
-             || self->compiled->exec (iter, 0, NULL, 0) == 0)
+             || self->compiled->exec (iter.c_str (), 0, NULL, 0) == 0)
            return;
        }
     }
@@ -8248,7 +8196,7 @@ add_solib_catchpoint (const char *arg, int is_load, int is_temp, int enabled)
    "catch unload".  */
 
 static void
-catch_load_or_unload (char *arg, int from_tty, int is_load,
+catch_load_or_unload (const char *arg, int from_tty, int is_load,
                      struct cmd_list_element *command)
 {
   int tempflag;
@@ -8260,14 +8208,14 @@ catch_load_or_unload (char *arg, int from_tty, int is_load,
 }
 
 static void
-catch_load_command_1 (char *arg, int from_tty,
+catch_load_command_1 (const char *arg, int from_tty,
                      struct cmd_list_element *command)
 {
   catch_load_or_unload (arg, from_tty, 1, command);
 }
 
 static void
-catch_unload_command_1 (char *arg, int from_tty,
+catch_unload_command_1 (const char *arg, int from_tty,
                        struct cmd_list_element *command)
 {
   catch_load_or_unload (arg, from_tty, 0, command);
@@ -8302,7 +8250,7 @@ install_breakpoint (int internal, std::unique_ptr<breakpoint> &&arg, int update_
     set_tracepoint_count (breakpoint_count);
   if (!internal)
     mention (b);
-  observer_notify_breakpoint_created (b);
+  gdb::observers::breakpoint_created.notify (b);
 
   if (update_gll)
     update_global_location_list (UGLL_MAY_INSERT);
@@ -8718,7 +8666,7 @@ add_location_to_breakpoint (struct breakpoint *b,
   loc->requested_address = sal->pc;
   loc->address = adjusted_address;
   loc->pspace = sal->pspace;
-  loc->probe.probe = sal->probe;
+  loc->probe.prob = sal->prob;
   loc->probe.objfile = sal->objfile;
   gdb_assert (loc->pspace != NULL);
   loc->section = sal->section;
@@ -8875,7 +8823,7 @@ update_dprintf_command_list (struct breakpoint *b)
    current style settings.  */
 
 static void
-update_dprintf_commands (char *args, int from_tty,
+update_dprintf_commands (const char *args, int from_tty,
                         struct cmd_list_element *c)
 {
   struct breakpoint *b;
@@ -8964,27 +8912,24 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
                  const char *p
                    = &event_location_to_string (b->location.get ())[3];
                  const char *endp;
-                 char *marker_str;
 
                  p = skip_spaces (p);
 
                  endp = skip_to_space (p);
 
-                 marker_str = savestring (p, endp - p);
-                 t->static_trace_marker_id = marker_str;
+                 t->static_trace_marker_id.assign (p, endp - p);
 
                  printf_filtered (_("Probed static tracepoint "
                                     "marker \"%s\"\n"),
-                                  t->static_trace_marker_id);
+                                  t->static_trace_marker_id.c_str ());
                }
              else if (target_static_tracepoint_marker_at (sal.pc, &marker))
                {
-                 t->static_trace_marker_id = xstrdup (marker.str_id);
-                 release_static_tracepoint_marker (&marker);
+                 t->static_trace_marker_id = std::move (marker.str_id);
 
                  printf_filtered (_("Probed static tracepoint "
                                     "marker \"%s\"\n"),
-                                  t->static_trace_marker_id);
+                                  t->static_trace_marker_id.c_str ());
                }
              else
                warning (_("Couldn't determine the static "
@@ -9126,9 +9071,9 @@ parse_breakpoint_sals (const struct event_location *location,
 
   if (event_location_type (location) == LINESPEC_LOCATION)
     {
-      const char *address = get_linespec_location (location);
+      const char *spec = get_linespec_location (location)->spec_string;
 
-      if (address == NULL)
+      if (spec == NULL)
        {
          /* The last displayed codepoint, if it's valid, is our default
             breakpoint address.  */
@@ -9174,15 +9119,15 @@ parse_breakpoint_sals (const struct event_location *location,
   cursal = get_current_source_symtab_and_line ();
   if (last_displayed_sal_is_valid ())
     {
-      const char *address = NULL;
+      const char *spec = NULL;
 
       if (event_location_type (location) == LINESPEC_LOCATION)
-       address = get_linespec_location (location);
+       spec = get_linespec_location (location)->spec_string;
 
       if (!cursal.symtab
-         || (address != NULL
-             && strchr ("+-", address[0]) != NULL
-             && address[1] != '['))
+         || (spec != NULL
+             && strchr ("+-", spec[0]) != NULL
+             && spec[1] != '['))
        {
          decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, NULL,
                            get_last_displayed_symtab (),
@@ -9218,10 +9163,6 @@ static void
 check_fast_tracepoint_sals (struct gdbarch *gdbarch,
                            gdb::array_view<const symtab_and_line> sals)
 {
-  int rslt;
-  char *msg;
-  struct cleanup *old_chain;
-
   for (const auto &sal : sals)
     {
       struct gdbarch *sarch;
@@ -9231,14 +9172,10 @@ check_fast_tracepoint_sals (struct gdbarch *gdbarch,
         associated with SAL.  */
       if (sarch == NULL)
        sarch = gdbarch;
-      rslt = gdbarch_fast_tracepoint_valid_at (sarch, sal.pc, &msg);
-      old_chain = make_cleanup (xfree, msg);
-
-      if (!rslt)
+      std::string msg;
+      if (!gdbarch_fast_tracepoint_valid_at (sarch, sal.pc, &msg))
        error (_("May not have a fast tracepoint at %s%s"),
-              paddress (sarch, sal.pc), (msg ? msg : ""));
-
-      do_cleanups (old_chain);
+              paddress (sarch, sal.pc), msg.c_str ());
     }
 }
 
@@ -9324,10 +9261,8 @@ find_condition_and_thread (const char *tok, CORE_ADDR pc,
 static std::vector<symtab_and_line>
 decode_static_tracepoint_spec (const char **arg_p)
 {
-  VEC(static_tracepoint_marker_p) *markers = NULL;
   const char *p = &(*arg_p)[3];
   const char *endp;
-  int i;
 
   p = skip_spaces (p);
 
@@ -9335,26 +9270,21 @@ decode_static_tracepoint_spec (const char **arg_p)
 
   std::string marker_str (p, endp - p);
 
-  markers = target_static_tracepoint_markers_by_strid (marker_str.c_str ());
-  if (VEC_empty(static_tracepoint_marker_p, markers))
+  std::vector<static_tracepoint_marker> markers
+    = target_static_tracepoint_markers_by_strid (marker_str.c_str ());
+  if (markers.empty ())
     error (_("No known static tracepoint marker named %s"),
           marker_str.c_str ());
 
   std::vector<symtab_and_line> sals;
-  sals.reserve (VEC_length(static_tracepoint_marker_p, markers));
+  sals.reserve (markers.size ());
 
-  for (i = 0; i < VEC_length(static_tracepoint_marker_p, markers); i++)
+  for (const static_tracepoint_marker &marker : markers)
     {
-      struct static_tracepoint_marker *marker;
-
-      marker = VEC_index (static_tracepoint_marker_p, markers, i);
-
-      symtab_and_line sal = find_pc_line (marker->address, 0);
-      sal.pc = marker->address;
+      symtab_and_line sal = find_pc_line (marker.address, 0);
+      sal.pc = marker.address;
       sals.push_back (sal);
-
-      release_static_tracepoint_marker (marker);
-    }
+   }
 
   *arg_p = endp;
   return sals;
@@ -9634,31 +9564,31 @@ resolve_sal_pc (struct symtab_and_line *sal)
 }
 
 void
-break_command (char *arg, int from_tty)
+break_command (const char *arg, int from_tty)
 {
   break_command_1 (arg, 0, from_tty);
 }
 
 void
-tbreak_command (char *arg, int from_tty)
+tbreak_command (const char *arg, int from_tty)
 {
   break_command_1 (arg, BP_TEMPFLAG, from_tty);
 }
 
 static void
-hbreak_command (char *arg, int from_tty)
+hbreak_command (const char *arg, int from_tty)
 {
   break_command_1 (arg, BP_HARDWAREFLAG, from_tty);
 }
 
 static void
-thbreak_command (char *arg, int from_tty)
+thbreak_command (const char *arg, int from_tty)
 {
   break_command_1 (arg, (BP_TEMPFLAG | BP_HARDWAREFLAG), from_tty);
 }
 
 static void
-stop_command (char *arg, int from_tty)
+stop_command (const char *arg, int from_tty)
 {
   printf_filtered (_("Specify the type of breakpoint to set.\n\
 Usage: stop in <function | address>\n\
@@ -9736,9 +9666,8 @@ stopat_command (const char *arg, int from_tty)
    line.  */
 
 static void
-dprintf_command (char *arg_in, int from_tty)
+dprintf_command (const char *arg, int from_tty)
 {
-  const char *arg = arg_in;
   event_location_up location = string_to_event_location (&arg, current_language);
 
   /* If non-NULL, ARG should have been advanced past the location;
@@ -9768,7 +9697,7 @@ dprintf_command (char *arg_in, int from_tty)
 }
 
 static void
-agent_printf_command (char *arg, int from_tty)
+agent_printf_command (const char *arg, int from_tty)
 {
   error (_("May only run agent-printf on the target"));
 }
@@ -9952,9 +9881,8 @@ find_breakpoint_range_end (struct symtab_and_line sal)
 /* Implement the "break-range" CLI command.  */
 
 static void
-break_range_command (char *arg_in, int from_tty)
+break_range_command (const char *arg, int from_tty)
 {
-  const char *arg = arg_in;
   const char *arg_start;
   struct linespec_result canonical_start, canonical_end;
   int bp_count, can_use_bp, length;
@@ -10051,7 +9979,7 @@ break_range_command (char *arg_in, int from_tty)
   b->loc->length = length;
 
   mention (b);
-  observer_notify_breakpoint_created (b);
+  gdb::observers::breakpoint_created.notify (b);
   update_global_location_list (UGLL_MAY_INSERT);
 }
 
@@ -10760,7 +10688,7 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
   /* Parse the rest of the arguments.  From here on out, everything
      is in terms of a newly allocated string instead of the original
      ARG.  */
-  innermost_block = NULL;
+  innermost_block.reset ();
   std::string expression (arg, exp_end - arg);
   exp_start = arg = expression.c_str ();
   expression_up exp = parse_exp_1 (&arg, 0, 0, 0);
@@ -10782,7 +10710,7 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
       error (_("Cannot watch constant value `%.*s'."), len, exp_start);
     }
 
-  exp_valid_block = innermost_block;
+  exp_valid_block = innermost_block.block ();
   mark = value_mark ();
   fetch_subexp_value (exp.get (), &pc, &val, &result, NULL, just_location);
 
@@ -10820,13 +10748,13 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
   toklen = end_tok - tok;
   if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
     {
-      innermost_block = NULL;
+      innermost_block.reset ();
       tok = cond_start = end_tok + 1;
       parse_exp_1 (&tok, 0, 0, 0);
 
       /* The watchpoint expression may not be local, but the condition
         may still be.  E.g.: `watch global if local > 0'.  */
-      cond_exp_valid_block = innermost_block;
+      cond_exp_valid_block = innermost_block.block ();
 
       cond_end = tok;
     }
@@ -11058,7 +10986,7 @@ watch_command_wrapper (const char *arg, int from_tty, int internal)
    calls watch_command_1.  */
 
 static void
-watch_maybe_just_location (char *arg, int accessflag, int from_tty)
+watch_maybe_just_location (const char *arg, int accessflag, int from_tty)
 {
   int just_location = 0;
 
@@ -11074,7 +11002,7 @@ watch_maybe_just_location (char *arg, int accessflag, int from_tty)
 }
 
 static void
-watch_command (char *arg, int from_tty)
+watch_command (const char *arg, int from_tty)
 {
   watch_maybe_just_location (arg, hw_write, from_tty);
 }
@@ -11086,7 +11014,7 @@ rwatch_command_wrapper (const char *arg, int from_tty, int internal)
 }
 
 static void
-rwatch_command (char *arg, int from_tty)
+rwatch_command (const char *arg, int from_tty)
 {
   watch_maybe_just_location (arg, hw_read, from_tty);
 }
@@ -11098,7 +11026,7 @@ awatch_command_wrapper (const char *arg, int from_tty, int internal)
 }
 
 static void
-awatch_command (char *arg, int from_tty)
+awatch_command (const char *arg, int from_tty)
 {
   watch_maybe_just_location (arg, hw_access, from_tty);
 }
@@ -11352,10 +11280,9 @@ typedef enum
 catch_fork_kind;
 
 static void
-catch_fork_command_1 (char *arg_entry, int from_tty,
+catch_fork_command_1 (const char *arg, int from_tty,
                      struct cmd_list_element *command)
 {
-  const char *arg = arg_entry;
   struct gdbarch *gdbarch = get_current_arch ();
   const char *cond_string = NULL;
   catch_fork_kind fork_kind;
@@ -11400,10 +11327,9 @@ catch_fork_command_1 (char *arg_entry, int from_tty,
 }
 
 static void
-catch_exec_command_1 (char *arg_entry, int from_tty,
+catch_exec_command_1 (const char *arg, int from_tty,
                      struct cmd_list_element *command)
 {
-  const char *arg = arg_entry;
   struct gdbarch *gdbarch = get_current_arch ();
   int tempflag;
   const char *cond_string = NULL;
@@ -11505,11 +11431,10 @@ compare_breakpoints (const breakpoint *a, const breakpoint *b)
 /* Delete breakpoints by address or line.  */
 
 static void
-clear_command (char *arg, int from_tty)
+clear_command (const char *arg, int from_tty)
 {
   struct breakpoint *b;
   int default_match;
-  int i;
 
   std::vector<symtab_and_line> decoded_sals;
   symtab_and_line last_sal;
@@ -11809,7 +11734,7 @@ download_tracepoint_locations (void)
       t = (struct tracepoint *) b;
       t->number_on_target = b->number;
       if (bp_location_downloaded)
-       observer_notify_breakpoint_modified (b);
+       gdb::observers::breakpoint_modified.notify (b);
     }
 }
 
@@ -12907,10 +12832,7 @@ bkpt_probe_insert_location (struct bp_location *bl)
     {
       /* The insertion was successful, now let's set the probe's semaphore
         if needed.  */
-      if (bl->probe.probe->pops->set_semaphore != NULL)
-       bl->probe.probe->pops->set_semaphore (bl->probe.probe,
-                                             bl->probe.objfile,
-                                             bl->gdbarch);
+      bl->probe.prob->set_semaphore (bl->probe.objfile, bl->gdbarch);
     }
 
   return v;
@@ -12921,10 +12843,7 @@ bkpt_probe_remove_location (struct bp_location *bl,
                            enum remove_bp_reason reason)
 {
   /* Let's clear the semaphore before removing the location.  */
-  if (bl->probe.probe->pops->clear_semaphore != NULL)
-    bl->probe.probe->pops->clear_semaphore (bl->probe.probe,
-                                           bl->probe.objfile,
-                                           bl->gdbarch);
+  bl->probe.prob->clear_semaphore (bl->probe.objfile, bl->gdbarch);
 
   return bkpt_remove_location (bl, reason);
 }
@@ -12976,7 +12895,7 @@ tracepoint_print_one_detail (const struct breakpoint *self,
                             struct ui_out *uiout)
 {
   struct tracepoint *tp = (struct tracepoint *) self;
-  if (tp->static_trace_marker_id)
+  if (!tp->static_trace_marker_id.empty ())
     {
       gdb_assert (self->type == bp_static_tracepoint);
 
@@ -13183,12 +13102,13 @@ strace_marker_create_sals_from_location (const struct event_location *location,
   struct linespec_sals lsal;
   const char *arg_start, *arg;
 
-  arg = arg_start = get_linespec_location (location);
+  arg = arg_start = get_linespec_location (location)->spec_string;
   lsal.sals = decode_static_tracepoint_spec (&arg);
 
   std::string str (arg_start, arg - arg_start);
   const char *ptr = str.c_str ();
-  canonical->location = new_linespec_location (&ptr);
+  canonical->location
+    = new_linespec_location (&ptr, symbol_name_match_type::FULL);
 
   lsal.canonical
     = xstrdup (event_location_to_string (canonical->location.get ()));
@@ -13249,7 +13169,7 @@ strace_marker_decode_location (struct breakpoint *b,
                               struct program_space *search_pspace)
 {
   struct tracepoint *tp = (struct tracepoint *) b;
-  const char *s = get_linespec_location (location);
+  const char *s = get_linespec_location (location)->spec_string;
 
   std::vector<symtab_and_line> sals = decode_static_tracepoint_spec (&s);
   if (sals.size () > tp->static_trace_marker_id_idx)
@@ -13259,7 +13179,7 @@ strace_marker_decode_location (struct breakpoint *b,
       return sals;
     }
   else
-    error (_("marker %s not found"), tp->static_trace_marker_id);
+    error (_("marker %s not found"), tp->static_trace_marker_id.c_str ());
 }
 
 static struct breakpoint_ops strace_marker_breakpoint_ops;
@@ -13327,7 +13247,7 @@ delete_breakpoint (struct breakpoint *bpt)
      a problem in that process, we'll be asked to delete the half-created
      watchpoint.  In that case, don't announce the deletion.  */
   if (bpt->number)
-    observer_notify_breakpoint_deleted (bpt);
+    gdb::observers::breakpoint_deleted.notify (bpt);
 
   if (breakpoint_chain == bpt)
     breakpoint_chain = bpt->next;
@@ -13540,14 +13460,12 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
 
   if (target_static_tracepoint_marker_at (pc, &marker))
     {
-      if (strcmp (tp->static_trace_marker_id, marker.str_id) != 0)
+      if (tp->static_trace_marker_id != marker.str_id)
        warning (_("static tracepoint %d changed probed marker from %s to %s"),
-                b->number,
-                tp->static_trace_marker_id, marker.str_id);
+                b->number, tp->static_trace_marker_id.c_str (),
+                marker.str_id.c_str ());
 
-      xfree (tp->static_trace_marker_id);
-      tp->static_trace_marker_id = xstrdup (marker.str_id);
-      release_static_tracepoint_marker (&marker);
+      tp->static_trace_marker_id = std::move (marker.str_id);
 
       return sal;
     }
@@ -13557,28 +13475,26 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
   if (!sal.explicit_pc
       && sal.line != 0
       && sal.symtab != NULL
-      && tp->static_trace_marker_id != NULL)
+      && !tp->static_trace_marker_id.empty ())
     {
-      VEC(static_tracepoint_marker_p) *markers;
-
-      markers
-       = target_static_tracepoint_markers_by_strid (tp->static_trace_marker_id);
+      std::vector<static_tracepoint_marker> markers
+       = target_static_tracepoint_markers_by_strid
+           (tp->static_trace_marker_id.c_str ());
 
-      if (!VEC_empty(static_tracepoint_marker_p, markers))
+      if (!markers.empty ())
        {
          struct symbol *sym;
          struct static_tracepoint_marker *tpmarker;
          struct ui_out *uiout = current_uiout;
          struct explicit_location explicit_loc;
 
-         tpmarker = VEC_index (static_tracepoint_marker_p, markers, 0);
+         tpmarker = &markers[0];
 
-         xfree (tp->static_trace_marker_id);
-         tp->static_trace_marker_id = xstrdup (tpmarker->str_id);
+         tp->static_trace_marker_id = std::move (tpmarker->str_id);
 
          warning (_("marker for static tracepoint %d (%s) not "
                     "found at previous line number"),
-                  b->number, tp->static_trace_marker_id);
+                  b->number, tp->static_trace_marker_id.c_str ());
 
          symtab_and_line sal2 = find_pc_line (tpmarker->address, 0);
          sym = find_pc_sect_function (tpmarker->address, NULL);
@@ -13615,8 +13531,6 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
 
          /* Might be nice to check if function changed, and warn if
             so.  */
-
-         release_static_tracepoint_marker (tpmarker);
        }
     }
   return sal;
@@ -13699,7 +13613,6 @@ update_breakpoint_locations (struct breakpoint *b,
                             gdb::array_view<const symtab_and_line> sals,
                             gdb::array_view<const symtab_and_line> sals_end)
 {
-  int i;
   struct bp_location *existing_locations;
 
   if (!sals_end.empty () && (sals.size () != 1 || sals_end.size () != 1))
@@ -13803,7 +13716,7 @@ update_breakpoint_locations (struct breakpoint *b,
   }
 
   if (!locations_are_equal (existing_locations, b->loc))
-    observer_notify_breakpoint_modified (b);
+    gdb::observers::breakpoint_modified.notify (b);
 }
 
 /* Find the SaL locations corresponding to the given LOCATION.
@@ -14100,7 +14013,7 @@ set_ignore_count (int bptnum, int count, int from_tty)
                               "crossings of breakpoint %d."),
                             count, bptnum);
        }
-      observer_notify_breakpoint_modified (b);
+      gdb::observers::breakpoint_modified.notify (b);
       return;
     }
 
@@ -14110,9 +14023,9 @@ set_ignore_count (int bptnum, int count, int from_tty)
 /* Command to set ignore-count of breakpoint N to COUNT.  */
 
 static void
-ignore_command (char *args, int from_tty)
+ignore_command (const char *args, int from_tty)
 {
-  char *p = args;
+  const char *p = args;
   int num;
 
   if (p == 0)
@@ -14131,59 +14044,66 @@ ignore_command (char *args, int from_tty)
     printf_filtered ("\n");
 }
 \f
-/* Call FUNCTION on each of the breakpoints
-   whose numbers are given in ARGS.  */
+
+/* Call FUNCTION on each of the breakpoints with numbers in the range
+   defined by BP_NUM_RANGE (an inclusive range).  */
 
 static void
-map_breakpoint_numbers (const char *args,
-                       gdb::function_view<void (breakpoint *)> function)
+map_breakpoint_number_range (std::pair<int, int> bp_num_range,
+                            gdb::function_view<void (breakpoint *)> function)
 {
-  int num;
-  struct breakpoint *b, *tmp;
-
-  if (args == 0 || *args == '\0')
-    error_no_arg (_("one or more breakpoint numbers"));
-
-  number_or_range_parser parser (args);
-
-  while (!parser.finished ())
+  if (bp_num_range.first == 0)
     {
-      const char *p = parser.cur_tok ();
-      bool match = false;
+      warning (_("bad breakpoint number at or near '%d'"),
+              bp_num_range.first);
+    }
+  else
+    {
+      struct breakpoint *b, *tmp;
 
-      num = parser.get_number ();
-      if (num == 0)
-       {
-         warning (_("bad breakpoint number at or near '%s'"), p);
-       }
-      else
+      for (int i = bp_num_range.first; i <= bp_num_range.second; i++)
        {
+         bool match = false;
+
          ALL_BREAKPOINTS_SAFE (b, tmp)
-           if (b->number == num)
+           if (b->number == i)
              {
                match = true;
                function (b);
                break;
              }
          if (!match)
-           printf_unfiltered (_("No breakpoint number %d.\n"), num);
+           printf_unfiltered (_("No breakpoint number %d.\n"), i);
        }
     }
 }
 
+/* Call FUNCTION on each of the breakpoints whose numbers are given in
+   ARGS.  */
+
+static void
+map_breakpoint_numbers (const char *args,
+                       gdb::function_view<void (breakpoint *)> function)
+{
+  if (args == NULL || *args == '\0')
+    error_no_arg (_("one or more breakpoint numbers"));
+
+  number_or_range_parser parser (args);
+
+  while (!parser.finished ())
+    {
+      int num = parser.get_number ();
+      map_breakpoint_number_range (std::make_pair (num, num), function);
+    }
+}
+
+/* Return the breakpoint location structure corresponding to the
+   BP_NUM and LOC_NUM values.  */
+
 static struct bp_location *
-find_location_by_number (const char *number)
+find_location_by_number (int bp_num, int loc_num)
 {
-  const char *p1;
-  int bp_num;
-  int loc_num;
   struct breakpoint *b;
-  struct bp_location *loc;  
-
-  p1 = number;
-  bp_num = get_number_trailer (&p1, '.');
-  if (bp_num == 0 || p1[0] != '.')
-    error (_("Bad breakpoint number '%s'"), number);
 
   ALL_BREAKPOINTS (b)
     if (b->number == bp_num)
@@ -14192,25 +14112,180 @@ find_location_by_number (const char *number)
       }
 
   if (!b || b->number != bp_num)
-    error (_("Bad breakpoint number '%s'"), number);
+    error (_("Bad breakpoint number '%d'"), bp_num);
   
-  /* Skip the dot.  */
-  ++p1;
-  const char *save = p1;
-  loc_num = get_number (&p1);
   if (loc_num == 0)
-    error (_("Bad breakpoint location number '%s'"), number);
+    error (_("Bad breakpoint location number '%d'"), loc_num);
 
-  --loc_num;
-  loc = b->loc;
-  for (;loc_num && loc; --loc_num, loc = loc->next)
-    ;
-  if (!loc)
-    error (_("Bad breakpoint location number '%s'"), save);
-    
-  return loc;  
+  int n = 0;
+  for (bp_location *loc = b->loc; loc != NULL; loc = loc->next)
+    if (++n == loc_num)
+      return loc;
+
+  error (_("Bad breakpoint location number '%d'"), loc_num);
 }
 
+/* Modes of operation for extract_bp_num.  */
+enum class extract_bp_kind
+{
+  /* Extracting a breakpoint number.  */
+  bp,
+
+  /* Extracting a location number.  */
+  loc,
+};
+
+/* Extract a breakpoint or location number (as determined by KIND)
+   from the string starting at START.  TRAILER is a character which
+   can be found after the number.  If you don't want a trailer, use
+   '\0'.  If END_OUT is not NULL, it is set to point after the parsed
+   string.  This always returns a positive integer.  */
+
+static int
+extract_bp_num (extract_bp_kind kind, const char *start,
+               int trailer, const char **end_out = NULL)
+{
+  const char *end = start;
+  int num = get_number_trailer (&end, trailer);
+  if (num < 0)
+    error (kind == extract_bp_kind::bp
+          ? _("Negative breakpoint number '%.*s'")
+          : _("Negative breakpoint location number '%.*s'"),
+          int (end - start), start);
+  if (num == 0)
+    error (kind == extract_bp_kind::bp
+          ? _("Bad breakpoint number '%.*s'")
+          : _("Bad breakpoint location number '%.*s'"),
+          int (end - start), start);
+
+  if (end_out != NULL)
+    *end_out = end;
+  return num;
+}
+
+/* Extract a breakpoint or location range (as determined by KIND) in
+   the form NUM1-NUM2 stored at &ARG[arg_offset].  Returns a std::pair
+   representing the (inclusive) range.  The returned pair's elements
+   are always positive integers.  */
+
+static std::pair<int, int>
+extract_bp_or_bp_range (extract_bp_kind kind,
+                       const std::string &arg,
+                       std::string::size_type arg_offset)
+{
+  std::pair<int, int> range;
+  const char *bp_loc = &arg[arg_offset];
+  std::string::size_type dash = arg.find ('-', arg_offset);
+  if (dash != std::string::npos)
+    {
+      /* bp_loc is a range (x-z).  */
+      if (arg.length () == dash + 1)
+       error (kind == extract_bp_kind::bp
+              ? _("Bad breakpoint number at or near: '%s'")
+              : _("Bad breakpoint location number at or near: '%s'"),
+              bp_loc);
+
+      const char *end;
+      const char *start_first = bp_loc;
+      const char *start_second = &arg[dash + 1];
+      range.first = extract_bp_num (kind, start_first, '-');
+      range.second = extract_bp_num (kind, start_second, '\0', &end);
+
+      if (range.first > range.second)
+       error (kind == extract_bp_kind::bp
+              ? _("Inverted breakpoint range at '%.*s'")
+              : _("Inverted breakpoint location range at '%.*s'"),
+              int (end - start_first), start_first);
+    }
+  else
+    {
+      /* bp_loc is a single value.  */
+      range.first = extract_bp_num (kind, bp_loc, '\0');
+      range.second = range.first;
+    }
+  return range;
+}
+
+/* Extract the breakpoint/location range specified by ARG.  Returns
+   the breakpoint range in BP_NUM_RANGE, and the location range in
+   BP_LOC_RANGE.
+
+   ARG may be in any of the following forms:
+
+   x     where 'x' is a breakpoint number.
+   x-y   where 'x' and 'y' specify a breakpoint numbers range.
+   x.y   where 'x' is a breakpoint number and 'y' a location number.
+   x.y-z where 'x' is a breakpoint number and 'y' and 'z' specify a
+        location number range.
+*/
+
+static void
+extract_bp_number_and_location (const std::string &arg,
+                               std::pair<int, int> &bp_num_range,
+                               std::pair<int, int> &bp_loc_range)
+{
+  std::string::size_type dot = arg.find ('.');
+
+  if (dot != std::string::npos)
+    {
+      /* Handle 'x.y' and 'x.y-z' cases.  */
+
+      if (arg.length () == dot + 1 || dot == 0)
+       error (_("Bad breakpoint number at or near: '%s'"), arg.c_str ());
+
+      bp_num_range.first
+       = extract_bp_num (extract_bp_kind::bp, arg.c_str (), '.');
+      bp_num_range.second = bp_num_range.first;
+
+      bp_loc_range = extract_bp_or_bp_range (extract_bp_kind::loc,
+                                            arg, dot + 1);
+    }
+  else
+    {
+      /* Handle x and x-y cases.  */
+
+      bp_num_range = extract_bp_or_bp_range (extract_bp_kind::bp, arg, 0);
+      bp_loc_range.first = 0;
+      bp_loc_range.second = 0;
+    }
+}
+
+/* Enable or disable a breakpoint location BP_NUM.LOC_NUM.  ENABLE
+   specifies whether to enable or disable.  */
+
+static void
+enable_disable_bp_num_loc (int bp_num, int loc_num, bool enable)
+{
+  struct bp_location *loc = find_location_by_number (bp_num, loc_num);
+  if (loc != NULL)
+    {
+      if (loc->enabled != enable)
+       {
+         loc->enabled = enable;
+         mark_breakpoint_location_modified (loc);
+       }
+      if (target_supports_enable_disable_tracepoint ()
+         && current_trace_status ()->running && loc->owner
+         && is_tracepoint (loc->owner))
+       target_disable_tracepoint (loc);
+    }
+  update_global_location_list (UGLL_DONT_INSERT);
+}
+
+/* Enable or disable a range of breakpoint locations.  BP_NUM is the
+   number of the breakpoint, and BP_LOC_RANGE specifies the
+   (inclusive) range of location numbers of that breakpoint to
+   enable/disable.  ENABLE specifies whether to enable or disable the
+   location.  */
+
+static void
+enable_disable_breakpoint_location_range (int bp_num,
+                                         std::pair<int, int> &bp_loc_range,
+                                         bool enable)
+{
+  for (int i = bp_loc_range.first; i <= bp_loc_range.second; i++)
+    enable_disable_bp_num_loc (bp_num, i, enable);
+}
 
 /* Set ignore-count of breakpoint number BPTNUM to COUNT.
    If from_tty is nonzero, it prints a message to that effect,
@@ -14241,11 +14316,16 @@ disable_breakpoint (struct breakpoint *bpt)
 
   update_global_location_list (UGLL_DONT_INSERT);
 
-  observer_notify_breakpoint_modified (bpt);
+  gdb::observers::breakpoint_modified.notify (bpt);
 }
 
+/* Enable or disable the breakpoint(s) or breakpoint location(s)
+   specified in ARGS.  ARGS may be in any of the formats handled by
+   extract_bp_number_and_location.  ENABLE specifies whether to enable
+   or disable the breakpoints/locations.  */
+
 static void
-disable_command (const char *args, int from_tty)
+enable_disable_command (const char *args, int from_tty, bool enable)
 {
   if (args == 0)
     {
@@ -14253,7 +14333,12 @@ disable_command (const char *args, int from_tty)
 
       ALL_BREAKPOINTS (bpt)
        if (user_breakpoint_p (bpt))
-         disable_breakpoint (bpt);
+         {
+           if (enable)
+             enable_breakpoint (bpt);
+           else
+             disable_breakpoint (bpt);
+         }
     }
   else
     {
@@ -14261,35 +14346,42 @@ disable_command (const char *args, int from_tty)
 
       while (!num.empty ())
        {
-         if (num.find ('.') != std::string::npos)
-           {
-             struct bp_location *loc = find_location_by_number (num.c_str ());
+         std::pair<int, int> bp_num_range, bp_loc_range;
 
-             if (loc)
-               {
-                 if (loc->enabled)
-                   {
-                     loc->enabled = 0;
-                     mark_breakpoint_location_modified (loc);
-                   }
-                 if (target_supports_enable_disable_tracepoint ()
-                     && current_trace_status ()->running && loc->owner
-                     && is_tracepoint (loc->owner))
-                   target_disable_tracepoint (loc);
-               }
-             update_global_location_list (UGLL_DONT_INSERT);
+         extract_bp_number_and_location (num, bp_num_range, bp_loc_range);
+
+         if (bp_loc_range.first == bp_loc_range.second
+             && bp_loc_range.first == 0)
+           {
+             /* Handle breakpoint ids with formats 'x' or 'x-z'.  */
+             map_breakpoint_number_range (bp_num_range,
+                                          enable
+                                          ? enable_breakpoint
+                                          : disable_breakpoint);
            }
          else
-           map_breakpoint_numbers
-             (num.c_str (), [&] (breakpoint *b)
-              {
-                iterate_over_related_breakpoints (b, disable_breakpoint);
-              });
+           {
+             /* Handle breakpoint ids with formats 'x.y' or
+                'x.y-z'.  */
+             enable_disable_breakpoint_location_range
+               (bp_num_range.first, bp_loc_range, enable);
+           }
          num = extract_arg (&args);
        }
     }
 }
 
+/* The disable command disables the specified breakpoints/locations
+   (or all defined breakpoints) so they're no longer effective in
+   stopping the inferior.  ARGS may be in any of the forms defined in
+   extract_bp_number_and_location.  */
+
+static void
+disable_command (const char *args, int from_tty)
+{
+  enable_disable_command (args, from_tty, false);
+}
+
 static void
 enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition,
                        int count)
@@ -14350,7 +14442,7 @@ enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition,
   bpt->enable_count = count;
   update_global_location_list (UGLL_MAY_INSERT);
 
-  observer_notify_breakpoint_modified (bpt);
+  gdb::observers::breakpoint_modified.notify (bpt);
 }
 
 
@@ -14360,54 +14452,15 @@ enable_breakpoint (struct breakpoint *bpt)
   enable_breakpoint_disp (bpt, bpt->disposition, 0);
 }
 
-/* The enable command enables the specified breakpoints (or all defined
-   breakpoints) so they once again become (or continue to be) effective
-   in stopping the inferior.  */
+/* The enable command enables the specified breakpoints/locations (or
+   all defined breakpoints) so they once again become (or continue to
+   be) effective in stopping the inferior.  ARGS may be in any of the
+   forms defined in extract_bp_number_and_location.  */
 
 static void
 enable_command (const char *args, int from_tty)
 {
-  if (args == 0)
-    {
-      struct breakpoint *bpt;
-
-      ALL_BREAKPOINTS (bpt)
-       if (user_breakpoint_p (bpt))
-         enable_breakpoint (bpt);
-    }
-  else
-    {
-      std::string num = extract_arg (&args);
-
-      while (!num.empty ())
-       {
-         if (num.find ('.') != std::string::npos)
-           {
-             struct bp_location *loc = find_location_by_number (num.c_str ());
-
-             if (loc)
-               {
-                 if (!loc->enabled)
-                   {
-                     loc->enabled = 1;
-                     mark_breakpoint_location_modified (loc);
-                   }
-                 if (target_supports_enable_disable_tracepoint ()
-                     && current_trace_status ()->running && loc->owner
-                     && is_tracepoint (loc->owner))
-                   target_enable_tracepoint (loc);
-               }
-             update_global_location_list (UGLL_MAY_INSERT);
-           }
-         else
-           map_breakpoint_numbers
-             (num.c_str (), [&] (breakpoint *b)
-              {
-                iterate_over_related_breakpoints (b, enable_breakpoint);
-              });
-         num = extract_arg (&args);
-       }
-    }
+  enable_disable_command (args, from_tty, true);
 }
 
 static void
@@ -14599,9 +14652,8 @@ set_tracepoint_count (int num)
 }
 
 static void
-trace_command (char *arg_in, int from_tty)
+trace_command (const char *arg, int from_tty)
 {
-  const char *arg = arg_in;
   struct breakpoint_ops *ops;
 
   event_location_up location = string_to_event_location (&arg,
@@ -14626,9 +14678,8 @@ trace_command (char *arg_in, int from_tty)
 }
 
 static void
-ftrace_command (char *arg_in, int from_tty)
+ftrace_command (const char *arg, int from_tty)
 {
-  const char *arg = arg_in;
   event_location_up location = string_to_event_location (&arg,
                                                         current_language);
   create_breakpoint (get_current_arch (),
@@ -14647,9 +14698,8 @@ ftrace_command (char *arg_in, int from_tty)
 /* strace command implementation.  Creates a static tracepoint.  */
 
 static void
-strace_command (char *arg_in, int from_tty)
+strace_command (const char *arg, int from_tty)
 {
-  const char *arg = arg_in;
   struct breakpoint_ops *ops;
   event_location_up location;
 
@@ -14658,7 +14708,7 @@ strace_command (char *arg_in, int from_tty)
   if (arg && startswith (arg, "-m") && isspace (arg[2]))
     {
       ops = &strace_marker_breakpoint_ops;
-      location = new_linespec_location (&arg);
+      location = new_linespec_location (&arg, symbol_name_match_type::FULL);
     }
   else
     {
@@ -14792,7 +14842,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
    omitted.  */
 
 static void
-info_tracepoints_command (char *args, int from_tty)
+info_tracepoints_command (const char *args, int from_tty)
 {
   struct ui_out *uiout = current_uiout;
   int num_printed;
@@ -14813,7 +14863,7 @@ info_tracepoints_command (char *args, int from_tty)
 /* The 'enable trace' command enables tracepoints.
    Not supported by all targets.  */
 static void
-enable_trace_command (char *args, int from_tty)
+enable_trace_command (const char *args, int from_tty)
 {
   enable_command (args, from_tty);
 }
@@ -14821,7 +14871,7 @@ enable_trace_command (char *args, int from_tty)
 /* The 'disable trace' command disables tracepoints.
    Not supported by all targets.  */
 static void
-disable_trace_command (char *args, int from_tty)
+disable_trace_command (const char *args, int from_tty)
 {
   disable_command (args, from_tty);
 }
@@ -14872,7 +14922,7 @@ static void
 trace_pass_set_count (struct tracepoint *tp, int count, int from_tty)
 {
   tp->pass_count = count;
-  observer_notify_breakpoint_modified (tp);
+  gdb::observers::breakpoint_modified.notify (tp);
   if (from_tty)
     printf_filtered (_("Setting tracepoint %d's passcount to %d\n"),
                     tp->number, count);
@@ -14885,16 +14935,16 @@ trace_pass_set_count (struct tracepoint *tp, int count, int from_tty)
    Also accepts special argument "all".  */
 
 static void
-trace_pass_command (char *args, int from_tty)
+trace_pass_command (const char *args, int from_tty)
 {
   struct tracepoint *t1;
-  unsigned int count;
+  ULONGEST count;
 
   if (args == 0 || *args == 0)
     error (_("passcount command requires an "
             "argument (count + optional TP num)"));
 
-  count = strtoul (args, &args, 10);   /* Count comes first, then TP num.  */
+  count = strtoulst (args, &args, 10); /* Count comes first, then TP num.  */
 
   args = skip_spaces (args);
   if (*args && strncasecmp (args, "all", 3) == 0)
@@ -14967,12 +15017,12 @@ get_tracepoint_by_number_on_target (int num)
    (tracepoint_count) is returned.  */
 
 struct tracepoint *
-get_tracepoint_by_number (char **arg,
+get_tracepoint_by_number (const char **arg,
                          number_or_range_parser *parser)
 {
   struct breakpoint *t;
   int tpnum;
-  char *instring = arg == NULL ? NULL : *arg;
+  const char *instring = arg == NULL ? NULL : *arg;
 
   if (parser != NULL)
     {
@@ -15188,7 +15238,14 @@ Explicit locations are similar to linespecs but use an option/argument\n\
 syntax to specify location parameters.\n\
 Example: To specify the start of the label named \"the_top\" in the\n\
 function \"fact\" in the file \"factorial.c\", use \"-source factorial.c\n\
--function fact -label the_top\".\n"
+-function fact -label the_top\".\n\
+\n\
+By default, a specified function is matched against the program's\n\
+functions in all scopes.  For C++, this means in all namespaces and\n\
+classes.  For Ada, this means in all packages.  E.g., in C++,\n\
+\"func()\" matches \"A::func()\", \"A::B::func()\", etc.  The\n\
+\"-qualified\" flag overrides this behavior, making GDB interpret the\n\
+specified name as a complete fully-qualified name instead.\n"
 
 /* This help string is used for the break, hbreak, tbreak and thbreak
    commands.  It is defined as a macro to prevent duplication.
@@ -15223,7 +15280,7 @@ static struct cmd_list_element *tcatch_cmdlist;
 
 void
 add_catch_command (const char *name, const char *docstring,
-                  cmd_sfunc_ftype *sfunc,
+                  cmd_const_sfunc_ftype *sfunc,
                   completer_ftype *completer,
                   void *user_data_catch,
                   void *user_data_tcatch)
@@ -15505,9 +15562,9 @@ _initialize_breakpoint (void)
 
   initialize_breakpoint_ops ();
 
-  observer_attach_solib_unloaded (disable_breakpoints_in_unloaded_shlib);
-  observer_attach_free_objfile (disable_breakpoints_in_freed_objfile);
-  observer_attach_memory_changed (invalidate_bp_value_on_memory_change);
+  gdb::observers::solib_unloaded.attach (disable_breakpoints_in_unloaded_shlib);
+  gdb::observers::free_objfile.attach (disable_breakpoints_in_freed_objfile);
+  gdb::observers::memory_changed.attach (invalidate_bp_value_on_memory_change);
 
   breakpoint_objfile_key
     = register_objfile_data_with_cleanup (NULL, free_breakpoint_objfile_data);
@@ -16058,6 +16115,6 @@ agent-printf \"printf format string\", arg1, arg2, arg3, ..., argn\n\
 
   automatic_hardware_breakpoints = 1;
 
-  observer_attach_about_to_proceed (breakpoint_about_to_proceed);
-  observer_attach_thread_exit (remove_threaded_breakpoints);
+  gdb::observers::about_to_proceed.attach (breakpoint_about_to_proceed);
+  gdb::observers::thread_exit.attach (remove_threaded_breakpoints);
 }
This page took 0.053175 seconds and 4 git commands to generate.