2012-05-14 Stan Shebs <stan@codesourcery.com>
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index fd9dced5557a44d94361d5e60db707e690d9aa69..b060e74d52ae8d13d084d109c771e8933284f1ba 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"
 
 /* readline include files */
 #include "readline/readline.h"
@@ -107,11 +109,11 @@ static void create_sals_from_address_default (char **,
 static void create_breakpoints_sal_default (struct gdbarch *,
                                            struct linespec_result *,
                                            struct linespec_sals *,
-                                           char *, enum bptype,
+                                           char *, char *, enum bptype,
                                            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 *);
@@ -258,6 +260,8 @@ static void trace_pass_command (char *, int);
 
 static int is_masked_watchpoint (const struct breakpoint *b);
 
+static struct bp_location **get_first_locp_gte_addr (CORE_ADDR address);
+
 /* Return 1 if B refers to a static tracepoint set by marker ("-m"), zero
    otherwise.  */
 
@@ -287,6 +291,12 @@ 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;
+
+/* Dynamic printf class type.  */
+static struct breakpoint_ops dprintf_breakpoint_ops;
+
 /* A reference-counted struct command_line.  This lets multiple
    breakpoints share a single command list.  */
 struct counted_command_line
@@ -401,9 +411,66 @@ 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";
+
+/* Modes for breakpoint condition evaluation.  */
+static const char condition_evaluation_auto[] = "auto";
+static const char condition_evaluation_host[] = "host";
+static const char condition_evaluation_target[] = "target";
+static const char *const condition_evaluation_enums[] = {
+  condition_evaluation_auto,
+  condition_evaluation_host,
+  condition_evaluation_target,
+  NULL
+};
+
+/* Global that holds the current mode for breakpoint condition evaluation.  */
+static const char *condition_evaluation_mode_1 = condition_evaluation_auto;
+
+/* Global that we use to display information to the user (gets its value from
+   condition_evaluation_mode_1.  */
+static const char *condition_evaluation_mode = condition_evaluation_auto;
+
+/* Translate a condition evaluation mode MODE into either "host"
+   or "target".  This is used mostly to translate from "auto" to the
+   real setting that is being used.  It returns the translated
+   evaluation mode.  */
+
+static const char *
+translate_condition_evaluation_mode (const char *mode)
+{
+  if (mode == condition_evaluation_auto)
+    {
+      if (target_supports_evaluation_of_breakpoint_conditions ())
+       return condition_evaluation_target;
+      else
+       return condition_evaluation_host;
+    }
+  else
+    return mode;
+}
+
+/* Discovers what condition_evaluation_auto translates to.  */
+
+static const char *
+breakpoint_condition_evaluation_mode (void)
+{
+  return translate_condition_evaluation_mode (condition_evaluation_mode);
+}
+
+/* Return true if GDB should evaluate breakpoint conditions or false
+   otherwise.  */
+
+static int
+gdb_evaluates_breakpoint_condition_p (void)
+{
+  const char *mode = breakpoint_condition_evaluation_mode ();
+
+  return (mode == condition_evaluation_host);
 }
 
 void _initialize_breakpoint (void);
@@ -437,6 +504,20 @@ int target_exact_watchpoints = 0;
             BP_TMP < bp_location + bp_location_count && (B = *BP_TMP); \
             BP_TMP++)
 
+/* Iterates through locations with address ADDRESS for the currently selected
+   program space.  BP_LOCP_TMP points to each object.  BP_LOCP_START points
+   to where the loop should start from.
+   If BP_LOCP_START is a NULL pointer, the macro automatically seeks the
+   appropriate location to start with.  */
+
+#define ALL_BP_LOCATIONS_AT_ADDR(BP_LOCP_TMP, BP_LOCP_START, ADDRESS)  \
+       for (BP_LOCP_START = BP_LOCP_START == NULL ? get_first_locp_gte_addr (ADDRESS) : BP_LOCP_START, \
+            BP_LOCP_TMP = BP_LOCP_START;                               \
+            BP_LOCP_START                                              \
+            && (BP_LOCP_TMP < bp_location + bp_location_count          \
+            && (*BP_LOCP_TMP)->address == ADDRESS);                    \
+            BP_LOCP_TMP++)
+
 /* Iterator for tracepoints only.  */
 
 #define ALL_TRACEPOINTS(B)  \
@@ -620,6 +701,179 @@ get_breakpoint (int num)
 
 \f
 
+/* Mark locations as "conditions have changed" in case the target supports
+   evaluating conditions on its side.  */
+
+static void
+mark_breakpoint_modified (struct breakpoint *b)
+{
+  struct bp_location *loc;
+
+  /* This is only meaningful if the target is
+     evaluating conditions and if the user has
+     opted for condition evaluation on the target's
+     side.  */
+  if (gdb_evaluates_breakpoint_condition_p ()
+      || !target_supports_evaluation_of_breakpoint_conditions ())
+    return;
+
+  if (!is_breakpoint (b))
+    return;
+
+  for (loc = b->loc; loc; loc = loc->next)
+    loc->condition_changed = condition_modified;
+}
+
+/* Mark location as "conditions have changed" in case the target supports
+   evaluating conditions on its side.  */
+
+static void
+mark_breakpoint_location_modified (struct bp_location *loc)
+{
+  /* This is only meaningful if the target is
+     evaluating conditions and if the user has
+     opted for condition evaluation on the target's
+     side.  */
+  if (gdb_evaluates_breakpoint_condition_p ()
+      || !target_supports_evaluation_of_breakpoint_conditions ())
+
+    return;
+
+  if (!is_breakpoint (loc->owner))
+    return;
+
+  loc->condition_changed = condition_modified;
+}
+
+/* Sets the condition-evaluation mode using the static global
+   condition_evaluation_mode.  */
+
+static void
+set_condition_evaluation_mode (char *args, int from_tty,
+                              struct cmd_list_element *c)
+{
+  struct breakpoint *b;
+  const char *old_mode, *new_mode;
+
+  if ((condition_evaluation_mode_1 == condition_evaluation_target)
+      && !target_supports_evaluation_of_breakpoint_conditions ())
+    {
+      condition_evaluation_mode_1 = condition_evaluation_mode;
+      warning (_("Target does not support breakpoint condition evaluation.\n"
+                "Using host evaluation mode instead."));
+      return;
+    }
+
+  new_mode = translate_condition_evaluation_mode (condition_evaluation_mode_1);
+  old_mode = translate_condition_evaluation_mode (condition_evaluation_mode);
+
+  /* Flip the switch.  Flip it even if OLD_MODE == NEW_MODE as one of the
+     settings was "auto".  */
+  condition_evaluation_mode = condition_evaluation_mode_1;
+
+  /* Only update the mode if the user picked a different one.  */
+  if (new_mode != old_mode)
+    {
+      struct bp_location *loc, **loc_tmp;
+      /* If the user switched to a different evaluation mode, we
+        need to synch the changes with the target as follows:
+
+        "host" -> "target": Send all (valid) conditions to the target.
+        "target" -> "host": Remove all the conditions from the target.
+      */
+
+      if (new_mode == condition_evaluation_target)
+       {
+         /* Mark everything modified and synch conditions with the
+            target.  */
+         ALL_BP_LOCATIONS (loc, loc_tmp)
+           mark_breakpoint_location_modified (loc);
+       }
+      else
+       {
+         /* Manually mark non-duplicate locations to synch conditions
+            with the target.  We do this to remove all the conditions the
+            target knows about.  */
+         ALL_BP_LOCATIONS (loc, loc_tmp)
+           if (is_breakpoint (loc->owner) && loc->inserted)
+             loc->needs_update = 1;
+       }
+
+      /* Do the update.  */
+      update_global_location_list (1);
+    }
+
+  return;
+}
+
+/* Shows the current mode of breakpoint condition evaluation.  Explicitly shows
+   what "auto" is translating to.  */
+
+static void
+show_condition_evaluation_mode (struct ui_file *file, int from_tty,
+                               struct cmd_list_element *c, const char *value)
+{
+  if (condition_evaluation_mode == condition_evaluation_auto)
+    fprintf_filtered (file,
+                     _("Breakpoint condition evaluation "
+                       "mode is %s (currently %s).\n"),
+                     value,
+                     breakpoint_condition_evaluation_mode ());
+  else
+    fprintf_filtered (file, _("Breakpoint condition evaluation mode is %s.\n"),
+                     value);
+}
+
+/* A comparison function for bp_location AP and BP that is used by
+   bsearch.  This comparison function only cares about addresses, unlike
+   the more general bp_location_compare function.  */
+
+static int
+bp_location_compare_addrs (const void *ap, const void *bp)
+{
+  struct bp_location *a = *(void **) ap;
+  struct bp_location *b = *(void **) bp;
+
+  if (a->address == b->address)
+    return 0;
+  else
+    return ((a->address > b->address) - (a->address < b->address));
+}
+
+/* Helper function to skip all bp_locations with addresses
+   less than ADDRESS.  It returns the first bp_location that
+   is greater than or equal to ADDRESS.  If none is found, just
+   return NULL.  */
+
+static struct bp_location **
+get_first_locp_gte_addr (CORE_ADDR address)
+{
+  struct bp_location dummy_loc;
+  struct bp_location *dummy_locp = &dummy_loc;
+  struct bp_location **locp_found = NULL;
+
+  /* Initialize the dummy location's address field.  */
+  memset (&dummy_loc, 0, sizeof (struct bp_location));
+  dummy_loc.address = address;
+
+  /* Find a close match to the first location at ADDRESS.  */
+  locp_found = bsearch (&dummy_locp, bp_location, bp_location_count,
+                       sizeof (struct bp_location **),
+                       bp_location_compare_addrs);
+
+  /* Nothing was found, nothing left to do.  */
+  if (locp_found == NULL)
+    return NULL;
+
+  /* We may have found a location that is at ADDRESS but is not the first in the
+     location's list.  Go backwards (if possible) and locate the first one.  */
+  while ((locp_found - 1) >= bp_location
+        && (*(locp_found - 1))->address == address)
+    locp_found--;
+
+  return locp_found;
+}
+
 void
 set_breakpoint_condition (struct breakpoint *b, char *exp,
                          int from_tty)
