gdb/gdbserver:
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 1158f0e229b24ea63087b60bae438696c5fe01da..ab5f3240fb7f967cdca22a0b2ec8e9342901b5e7 100644 (file)
 #include "jit.h"
 #include "xml-syscall.h"
 #include "parser-defs.h"
+#include "gdb_regex.h"
+#include "probe.h"
 #include "cli/cli-utils.h"
 #include "continuations.h"
 #include "stack.h"
 #include "skip.h"
-#include "record.h"
 #include "gdb_regex.h"
 #include "ax-gdb.h"
 
@@ -112,7 +113,7 @@ static void create_breakpoints_sal_default (struct gdbarch *,
                                            enum bpdisp, int, int,
                                            int,
                                            const struct breakpoint_ops *,
-                                           int, int, int);
+                                           int, int, int, unsigned);
 
 static void decode_linespec_default (struct breakpoint *, char **,
                                     struct symtabs_and_lines *);
@@ -290,6 +291,9 @@ static struct breakpoint_ops momentary_breakpoint_ops;
    breakpoints.  */
 struct breakpoint_ops bkpt_breakpoint_ops;
 
+/* Breakpoints set on probes.  */
+static struct breakpoint_ops bkpt_probe_breakpoint_ops;
+
 /* A reference-counted struct command_line.  This lets multiple
    breakpoints share a single command list.  */
 struct counted_command_line
@@ -404,9 +408,8 @@ show_always_inserted_mode (struct ui_file *file, int from_tty,
 int
 breakpoints_always_inserted_mode (void)
 {
-  return ((always_inserted_mode == always_inserted_on
-          || (always_inserted_mode == always_inserted_auto && non_stop))
-         && !RECORD_IS_USED);
+  return (always_inserted_mode == always_inserted_on
+         || (always_inserted_mode == always_inserted_auto && non_stop));
 }
 
 static const char condition_evaluation_both[] = "host or target";
@@ -1318,6 +1321,10 @@ bp_location_has_shadow (struct bp_location *bl)
 /* Update BUF, which is LEN bytes read from the target address MEMADDR,
    by replacing any memory breakpoints with their shadowed contents.
 
+   If READBUF is not NULL, this buffer must not overlap with any of
+   the breakpoint location's shadow_contents buffers.  Otherwise,
+   a failed assertion internal error will be raised.
+
    The range of shadowed area by each bp_location is:
      bl->address - bp_location_placed_address_before_address_max
      up to bl->address + bp_location_shadow_len_after_address_max
@@ -1446,6 +1453,12 @@ breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
 
     if (readbuf != NULL)
       {
+       /* Verify that the readbuf buffer does not overlap with
+          the shadow_contents buffer.  */
+       gdb_assert (bl->target_info.shadow_contents >= readbuf + len
+                   || readbuf >= (bl->target_info.shadow_contents
+                                  + bl->target_info.shadow_len));
+
        /* Update the read buffer with this inserted breakpoint's
           shadow.  */
        memcpy (readbuf + bp_addr - memaddr,
@@ -2082,8 +2095,15 @@ insert_bp_location (struct bp_location *bl,
   if (!should_be_inserted (bl) || (bl->inserted && !bl->needs_update))
     return 0;
 
-  /* Initialize the target-specific information.  */
-  memset (&bl->target_info, 0, sizeof (bl->target_info));
+  /* Note we don't initialize bl->target_info, as that wipes out
+     the breakpoint location's shadow_contents if the breakpoint
+     is still inserted at that location.  This in turn breaks
+     target_read_memory which depends on these buffers when
+     a memory read is requested at the breakpoint location:
+     Once the target_info has been wiped, we fail to see that
+     we have a breakpoint inserted at that address and thus
+     read the breakpoint instead of returning the data saved in
+     the breakpoint location's shadow contents.  */
   bl->target_info.placed_address = bl->address;
   bl->target_info.placed_address_space = bl->pspace->aspace;
   bl->target_info.length = bl->length;
@@ -2408,6 +2428,19 @@ insert_breakpoints (void)
     insert_breakpoint_locations ();
 }
 
+/* Invoke CALLBACK for each of bp_location.  */
+
+void
+iterate_over_bp_locations (walk_bp_location_callback callback)
+{
+  struct bp_location *loc, **loc_tmp;
+
+  ALL_BP_LOCATIONS (loc, loc_tmp)
+    {
+      callback (loc, NULL);
+    }
+}
+
 /* This is used when we need to synch breakpoint conditions between GDB and the
    target.  It is the case with deleting and disabling of breakpoints when using
    always-inserted mode.  */
@@ -2711,11 +2744,23 @@ struct breakpoint_objfile_data
   /* Minimal symbol(s) for "longjmp", "siglongjmp", etc. (if any).  */
   struct minimal_symbol *longjmp_msym[NUM_LONGJMP_NAMES];
 
+  /* True if we have looked for longjmp probes.  */
+  int longjmp_searched;
+
+  /* SystemTap probe points for longjmp (if any).  */
+  VEC (probe_p) *longjmp_probes;
+
   /* Minimal symbol for "std::terminate()" (if any).  */
   struct minimal_symbol *terminate_msym;
 
   /* Minimal symbol for "_Unwind_DebugHook" (if any).  */
   struct minimal_symbol *exception_msym;
+
+  /* True if we have looked for exception probes.  */
+  int exception_searched;
+
+  /* SystemTap probe points for unwinding (if any).  */
+  VEC (probe_p) *exception_probes;
 };
 
 static const struct objfile_data *breakpoint_objfile_key;
@@ -2751,6 +2796,15 @@ get_breakpoint_objfile_data (struct objfile *objfile)
   return bp_objfile_data;
 }
 
