gdb/
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 172e4198b5b63942811fee0ac1cea46608240ff5..7d363b2d89b6b6564a4d75272d8257cae1446040 100644 (file)
@@ -1,8 +1,6 @@
 /* Everything about breakpoints, for GDB.
 
-   Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
-   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-   2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1986-2012 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -58,7 +56,6 @@
 #include "memattr.h"
 #include "ada-lang.h"
 #include "top.h"
-#include "wrapper.h"
 #include "valprint.h"
 #include "jit.h"
 #include "xml-syscall.h"
@@ -68,6 +65,7 @@
 #include "stack.h"
 #include "skip.h"
 #include "record.h"
+#include "gdb_regex.h"
 
 /* readline include files */
 #include "readline/readline.h"
@@ -99,6 +97,23 @@ static int breakpoint_re_set_one (void *);
 
 static void breakpoint_re_set_default (struct breakpoint *);
 
+static void create_sals_from_address_default (char **,
+                                             struct linespec_result *,
+                                             enum bptype, char *,
+                                             char **);
+
+static void create_breakpoints_sal_default (struct gdbarch *,
+                                           struct linespec_result *,
+                                           struct linespec_sals *,
+                                           char *, enum bptype,
+                                           enum bpdisp, int, int,
+                                           int,
+                                           const struct breakpoint_ops *,
+                                           int, int, int);
+
+static void decode_linespec_default (struct breakpoint *, char **,
+                                    struct symtabs_and_lines *);
+
 static void clear_command (char *, int);
 
 static void catch_command (char *, int);
@@ -240,10 +255,15 @@ static void trace_pass_command (char *, int);
 
 static int is_masked_watchpoint (const struct breakpoint *b);
 
-/* Assuming we're creating a static tracepoint, does S look like a
-   static tracepoint marker spec ("-m MARKER_ID")?  */
-#define is_marker_spec(s)                                              \
-  (s != NULL && strncmp (s, "-m", 2) == 0 && ((s)[2] == ' ' || (s)[2] == '\t'))
+/* Return 1 if B refers to a static tracepoint set by marker ("-m"), zero
+   otherwise.  */
+
+static int strace_marker_p (struct breakpoint *b);
+
+static void init_catchpoint (struct breakpoint *b,
+                            struct gdbarch *gdbarch, int tempflag,
+                            char *cond_string,
+                            const struct breakpoint_ops *ops);
 
 /* The abstract base class all breakpoint_ops structures inherit
    from.  */
@@ -353,7 +373,7 @@ show_automatic_hardware_breakpoints (struct ui_file *file, int from_tty,
 static const char always_inserted_auto[] = "auto";
 static const char always_inserted_on[] = "on";
 static const char always_inserted_off[] = "off";
-static const char *always_inserted_enums[] = {
+static const char *const always_inserted_enums[] = {
   always_inserted_auto,
   always_inserted_off,
   always_inserted_on,
@@ -1225,9 +1245,10 @@ is_watchpoint (const struct breakpoint *bpt)
 static int
 watchpoint_in_thread_scope (struct watchpoint *b)
 {
-  return (ptid_equal (b->watchpoint_thread, null_ptid)
-         || (ptid_equal (inferior_ptid, b->watchpoint_thread)
-             && !is_executing (inferior_ptid)));
+  return (b->base.pspace == current_program_space
+         && (ptid_equal (b->watchpoint_thread, null_ptid)
+             || (ptid_equal (inferior_ptid, b->watchpoint_thread)
+                 && !is_executing (inferior_ptid))));
 }
 
 /* Set watchpoint B to disp_del_at_next_stop, even including its possible
@@ -3475,6 +3496,78 @@ print_bp_stop_message (bpstat bs)
     }
 }
 
+/* A helper function that prints a shared library stopped event.  */
+
+static void
+print_solib_event (int is_catchpoint)
+{
+  int any_deleted
+    = !VEC_empty (char_ptr, current_program_space->deleted_solibs);
+  int any_added
+    = !VEC_empty (so_list_ptr, current_program_space->added_solibs);
+
+  if (!is_catchpoint)
+    {
+      if (any_added || any_deleted)
+       ui_out_text (current_uiout,
+                    _("Stopped due to shared library event:\n"));
+      else
+       ui_out_text (current_uiout,
+                    _("Stopped due to shared library event (no "
+                      "libraries added or removed)\n"));
+    }
+
+  if (ui_out_is_mi_like_p (current_uiout))
+    ui_out_field_string (current_uiout, "reason",
+                        async_reason_lookup (EXEC_ASYNC_SOLIB_EVENT));
+
+  if (any_deleted)
+    {
+      struct cleanup *cleanup;
+      char *name;
+      int ix;
+
+      ui_out_text (current_uiout, _("  Inferior unloaded "));
+      cleanup = make_cleanup_ui_out_list_begin_end (current_uiout,
+                                                   "removed");
+      for (ix = 0;
+          VEC_iterate (char_ptr, current_program_space->deleted_solibs,
+                       ix, name);
+          ++ix)
+       {
+         if (ix > 0)
+           ui_out_text (current_uiout, "    ");
+         ui_out_field_string (current_uiout, "library", name);
+         ui_out_text (current_uiout, "\n");
+       }
+
+      do_cleanups (cleanup);
+    }
+
+  if (any_added)
+    {
+      struct so_list *iter;
+      int ix;
+      struct cleanup *cleanup;
+
+      ui_out_text (current_uiout, _("  Inferior loaded "));
+      cleanup = make_cleanup_ui_out_list_begin_end (current_uiout,
+                                                   "added");
+      for (ix = 0;
+          VEC_iterate (so_list_ptr, current_program_space->added_solibs,
+                       ix, iter);
+          ++ix)
+       {
+         if (ix > 0)
+           ui_out_text (current_uiout, "    ");
+         ui_out_field_string (current_uiout, "library", iter->so_name);
+         ui_out_text (current_uiout, "\n");
+       }
+
+      do_cleanups (cleanup);
+    }
+}
+
 /* Print a message indicating what happened.  This is called from
    normal_stop().  The input to this routine is the head of the bpstat
    list - a list of the eventpoints that caused this stop.  KIND is
@@ -3519,10 +3612,7 @@ bpstat_print (bpstat bs, int kind)
      OS-level shared library event, do the same thing.  */
   if (kind == TARGET_WAITKIND_LOADED)
     {
-      ui_out_text (current_uiout, _("Stopped due to shared library event\n"));
-      if (ui_out_is_mi_like_p (current_uiout))
-       ui_out_field_string (current_uiout, "reason",
-                            async_reason_lookup (EXEC_ASYNC_SOLIB_EVENT));
+      print_solib_event (0);
       return PRINT_NOTHING;
     }
 
@@ -3810,14 +3900,15 @@ which its expression is valid.\n");
 
 static int
 bpstat_check_location (const struct bp_location *bl,
-                      struct address_space *aspace, CORE_ADDR bp_addr)
+                      struct address_space *aspace, CORE_ADDR bp_addr,
+                      const struct target_waitstatus *ws)
 {
   struct breakpoint *b = bl->owner;
 
   /* BL is from an existing breakpoint.  */
   gdb_assert (b != NULL);
 
-  return b->ops->breakpoint_hit (bl, aspace, bp_addr);
+  return b->ops->breakpoint_hit (bl, aspace, bp_addr, ws);
 }
 
 /* Determine if the watched values have actually changed, and we
@@ -4127,7 +4218,8 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
 
 bpstat
 bpstat_stop_status (struct address_space *aspace,
-                   CORE_ADDR bp_addr, ptid_t ptid)
+                   CORE_ADDR bp_addr, ptid_t ptid,
+                   const struct target_waitstatus *ws)
 {
   struct breakpoint *b = NULL;
   struct bp_location *bl;
@@ -4165,7 +4257,7 @@ bpstat_stop_status (struct address_space *aspace,
          if (bl->shlib_disabled)
            continue;
 
-         if (!bpstat_check_location (bl, aspace, bp_addr))
+         if (!bpstat_check_location (bl, aspace, bp_addr, ws))
            continue;
 
          /* Come here if it's a watchpoint, or if the break address
@@ -4205,6 +4297,19 @@ bpstat_stop_status (struct address_space *aspace,
        }
     }
 
+  /* A bit of special processing for shlib breakpoints.  We need to
+     process solib loading here, so that the lists of loaded and
+     unloaded libraries are correct before we handle "catch load" and
+     "catch unload".  */
+  for (bs = bs_head; bs != NULL; bs = bs->next)
+    {
+      if (bs->breakpoint_at && bs->breakpoint_at->type == bp_shlib_event)
+       {
+         handle_solib_event ();
+         break;
+       }
+    }
+
   /* Now go through the locations that caused the target to stop, and
      check whether we're interested in reporting this stop to higher
      layers, or whether we should resume the target transparently.  */
@@ -4243,10 +4348,12 @@ bpstat_stop_status (struct address_space *aspace,
                bs->print = 0;
            }
 
-         /* Print nothing for this entry if we don't stop or don't print.  */
-         if (bs->stop == 0 || bs->print == 0)
-           bs->print_it = print_it_noop;
        }
+
+      /* Print nothing for this entry if we don't stop or don't
+        print.  */
+      if (!bs->stop || !bs->print)
+       bs->print_it = print_it_noop;
     }
 
   /* If we aren't stopping, the value of some hardware watchpoint may
@@ -4292,6 +4399,25 @@ handle_jit_event (void)
   target_terminal_inferior ();
 }
 
+/* Handle an solib event by calling solib_add.  */
+
+void
+handle_solib_event (void)
+{
+  clear_program_space_solib_cache (current_inferior ()->pspace);
+
+  /* Check for any newly added shared libraries if we're supposed to
+     be adding them automatically.  Switch terminal for any messages
+     produced by breakpoint_re_set.  */
+  target_terminal_ours_for_output ();
+#ifdef SOLIB_ADD
+  SOLIB_ADD (NULL, 0, &current_target, auto_solib_add);
+#else
+  solib_add (NULL, 0, &current_target, auto_solib_add);
+#endif
+  target_terminal_inferior ();
+}
+
 /* Prepare WHAT final decision for infrun.  */
 
 /* Decide what infrun needs to do with this bpstat.  */