@@ -642,6 +896,10 @@ set_breakpoint_condition (struct breakpoint *b, char *exp,
        {
          xfree (loc->cond);
          loc->cond = NULL;
+
+         /* No need to free the condition agent expression
+            bytecode (if we have one).  We will handle this
+            when we go through update_global_location_list.  */
        }
     }
 
@@ -684,6 +942,8 @@ set_breakpoint_condition (struct breakpoint *b, char *exp,
            }
        }
     }
+  mark_breakpoint_modified (b);
+
   breakpoints_changed ();
   observer_notify_breakpoint_modified (b);
 }
@@ -717,6 +977,10 @@ condition_command (char *arg, int from_tty)
          error (_("Cannot set a condition where a Python 'stop' "
                   "method has been defined in the breakpoint."));
        set_breakpoint_condition (b, p, from_tty);
+
+       if (is_breakpoint (b))
+         update_global_location_list (1);
+
        return;
       }
 
@@ -1060,6 +1324,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
@@ -1188,6 +1456,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,
@@ -1216,6 +1490,17 @@ breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
 }
 \f
 
+/* Return true if BPT is either a software breakpoint or a hardware
+   breakpoint.  */
+
+int
+is_breakpoint (const struct breakpoint *bpt)
+{
+  return (bpt->type == bp_breakpoint
+         || bpt->type == bp_hardware_breakpoint
+         || bpt->type == bp_dprintf);
+}
+
 /* Return true if BPT is of any hardware watchpoint kind.  */
 
 static int
@@ -1658,6 +1943,143 @@ unduplicated_should_be_inserted (struct bp_location *bl)
   return result;
 }
 