+static void
+free_breakpoint_probes (struct objfile *obj, void *data)
+{
+  struct breakpoint_objfile_data *bp_objfile_data = data;
+
+  VEC_free (probe_p, bp_objfile_data->longjmp_probes);
+  VEC_free (probe_p, bp_objfile_data->exception_probes);
+}
+
 static void
 create_overlay_event_breakpoint (void)
 {
@@ -2828,6 +2882,37 @@ create_longjmp_master_breakpoint (void)
 
       bp_objfile_data = get_breakpoint_objfile_data (objfile);
 
+      if (!bp_objfile_data->longjmp_searched)
+       {
+         bp_objfile_data->longjmp_probes
+           = find_probes_in_objfile (objfile, "libc", "longjmp");
+         bp_objfile_data->longjmp_searched = 1;
+       }
+
+      if (bp_objfile_data->longjmp_probes != NULL)
+       {
+         int i;
+         struct probe *probe;
+         struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
+         for (i = 0;
+              VEC_iterate (probe_p,
+                           bp_objfile_data->longjmp_probes,
+                           i, probe);
+              ++i)
+           {
+             struct breakpoint *b;
+
+             b = create_internal_breakpoint (gdbarch, probe->address,
+                                             bp_longjmp_master,
+                                             &internal_breakpoint_ops);
+             b->addr_string = xstrdup ("-probe-stap libc:longjmp");
+             b->enable_state = bp_disabled;
+           }
+
+         continue;
+       }
+
       for (i = 0; i < NUM_LONGJMP_NAMES; i++)
        {
          struct breakpoint *b;
@@ -2938,6 +3023,40 @@ create_exception_master_breakpoint (void)
 
       bp_objfile_data = get_breakpoint_objfile_data (objfile);
 
+      /* We prefer the SystemTap probe point if it exists.  */
+      if (!bp_objfile_data->exception_searched)
+       {
+         bp_objfile_data->exception_probes
+           = find_probes_in_objfile (objfile, "libgcc", "unwind");
+         bp_objfile_data->exception_searched = 1;
+       }
+
+      if (bp_objfile_data->exception_probes != NULL)
+       {
+         struct gdbarch *gdbarch = get_objfile_arch (objfile);
+         int i;
+         struct probe *probe;
+
+         for (i = 0;
+              VEC_iterate (probe_p,
+                           bp_objfile_data->exception_probes,
+                           i, probe);
+              ++i)
+           {
+             struct breakpoint *b;
+
+             b = create_internal_breakpoint (gdbarch, probe->address,
+                                             bp_exception_master,
+                                             &internal_breakpoint_ops);
+             b->addr_string = xstrdup ("-probe-stap libgcc:unwind");
+             b->enable_state = bp_disabled;
+           }
+
+         continue;
+       }
+
+      /* Otherwise, try the hook function.  */
+
       if (msym_not_found_p (bp_objfile_data->exception_msym))
        continue;
 
@@ -3618,7 +3737,7 @@ breakpoint_thread_match (struct address_space *aspace, CORE_ADDR pc,
    in breakpoint.h.  */
 
 int
-ep_is_catchpoint (struct breakpoint *ep)
+is_catchpoint (struct breakpoint *ep)
 {
   return (ep->type == bp_catchpoint);
 }
@@ -5260,10 +5379,10 @@ print_breakpoint_location (struct breakpoint *b,
     }
   else if (loc)
     {
-      struct ui_stream *stb = ui_out_stream_new (uiout);
-      struct cleanup *stb_chain = make_cleanup_ui_out_stream_delete (stb);
+      struct ui_file *stb = mem_fileopen ();
+      struct cleanup *stb_chain = make_cleanup_ui_file_delete (stb);
 
-      print_address_symbolic (loc->gdbarch, loc->address, stb->stream,
+      print_address_symbolic (loc->gdbarch, loc->address, stb,
                              demangle, "");
       ui_out_field_stream (uiout, "at", stb);
 
@@ -5583,7 +5702,7 @@ print_one_breakpoint_location (struct breakpoint *b,
   if (!part_of_multiple && b->hit_count)
     {
       /* FIXME should make an annotation for this.  */
-      if (ep_is_catchpoint (b))
+      if (is_catchpoint (b))
        ui_out_text (uiout, "\tcatchpoint");
       else if (is_tracepoint (b))
        ui_out_text (uiout, "\ttracepoint");
@@ -7374,6 +7493,8 @@ catch_unload_command_1 (char *arg, int from_tty,
   catch_load_or_unload (arg, from_tty, 0, command);
 }
 
+DEF_VEC_I(int);
+
 /* 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
@@ -7405,6 +7526,47 @@ dtor_catch_syscall (struct breakpoint *b)
   base_breakpoint_ops.dtor (b);
 }
 
+static const struct inferior_data *catch_syscall_inferior_data = NULL;
+
+struct catch_syscall_inferior_data
+{
+  /* We keep a count of the number of times the user has requested a
+     particular syscall to be tracked, and pass this information to the
+     target.  This lets capable targets implement filtering directly.  */
+
+  /* Number of times that "any" syscall is requested.  */
+  int any_syscall_count;
+
+  /* Count of each system call.  */
+  VEC(int) *syscalls_counts;
+
+  /* This counts all syscall catch requests, so we can readily determine
+     if any catching is necessary.  */
+  int total_syscalls_count;
+};
+
+static struct catch_syscall_inferior_data*
+get_catch_syscall_inferior_data (struct inferior *inf)
+{
+  struct catch_syscall_inferior_data *inf_data;
+
+  inf_data = inferior_data (inf, catch_syscall_inferior_data);
+  if (inf_data == NULL)
+    {
+      inf_data = XZALLOC (struct catch_syscall_inferior_data);
+      set_inferior_data (inf, catch_syscall_inferior_data, inf_data);
+    }
+
+  return inf_data;
+}
+
+static void
+catch_syscall_inferior_data_cleanup (struct inferior *inf, void *arg)
+{
+  xfree (arg);
+}
+
+
 /* Implement the "insert" breakpoint_ops method for syscall
    catchpoints.  */
 
@@ -7413,10 +7575,12 @@ insert_catch_syscall (struct bp_location *bl)
 {
   struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
   struct inferior *inf = current_inferior ();
+  struct catch_syscall_inferior_data *inf_data
+    = get_catch_syscall_inferior_data (inf);
 
-  ++inf->total_syscalls_count;
+  ++inf_data->total_syscalls_count;
   if (!c->syscalls_to_be_caught)
-    ++inf->any_syscall_count;
+    ++inf_data->any_syscall_count;
   else
     {
       int i, iter;
@@ -7427,28 +7591,31 @@ insert_catch_syscall (struct bp_location *bl)
        {
           int elem;
 
-         if (iter >= VEC_length (int, inf->syscalls_counts))
+         if (iter >= VEC_length (int, inf_data->syscalls_counts))
            {
-              int old_size = VEC_length (int, inf->syscalls_counts);
+              int old_size = VEC_length (int, inf_data->syscalls_counts);
               uintptr_t vec_addr_offset
                = old_size * ((uintptr_t) sizeof (int));
               uintptr_t vec_addr;
-              VEC_safe_grow (int, inf->syscalls_counts, iter + 1);
-              vec_addr = (uintptr_t) VEC_address (int, inf->syscalls_counts) +
-               vec_addr_offset;
+              VEC_safe_grow (int, inf_data->syscalls_counts, iter + 1);
+              vec_addr = ((uintptr_t) VEC_address (int,
+                                                 inf_data->syscalls_counts)
+                         + vec_addr_offset);
               memset ((void *) vec_addr, 0,
                       (iter + 1 - old_size) * sizeof (int));
            }
-          elem = VEC_index (int, inf->syscalls_counts, iter);
-          VEC_replace (int, inf->syscalls_counts, iter, ++elem);
+          elem = VEC_index (int, inf_data->syscalls_counts, iter);
+          VEC_replace (int, inf_data->syscalls_counts, iter, ++elem);
        }
     }
 
   return target_set_syscall_catchpoint (PIDGET (inferior_ptid),
-                                       inf->total_syscalls_count != 0,
-                                       inf->any_syscall_count,
-                                       VEC_length (int, inf->syscalls_counts),
-                                       VEC_address (int, inf->syscalls_counts));
+                                       inf_data->total_syscalls_count != 0,
+                                       inf_data->any_syscall_count,
+                                       VEC_length (int,
+                                                   inf_data->syscalls_counts),
+                                       VEC_address (int,
+                                                    inf_data->syscalls_counts));
 }
 
 /* Implement the "remove" breakpoint_ops method for syscall
@@ -7459,10 +7626,12 @@ remove_catch_syscall (struct bp_location *bl)
 {
   struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
   struct inferior *inf = current_inferior ();
+  struct catch_syscall_inferior_data *inf_data
+    = get_catch_syscall_inferior_data (inf);
 
-  --inf->total_syscalls_count;
+  --inf_data->total_syscalls_count;
   if (!c->syscalls_to_be_caught)
-    --inf->any_syscall_count;
+    --inf_data->any_syscall_count;
   else
     {
       int i, iter;
@@ -7472,20 +7641,21 @@ remove_catch_syscall (struct bp_location *bl)
            i++)
        {
           int elem;
-         if (iter >= VEC_length (int, inf->syscalls_counts))
+         if (iter >= VEC_length (int, inf_data->syscalls_counts))
            /* Shouldn't happen.  */
            continue;
-          elem = VEC_index (int, inf->syscalls_counts, iter);
-          VEC_replace (int, inf->syscalls_counts, iter, --elem);
+          elem = VEC_index (int, inf_data->syscalls_counts, iter);
+          VEC_replace (int, inf_data->syscalls_counts, iter, --elem);
         }
     }
 
   return target_set_syscall_catchpoint (PIDGET (inferior_ptid),
-                                       inf->total_syscalls_count != 0,
-                                       inf->any_syscall_count,
-                                       VEC_length (int, inf->syscalls_counts),
+                                       inf_data->total_syscalls_count != 0,
+                                       inf_data->any_syscall_count,
+                                       VEC_length (int,
+                                                   inf_data->syscalls_counts),
                                        VEC_address (int,
-                                                    inf->syscalls_counts));
+                                                    inf_data->syscalls_counts));
 }
 
 /* Implement the "breakpoint_hit" breakpoint_ops method for syscall
@@ -8070,6 +8240,7 @@ momentary_breakpoint_from_master (struct breakpoint *orig,
   copy->loc->address = orig->loc->address;
   copy->loc->section = orig->loc->section;
   copy->loc->pspace = orig->loc->pspace;
+  copy->loc->probe = orig->loc->probe;
 
   if (orig->loc->source_file != NULL)
     copy->loc->source_file = xstrdup (orig->loc->source_file);
@@ -8155,6 +8326,7 @@ add_location_to_breakpoint (struct breakpoint *b,
   loc->requested_address = sal->pc;
   loc->address = adjusted_address;
   loc->pspace = sal->pspace;
+  loc->probe = sal->probe;
   gdb_assert (loc->pspace != NULL);
   loc->section = sal->section;
   loc->gdbarch = loc_gdbarch;
@@ -8223,7 +8395,8 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
                     enum bptype type, enum bpdisp disposition,
                     int thread, int task, int ignore_count,
                     const struct breakpoint_ops *ops, int from_tty,
-                    int enabled, int internal, int display_canonical)
+                    int enabled, int internal, unsigned flags,
+                    int display_canonical)
 {
   int i;
 
@@ -8269,6 +8442,9 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
          b->enable_state = enabled ? bp_enabled : bp_disabled;
          b->disposition = disposition;
 
+         if ((flags & CREATE_BREAKPOINT_FLAGS_INSERTED) != 0)
+           b->loc->inserted = 1;
+
          if (type == bp_static_tracepoint)
            {
              struct tracepoint *t = (struct tracepoint *) b;
@@ -8312,6 +8488,8 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
       else
        {
          loc = add_location_to_breakpoint (b, &sal);
+         if ((flags & CREATE_BREAKPOINT_FLAGS_INSERTED) != 0)
+           loc->inserted = 1;
        }
 
       if (bp_loc_is_permanent (loc))
@@ -8344,7 +8522,8 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
                       enum bptype type, enum bpdisp disposition,
                       int thread, int task, int ignore_count,
                       const struct breakpoint_ops *ops, int from_tty,
-                      int enabled, int internal, int display_canonical)
+                      int enabled, int internal, unsigned flags,
+                      int display_canonical)
 {
   struct breakpoint *b;
   struct cleanup *old_chain;
@@ -8367,7 +8546,8 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
                       type, disposition,
                       thread, task, ignore_count,
                       ops, from_tty,
-                      enabled, internal, display_canonical);
+                      enabled, internal, flags,
+                      display_canonical);
   discard_cleanups (old_chain);
 
   install_breakpoint (internal, b, 0);
@@ -8395,7 +8575,7 @@ create_breakpoints_sal (struct gdbarch *gdbarch,
                        enum bptype type, enum bpdisp disposition,
                        int thread, int task, int ignore_count,
                        const struct breakpoint_ops *ops, int from_tty,
-                       int enabled, int internal)
+                       int enabled, int internal, unsigned flags)
 {
   int i;
   struct linespec_sals *lsal;
@@ -8419,7 +8599,7 @@ create_breakpoints_sal (struct gdbarch *gdbarch,
                             filter_string,
                             cond_string, type, disposition,
                             thread, task, ignore_count, ops,
-                            from_tty, enabled, internal,
+                            from_tty, enabled, internal, flags,
                             canonical->special_display);
       discard_cleanups (inner);
     }
@@ -8679,7 +8859,8 @@ create_breakpoint (struct gdbarch *gdbarch,
                   int ignore_count,
                   enum auto_boolean pending_break_support,
                   const struct breakpoint_ops *ops,
-                  int from_tty, int enabled, int internal)
+                  int from_tty, int enabled, int internal,
+                  unsigned flags)
 {
   volatile struct gdb_exception e;
   char *copy_arg = NULL;
@@ -8819,7 +9000,7 @@ create_breakpoint (struct gdbarch *gdbarch,
                                   cond_string, type_wanted,
                                   tempflag ? disp_del : disp_donttouch,
                                   thread, task, ignore_count, ops,
-                                  from_tty, enabled, internal);
+                                  from_tty, enabled, internal, flags);
     }
   else
     {
@@ -8885,6 +9066,14 @@ break_command_1 (char *arg, int flag, int from_tty)
   enum bptype type_wanted = (flag & BP_HARDWAREFLAG
                             ? bp_hardware_breakpoint
                             : bp_breakpoint);
+  struct breakpoint_ops *ops;
+  const char *arg_cp = arg;
+
+  /* Matching breakpoints on probes.  */
+  if (arg && probe_linespec_to_ops (&arg_cp) != NULL)
+    ops = &bkpt_probe_breakpoint_ops;
+  else
+    ops = &bkpt_breakpoint_ops;
 
   create_breakpoint (get_current_arch (),
                     arg,
@@ -8892,10 +9081,11 @@ break_command_1 (char *arg, int flag, int from_tty)
                     tempflag, type_wanted,
                     0 /* Ignore count */,
                     pending_break_support,
-                    &bkpt_breakpoint_ops,
+                    ops,
                     from_tty,
                     1 /* enabled */,
-                    0 /* internal */);
+                    0 /* internal */,
+                    0);
 }
 
 /* Helper function for break_command_1 and disassemble_command.  */