@@ -4300,10 +4426,6 @@ struct bpstat_what
 bpstat_what (bpstat bs_head)
 {
   struct bpstat_what retval;
-  /* We need to defer calling `solib_add', as adding new symbols
-     resets breakpoints, which in turn deletes breakpoint locations,
-     and hence may clear unprocessed entries in the BS chain.  */
-  int shlib_event = 0;
   int jit_event = 0;
   bpstat bs;
 
@@ -4335,6 +4457,7 @@ bpstat_what (bpstat bs_head)
        case bp_hardware_breakpoint:
        case bp_until:
        case bp_finish:
+       case bp_shlib_event:
          if (bs->stop)
            {
              if (bs->print)
@@ -4412,18 +4535,6 @@ bpstat_what (bpstat bs_head)
                 This requires no further action.  */
            }
          break;
-       case bp_shlib_event:
-         shlib_event = 1;
-
-         /* If requested, stop when the dynamic linker notifies GDB
-            of events.  This allows the user to get control and place
-            breakpoints in initializer routines for dynamically
-            loaded objects (among other things).  */
-         if (stop_on_solib_events)
-           this_action = BPSTAT_WHAT_STOP_NOISY;
-         else
-           this_action = BPSTAT_WHAT_SINGLE;
-         break;
        case bp_jit_event:
          jit_event = 1;
          this_action = BPSTAT_WHAT_SINGLE;
@@ -4469,27 +4580,6 @@ bpstat_what (bpstat bs_head)
   /* 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)
-       fprintf_unfiltered (gdb_stdlog, "bpstat_what: bp_shlib_event\n");
-
-      /* Check for any newly added shared libraries if we're supposed
-        to be adding them automatically.  */
-
-      /* Switch terminal for any messages produced by
-        breakpoint_re_set.  */
-      target_terminal_ours_for_output ();
-
-#ifdef SOLIB_ADD
-      SOLIB_ADD (NULL, 0, &current_target, auto_solib_add);
-#else
-      solib_add (NULL, 0, &current_target, auto_solib_add);
-#endif
-
-      target_terminal_inferior ();
-    }
-
   if (jit_event)
     {
       if (debug_infrun)
@@ -6216,11 +6306,16 @@ remove_catch_fork (struct bp_location *bl)
 
 static int
 breakpoint_hit_catch_fork (const struct bp_location *bl,
-                          struct address_space *aspace, CORE_ADDR bp_addr)
+                          struct address_space *aspace, CORE_ADDR bp_addr,
+                          const struct target_waitstatus *ws)
 {
   struct fork_catchpoint *c = (struct fork_catchpoint *) bl->owner;
 
-  return inferior_has_forked (inferior_ptid, &c->forked_inferior_pid);
+  if (ws->kind != TARGET_WAITKIND_FORKED)
+    return 0;
+
+  c->forked_inferior_pid = ws->value.related_pid;
+  return 1;
 }
 
 /* Implement the "print_it" breakpoint_ops method for fork
@@ -6325,11 +6420,16 @@ remove_catch_vfork (struct bp_location *bl)
 
 static int
 breakpoint_hit_catch_vfork (const struct bp_location *bl,
-                           struct address_space *aspace, CORE_ADDR bp_addr)
+                           struct address_space *aspace, CORE_ADDR bp_addr,
+                           const struct target_waitstatus *ws)
 {
   struct fork_catchpoint *c = (struct fork_catchpoint *) bl->owner;
 
-  return inferior_has_vforked (inferior_ptid, &c->forked_inferior_pid);
+  if (ws->kind != TARGET_WAITKIND_VFORKED)
+    return 0;
+
+  c->forked_inferior_pid = ws->value.related_pid;
+  return 1;
 }
 
 /* Implement the "print_it" breakpoint_ops method for vfork
@@ -6410,6 +6510,264 @@ print_recreate_catch_vfork (struct breakpoint *b, struct ui_file *fp)
 
 static struct breakpoint_ops catch_vfork_breakpoint_ops;
 
+/* An instance of this type is used to represent an solib catchpoint.
+   It includes a "struct breakpoint" as a kind of base class; users
+   downcast to "struct breakpoint *" when needed.  A breakpoint is
+   really of this type iff its ops pointer points to
+   CATCH_SOLIB_BREAKPOINT_OPS.  */
+
+struct solib_catchpoint
+{
+  /* The base class.  */
+  struct breakpoint base;
+
+  /* True for "catch load", false for "catch unload".  */
+  unsigned char is_load;
+
+  /* Regular expression to match, if any.  COMPILED is only valid when
+     REGEX is non-NULL.  */
+  char *regex;
+  regex_t compiled;
+};
+
+static void
+dtor_catch_solib (struct breakpoint *b)
+{
+  struct solib_catchpoint *self = (struct solib_catchpoint *) b;
+
+  if (self->regex)
+    regfree (&self->compiled);
+  xfree (self->regex);
+
+  base_breakpoint_ops.dtor (b);
+}
+
+static int
+insert_catch_solib (struct bp_location *ignore)
+{
+  return 0;
+}
+
+static int
+remove_catch_solib (struct bp_location *ignore)
+{
+  return 0;
+}
+
+static int
+breakpoint_hit_catch_solib (const struct bp_location *bl,
+                           struct address_space *aspace,
+                           CORE_ADDR bp_addr,
+                           const struct target_waitstatus *ws)
+{
+  struct solib_catchpoint *self = (struct solib_catchpoint *) bl->owner;
+  struct breakpoint *other;
+
+  if (ws->kind == TARGET_WAITKIND_LOADED)
+    return 1;
+
+  ALL_BREAKPOINTS (other)
+  {
+    struct bp_location *other_bl;
+
+    if (other == bl->owner)
+      continue;
+
+    if (other->type != bp_shlib_event)
+      continue;
+
+    if (self->base.pspace != NULL && other->pspace != self->base.pspace)
+      continue;
+
+    for (other_bl = other->loc; other_bl != NULL; other_bl = other_bl->next)
+      {
+       if (other->ops->breakpoint_hit (other_bl, aspace, bp_addr, ws))
+         return 1;
+      }
+  }
+
+  return 0;
+}
+
+static void
+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;
+          VEC_iterate (so_list_ptr, current_program_space->added_solibs,
+                       ix, iter);
+          ++ix)
+       {
+         if (!self->regex
+             || regexec (&self->compiled, iter->so_name, 0, NULL, 0) == 0)
+           return;
+       }
+    }
+  else
+    {
+      char *iter;
+
+      for (ix = 0;
+          VEC_iterate (char_ptr, current_program_space->deleted_solibs,
+                       ix, iter);
+          ++ix)
+       {
+         if (!self->regex
+             || regexec (&self->compiled, iter, 0, NULL, 0) == 0)
+           return;
+       }
+    }
+
+  bs->stop = 0;
+  bs->print_it = print_it_noop;
+}
+
+static enum print_stop_action
+print_it_catch_solib (bpstat bs)
+{
+  struct breakpoint *b = bs->breakpoint_at;
+  struct ui_out *uiout = current_uiout;
+
+  annotate_catchpoint (b->number);
+  if (b->disposition == disp_del)
+    ui_out_text (uiout, "\nTemporary catchpoint ");
+  else
+    ui_out_text (uiout, "\nCatchpoint ");
+  ui_out_field_int (uiout, "bkptno", b->number);
+  ui_out_text (uiout, "\n");
+  if (ui_out_is_mi_like_p (uiout))
+    ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+  print_solib_event (1);
+  return PRINT_SRC_AND_LOC;
+}
+
+static void
+print_one_catch_solib (struct breakpoint *b, struct bp_location **locs)
+{
+  struct solib_catchpoint *self = (struct solib_catchpoint *) b;
+  struct value_print_options opts;
+  struct ui_out *uiout = current_uiout;
+  char *msg;
+
+  get_user_print_options (&opts);
+  /* Field 4, the address, is omitted (which makes the columns not
+     line up too nicely with the headers, but the effect is relatively
+     readable).  */
+  if (opts.addressprint)
+    {
+      annotate_field (4);
+      ui_out_field_skip (uiout, "addr");
+    }
+
+  annotate_field (5);
+  if (self->is_load)
+    {
+      if (self->regex)
+       msg = xstrprintf (_("load of library matching %s"), self->regex);
+      else
+       msg = xstrdup (_("load of library"));
+    }
+  else
+    {
+      if (self->regex)
+       msg = xstrprintf (_("unload of library matching %s"), self->regex);
+      else
+       msg = xstrdup (_("unload of library"));
+    }
+  ui_out_field_string (uiout, "what", msg);
+  xfree (msg);
+}
+
+static void
+print_mention_catch_solib (struct breakpoint *b)
+{
+  struct solib_catchpoint *self = (struct solib_catchpoint *) b;
+
+  printf_filtered (_("Catchpoint %d (%s)"), b->number,
+                  self->is_load ? "load" : "unload");
+}
+
+static void
+print_recreate_catch_solib (struct breakpoint *b, struct ui_file *fp)
+{
+  struct solib_catchpoint *self = (struct solib_catchpoint *) b;
+
+  fprintf_unfiltered (fp, "%s %s",
+                     b->disposition == disp_del ? "tcatch" : "catch",
+                     self->is_load ? "load" : "unload");
+  if (self->regex)
+    fprintf_unfiltered (fp, " %s", self->regex);
+  fprintf_unfiltered (fp, "\n");
+}
+
+static struct breakpoint_ops catch_solib_breakpoint_ops;
+
+/* A helper function that does all the work for "catch load" and
+   "catch unload".  */
+
+static void
+catch_load_or_unload (char *arg, int from_tty, int is_load,
+                     struct cmd_list_element *command)
+{
+  struct solib_catchpoint *c;
+  struct gdbarch *gdbarch = get_current_arch ();
+  int tempflag;
+  regex_t compiled;
+  struct cleanup *cleanup;
+
+  tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
+
+  if (!arg)
+    arg = "";
+  arg = skip_spaces (arg);
+
+  c = XCNEW (struct solib_catchpoint);
+  cleanup = make_cleanup (xfree, c);
+
+  if (*arg != '\0')
+    {
+      int errcode;
+
+      errcode = regcomp (&c->compiled, arg, REG_NOSUB);
+      if (errcode != 0)
+       {
+         char *err = get_regcomp_error (errcode, &c->compiled);
+
+         make_cleanup (xfree, err);
+         error (_("Invalid regexp (%s): %s"), err, arg);
+       }
+      c->regex = xstrdup (arg);
+    }
+
+  c->is_load = is_load;
+  init_catchpoint (&c->base, gdbarch, tempflag, NULL,
+                  &catch_solib_breakpoint_ops);
+
+  discard_cleanups (cleanup);
+  install_breakpoint (0, &c->base, 1);
+}
+
+static void
+catch_load_command_1 (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,
+                       struct cmd_list_element *command)
+{
+  catch_load_or_unload (arg, from_tty, 0, command);
+}
+
 /* An instance of this type is used to represent a syscall catchpoint.
    It includes a "struct breakpoint" as a kind of base class; users
    downcast to "struct breakpoint *" when needed.  A breakpoint is
@@ -6529,7 +6887,8 @@ remove_catch_syscall (struct bp_location *bl)
 
 static int
 breakpoint_hit_catch_syscall (const struct bp_location *bl,
-                             struct address_space *aspace, CORE_ADDR bp_addr)
+                             struct address_space *aspace, CORE_ADDR bp_addr,
+                             const struct target_waitstatus *ws)
 {
   /* We must check if we are catching specific syscalls in this
      breakpoint.  If we are, then we must guarantee that the called
@@ -6538,9 +6897,12 @@ breakpoint_hit_catch_syscall (const struct bp_location *bl,
   const struct syscall_catchpoint *c
     = (const struct syscall_catchpoint *) bl->owner;
 
-  if (!inferior_has_called_syscall (inferior_ptid, &syscall_number))
+  if (ws->kind != TARGET_WAITKIND_SYSCALL_ENTRY
+      && ws->kind != TARGET_WAITKIND_SYSCALL_RETURN)
     return 0;
 
+  syscall_number = ws->value.syscall_number;
+
   /* Now, checking if the syscall is the same.  */
   if (c->syscalls_to_be_caught)
     {
@@ -6841,11 +7203,16 @@ remove_catch_exec (struct bp_location *bl)
 
 static int
 breakpoint_hit_catch_exec (const struct bp_location *bl,
-                          struct address_space *aspace, CORE_ADDR bp_addr)
+                          struct address_space *aspace, CORE_ADDR bp_addr,
+                          const struct target_waitstatus *ws)
 {
   struct exec_catchpoint *c = (struct exec_catchpoint *) bl->owner;
 
-  return inferior_has_execd (inferior_ptid, &c->exec_pathname);
+  if (ws->kind != TARGET_WAITKIND_EXECD)
+    return 0;
+
+  c->exec_pathname = xstrdup (ws->value.execd_pathname);
+  return 1;
 }
 
 static enum print_stop_action