+/* Parses a conditional described by an expression COND into an
+   agent expression bytecode suitable for evaluation
+   by the bytecode interpreter.  Return NULL if there was
+   any error during parsing.  */
+
+static struct agent_expr *
+parse_cond_to_aexpr (CORE_ADDR scope, struct expression *cond)
+{
+  struct agent_expr *aexpr = NULL;
+  struct cleanup *old_chain = NULL;
+  volatile struct gdb_exception ex;
+
+  if (!cond)
+    return NULL;
+
+  /* We don't want to stop processing, so catch any errors
+     that may show up.  */
+  TRY_CATCH (ex, RETURN_MASK_ERROR)
+    {
+      aexpr = gen_eval_for_expr (scope, cond);
+    }
+
+  if (ex.reason < 0)
+    {
+      /* If we got here, it means the condition could not be parsed to a valid
+        bytecode expression and thus can't be evaluated on the target's side.
+        It's no use iterating through the conditions.  */
+      return NULL;
+    }
+
+  /* We have a valid agent expression.  */
+  return aexpr;
+}
+
+/* Based on location BL, create a list of breakpoint conditions to be
+   passed on to the target.  If we have duplicated locations with different
+   conditions, we will add such conditions to the list.  The idea is that the
+   target will evaluate the list of conditions and will only notify GDB when
+   one of them is true.  */
+
+static void
+build_target_condition_list (struct bp_location *bl)
+{
+  struct bp_location **locp = NULL, **loc2p;
+  int null_condition_or_parse_error = 0;
+  int modified = bl->needs_update;
+  struct bp_location *loc;
+
+  /* This is only meaningful if the target is
+     evaluating conditions and if the user has
+     opted for condition evaluation on the target's
+     side.  */
+  if (gdb_evaluates_breakpoint_condition_p ()
+      || !target_supports_evaluation_of_breakpoint_conditions ())
+    return;
+
+  /* Do a first pass to check for locations with no assigned
+     conditions or conditions that fail to parse to a valid agent expression
+     bytecode.  If any of these happen, then it's no use to send conditions
+     to the target since this location will always trigger and generate a
+     response back to GDB.  */
+  ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, bl->address)
+    {
+      loc = (*loc2p);
+      if (is_breakpoint (loc->owner) && loc->pspace->num == bl->pspace->num)
+       {
+         if (modified)
+           {
+             struct agent_expr *aexpr;
+
+             /* Re-parse the conditions since something changed.  In that
+                case we already freed the condition bytecodes (see
+                force_breakpoint_reinsertion).  We just
+                need to parse the condition to bytecodes again.  */
+             aexpr = parse_cond_to_aexpr (bl->address, loc->cond);
+             loc->cond_bytecode = aexpr;
+
+             /* Check if we managed to parse the conditional expression
+                correctly.  If not, we will not send this condition
+                to the target.  */
+             if (aexpr)
+               continue;
+           }
+
+         /* If we have a NULL bytecode expression, it means something
+            went wrong or we have a null condition expression.  */
+         if (!loc->cond_bytecode)
+           {
+             null_condition_or_parse_error = 1;
+             break;
+           }
+       }
+    }
+
+  /* If any of these happened, it means we will have to evaluate the conditions
+     for the location's address on gdb's side.  It is no use keeping bytecodes
+     for all the other duplicate locations, thus we free all of them here.
+
+     This is so we have a finer control over which locations' conditions are
+     being evaluated by GDB or the remote stub.  */
+  if (null_condition_or_parse_error)
+    {
+      ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, bl->address)
+       {
+         loc = (*loc2p);
+         if (is_breakpoint (loc->owner) && loc->pspace->num == bl->pspace->num)
+           {
+             /* Only go as far as the first NULL bytecode is
+                located.  */
+             if (!loc->cond_bytecode)
+               return;
+
+             free_agent_expr (loc->cond_bytecode);
+             loc->cond_bytecode = NULL;
+           }
+       }
+    }
+
+  /* No NULL conditions or failed bytecode generation.  Build a condition list
+     for this location's address.  */
+  ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, bl->address)
+    {
+      loc = (*loc2p);
+      if (loc->cond
+         && is_breakpoint (loc->owner)
+         && loc->pspace->num == bl->pspace->num
+         && loc->owner->enable_state == bp_enabled
+         && loc->enabled)
+       /* Add the condition to the vector.  This will be used later to send the
+          conditions to the target.  */
+       VEC_safe_push (agent_expr_p, bl->target_info.conditions,
+                      loc->cond_bytecode);
+    }
+
+  return;
+}
+
 /* Insert a low-level "breakpoint" of some type.  BL is the breakpoint
    location.  Any error messages are printed to TMP_ERROR_STREAM; and
    DISABLED_BREAKS, and HW_BREAKPOINT_ERROR are used to report problems.
@@ -1674,15 +2096,34 @@ insert_bp_location (struct bp_location *bl,
 {
   int val = 0;
 
-  if (!should_be_inserted (bl) || bl->inserted)
+  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;
 
+  /* When working with target-side conditions, we must pass all the conditions
+     for the same breakpoint address down to the target since GDB will not
+     insert those locations.  With a list of breakpoint conditions, the target
+     can decide when to stop and notify GDB.  */
+
+  if (is_breakpoint (bl->owner))
+    {
+      build_target_condition_list (bl);
+      /* Reset the condition modification marker.  */
+      bl->needs_update = 0;
+    }
+
   if (bl->loc_type == bp_loc_software_breakpoint
       || bl->loc_type == bp_loc_hardware_breakpoint)
     {
@@ -1991,6 +2432,79 @@ 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.  */
+
+static void
+update_inserted_breakpoint_locations (void)
+{
+  struct bp_location *bl, **blp_tmp;
+  int error_flag = 0;
+  int val = 0;
+  int disabled_breaks = 0;
+  int hw_breakpoint_error = 0;
+
+  struct ui_file *tmp_error_stream = mem_fileopen ();
+  struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_error_stream);
+
+  /* Explicitly mark the warning -- this will only be printed if
+     there was an error.  */
+  fprintf_unfiltered (tmp_error_stream, "Warning:\n");
+
+  save_current_space_and_thread ();
+
+  ALL_BP_LOCATIONS (bl, blp_tmp)
+    {
+      /* We only want to update software breakpoints and hardware
+        breakpoints.  */
+      if (!is_breakpoint (bl->owner))
+       continue;
+
+      /* We only want to update locations that are already inserted
+        and need updating.  This is to avoid unwanted insertion during
+        deletion of breakpoints.  */
+      if (!bl->inserted || (bl->inserted && !bl->needs_update))
+       continue;
+
+      switch_to_program_space_and_thread (bl->pspace);
+
+      /* For targets that support global breakpoints, there's no need
+        to select an inferior to insert breakpoint to.  In fact, even
+        if we aren't attached to any process yet, we should still
+        insert breakpoints.  */
+      if (!gdbarch_has_global_breakpoints (target_gdbarch)
+         && ptid_equal (inferior_ptid, null_ptid))
+       continue;
+
+      val = insert_bp_location (bl, tmp_error_stream, &disabled_breaks,
+                                   &hw_breakpoint_error);
+      if (val)
+       error_flag = val;
+    }
+
+  if (error_flag)
+    {
+      target_terminal_ours_for_output ();
+      error_stream (tmp_error_stream);
+    }
+
+  do_cleanups (cleanups);
+}
+
 /* Used when starting or continuing the program.  */
 
 static void
@@ -2014,7 +2528,7 @@ insert_breakpoint_locations (void)
 
   ALL_BP_LOCATIONS (bl, blp_tmp)
     {
-      if (!should_be_inserted (bl) || bl->inserted)
+      if (!should_be_inserted (bl) || (bl->inserted && !bl->needs_update))
        continue;
 
       /* There is no point inserting thread-specific breakpoints if
@@ -2234,11 +2748,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;
@@ -2274,6 +2800,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)
 {
@@ -2351,6 +2886,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;
@@ -2446,7 +3012,7 @@ create_std_terminate_master_breakpoint (void)
 
 /* Install a master breakpoint on the unwinder's debug hook.  */
 
-void
+static void
 create_exception_master_breakpoint (void)
 {
   struct objfile *objfile;
@@ -2461,6 +3027,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;
 
@@ -2865,6 +3465,10 @@ breakpoint_init_inferior (enum inf_context context)
           (gdb) tar rem :9999     # remote Windows gdbserver.
        */
 
+      case bp_step_resume:
+
+       /* Also remove step-resume breakpoints.  */
+
        delete_breakpoint (b);
        break;
 
@@ -3137,7 +3741,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);
 }
@@ -4092,6 +4696,10 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
   b = bs->breakpoint_at;
   gdb_assert (b != NULL);
 
+  /* Even if the target evaluated the condition on its end and notified GDB, we
+     need to do so again since GDB does not know if we stopped due to a
+     breakpoint or a single step breakpoint.  */
+
   if (frame_id_p (b->frame_id)
       && !frame_id_eq (b->frame_id, get_stack_frame_id (get_current_frame ())))
     bs->stop = 0;
@@ -4574,6 +5182,11 @@ bpstat_what (bpstat bs_head)
             PC of the former breakpoint.  */
          this_action = BPSTAT_WHAT_KEEP_CHECKING;
          break;
+
+       case bp_dprintf:
+         this_action = BPSTAT_WHAT_STOP_SILENT;
+         break;
+
        default:
          internal_error (__FILE__, __LINE__,
                          _("bpstat_what: unhandled bptype %d"), (int) bptype);
@@ -4663,10 +5276,70 @@ wrap_indent_at_field (struct ui_out *uiout, const char *col_name)
          return wrap_indent;
        }
 
-      total_width += width + 1;
-    }
+      total_width += width + 1;
+    }
+
+  return NULL;
+}
+
+/* Determine if the locations of this breakpoint will have their conditions
+   evaluated by the target, host or a mix of both.  Returns the following:
+
+    "host": Host evals condition.
+    "host or target": Host or Target evals condition.
+    "target": Target evals condition.
+*/
+
+static const char *
+bp_condition_evaluator (struct breakpoint *b)
+{
+  struct bp_location *bl;
+  char host_evals = 0;
+  char target_evals = 0;
+
+  if (!b)
+    return NULL;
+
+  if (!is_breakpoint (b))
+    return NULL;
+
+  if (gdb_evaluates_breakpoint_condition_p ()
+      || !target_supports_evaluation_of_breakpoint_conditions ())
+    return condition_evaluation_host;
+
+  for (bl = b->loc; bl; bl = bl->next)
+    {
+      if (bl->cond_bytecode)
+       target_evals++;
+      else
+       host_evals++;
+    }
+
+  if (host_evals && target_evals)
+    return condition_evaluation_both;
+  else if (target_evals)
+    return condition_evaluation_target;
+  else
+    return condition_evaluation_host;
+}
+
+/* Determine the breakpoint location's condition evaluator.  This is
+   similar to bp_condition_evaluator, but for locations.  */
+
+static const char *
+bp_location_condition_evaluator (struct bp_location *bl)
+{
+  if (bl && !is_breakpoint (bl->owner))
+    return NULL;
+
+  if (gdb_evaluates_breakpoint_condition_p ()
+      || !target_supports_evaluation_of_breakpoint_conditions ())
+    return condition_evaluation_host;
 
-  return NULL;
+  if (bl && bl->cond_bytecode)
+    return condition_evaluation_target;
+  else
+    return condition_evaluation_host;
 }
 
 /* Print the LOC location out of the list of B->LOC locations.  */