@@ -9144,8 +9334,8 @@ print_one_detail_ranged_breakpoint (const struct breakpoint *b,
 {
   CORE_ADDR address_start, address_end;
   struct bp_location *bl = b->loc;
-  struct ui_stream *stb = ui_out_stream_new (uiout);
-  struct cleanup *cleanup = make_cleanup_ui_out_stream_delete (stb);
+  struct ui_file *stb = mem_fileopen ();
+  struct cleanup *cleanup = make_cleanup_ui_file_delete (stb);
 
   gdb_assert (bl);
 
@@ -9153,7 +9343,7 @@ print_one_detail_ranged_breakpoint (const struct breakpoint *b,
   address_end = address_start + bl->length - 1;
 
   ui_out_text (uiout, "\taddress range: ");
-  fprintf_unfiltered (stb->stream, "[%s, %s]",
+  fprintf_unfiltered (stb, "[%s, %s]",
                      print_core_address (bl->gdbarch, address_start),
                      print_core_address (bl->gdbarch, address_end));
   ui_out_field_stream (uiout, "addr", stb);
@@ -9588,7 +9778,7 @@ print_it_watchpoint (bpstat bs)
   struct cleanup *old_chain;
   struct breakpoint *b;
   const struct bp_location *bl;
-  struct ui_stream *stb;
+  struct ui_file *stb;
   enum print_stop_action result;
   struct watchpoint *w;
   struct ui_out *uiout = current_uiout;
@@ -9599,8 +9789,8 @@ print_it_watchpoint (bpstat bs)
   b = bs->breakpoint_at;
   w = (struct watchpoint *) b;
 
-  stb = ui_out_stream_new (uiout);
-  old_chain = make_cleanup_ui_out_stream_delete (stb);
+  stb = mem_fileopen ();
+  old_chain = make_cleanup_ui_file_delete (stb);
 
   switch (b->type)
     {
@@ -9614,10 +9804,10 @@ print_it_watchpoint (bpstat bs)
       mention (b);
       make_cleanup_ui_out_tuple_begin_end (uiout, "value");
       ui_out_text (uiout, "\nOld value = ");
-      watchpoint_value_print (bs->old_val, stb->stream);
+      watchpoint_value_print (bs->old_val, stb);
       ui_out_field_stream (uiout, "old", stb);
       ui_out_text (uiout, "\nNew value = ");
-      watchpoint_value_print (w->val, stb->stream);
+      watchpoint_value_print (w->val, stb);
       ui_out_field_stream (uiout, "new", stb);
       ui_out_text (uiout, "\n");
       /* More than one watchpoint may have been triggered.  */
@@ -9632,7 +9822,7 @@ print_it_watchpoint (bpstat bs)
       mention (b);
       make_cleanup_ui_out_tuple_begin_end (uiout, "value");
       ui_out_text (uiout, "\nValue = ");
-      watchpoint_value_print (w->val, stb->stream);
+      watchpoint_value_print (w->val, stb);
       ui_out_field_stream (uiout, "value", stb);
       ui_out_text (uiout, "\n");
       result = PRINT_UNKNOWN;
@@ -9649,7 +9839,7 @@ print_it_watchpoint (bpstat bs)
          mention (b);
          make_cleanup_ui_out_tuple_begin_end (uiout, "value");
          ui_out_text (uiout, "\nOld value = ");
-         watchpoint_value_print (bs->old_val, stb->stream);
+         watchpoint_value_print (bs->old_val, stb);
          ui_out_field_stream (uiout, "old", stb);
          ui_out_text (uiout, "\nNew value = ");
        }
@@ -9663,7 +9853,7 @@ print_it_watchpoint (bpstat bs)
          make_cleanup_ui_out_tuple_begin_end (uiout, "value");
          ui_out_text (uiout, "\nValue = ");
        }
-      watchpoint_value_print (w->val, stb->stream);
+      watchpoint_value_print (w->val, stb);
       ui_out_field_stream (uiout, "new", stb);
       ui_out_text (uiout, "\n");
       result = PRINT_UNKNOWN;
@@ -10770,7 +10960,8 @@ handle_gnu_v3_exceptions (int tempflag, char *cond_string,
                     AUTO_BOOLEAN_TRUE /* pending */,
                     &gnu_v3_exception_catchpoint_ops, from_tty,
                     1 /* enabled */,
-                    0 /* internal */);
+                    0 /* internal */,
+                    0);
 
   return 1;
 }
@@ -11997,7 +12188,7 @@ base_breakpoint_create_breakpoints_sal (struct gdbarch *gdbarch,
                                        int task, int ignore_count,
                                        const struct breakpoint_ops *o,
                                        int from_tty, int enabled,
-                                       int internal)
+                                       int internal, unsigned flags)
 {
   internal_error_pure_virtual_called ();
 }