@@ -7301,7 +7668,7 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
              struct tracepoint *t = (struct tracepoint *) b;
              struct static_tracepoint_marker marker;
 
-             if (is_marker_spec (addr_string))
+             if (strace_marker_p (b))
                {
                  /* We already know the marker exists, otherwise, we
                     wouldn't see a sal for it.  */
@@ -7723,32 +8090,19 @@ create_breakpoint (struct gdbarch *gdbarch,
 
   init_linespec_result (&canonical);
 
-  if (type_wanted == bp_static_tracepoint && is_marker_spec (arg))
-    {
-      int i;
-      struct linespec_sals lsal;
-
-      lsal.sals = decode_static_tracepoint_spec (&arg);
-
-      copy_arg = savestring (addr_start, arg - addr_start);
-
-      canonical.addr_string = xstrdup (copy_arg);
-      lsal.canonical = xstrdup (copy_arg);
-      VEC_safe_push (linespec_sals, canonical.sals, &lsal);
-
-      goto done;
-    }
-
   TRY_CATCH (e, RETURN_MASK_ALL)
     {
-      parse_breakpoint_sals (&arg, &canonical);
+      ops->create_sals_from_address (&arg, &canonical, type_wanted,
+                                    addr_start, &copy_arg);
     }
 
   /* If caller is interested in rc value from parse, set value.  */
   switch (e.reason)
     {
-    case RETURN_QUIT:
-      throw_exception (e);
+    case GDB_NO_ERROR:
+      if (VEC_empty (linespec_sals, canonical.sals))
+       return 0;
+      break;
     case RETURN_ERROR:
       switch (e.error)
        {
@@ -7790,12 +8144,9 @@ create_breakpoint (struct gdbarch *gdbarch,
        }
       break;
     default:
-      if (VEC_empty (linespec_sals, canonical.sals))
-       return 0;
+      throw_exception (e);
     }
 
-  done:
-
   /* Create a chain of things that always need to be cleaned up.  */
   old_chain = make_cleanup_destroy_linespec_result (&canonical);
 
@@ -7858,57 +8209,11 @@ create_breakpoint (struct gdbarch *gdbarch,
             }
         }
 
-      /* If the user is creating a static tracepoint by marker id
-        (strace -m MARKER_ID), then store the sals index, so that
-        breakpoint_re_set can try to match up which of the newly
-        found markers corresponds to this one, and, don't try to
-        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 (copy_arg))
-       {
-         int i;
-
-         for (i = 0; i < lsal->sals.nelts; ++i)
-           {
-             struct symtabs_and_lines expanded;
-             struct tracepoint *tp;
-             struct cleanup *old_chain;
-             char *addr_string;
-
-             expanded.nelts = 1;
-             expanded.sals = &lsal->sals.sals[i];
-
-             addr_string = xstrdup (canonical.addr_string);
-             old_chain = make_cleanup (xfree, addr_string);
-
-             tp = XCNEW (struct tracepoint);
-             init_breakpoint_sal (&tp->base, gdbarch, expanded,
-                                  addr_string, NULL,
+      ops->create_breakpoints_sal (gdbarch, &canonical, lsal,
                                   cond_string, type_wanted,
                                   tempflag ? disp_del : disp_donttouch,
                                   thread, task, ignore_count, ops,
-                                  from_tty, enabled, internal,
-                                  canonical.special_display);
-             /* Given that its possible to have multiple markers with
-                the same string id, if the user is creating a static
-                tracepoint by marker id ("strace -m MARKER_ID"), then
-                store the sals index, so that breakpoint_re_set can
-                try to match up which of the newly found markers
-                corresponds to this one  */
-             tp->static_trace_marker_id_idx = i;
-
-             install_breakpoint (internal, &tp->base, 0);
-
-             discard_cleanups (old_chain);
-           }
-       }
-      else
-       create_breakpoints_sal (gdbarch, &canonical, cond_string,
-                               type_wanted,
-                               tempflag ? disp_del : disp_donttouch,
-                               thread, task, ignore_count, ops, from_tty,
-                               enabled, internal);
+                                  from_tty, enabled, internal);
     }
   else
     {
@@ -8147,8 +8452,13 @@ stopat_command (char *arg, int from_tty)
 static int
 breakpoint_hit_ranged_breakpoint (const struct bp_location *bl,
                                  struct address_space *aspace,
-                                 CORE_ADDR bp_addr)
+                                 CORE_ADDR bp_addr,
+                                 const struct target_waitstatus *ws)
 {
+  if (ws->kind != TARGET_WAITKIND_STOPPED
+      || ws->value.sig != TARGET_SIGNAL_TRAP)
+    return 0;
+
   return breakpoint_address_match_range (bl->pspace->aspace, bl->address,
                                         bl->length, aspace, bp_addr);
 }