@@ -4715,10 +5388,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);
 
@@ -4727,6 +5400,16 @@ print_breakpoint_location (struct breakpoint *b,
   else
     ui_out_field_string (uiout, "pending", b->addr_string);
 
+  if (loc && is_breakpoint (b)
+      && breakpoint_condition_evaluation_mode () == condition_evaluation_target
+      && bp_condition_evaluator (b) == condition_evaluation_both)
+    {
+      ui_out_text (uiout, " (");
+      ui_out_field_string (uiout, "evaluated-by",
+                          bp_location_condition_evaluator (loc));
+      ui_out_text (uiout, ")");
+    }
+
   do_cleanups (old_chain);
 }
 
@@ -4768,6 +5451,7 @@ bptype_string (enum bptype type)
     {bp_tracepoint, "tracepoint"},
     {bp_fast_tracepoint, "fast tracepoint"},
     {bp_static_tracepoint, "static tracepoint"},
+    {bp_dprintf, "dprintf"},
     {bp_jit_event, "jit events"},
     {bp_gnu_ifunc_resolver, "STT_GNU_IFUNC resolver"},
     {bp_gnu_ifunc_resolver_return, "STT_GNU_IFUNC resolver return"},
@@ -4908,6 +5592,7 @@ print_one_breakpoint_location (struct breakpoint *b,
       case bp_tracepoint:
       case bp_fast_tracepoint:
       case bp_static_tracepoint:
+      case bp_dprintf:
       case bp_jit_event:
       case bp_gnu_ifunc_resolver:
       case bp_gnu_ifunc_resolver_return:
@@ -5002,6 +5687,18 @@ print_one_breakpoint_location (struct breakpoint *b,
       else
        ui_out_text (uiout, "\tstop only if ");
       ui_out_field_string (uiout, "cond", b->cond_string);
+
+      /* Print whether the target is doing the breakpoint's condition
+        evaluation.  If GDB is doing the evaluation, don't print anything.  */
+      if (is_breakpoint (b)
+         && breakpoint_condition_evaluation_mode ()
+         == condition_evaluation_target)
+       {
+         ui_out_text (uiout, " (");
+         ui_out_field_string (uiout, "evaluated-by",
+                              bp_condition_evaluator (b));
+         ui_out_text (uiout, " evals)");
+       }
       ui_out_text (uiout, "\n");
     }
 
@@ -5016,7 +5713,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");
@@ -5731,6 +6428,7 @@ init_bp_location (struct bp_location *loc, const struct bp_location_ops *ops,
   loc->ops = ops;
   loc->owner = owner;
   loc->cond = NULL;
+  loc->cond_bytecode = NULL;
   loc->shlib_disabled = 0;
   loc->enabled = 1;
 
@@ -5757,10 +6455,13 @@ init_bp_location (struct bp_location *loc, const struct bp_location_ops *ops,
     case bp_exception_master:
     case bp_gnu_ifunc_resolver:
     case bp_gnu_ifunc_resolver_return:
+    case bp_dprintf:
       loc->loc_type = bp_loc_software_breakpoint;
+      mark_breakpoint_location_modified (loc);
       break;
     case bp_hardware_breakpoint:
       loc->loc_type = bp_loc_hardware_breakpoint;
+      mark_breakpoint_location_modified (loc);
       break;
     case bp_hardware_watchpoint:
     case bp_read_watchpoint:
@@ -6059,6 +6760,19 @@ delete_longjmp_breakpoint (int thread)
       }
 }
 
+void
+delete_longjmp_breakpoint_at_next_stop (int thread)
+{
+  struct breakpoint *b, *b_tmp;
+
+  ALL_BREAKPOINTS_SAFE (b, b_tmp)
+    if (b->type == bp_longjmp || b->type == bp_exception)
+      {
+       if (b->thread == thread)
+         b->disposition = disp_del_at_next_stop;
+      }
+}
+
 void
 enable_overlay_breakpoints (void)
 {
@@ -6791,6 +7505,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
@@ -6822,6 +7538,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.  */
 
@@ -6830,10 +7587,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;
@@ -6844,28 +7603,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
@@ -6876,10 +7638,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;
@@ -6889,20 +7653,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
@@ -7487,6 +8252,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);
@@ -7572,6 +8338,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;
@@ -7627,7 +8394,122 @@ bp_loc_is_permanent (struct bp_location *loc)
   return retval;
 }
 
+/* The style in which to perform a dynamic printf.  This is a user
+   option because different output options have different tradeoffs;
+   if GDB does the printing, there is better error handling if there
+   is a problem with any of the arguments, but using an inferior
+   function lets you have special-purpose printers and sending of
+   output to the same place as compiled-in print functions.  (Future
+   styles may include the ability to do a target-side printf.)  */
+
+static const char dprintf_style_gdb[] = "gdb";
+static const char dprintf_style_call[] = "call";
+static const char *const dprintf_style_enums[] = {
+  dprintf_style_gdb,
+  dprintf_style_call,
+  NULL
+};
+static const char *dprintf_style = dprintf_style_gdb;
+
+/* The function to use for dynamic printf if the preferred style is to
+   call into the inferior.  The value is simply a string that is
+   copied into the command, so it can be anything that GDB can
+   evaluate to a callable address, not necessarily a function name.  */
+
+static char *dprintf_function = "";
+
+/* The channel to use for dynamic printf if the preferred style is to
+   call into the inferior; if a nonempty string, it will be passed to
+   the call as the first argument, with the format string as the
+   second.  As with the dprintf function, this can be anything that
+   GDB knows how to evaluate, so in addition to common choices like
+   "stderr", this could be an app-specific expression like
+   "mystreams[curlogger]".  */
+
+static char *dprintf_channel = "";
+
+/* Build a command list for the dprintf corresponding to the current
+   settings of the dprintf style options.  */
+
+static void
+update_dprintf_command_list (struct breakpoint *b)
+{
+  char *dprintf_args = b->extra_string;
+  char *printf_line = NULL;
+
+  if (!dprintf_args)
+    return;
+
+  dprintf_args = skip_spaces (dprintf_args);
+
+  /* Allow a comma, as it may have terminated a location, but don't
+     insist on it.  */
+  if (*dprintf_args == ',')
+    ++dprintf_args;
+  dprintf_args = skip_spaces (dprintf_args);
+
+  if (*dprintf_args != '"')
+    error (_("Bad format string, missing '\"'."));
+
+  if (strcmp (dprintf_style, "gdb") == 0)
+    printf_line = xstrprintf ("printf %s", dprintf_args);
+  else if (strcmp (dprintf_style, "call") == 0)
+    {
+      if (!dprintf_function)
+       error (_("No function supplied for dprintf call"));
+
+      if (dprintf_channel && strlen (dprintf_channel) > 0)
+       printf_line = xstrprintf ("call (void) %s (%s,%s)",
+                                 dprintf_function,
+                                 dprintf_channel,
+                                 dprintf_args);
+      else
+       printf_line = xstrprintf ("call (void) %s (%s)",
+                                 dprintf_function,
+                                 dprintf_args);
+    }
+  else
+    internal_error (__FILE__, __LINE__,
+                   _("Invalid dprintf style."));
+
+  /* Manufacture a printf/continue sequence.  */
+  if (printf_line)
+    {
+      struct command_line *printf_cmd_line, *cont_cmd_line = NULL;
+
+      cont_cmd_line = xmalloc (sizeof (struct command_line));
+      cont_cmd_line->control_type = simple_control;
+      cont_cmd_line->body_count = 0;
+      cont_cmd_line->body_list = NULL;
+      cont_cmd_line->next = NULL;
+      cont_cmd_line->line = xstrdup ("continue");
+
+      printf_cmd_line = xmalloc (sizeof (struct command_line));
+      printf_cmd_line->control_type = simple_control;
+      printf_cmd_line->body_count = 0;
+      printf_cmd_line->body_list = NULL;
+      printf_cmd_line->next = cont_cmd_line;
+      printf_cmd_line->line = printf_line;
+
+      breakpoint_set_commands (b, printf_cmd_line);
+    }
+}
+
+/* Update all dprintf commands, making their command lists reflect
+   current style settings.  */
+
+static void
+update_dprintf_commands (char *args, int from_tty,
+                        struct cmd_list_element *c)
+{
+  struct breakpoint *b;
 
+  ALL_BREAKPOINTS (b)
+    {
+      if (b->type == bp_dprintf)
+       update_dprintf_command_list (b);
+    }
+}
 
 /* Create a breakpoint with SAL as location.  Use ADDR_STRING
    as textual description of the location, and COND_STRING
@@ -7637,10 +8519,12 @@ static void
 init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
                     struct symtabs_and_lines sals, char *addr_string,
                     char *filter, char *cond_string,
+                    char *extra_string,
                     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;
 
@@ -7682,10 +8566,14 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
          b->task = task;
   
          b->cond_string = cond_string;
+         b->extra_string = extra_string;
          b->ignore_count = ignore_count;
          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;
@@ -7729,6 +8617,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))
@@ -7741,6 +8631,18 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
          if (*arg)
               error (_("Garbage %s follows condition"), arg);
        }
+
+      /* Dynamic printf requires and uses additional arguments on the
+        command line, otherwise it's an error.  */
+      if (type == bp_dprintf)
+       {
+         if (b->extra_string)
+           update_dprintf_command_list (b);
+         else
+           error (_("Format string required"));
+       }
+      else if (b->extra_string)
+       error (_("Garbage %s at end of command"), b->extra_string);
     }   
 
   b->display_canonical = display_canonical;