@@ -12199,13 +12390,13 @@ bkpt_create_breakpoints_sal (struct gdbarch *gdbarch,
                             int task, int ignore_count,
                             const struct breakpoint_ops *ops,
                             int from_tty, int enabled,
-                            int internal)
+                            int internal, unsigned flags)
 {
   create_breakpoints_sal_default (gdbarch, canonical, lsal,
                                  cond_string, type_wanted,
                                  disposition, thread, task,
                                  ignore_count, ops, from_tty,
-                                 enabled, internal);
+                                 enabled, internal, flags);
 }
 
 static void
@@ -12364,6 +12555,57 @@ momentary_bkpt_print_mention (struct breakpoint *b)
   /* Nothing to mention.  These breakpoints are internal.  */
 }
 
+/* Specific methods for probe breakpoints.  */
+
+static int
+bkpt_probe_insert_location (struct bp_location *bl)
+{
+  int v = bkpt_insert_location (bl);
+
+  if (v == 0)
+    {
+      /* The insertion was successful, now let's set the probe's semaphore
+        if needed.  */
+      bl->probe->pops->set_semaphore (bl->probe, bl->gdbarch);
+    }
+
+  return v;
+}
+
+static int
+bkpt_probe_remove_location (struct bp_location *bl)
+{
+  /* Let's clear the semaphore before removing the location.  */
+  bl->probe->pops->clear_semaphore (bl->probe, bl->gdbarch);
+
+  return bkpt_remove_location (bl);
+}
+
+static void
+bkpt_probe_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 = parse_probes (arg, canonical);
+
+  *copy_arg = xstrdup (canonical->addr_string);
+  lsal.canonical = xstrdup (*copy_arg);
+
+  VEC_safe_push (linespec_sals, canonical->sals, &lsal);
+}
+
+static void
+bkpt_probe_decode_linespec (struct breakpoint *b, char **s,
+                           struct symtabs_and_lines *sals)
+{
+  *sals = parse_probes (s, NULL);
+  if (!sals->sals)
+    error (_("probe not found"));
+}
+
 /* The breakpoint_ops structure to be used in tracepoints.  */
 
 static void