@@ -8615,7 +8925,8 @@ remove_watchpoint (struct bp_location *bl)
 
 static int
 breakpoint_hit_watchpoint (const struct bp_location *bl,
-                          struct address_space *aspace, CORE_ADDR bp_addr)
+                          struct address_space *aspace, CORE_ADDR bp_addr,
+                          const struct target_waitstatus *ws)
 {
   struct breakpoint *b = bl->owner;
   struct watchpoint *w = (struct watchpoint *) b;
@@ -10118,6 +10429,8 @@ clear_command (char *arg, int from_tty)
   make_cleanup (VEC_cleanup (breakpoint_p), &found);
   for (i = 0; i < sals.nelts; i++)
     {
+      int is_abs, sal_name_len;
+
       /* If exact pc given, clear bpts at that pc.
          If line given (pc == 0), clear all bpts on specified line.
          If defaulting, clear all bpts on default line
@@ -10131,6 +10444,8 @@ clear_command (char *arg, int from_tty)
          1              0             <can't happen> */
 
       sal = sals.sals[i];
+      is_abs = sal.symtab == NULL ? 1 : IS_ABSOLUTE_PATH (sal.symtab->filename);
+      sal_name_len = is_abs ? 0 : strlen (sal.symtab->filename);
 
       /* Find all matching breakpoints and add them to 'found'.  */
       ALL_BREAKPOINTS (b)
@@ -10150,13 +10465,24 @@ clear_command (char *arg, int from_tty)
                                  && (loc->address == sal.pc)
                                  && (!section_is_overlay (loc->section)
                                      || loc->section == sal.section));
-                 int line_match = ((default_match || sal.explicit_line)
-                                   && loc->source_file != NULL
-                                   && sal.symtab != NULL
-                                   && sal.pspace == loc->pspace
-                                   && filename_cmp (loc->source_file,
-                                                    sal.symtab->filename) == 0
-                                   && loc->line_number == sal.line);
+                 int line_match = 0;
+
+                 if ((default_match || sal.explicit_line)
+                     && loc->source_file != NULL
+                     && sal.symtab != NULL
+                     && sal.pspace == loc->pspace
+                     && loc->line_number == sal.line)
+                   {
+                     if (filename_cmp (loc->source_file,
+                                       sal.symtab->filename) == 0)
+                       line_match = 1;
+                     else if (!IS_ABSOLUTE_PATH (sal.symtab->filename)
+                              && compare_filenames_for_search (loc->source_file,
+                                                               sal.symtab->filename,
+                                                               sal_name_len))
+                       line_match = 1;
+                   }
+
                  if (pc_match || line_match)
                    {
                      match = 1;
@@ -10715,7 +11041,7 @@ breakpoint_retire_moribund (void)
 static void
 update_global_location_list_nothrow (int inserting)
 {
-  struct gdb_exception e;
+  volatile struct gdb_exception e;
 
   TRY_CATCH (e, RETURN_MASK_ERROR)
     update_global_location_list (inserting);
@@ -10859,7 +11185,8 @@ base_breakpoint_remove_location (struct bp_location *bl)
 static int
 base_breakpoint_breakpoint_hit (const struct bp_location *bl,
                                struct address_space *aspace,
-                               CORE_ADDR bp_addr)
+                               CORE_ADDR bp_addr,
+                               const struct target_waitstatus *ws)
 {
   internal_error_pure_virtual_called ();
 }
@@ -10913,6 +11240,39 @@ base_breakpoint_print_recreate (struct breakpoint *b, struct ui_file *fp)
   internal_error_pure_virtual_called ();
 }
 
+static void
+base_breakpoint_create_sals_from_address (char **arg,
+                                         struct linespec_result *canonical,
+                                         enum bptype type_wanted,
+                                         char *addr_start,
+                                         char **copy_arg)
+{
+  internal_error_pure_virtual_called ();
+}
+
+static void
+base_breakpoint_create_breakpoints_sal (struct gdbarch *gdbarch,
+                                       struct linespec_result *c,
+                                       struct linespec_sals *lsal,
+                                       char *cond_string,
+                                       enum bptype type_wanted,
+                                       enum bpdisp disposition,
+                                       int thread,
+                                       int task, int ignore_count,
+                                       const struct breakpoint_ops *o,
+                                       int from_tty, int enabled,
+                                       int internal)
+{
+  internal_error_pure_virtual_called ();
+}
+
+static void
+base_breakpoint_decode_linespec (struct breakpoint *b, char **s,
+                                struct symtabs_and_lines *sals)
+{
+  internal_error_pure_virtual_called ();
+}
+
 static struct breakpoint_ops base_breakpoint_ops =
 {
   base_breakpoint_dtor,
@@ -10928,7 +11288,10 @@ static struct breakpoint_ops base_breakpoint_ops =
   NULL,
   base_breakpoint_print_one_detail,
   base_breakpoint_print_mention,
-  base_breakpoint_print_recreate
+  base_breakpoint_print_recreate,
+  base_breakpoint_create_sals_from_address,
+  base_breakpoint_create_breakpoints_sal,
+  base_breakpoint_decode_linespec,
 };
 
 /* Default breakpoint_ops methods.  */
@@ -10969,10 +11332,15 @@ bkpt_remove_location (struct bp_location *bl)
 
 static int
 bkpt_breakpoint_hit (const struct bp_location *bl,
-                    struct address_space *aspace, CORE_ADDR bp_addr)
+                    struct address_space *aspace, CORE_ADDR bp_addr,
+                    const struct target_waitstatus *ws)
 {
   struct breakpoint *b = bl->owner;
 
+  if (ws->kind != TARGET_WAITKIND_STOPPED
+      || ws->value.sig != TARGET_SIGNAL_TRAP)
+    return 0;
+
   if (!breakpoint_address_match (bl->pspace->aspace, bl->address,
                                 aspace, bp_addr))
     return 0;
@@ -11074,6 +11442,43 @@ bkpt_print_recreate (struct breakpoint *tp, struct ui_file *fp)
   print_recreate_thread (tp, fp);
 }
 