@@ -7758,10 +8660,12 @@ static void
 create_breakpoint_sal (struct gdbarch *gdbarch,
                       struct symtabs_and_lines sals, char *addr_string,
                       char *filter, char *cond_string,
+                      char *extra_string,
                       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;
@@ -7780,11 +8684,12 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
 
   init_breakpoint_sal (b, gdbarch,
                       sals, addr_string,
-                      filter, cond_string,
+                      filter, cond_string, extra_string,
                       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);
@@ -7808,11 +8713,11 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
 static void
 create_breakpoints_sal (struct gdbarch *gdbarch,
                        struct linespec_result *canonical,
-                       char *cond_string,
+                       char *cond_string, char *extra_string,
                        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;
@@ -7834,9 +8739,10 @@ create_breakpoints_sal (struct gdbarch *gdbarch,
       create_breakpoint_sal (gdbarch, lsal->sals,
                             addr_string,
                             filter_string,
-                            cond_string, type, disposition,
+                            cond_string, extra_string,
+                            type, disposition,
                             thread, task, ignore_count, ops,
-                            from_tty, enabled, internal,
+                            from_tty, enabled, internal, flags,
                             canonical->special_display);
       discard_cleanups (inner);
     }
@@ -7971,7 +8877,8 @@ check_fast_tracepoint_sals (struct gdbarch *gdbarch,
    If no thread is found, *THREAD is set to -1.  */
 static void 
 find_condition_and_thread (char *tok, CORE_ADDR pc, 
-                          char **cond_string, int *thread, int *task)
+                          char **cond_string, int *thread, int *task,
+                          char **rest)
 {
   *cond_string = NULL;
   *thread = -1;
@@ -7983,7 +8890,13 @@ find_condition_and_thread (char *tok, CORE_ADDR pc,
       char *cond_end = NULL;
 
       tok = skip_spaces (tok);
-      
+
+      if ((*tok == '"' || *tok == ',') && rest)
+       {
+         *rest = savestring (tok, strlen (tok));
+         return;
+       }
+
       end_tok = skip_to_space (tok);
       
       toklen = end_tok - tok;
@@ -8023,6 +8936,11 @@ find_condition_and_thread (char *tok, CORE_ADDR pc,
          if (!valid_task_id (*task))
            error (_("Unknown task %d."), *task);
        }
+      else if (rest)
+       {
+         *rest = savestring (tok, strlen (tok));
+         tok += toklen;
+       }
       else
        error (_("Junk at end of arguments."));
     }
@@ -8090,13 +9008,15 @@ decode_static_tracepoint_spec (char **arg_p)
 
 int
 create_breakpoint (struct gdbarch *gdbarch,
-                  char *arg, char *cond_string, int thread,
+                  char *arg, char *cond_string,
+                  int thread, char *extra_string,
                   int parse_condition_and_thread,
                   int tempflag, enum bptype type_wanted,
                   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;
@@ -8211,16 +9131,22 @@ create_breakpoint (struct gdbarch *gdbarch,
 
       if (parse_condition_and_thread)
         {
+           char *rest;
             /* Here we only parse 'arg' to separate condition
                from thread number, so parsing in context of first
                sal is OK.  When setting the breakpoint we'll 
                re-parse it in context of each sal.  */
             cond_string = NULL;
             thread = -1;
+           rest = NULL;
             find_condition_and_thread (arg, lsal->sals.sals[0].pc, &cond_string,
-                                       &thread, &task);
+                                       &thread, &task, &rest);
             if (cond_string)
                 make_cleanup (xfree, cond_string);
+           if (rest)
+             make_cleanup (xfree, rest);
+           if (rest)
+             extra_string = rest;
         }
       else
         {
@@ -8230,13 +9156,19 @@ create_breakpoint (struct gdbarch *gdbarch,
                 cond_string = xstrdup (cond_string);
                 make_cleanup (xfree, cond_string);
             }
+            /* Create a private copy of any extra string.  */
+            if (extra_string)
+             {
+                extra_string = xstrdup (extra_string);
+                make_cleanup (xfree, extra_string);
+             }
         }
 
       ops->create_breakpoints_sal (gdbarch, &canonical, lsal,
-                                  cond_string, type_wanted,
+                                  cond_string, extra_string, type_wanted,
                                   tempflag ? disp_del : disp_donttouch,
                                   thread, task, ignore_count, ops,
-                                  from_tty, enabled, internal);
+                                  from_tty, enabled, internal, flags);
     }
   else
     {
@@ -8258,6 +9190,7 @@ create_breakpoint (struct gdbarch *gdbarch,
 
       b->addr_string = copy_arg;
       b->cond_string = NULL;
+      b->extra_string = NULL;
       b->ignore_count = ignore_count;
       b->disposition = tempflag ? disp_del : disp_donttouch;
       b->condition_not_parsed = 1;
@@ -8302,17 +9235,26 @@ 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,
-                    NULL, 0, 1 /* parse arg */,
+                    NULL, 0, NULL, 1 /* parse arg */,
                     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.  */
@@ -8469,6 +9411,29 @@ stopat_command (char *arg, int from_tty)
     break_command_1 (arg, 0, from_tty);
 }
 
+void dprintf_command (char *arg, int from_tty);
+
+/* The dynamic printf command is mostly like a regular breakpoint, but
+   with a prewired command list consisting of a single output command,
+   built from extra arguments supplied on the dprintf command
+   line.  */
+
+void
+dprintf_command (char *arg, int from_tty)
+{
+  create_breakpoint (get_current_arch (),
+                    arg,
+                    NULL, 0, NULL, 1 /* parse arg */,
+                    0, bp_dprintf,
+                    0 /* Ignore count */,
+                    pending_break_support,
+                    &dprintf_breakpoint_ops,
+                    from_tty,
+                    1 /* enabled */,
+                    0 /* internal */,
+                    0);
+}
+
 /* Implement the "breakpoint_hit" breakpoint_ops method for
    ranged breakpoints.  */
 
@@ -8561,8 +9526,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);
 
@@ -8570,7 +9535,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);
@@ -9005,7 +9970,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;
@@ -9016,8 +9981,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)
     {
@@ -9031,10 +9996,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.  */
@@ -9049,7 +10014,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;
@@ -9066,7 +10031,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 = ");
        }