@@ -12469,13 +12711,13 @@ tracepoint_create_breakpoints_sal (struct gdbarch *gdbarch,
                                   int task, int ignore_count,
                                   const struct breakpoint_ops *ops,
                                   int from_tty, int enabled,
-                                  int internal)
+                                  int internal, unsigned flags)
 {
   create_breakpoints_sal_default (gdbarch, canonical, lsal,
                                  cond_string, type_wanted,
                                  disposition, thread, task,
                                  ignore_count, ops, from_tty,
-                                 enabled, internal);
+                                 enabled, internal, flags);
 }
 
 static void
@@ -12487,6 +12729,30 @@ tracepoint_decode_linespec (struct breakpoint *b, char **s,
 
 struct breakpoint_ops tracepoint_breakpoint_ops;
 
+/* The breakpoint_ops structure to be use on tracepoints placed in a
+   static probe.  */
+
+static void
+tracepoint_probe_create_sals_from_address (char **arg,
+                                          struct linespec_result *canonical,
+                                          enum bptype type_wanted,
+                                          char *addr_start, char **copy_arg)
+{
+  /* We use the same method for breakpoint on probes.  */
+  bkpt_probe_create_sals_from_address (arg, canonical, type_wanted,
+                                      addr_start, copy_arg);
+}
+
+static void
+tracepoint_probe_decode_linespec (struct breakpoint *b, char **s,
+                                 struct symtabs_and_lines *sals)
+{
+  /* We use the same method for breakpoint on probes.  */
+  bkpt_probe_decode_linespec (b, s, sals);
+}
+
+static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
+
 /* The breakpoint_ops structure to be used on static tracepoints with
    markers (`-m').  */
 
@@ -12518,7 +12784,7 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
                                      int task, int ignore_count,
                                      const struct breakpoint_ops *ops,
                                      int from_tty, int enabled,
-                                     int internal)
+                                     int internal, unsigned flags)
 {
   int i;
 
@@ -12547,7 +12813,7 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
                           addr_string, NULL,
                           cond_string, type_wanted, disposition,
                           thread, task, ignore_count, ops,
-                          from_tty, enabled, internal,
+                          from_tty, enabled, internal, flags,
                           canonical->special_display);
       /* Given that its possible to have multiple markers with
         the same string id, if the user is creating a static
@@ -13252,12 +13518,12 @@ create_breakpoints_sal_default (struct gdbarch *gdbarch,
                                int task, int ignore_count,
                                const struct breakpoint_ops *ops,
                                int from_tty, int enabled,
-                               int internal)
+                               int internal, unsigned flags)
 {
   create_breakpoints_sal (gdbarch, canonical, cond_string,
                          type_wanted, disposition,
                          thread, task, ignore_count, ops, from_tty,
-                         enabled, internal);
+                         enabled, internal, flags);
 }
 
 /* Decode the line represented by S by calling decode_line_full.  This is the
@@ -14060,9 +14326,10 @@ is_syscall_catchpoint_enabled (struct breakpoint *bp)
 int
 catch_syscall_enabled (void)
 {
-  struct inferior *inf = current_inferior ();
+  struct catch_syscall_inferior_data *inf_data
+    = get_catch_syscall_inferior_data (current_inferior ());
 
-  return inf->total_syscalls_count != 0;
+  return inf_data->total_syscalls_count != 0;
 }
 
 int
@@ -14117,6 +14384,14 @@ set_tracepoint_count (int num)
 static void
 trace_command (char *arg, int from_tty)
 {
+  struct breakpoint_ops *ops;
+  const char *arg_cp = arg;
+
+  if (arg && probe_linespec_to_ops (&arg_cp))
+    ops = &tracepoint_probe_breakpoint_ops;
+  else
+    ops = &tracepoint_breakpoint_ops;
+
   if (create_breakpoint (get_current_arch (),
                         arg,
                         NULL, 0, 1 /* parse arg */,