+static void
+bkpt_create_sals_from_address (char **arg,
+                              struct linespec_result *canonical,
+                              enum bptype type_wanted,
+                              char *addr_start, char **copy_arg)
+{
+  create_sals_from_address_default (arg, canonical, type_wanted,
+                                   addr_start, copy_arg);
+}
+
+static void
+bkpt_create_breakpoints_sal (struct gdbarch *gdbarch,
+                            struct linespec_result *canonical,
+                            struct linespec_sals *lsal,
+                            char *cond_string,
+                            enum bptype type_wanted,
+                            enum bpdisp disposition,
+                            int thread,
+                            int task, int ignore_count,
+                            const struct breakpoint_ops *ops,
+                            int from_tty, int enabled,
+                            int internal)
+{
+  create_breakpoints_sal_default (gdbarch, canonical, lsal,
+                                 cond_string, type_wanted,
+                                 disposition, thread, task,
+                                 ignore_count, ops, from_tty,
+                                 enabled, internal);
+}
+
+static void
+bkpt_decode_linespec (struct breakpoint *b, char **s,
+                     struct symtabs_and_lines *sals)
+{
+  decode_linespec_default (b, s, sals);
+}
+
 /* Virtual table for internal breakpoints.  */
 
 static void
@@ -11104,8 +11509,17 @@ internal_bkpt_re_set (struct breakpoint *b)
 static void
 internal_bkpt_check_status (bpstat bs)
 {
-  /* We do not stop for these.  */
-  bs->stop = 0;
+  if (bs->breakpoint_at->type == bp_shlib_event)
+    {
+      /* If requested, stop when the dynamic linker notifies GDB of
+        events.  This allows the user to get control and place
+        breakpoints in initializer routines for dynamically loaded
+        objects (among other things).  */
+      bs->stop = stop_on_solib_events;
+      bs->print = stop_on_solib_events;
+    }
+  else
+    bs->stop = 0;
 }
 
 static enum print_stop_action