@@ -9080,7 +10045,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;
@@ -9853,6 +10818,9 @@ until_break_command (char *arg, int from_tty, int anywhere)
   struct symtabs_and_lines sals;
   struct symtab_and_line sal;
   struct frame_info *frame = get_selected_frame (NULL);
+  struct gdbarch *frame_gdbarch = get_frame_arch (frame);
+  struct frame_id stack_frame_id = get_stack_frame_id (frame);
+  struct frame_id caller_frame_id = frame_unwind_caller_id (frame);
   struct breakpoint *breakpoint;
   struct breakpoint *breakpoint2 = NULL;
   struct cleanup *old_chain;
@@ -9883,40 +10851,48 @@ until_break_command (char *arg, int from_tty, int anywhere)
 
   resolve_sal_pc (&sal);
 
-  if (anywhere)
-    /* If the user told us to continue until a specified location,
-       we don't specify a frame at which we need to stop.  */
-    breakpoint = set_momentary_breakpoint (get_frame_arch (frame), sal,
-                                          null_frame_id, bp_until);
-  else
-    /* Otherwise, specify the selected frame, because we want to stop
-       only at the very same frame.  */
-    breakpoint = set_momentary_breakpoint (get_frame_arch (frame), sal,
-                                          get_stack_frame_id (frame),
-                                          bp_until);
-
-  old_chain = make_cleanup_delete_breakpoint (breakpoint);
-
   tp = inferior_thread ();
   thread = tp->num;
 
+  old_chain = make_cleanup (null_cleanup, NULL);
+
+  /* Installing a breakpoint invalidates the frame chain (as it may
+     need to switch threads), so do any frame handling first.  */
+
   /* Keep within the current frame, or in frames called by the current
      one.  */
 
-  if (frame_id_p (frame_unwind_caller_id (frame)))
+  if (frame_id_p (caller_frame_id))
     {
-      sal = find_pc_line (frame_unwind_caller_pc (frame), 0);
-      sal.pc = frame_unwind_caller_pc (frame);
+      struct symtab_and_line sal2;
+
+      sal2 = find_pc_line (frame_unwind_caller_pc (frame), 0);
+      sal2.pc = frame_unwind_caller_pc (frame);
       breakpoint2 = set_momentary_breakpoint (frame_unwind_caller_arch (frame),
-                                             sal,
-                                             frame_unwind_caller_id (frame),
+                                             sal2,
+                                             caller_frame_id,
                                              bp_until);
       make_cleanup_delete_breakpoint (breakpoint2);
 
-      set_longjmp_breakpoint (tp, frame_unwind_caller_id (frame));
+      set_longjmp_breakpoint (tp, caller_frame_id);
       make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
     }
 
+  /* set_momentary_breakpoint could invalidate FRAME.  */
+  frame = NULL;
+
+  if (anywhere)
+    /* If the user told us to continue until a specified location,
+       we don't specify a frame at which we need to stop.  */
+    breakpoint = set_momentary_breakpoint (frame_gdbarch, sal,
+                                          null_frame_id, bp_until);
+  else
+    /* Otherwise, specify the selected frame, because we want to stop
+       only at the very same frame.  */
+    breakpoint = set_momentary_breakpoint (frame_gdbarch, sal,
+                                          stack_frame_id, bp_until);
+  make_cleanup_delete_breakpoint (breakpoint);
+
   proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
 
   /* If we are running asynchronously, and proceed call above has
@@ -10169,14 +11145,15 @@ handle_gnu_v3_exceptions (int tempflag, char *cond_string,
     trigger_func_name = "__cxa_throw";
 
   create_breakpoint (get_current_arch (),
-                    trigger_func_name, cond_string, -1,
+                    trigger_func_name, cond_string, -1, NULL,
                     0 /* condition and thread are valid.  */,
                     tempflag, bp_breakpoint,
                     0,
                     AUTO_BOOLEAN_TRUE /* pending */,
                     &gnu_v3_exception_catchpoint_ops, from_tty,
                     1 /* enabled */,
-                    0 /* internal */);
+                    0 /* internal */,
+                    0);
 
   return 1;
 }
@@ -10718,6 +11695,7 @@ swap_insertion (struct bp_location *left, struct bp_location *right)
 {
   const int left_inserted = left->inserted;
   const int left_duplicate = left->duplicate;
+  const int left_needs_update = left->needs_update;
   const struct bp_target_info left_target_info = left->target_info;
 
   /* Locations of tracepoints can never be duplicated.  */
@@ -10728,12 +11706,67 @@ swap_insertion (struct bp_location *left, struct bp_location *right)
 
   left->inserted = right->inserted;
   left->duplicate = right->duplicate;
+  left->needs_update = right->needs_update;
   left->target_info = right->target_info;
   right->inserted = left_inserted;
   right->duplicate = left_duplicate;
+  right->needs_update = left_needs_update;
   right->target_info = left_target_info;
 }
 
+/* Force the re-insertion of the locations at ADDRESS.  This is called
+   once a new/deleted/modified duplicate location is found and we are evaluating
+   conditions on the target's side.  Such conditions need to be updated on
+   the target.  */
+
+static void
+force_breakpoint_reinsertion (struct bp_location *bl)
+{
+  struct bp_location **locp = NULL, **loc2p;
+  struct bp_location *loc;
+  CORE_ADDR address = 0;
+  int pspace_num;
+
+  address = bl->address;
+  pspace_num = bl->pspace->num;
+
+  /* This is only meaningful if the target is
+     evaluating conditions and if the user has
+     opted for condition evaluation on the target's
+     side.  */
+  if (gdb_evaluates_breakpoint_condition_p ()
+      || !target_supports_evaluation_of_breakpoint_conditions ())
+    return;
+
+  /* Flag all breakpoint locations with this address and
+     the same program space as the location
+     as "its condition has changed".  We need to
+     update the conditions on the target's side.  */
+  ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, address)
+    {
+      loc = *loc2p;
+
+      if (!is_breakpoint (loc->owner)
+         || pspace_num != loc->pspace->num)
+       continue;
+
+      /* Flag the location appropriately.  We use a different state to
+        let everyone know that we already updated the set of locations
+        with addr bl->address and program space bl->pspace.  This is so
+        we don't have to keep calling these functions just to mark locations
+        that have already been marked.  */
+      loc->condition_changed = condition_updated;
+
+      /* Free the agent expression bytecode as well.  We will compute
+        it later on.  */
+      if (loc->cond_bytecode)
+       {
+         free_agent_expr (loc->cond_bytecode);
+         loc->cond_bytecode = NULL;
+       }
+    }
+}
+
 /* If SHOULD_INSERT is false, do not insert any breakpoint locations
    into the inferior, only remove already-inserted locations that no
    longer should be inserted.  Functions that delete a breakpoint or
@@ -10755,6 +11788,10 @@ update_global_location_list (int should_insert)
   struct breakpoint *b;
   struct bp_location **locp, *loc;
   struct cleanup *cleanups;
+  /* Last breakpoint location address that was marked for update.  */
+  CORE_ADDR last_addr = 0;
+  /* Last breakpoint location program space that was marked for update.  */
+  int last_pspace_num = -1;
 
   /* Used in the duplicates detection below.  When iterating over all
      bp_locations, points to the first bp_location of a given address.
@@ -10827,13 +11864,30 @@ update_global_location_list (int should_insert)
            && (*loc2p)->address == old_loc->address);
           loc2p++)
        {
-         if (*loc2p == old_loc)
+         /* Check if this is a new/duplicated location or a duplicated
+            location that had its condition modified.  If so, we want to send
+            its condition to the target if evaluation of conditions is taking
+            place there.  */
+         if ((*loc2p)->condition_changed == condition_modified
+             && (last_addr != old_loc->address
+                 || last_pspace_num != old_loc->pspace->num))
            {
-             found_object = 1;
-             break;
+             force_breakpoint_reinsertion (*loc2p);
+             last_pspace_num = old_loc->pspace->num;
            }