@@ -14124,10 +14399,10 @@ trace_command (char *arg, int from_tty)
                         bp_tracepoint /* type_wanted */,
                         0 /* Ignore count */,
                         pending_break_support,
-                        &tracepoint_breakpoint_ops,
+                        ops,
                         from_tty,
                         1 /* enabled */,
-                        0 /* internal */))
+                        0 /* internal */, 0))
     set_tracepoint_count (breakpoint_count);
 }
 
@@ -14144,7 +14419,7 @@ ftrace_command (char *arg, int from_tty)
                         &tracepoint_breakpoint_ops,
                         from_tty,
                         1 /* enabled */,
-                        0 /* internal */))
+                        0 /* internal */, 0))
     set_tracepoint_count (breakpoint_count);
 }
 
@@ -14172,7 +14447,7 @@ strace_command (char *arg, int from_tty)
                         ops,
                         from_tty,
                         1 /* enabled */,
-                        0 /* internal */))
+                        0 /* internal */, 0))
     set_tracepoint_count (breakpoint_count);
 }
 
@@ -14237,7 +14512,8 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
                          &tracepoint_breakpoint_ops,
                          0 /* from_tty */,
                          utp->enabled /* enabled */,
-                         0 /* internal */))
+                         0 /* internal */,
+                         CREATE_BREAKPOINT_FLAGS_INSERTED))
     return NULL;
 
   set_tracepoint_count (breakpoint_count);