@@ -11122,10 +11536,7 @@ internal_bkpt_print_it (bpstat bs)
       /* Did we stop because the user set the stop_on_solib_events
         variable?  (If so, we report this as a generic, "Stopped due
         to shlib event" message.) */
-      ui_out_text (uiout, _("Stopped due to shared library event\n"));
-      if (ui_out_is_mi_like_p (uiout))
-       ui_out_field_string (uiout, "reason",
-                            async_reason_lookup (EXEC_ASYNC_SOLIB_EVENT));
+      print_solib_event (0);
       break;
 
     case bp_thread_event:
@@ -11227,7 +11638,8 @@ tracepoint_re_set (struct breakpoint *b)
 
 static int
 tracepoint_breakpoint_hit (const struct bp_location *bl,
-                          struct address_space *aspace, CORE_ADDR bp_addr)
+                          struct address_space *aspace, CORE_ADDR bp_addr,
+                          const struct target_waitstatus *ws)
 {
   /* By definition, the inferior does not report stops at
      tracepoints.  */
@@ -11300,8 +11712,145 @@ tracepoint_print_recreate (struct breakpoint *self, struct ui_file *fp)
     fprintf_unfiltered (fp, "  passcount %d\n", tp->pass_count);
 }
 
+static void
+tracepoint_create_sals_from_address (char **arg,
+                                    struct linespec_result *canonical,
+                                    enum bptype type_wanted,
+                                    char *addr_start, char **copy_arg)
+{
+  create_sals_from_address_default (arg, canonical, type_wanted,
+                                   addr_start, copy_arg);
+}
+
+static void
+tracepoint_create_breakpoints_sal (struct gdbarch *gdbarch,
+                                  struct linespec_result *canonical,
+                                  struct linespec_sals *lsal,
+                                  char *cond_string,
+                                  enum bptype type_wanted,
+                                  enum bpdisp disposition,
+                                  int thread,
+                                  int task, int ignore_count,
+                                  const struct breakpoint_ops *ops,
+                                  int from_tty, int enabled,
+                                  int internal)
+{
+  create_breakpoints_sal_default (gdbarch, canonical, lsal,
+                                 cond_string, type_wanted,
+                                 disposition, thread, task,
+                                 ignore_count, ops, from_tty,
+                                 enabled, internal);
+}
+
+static void
+tracepoint_decode_linespec (struct breakpoint *b, char **s,
+                           struct symtabs_and_lines *sals)
+{
+  decode_linespec_default (b, s, sals);
+}
+
 struct breakpoint_ops tracepoint_breakpoint_ops;
 