+
+         if (*loc2p == old_loc)
+           found_object = 1;
        }
 
+      /* We have already handled this address, update it so that we don't
+        have to go through updates again.  */
+      last_addr = old_loc->address;
+
+      /* Target-side condition evaluation: Handle deleted locations.  */
+      if (!found_object)
+       force_breakpoint_reinsertion (old_loc);
+
       /* If this location is no longer present, and inserted, look if
         there's maybe a new location at the same address.  If so,
         mark that one inserted, and don't remove this one.  This is
@@ -10853,6 +11907,10 @@ update_global_location_list (int should_insert)
            }
          else
            {
+             /* This location still exists, but it won't be kept in the
+                target since it may have been disabled.  We proceed to
+                remove its target-side condition.  */
+
              /* The location is either no longer present, or got
                 disabled.  See if there's another location at the
                 same address, in which case we don't need to remove
@@ -11005,7 +12063,11 @@ update_global_location_list (int should_insert)
           never duplicated.  See the comments in field `duplicate' of
           `struct bp_location'.  */
          || is_tracepoint (b))
-       continue;
+       {
+         /* Clear the condition modification flag.  */
+         loc->condition_changed = condition_unchanged;
+         continue;
+       }
 
       /* Permanent breakpoint should always be inserted.  */
       if (b->enable_state == bp_permanent && ! loc->inserted)
@@ -11028,6 +12090,13 @@ update_global_location_list (int should_insert)
        {
          *loc_first_p = loc;
          loc->duplicate = 0;
+
+         if (is_breakpoint (loc->owner) && loc->condition_changed)
+           {
+             loc->needs_update = 1;
+             /* Clear the condition modification flag.  */
+             loc->condition_changed = condition_unchanged;
+           }
          continue;
        }
 
@@ -11039,6 +12108,9 @@ update_global_location_list (int should_insert)
        swap_insertion (loc, *loc_first_p);
       loc->duplicate = 1;
 
+      /* Clear the condition modification flag.  */
+      loc->condition_changed = condition_unchanged;
+
       if ((*loc_first_p)->owner->enable_state == bp_permanent && loc->inserted
          && b->enable_state != bp_permanent)
        internal_error (__FILE__, __LINE__,
@@ -11046,10 +12118,21 @@ update_global_location_list (int should_insert)
                        "a permanent breakpoint"));
     }
 
-  if (breakpoints_always_inserted_mode () && should_insert
+  if (breakpoints_always_inserted_mode ()
       && (have_live_inferiors ()
          || (gdbarch_has_global_breakpoints (target_gdbarch))))
-    insert_breakpoint_locations ();
+    {
+      if (should_insert)
+       insert_breakpoint_locations ();
+      else
+       {
+         /* Though should_insert is false, we may need to update conditions
+            on the target's side if it is evaluating such conditions.  We
+            only update conditions for locations that are marked
+            "needs_update".  */
+         update_inserted_breakpoint_locations ();
+       }
+    }
 
   if (should_insert)
     download_tracepoint_locations ();
@@ -11163,6 +12246,8 @@ static void
 bp_location_dtor (struct bp_location *self)
 {
   xfree (self->cond);
+  if (self->cond_bytecode)
+    free_agent_expr (self->cond_bytecode);
   xfree (self->function_name);
   xfree (self->source_file);
 }
@@ -11289,13 +12374,14 @@ base_breakpoint_create_breakpoints_sal (struct gdbarch *gdbarch,
                                        struct linespec_result *c,
                                        struct linespec_sals *lsal,
                                        char *cond_string,
+                                       char *extra_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)
+                                       int internal, unsigned flags)
 {
   internal_error_pure_virtual_called ();
 }
@@ -11451,6 +12537,9 @@ bkpt_print_mention (struct breakpoint *b)
     case bp_hardware_breakpoint:
       printf_filtered (_("Hardware assisted breakpoint %d"), b->number);
       break;
+    case bp_dprintf:
+      printf_filtered (_("Dprintf %d"), b->number);
+      break;
     }
 
   say_where (b);
@@ -11491,19 +12580,21 @@ bkpt_create_breakpoints_sal (struct gdbarch *gdbarch,
                             struct linespec_result *canonical,
                             struct linespec_sals *lsal,
                             char *cond_string,
+                            char *extra_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 internal, unsigned flags)
 {
   create_breakpoints_sal_default (gdbarch, canonical, lsal,
-                                 cond_string, type_wanted,
+                                 cond_string, extra_string,
+                                 type_wanted,
                                  disposition, thread, task,
                                  ignore_count, ops, from_tty,
-                                 enabled, internal);
+                                 enabled, internal, flags);
 }
 
 static void
@@ -11662,6 +12753,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
@@ -11761,19 +12903,21 @@ tracepoint_create_breakpoints_sal (struct gdbarch *gdbarch,
                                   struct linespec_result *canonical,
                                   struct linespec_sals *lsal,
                                   char *cond_string,
+                                  char *extra_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 internal, unsigned flags)
 {
   create_breakpoints_sal_default (gdbarch, canonical, lsal,
-                                 cond_string, type_wanted,
+                                 cond_string, extra_string,
+                                 type_wanted,
                                  disposition, thread, task,
                                  ignore_count, ops, from_tty,
-                                 enabled, internal);
+                                 enabled, internal, flags);
 }
 
 static void
@@ -11785,6 +12929,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').  */
 
@@ -11810,13 +12978,14 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
                                      struct linespec_result *canonical,
                                      struct linespec_sals *lsal,
                                      char *cond_string,
+                                     char *extra_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 internal, unsigned flags)
 {
   int i;
 
@@ -11843,9 +13012,10 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
       tp = XCNEW (struct tracepoint);
       init_breakpoint_sal (&tp->base, gdbarch, expanded,
                           addr_string, NULL,
-                          cond_string, type_wanted, disposition,
+                          cond_string, extra_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
@@ -12470,13 +13640,17 @@ addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
          char *cond_string = 0;
          int thread = -1;
          int task = 0;
+         char *extra_string = NULL;
 
          find_condition_and_thread (s, sals.sals[0].pc,
-                                    &cond_string, &thread, &task);
+                                    &cond_string, &thread, &task,
+                                    &extra_string);
          if (cond_string)
            b->cond_string = cond_string;
          b->thread = thread;
          b->task = task;
+         if (extra_string)
+           b->extra_string = extra_string;
          b->condition_not_parsed = 0;
        }
 