@@ -14727,9 +15003,12 @@ add_catch_command (char *name, char *docstring,
 static void
 clear_syscall_counts (struct inferior *inf)
 {
-  inf->total_syscalls_count = 0;
-  inf->any_syscall_count = 0;
-  VEC_free (int, inf->syscalls_counts);
+  struct catch_syscall_inferior_data *inf_data
+    = get_catch_syscall_inferior_data (inf);
+
+  inf_data->total_syscalls_count = 0;
+  inf_data->any_syscall_count = 0;
+  VEC_free (int, inf_data->syscalls_counts);
 }
 
 static void
@@ -14855,6 +15134,14 @@ initialize_breakpoint_ops (void)
   ops->print_it = momentary_bkpt_print_it;
   ops->print_mention = momentary_bkpt_print_mention;
 
+  /* Probe breakpoints.  */
+  ops = &bkpt_probe_breakpoint_ops;
+  *ops = bkpt_breakpoint_ops;
+  ops->insert_location = bkpt_probe_insert_location;
+  ops->remove_location = bkpt_probe_remove_location;
+  ops->create_sals_from_address = bkpt_probe_create_sals_from_address;
+  ops->decode_linespec = bkpt_probe_decode_linespec;
+
   /* GNU v3 exception catchpoints.  */
   ops = &gnu_v3_exception_catchpoint_ops;
   *ops = bkpt_breakpoint_ops;
@@ -14902,6 +15189,12 @@ initialize_breakpoint_ops (void)
   ops->create_breakpoints_sal = tracepoint_create_breakpoints_sal;
   ops->decode_linespec = tracepoint_decode_linespec;
 
+  /* Probe tracepoints.  */
+  ops = &tracepoint_probe_breakpoint_ops;
+  *ops = tracepoint_breakpoint_ops;
+  ops->create_sals_from_address = tracepoint_probe_create_sals_from_address;
+  ops->decode_linespec = tracepoint_probe_decode_linespec;
+
   /* Static tracepoints with marker (`-m').  */
   ops = &strace_marker_breakpoint_ops;
   *ops = tracepoint_breakpoint_ops;
@@ -14980,7 +15273,11 @@ _initialize_breakpoint (void)
   observer_attach_inferior_exit (clear_syscall_counts);
   observer_attach_memory_changed (invalidate_bp_value_on_memory_change);
 
-  breakpoint_objfile_key = register_objfile_data ();
+  breakpoint_objfile_key
+    = register_objfile_data_with_cleanup (NULL, free_breakpoint_probes);
+
+  catch_syscall_inferior_data
+    = register_inferior_data_with_cleanup (catch_syscall_inferior_data_cleanup);
 
   breakpoint_chain = 0;
   /* Don't bother to call set_breakpoint_count.  $bpnum isn't useful
This page took 0.059054 seconds and 4 git commands to generate.