+/* The breakpoint_ops structure to be used on static tracepoints with
+   markers (`-m').  */
+
+static void
+strace_marker_create_sals_from_address (char **arg,
+                                       struct linespec_result *canonical,
+                                       enum bptype type_wanted,
+                                       char *addr_start, char **copy_arg)
+{
+  struct linespec_sals lsal;
+
+  lsal.sals = decode_static_tracepoint_spec (arg);
+
+  *copy_arg = savestring (addr_start, *arg - addr_start);
+
+  canonical->addr_string = xstrdup (*copy_arg);
+  lsal.canonical = xstrdup (*copy_arg);
+  VEC_safe_push (linespec_sals, canonical->sals, &lsal);
+}
+
+static void
+strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
+                                     struct linespec_result *canonical,
+                                     struct linespec_sals *lsal,
+                                     char *cond_string,
+                                     enum bptype type_wanted,
+                                     enum bpdisp disposition,
+                                     int thread,
+                                     int task, int ignore_count,
+                                     const struct breakpoint_ops *ops,
+                                     int from_tty, int enabled,
+                                     int internal)
+{
+  int i;
+
+  /* If the user is creating a static tracepoint by marker id
+     (strace -m MARKER_ID), then store the sals index, so that
+     breakpoint_re_set can try to match up which of the newly
+     found markers corresponds to this one, and, don't try to
+     expand multiple locations for each sal, given than SALS
+     already should contain all sals for MARKER_ID.  */
+
+  for (i = 0; i < lsal->sals.nelts; ++i)
+    {
+      struct symtabs_and_lines expanded;
+      struct tracepoint *tp;
+      struct cleanup *old_chain;
+      char *addr_string;
+
+      expanded.nelts = 1;
+      expanded.sals = &lsal->sals.sals[i];
+
+      addr_string = xstrdup (canonical->addr_string);
+      old_chain = make_cleanup (xfree, addr_string);
+
+      tp = XCNEW (struct tracepoint);
+      init_breakpoint_sal (&tp->base, gdbarch, expanded,
+                          addr_string, NULL,
+                          cond_string, type_wanted, disposition,
+                          thread, task, ignore_count, ops,
+                          from_tty, enabled, internal,
+                          canonical->special_display);
+      /* Given that its possible to have multiple markers with
+        the same string id, if the user is creating a static
+        tracepoint by marker id ("strace -m MARKER_ID"), then
+        store the sals index, so that breakpoint_re_set can
+        try to match up which of the newly found markers
+        corresponds to this one  */
+      tp->static_trace_marker_id_idx = i;
+
+      install_breakpoint (internal, &tp->base, 0);
+
+      discard_cleanups (old_chain);
+    }
+}
+
+static void
+strace_marker_decode_linespec (struct breakpoint *b, char **s,
+                              struct symtabs_and_lines *sals)
+{
+  struct tracepoint *tp = (struct tracepoint *) b;
+
+  *sals = decode_static_tracepoint_spec (s);
+  if (sals->nelts > tp->static_trace_marker_id_idx)
+    {
+      sals->sals[0] = sals->sals[tp->static_trace_marker_id_idx];
+      sals->nelts = 1;
+    }
+  else
+    error (_("marker %s not found"), tp->static_trace_marker_id);
+}
+
+static struct breakpoint_ops strace_marker_breakpoint_ops;
+
+static int
+strace_marker_p (struct breakpoint *b)
+{
+  return b->ops == &strace_marker_breakpoint_ops;
+}
+
 /* Delete a breakpoint and clean up all traces of it in the data
    structures.  */
 
@@ -11500,7 +12049,8 @@ static int
 all_locations_are_pending (struct bp_location *loc)
 {
   for (; loc; loc = loc->next)
-    if (!loc->shlib_disabled)
+    if (!loc->shlib_disabled
+       && !loc->pspace->executing_startup)
       return 0;
   return 1;
 }
@@ -11754,7 +12304,7 @@ update_breakpoint_locations (struct breakpoint *b,
       if (b->cond_string != NULL)
        {
          char *s;
-         struct gdb_exception e;
+         volatile struct gdb_exception e;
 
          s = b->cond_string;
          TRY_CATCH (e, RETURN_MASK_ERROR)
@@ -11835,54 +12385,15 @@ 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};
   volatile struct gdb_exception e;
 
+  gdb_assert (b->ops != NULL);
   s = addr_string;
-  marker_spec = b->type == bp_static_tracepoint && is_marker_spec (s);
 
   TRY_CATCH (e, RETURN_MASK_ERROR)
     {
-      if (marker_spec)
-       {
-         struct tracepoint *tp = (struct tracepoint *) b;
-
-         sals = decode_static_tracepoint_spec (&s);
-         if (sals.nelts > tp->static_trace_marker_id_idx)
-           {
-             sals.sals[0] = sals.sals[tp->static_trace_marker_id_idx];
-             sals.nelts = 1;
-           }
-         else
-           error (_("marker %s not found"), tp->static_trace_marker_id);
-       }
-      else
-       {
-         struct linespec_result canonical;
-
-         init_linespec_result (&canonical);
-         decode_line_full (&s, DECODE_LINE_FUNFIRSTLINE,
-                           (struct symtab *) NULL, 0,
-                           &canonical, multiple_symbols_all,
-                           b->filter);
-
-         /* We should get 0 or 1 resulting SALs.  */
-         gdb_assert (VEC_length (linespec_sals, canonical.sals) < 2);
-
-         if (VEC_length (linespec_sals, canonical.sals) > 0)
-           {
-             struct linespec_sals *lsal;
-
-             lsal = VEC_index (linespec_sals, canonical.sals, 0);
-             sals = lsal->sals;
-             /* Arrange it so the destructor does not free the
-                contents.  */
-             lsal->sals.sals = NULL;
-           }
-
-         destroy_linespec_result (&canonical);
-       }
+      b->ops->decode_linespec (b, &s, &sals);
     }
   if (e.reason < 0)
     {
@@ -11935,7 +12446,7 @@ addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
          b->condition_not_parsed = 0;
        }
 
-      if (b->type == bp_static_tracepoint && !marker_spec)
+      if (b->type == bp_static_tracepoint && !strace_marker_p (b))
        sals.sals[0] = update_static_tracepoint (b, sals.sals[0]);
 
       *found = 1;
@@ -11978,6 +12489,73 @@ breakpoint_re_set_default (struct breakpoint *b)
   update_breakpoint_locations (b, expanded, expanded_end);
 }
 
+/* Default method for creating SALs from an address string.  It basically
+   calls parse_breakpoint_sals.  Return 1 for success, zero for failure.  */
+
+static void
+create_sals_from_address_default (char **arg,
+                                 struct linespec_result *canonical,
+                                 enum bptype type_wanted,
+                                 char *addr_start, char **copy_arg)
+{
+  parse_breakpoint_sals (arg, canonical);
+}
+
+/* Call create_breakpoints_sal for the given arguments.  This is the default
+   function for the `create_breakpoints_sal' method of
+   breakpoint_ops.  */
+
+static void
+create_breakpoints_sal_default (struct gdbarch *gdbarch,
+                               struct linespec_result *canonical,
+                               struct linespec_sals *lsal,
+                               char *cond_string,
+                               enum bptype type_wanted,
+                               enum bpdisp disposition,
+                               int thread,
+                               int task, int ignore_count,
+                               const struct breakpoint_ops *ops,
+                               int from_tty, int enabled,
+                               int internal)
+{
+  create_breakpoints_sal (gdbarch, canonical, cond_string,
+                         type_wanted, disposition,
+                         thread, task, ignore_count, ops, from_tty,
+                         enabled, internal);
+}
+
+/* Decode the line represented by S by calling decode_line_full.  This is the
+   default function for the `decode_linespec' method of breakpoint_ops.  */
+
+static void
+decode_linespec_default (struct breakpoint *b, char **s,
+                        struct symtabs_and_lines *sals)
+{
+  struct linespec_result canonical;
+
+  init_linespec_result (&canonical);
+  decode_line_full (s, DECODE_LINE_FUNFIRSTLINE,
+                   (struct symtab *) NULL, 0,
+                   &canonical, multiple_symbols_all,
+                   b->filter);
+
+  /* We should get 0 or 1 resulting SALs.  */
+  gdb_assert (VEC_length (linespec_sals, canonical.sals) < 2);
+
+  if (VEC_length (linespec_sals, canonical.sals) > 0)
+    {
+      struct linespec_sals *lsal;
+
+      lsal = VEC_index (linespec_sals, canonical.sals, 0);
+      *sals = lsal->sals;
+      /* Arrange it so the destructor does not free the
+        contents.  */
+      lsal->sals.sals = NULL;
+    }
+
+  destroy_linespec_result (&canonical);
+}
+
 /* Prepare the global context for a re-set of breakpoint B.  */
 
 static struct cleanup *