@@ -12544,18 +13718,20 @@ create_breakpoints_sal_default (struct gdbarch *gdbarch,
                                struct linespec_result *canonical,
                                struct linespec_sals *lsal,
                                char *cond_string,
+                               char *extra_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 internal, unsigned flags)
 {
   create_breakpoints_sal (gdbarch, canonical, cond_string,
+                         extra_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
@@ -12856,6 +14032,9 @@ disable_breakpoint (struct breakpoint *bpt)
 
   bpt->enable_state = bp_disabled;
 
+  /* Mark breakpoint locations modified.  */
+  mark_breakpoint_modified (bpt);
+
   if (target_supports_enable_disable_tracepoint ()
       && current_trace_status ()->running && is_tracepoint (bpt))
     {
@@ -12903,7 +14082,11 @@ disable_command (char *args, int from_tty)
       struct bp_location *loc = find_location_by_number (args);
       if (loc)
        {
-         loc->enabled = 0;
+         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))
@@ -12960,6 +14143,11 @@ enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition,
   if (bpt->enable_state != bp_permanent)
     bpt->enable_state = bp_enabled;
 
+  bpt->enable_state = bp_enabled;
+
+  /* Mark breakpoint locations modified.  */
+  mark_breakpoint_modified (bpt);
+
   if (target_supports_enable_disable_tracepoint ()
       && current_trace_status ()->running && is_tracepoint (bpt))
     {
@@ -13019,7 +14207,11 @@ enable_command (char *args, int from_tty)
       struct bp_location *loc = find_location_by_number (args);
       if (loc)
        {
-         loc->enabled = 1;
+         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))
@@ -13342,9 +14534,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
@@ -13396,29 +14589,37 @@ set_tracepoint_count (int num)
   set_internalvar_integer (lookup_internalvar ("tpnum"), num);
 }
 
-void
+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 */,
+                        NULL, 0, NULL, 1 /* parse arg */,
                         0 /* tempflag */,
                         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);
 }
 
-void
+static void
 ftrace_command (char *arg, int from_tty)
 {
   if (create_breakpoint (get_current_arch (),
                         arg,
-                        NULL, 0, 1 /* parse arg */,
+                        NULL, 0, NULL, 1 /* parse arg */,
                         0 /* tempflag */,
                         bp_fast_tracepoint /* type_wanted */,
                         0 /* Ignore count */,
@@ -13426,13 +14627,13 @@ ftrace_command (char *arg, int from_tty)
                         &tracepoint_breakpoint_ops,
                         from_tty,
                         1 /* enabled */,
-                        0 /* internal */))
+                        0 /* internal */, 0))
     set_tracepoint_count (breakpoint_count);
 }
 
 /* strace command implementation.  Creates a static tracepoint.  */
 
-void
+static void
 strace_command (char *arg, int from_tty)
 {
   struct breakpoint_ops *ops;
@@ -13446,7 +14647,7 @@ strace_command (char *arg, int from_tty)
 
   if (create_breakpoint (get_current_arch (),
                         arg,
-                        NULL, 0, 1 /* parse arg */,
+                        NULL, 0, NULL, 1 /* parse arg */,
                         0 /* tempflag */,
                         bp_static_tracepoint /* type_wanted */,
                         0 /* Ignore count */,
@@ -13454,7 +14655,7 @@ strace_command (char *arg, int from_tty)
                         ops,
                         from_tty,
                         1 /* enabled */,
-                        0 /* internal */))
+                        0 /* internal */, 0))
     set_tracepoint_count (breakpoint_count);
 }
 
@@ -13511,7 +14712,8 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
 
   if (!create_breakpoint (get_current_arch (),
                          addr_str,
-                         utp->cond_string, -1, 0 /* parse cond/thread */,
+                         utp->cond_string, -1, NULL,
+                         0 /* parse cond/thread */,
                          0 /* tempflag */,
                          utp->type /* type_wanted */,
                          0 /* Ignore count */,
@@ -13519,7 +14721,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);
@@ -14009,9 +15212,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
@@ -14137,6 +15343,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;
@@ -14184,6 +15398,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;
@@ -14249,6 +15469,14 @@ initialize_breakpoint_ops (void)
   ops->print_one = print_one_catch_solib;
   ops->print_mention = print_mention_catch_solib;
   ops->print_recreate = print_recreate_catch_solib;
+
+  ops = &dprintf_breakpoint_ops;
+  *ops = bkpt_base_breakpoint_ops;
+  ops->re_set = bkpt_re_set;
+  ops->resources_needed = bkpt_resources_needed;
+  ops->print_it = bkpt_print_it;
+  ops->print_mention = bkpt_print_mention;
+  ops->print_recreate = bkpt_print_recreate;
 }
 
 void
@@ -14262,7 +15490,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
@@ -14794,6 +16026,23 @@ inferior in all-stop mode, gdb behaves as if always-inserted mode is off."),
                           &breakpoint_set_cmdlist,
                           &breakpoint_show_cmdlist);
 
+  add_setshow_enum_cmd ("condition-evaluation", class_breakpoint,
+                       condition_evaluation_enums,
+                       &condition_evaluation_mode_1, _("\
+Set mode of breakpoint condition evaluation."), _("\
+Show mode of breakpoint condition evaluation."), _("\
+When this is set to \"host\", breakpoint conditions will be\n\
+evaluated on the host's side by GDB.  When it is set to \"target\",\n\
+breakpoint conditions will be downloaded to the target (if the target\n\
+supports such feature) and conditions will be evaluated on the target's side.\n\
+If this is set to \"auto\" (default), this will be automatically set to\n\
+\"target\" if it supports condition evaluation, otherwise it will\n\
+be set to \"gdb\""),
+                          &set_condition_evaluation_mode,
+                          &show_condition_evaluation_mode,
+                          &breakpoint_set_cmdlist,
+                          &breakpoint_show_cmdlist);
+
   add_com ("break-range", class_breakpoint, break_range_command, _("\
 Set a breakpoint for an address range.\n\
 break-range START-LOCATION, END-LOCATION\n\
@@ -14810,6 +16059,44 @@ The breakpoint will stop execution of the inferior whenever it executes\n\
 an instruction at any address within the [START-LOCATION, END-LOCATION]\n\
 range (including START-LOCATION and END-LOCATION)."));
 
+  c = add_com ("dprintf", class_breakpoint, dprintf_command, _("\
+Set a dynamic printf at specified line or function.\n\
+dprintf location,format string,arg1,arg2,...\n\
+location may be a line number, function name, or \"*\" and an address.\n\
+If a line number is specified, break at start of code for that line.\n\
+If a function is specified, break at start of code for that function.\n\
+"));
+  set_cmd_completer (c, location_completer);
+
+  add_setshow_enum_cmd ("dprintf-style", class_support,
+                       dprintf_style_enums, &dprintf_style, _("\
+Set the style of usage for dynamic printf."), _("\
+Show the style of usage for dynamic printf."), _("\
+This setting chooses how GDB will do a dynamic printf.\n\
+If the value is \"gdb\", then the printing is done by GDB to its own\n\
+console, as with the \"printf\" command.\n\
+If the value is \"call\", the print is done by calling a function in your\n\
+program; by default printf(), but you can choose a different function or\n\
+output stream by setting dprintf-function and dprintf-channel."),
+                       update_dprintf_commands, NULL,
+                       &setlist, &showlist);
+
+  dprintf_function = xstrdup ("printf");
+  add_setshow_string_cmd ("dprintf-function", class_support,
+                         &dprintf_function, _("\
+Set the function to use for dynamic printf"), _("\
+Show the function to use for dynamic printf"), NULL,
+                         update_dprintf_commands, NULL,
+                         &setlist, &showlist);
+
+  dprintf_channel = xstrdup ("");
+  add_setshow_string_cmd ("dprintf-channel", class_support,
+                         &dprintf_channel, _("\
+Set the channel to use for dynamic printf"), _("\
+Show the channel to use for dynamic printf"), NULL,
+                         update_dprintf_commands, NULL,
+                         &setlist, &showlist);
+
   automatic_hardware_breakpoints = 1;
 
   observer_attach_about_to_proceed (breakpoint_about_to_proceed);
This page took 0.064841 seconds and 4 git commands to generate.