@@ -12325,7 +12903,7 @@ enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition)
     {
       /* Initialize it just to avoid a GCC false warning.  */
       enum enable_state orig_enable_state = 0;
-      struct gdb_exception e;
+      volatile struct gdb_exception e;
 
       TRY_CATCH (e, RETURN_MASK_ALL)
        {
@@ -12796,6 +13374,15 @@ ftrace_command (char *arg, int from_tty)
 void
 strace_command (char *arg, int from_tty)
 {
+  struct breakpoint_ops *ops;
+
+  /* Decide if we are dealing with a static tracepoint marker (`-m'),
+     or with a normal static tracepoint.  */
+  if (arg && strncmp (arg, "-m", 2) == 0 && isspace (arg[2]))
+    ops = &strace_marker_breakpoint_ops;
+  else
+    ops = &tracepoint_breakpoint_ops;
+
   if (create_breakpoint (get_current_arch (),
                         arg,
                         NULL, 0, 1 /* parse arg */,
@@ -12803,7 +13390,7 @@ strace_command (char *arg, int from_tty)
                         bp_static_tracepoint /* type_wanted */,
                         0 /* Ignore count */,
                         pending_break_support,
-                        &tracepoint_breakpoint_ops,
+                        ops,
                         from_tty,
                         1 /* enabled */,
                         0 /* internal */))
@@ -13407,7 +13994,8 @@ is_non_inline_function (struct breakpoint *b)
    have been inlined.  */
 
 int
-pc_at_non_inline_function (struct address_space *aspace, CORE_ADDR pc)
+pc_at_non_inline_function (struct address_space *aspace, CORE_ADDR pc,
+                          const struct target_waitstatus *ws)
 {
   struct breakpoint *b;
   struct bp_location *bl;
@@ -13420,7 +14008,7 @@ pc_at_non_inline_function (struct address_space *aspace, CORE_ADDR pc)
       for (bl = b->loc; bl != NULL; bl = bl->next)
        {
          if (!bl->shlib_disabled
-             && bpstat_check_location (bl, aspace, pc))
+             && bpstat_check_location (bl, aspace, pc, ws))
            return 1;
        }
     }
@@ -13448,6 +14036,9 @@ initialize_breakpoint_ops (void)
   ops->insert_location = bkpt_insert_location;
   ops->remove_location = bkpt_remove_location;
   ops->breakpoint_hit = bkpt_breakpoint_hit;
+  ops->create_sals_from_address = bkpt_create_sals_from_address;
+  ops->create_breakpoints_sal = bkpt_create_breakpoints_sal;
+  ops->decode_linespec = bkpt_decode_linespec;
 
   /* The breakpoint_ops structure to be used in regular breakpoints.  */
   ops = &bkpt_breakpoint_ops;
@@ -13528,6 +14119,16 @@ initialize_breakpoint_ops (void)
   ops->print_one_detail = tracepoint_print_one_detail;
   ops->print_mention = tracepoint_print_mention;
   ops->print_recreate = tracepoint_print_recreate;
+  ops->create_sals_from_address = tracepoint_create_sals_from_address;
+  ops->create_breakpoints_sal = tracepoint_create_breakpoints_sal;
+  ops->decode_linespec = tracepoint_decode_linespec;
+
+  /* Static tracepoints with marker (`-m').  */
+  ops = &strace_marker_breakpoint_ops;
+  *ops = tracepoint_breakpoint_ops;
+  ops->create_sals_from_address = strace_marker_create_sals_from_address;
+  ops->create_breakpoints_sal = strace_marker_create_breakpoints_sal;
+  ops->decode_linespec = strace_marker_decode_linespec;
 
   /* Fork catchpoints.  */
   ops = &catch_fork_breakpoint_ops;
@@ -13574,6 +14175,19 @@ initialize_breakpoint_ops (void)
   ops->print_one = print_one_catch_syscall;
   ops->print_mention = print_mention_catch_syscall;
   ops->print_recreate = print_recreate_catch_syscall;
+
+  /* Solib-related catchpoints.  */
+  ops = &catch_solib_breakpoint_ops;
+  *ops = base_breakpoint_ops;
+  ops->dtor = dtor_catch_solib;
+  ops->insert_location = insert_catch_solib;
+  ops->remove_location = remove_catch_solib;
+  ops->breakpoint_hit = breakpoint_hit_catch_solib;
+  ops->check_status = check_status_catch_solib;
+  ops->print_it = print_it_catch_solib;
+  ops->print_one = print_one_catch_solib;
+  ops->print_mention = print_mention_catch_solib;
+  ops->print_recreate = print_recreate_catch_solib;
 }
 
 void
@@ -13851,15 +14465,13 @@ Set temporary catchpoints to catch events."),
 
   /* Add catch and tcatch sub-commands.  */
   add_catch_command ("catch", _("\
-Catch an exception, when caught.\n\
-With an argument, catch only exceptions with the given name."),
+Catch an exception, when caught."),
                     catch_catch_command,
                      NULL,
                     CATCH_PERMANENT,
                     CATCH_TEMPORARY);
   add_catch_command ("throw", _("\
-Catch an exception, when thrown.\n\
-With an argument, catch only exceptions with the given name."),
+Catch an exception, when thrown."),
                     catch_throw_command,
                      NULL,
                     CATCH_PERMANENT,
@@ -13879,6 +14491,20 @@ With an argument, catch only exceptions with the given name."),
                      NULL,
                     CATCH_PERMANENT,
                     CATCH_TEMPORARY);
+  add_catch_command ("load", _("Catch loads of shared libraries.\n\
+Usage: catch load [REGEX]\n\
+If REGEX is given, only stop for libraries matching the regular expression."),
+                    catch_load_command_1,
+                    NULL,
+                    CATCH_PERMANENT,
+                    CATCH_TEMPORARY);
+  add_catch_command ("unload", _("Catch unloads of shared libraries.\n\
+Usage: catch unload [REGEX]\n\
+If REGEX is given, only stop for libraries matching the regular expression."),
+                    catch_unload_command_1,
+                    NULL,
+                    CATCH_PERMANENT,
+                    CATCH_TEMPORARY);
   add_catch_command ("syscall", _("\
 Catch system calls by their names and/or numbers.\n\
 Arguments say which system calls to catch.  If no arguments\n\
This page took 0.048582 seconds and 4 git commands to generate.