2011-06-22 Pedro Alves <pedro@codesourcery.com>
authorPedro Alves <palves@redhat.com>
Wed, 22 Jun 2011 17:53:44 +0000 (17:53 +0000)
committerPedro Alves <palves@redhat.com>
Wed, 22 Jun 2011 17:53:44 +0000 (17:53 +0000)
* breakpoint.c (bpstat_stop_status): Call the check_status
breakpoint_ops method.
(print_one_breakpoint_location): Also print the condition for Ada
exception catchpoints.
(allocate_bp_location): New, factored out from
allocate_bp_location.
(allocate_bp_location): Adjust.  Call the owner breakpoint's
allocate_location method, if there is one.
(free_bp_location): Call the locations's dtor method, if there is
one.
(init_raw_breakpoint_without_location): New breakpoint_ops
parameter.  Use it.
(set_raw_breakpoint_without_location): Adjust.
(init_raw_breakpoint): New breakpoint_ops parameter.  Pass it down.
(set_raw_breakpoint): Adjust.
(catch_fork_breakpoint_ops, catch_vfork_breakpoint_ops)
(catch_syscall_breakpoint_ops): Install NULL allocate_location,
re_set and check_status methods.
(init_catchpoint): Don't memset, initialize thread, addr_string
and enable_state.  Pass the ops down to init_raw_breakpoint.
(install_catchpoint): Rename to ...
(install_breakpoint): ... this, and make extern.
(create_fork_vfork_event_catchpoint): Adjust.
(catch_exec_breakpoint_ops): Install NULL allocate_location,
re_set and check_status methods.
(create_syscall_event_catchpoint): Adjust.
(ranged_breakpoint_ops, watchpoint_breakpoint_ops)
(masked_watchpoint_breakpoint_ops): Install NULL
allocate_location, re_set and check_status methods.
(catch_exec_command_1): Adjust.
(gnu_v3_exception_catchpoint_ops): Install NULL allocate_location,
re_set and check_status methods.
(create_ada_exception_breakpoint): Rename to ...
(init_ada_exception_breakpoint): ... this.  Add a struct
breakpoint parameter, and delete the exp_string, cond_string and
cond parameters.  Use init_raw_breakpoint, and don't install or
mention the breakpoint yet.  Don't clear breakpoint fields that
init_raw_breakpoint already clears.
(re_set_breakpoint): Delete, split into ...
(breakpoint_re_set_default, prepare_re_set_context): ... these new
functions.
(breakpoint_re_set_one): Call the breakpoint's
breakpoint_ops->re_set implementation, if there's one.  Adjust.
* breakpoint.h: Forward declare struct bpstats and struct bp_location.
(struct bp_location_ops): New type.
(struct bp_location): New field `ops'.
(struct breakpoint_ops): New `allocate_location', `re_set' and
`check_status' fields.  Make `breakpoint_hit''s description match
reality.
(init_bp_location): Declare.
(breakpoint_re_set_default): Declare.
(create_ada_exception_breakpoint): Rename to ...
(init_ada_exception_breakpoint): ... this.  Add a struct
breakpoint parameter, and delete the exp_string, cond_string and
cond parameters.
(install_breakpoint): Declare.
* ada-lang.c: Include exceptions.h.
<Ada exceptions description>: Update.
(struct ada_catchpoint_location): New type.
(ada_catchpoint_location_dtor): New function.
(ada_catchpoint_location_ops): New global.
(ada_catchpoint): New type.
(create_excep_cond_exprs): New function.
(dtor_exception, allocate_location_exception, re_set_exception)
(should_stop_exception, check_status_exception): New functions.
(print_one_exception, print_mention_exception)
(print_recreate_exception): Adjust.
(dtor_catch_exception, allocate_location_catch_exception)
(re_set_catch_exception, check_status_catch_exception): New
functions.
(catch_exception_breakpoint_ops): Install them.
(dtor_catch_exception_unhandled)
(allocate_location_catch_exception_unhandled)
(re_set_catch_exception_unhandled)
(check_status_catch_exception_unhandled): New functions.
(catch_exception_unhandled_breakpoint_ops): Install them.
(dtor_catch_assert, allocate_location_catch_assert)
(re_set_catch_assert, check_status_catch_assert): New functions.
(catch_assert_breakpoint_ops): Install them.
(ada_exception_catchpoint_p): Delete.
(catch_ada_exception_command_split)
(ada_exception_catchpoint_cond_string): Rename exp_string
parameter to excep_string.  Adjust.
(ada_parse_catchpoint_condition): Delete.
(ada_exception_sal): Rename the exp_string parameter to
excep_string.  Delete the cond_string and cond parameters.
Adjust.
(ada_decode_exception_location): Rename the exp_string parameter
to excep_string.  Delete the cond_string and cond parameters.
Adjust.
(create_ada_exception_catchpoint): New function.
(catch_ada_exception_command, ada_decode_assert_location)
(catch_assert_command): Adjust.
* ada-lang.h (ada_exception_catchpoint_p): Delete declaration.

gdb/ChangeLog
gdb/ada-lang.c
gdb/ada-lang.h
gdb/breakpoint.c
gdb/breakpoint.h

index c5224225de85632ea94b0696da97d055e92d2ac7..fb4c664797f6edf7dc4613dba68ee28a869277d2 100644 (file)
@@ -1,3 +1,100 @@
+2011-06-22  Pedro Alves  <pedro@codesourcery.com>
+
+       * breakpoint.c (bpstat_stop_status): Call the check_status
+       breakpoint_ops method.
+       (print_one_breakpoint_location): Also print the condition for Ada
+       exception catchpoints.
+       (allocate_bp_location): New, factored out from
+       allocate_bp_location.
+       (allocate_bp_location): Adjust.  Call the owner breakpoint's
+       allocate_location method, if there is one.
+       (free_bp_location): Call the locations's dtor method, if there is
+       one.
+       (init_raw_breakpoint_without_location): New breakpoint_ops
+       parameter.  Use it.
+       (set_raw_breakpoint_without_location): Adjust.
+       (init_raw_breakpoint): New breakpoint_ops parameter.  Pass it down.
+       (set_raw_breakpoint): Adjust.
+       (catch_fork_breakpoint_ops, catch_vfork_breakpoint_ops)
+       (catch_syscall_breakpoint_ops): Install NULL allocate_location,
+       re_set and check_status methods.
+       (init_catchpoint): Don't memset, initialize thread, addr_string
+       and enable_state.  Pass the ops down to init_raw_breakpoint.
+       (install_catchpoint): Rename to ...
+       (install_breakpoint): ... this, and make extern.
+       (create_fork_vfork_event_catchpoint): Adjust.
+       (catch_exec_breakpoint_ops): Install NULL allocate_location,
+       re_set and check_status methods.
+       (create_syscall_event_catchpoint): Adjust.
+       (ranged_breakpoint_ops, watchpoint_breakpoint_ops)
+       (masked_watchpoint_breakpoint_ops): Install NULL
+       allocate_location, re_set and check_status methods.
+       (catch_exec_command_1): Adjust.
+       (gnu_v3_exception_catchpoint_ops): Install NULL allocate_location,
+       re_set and check_status methods.
+       (create_ada_exception_breakpoint): Rename to ...
+       (init_ada_exception_breakpoint): ... this.  Add a struct
+       breakpoint parameter, and delete the exp_string, cond_string and
+       cond parameters.  Use init_raw_breakpoint, and don't install or
+       mention the breakpoint yet.  Don't clear breakpoint fields that
+       init_raw_breakpoint already clears.
+       (re_set_breakpoint): Delete, split into ...
+       (breakpoint_re_set_default, prepare_re_set_context): ... these new
+       functions.
+       (breakpoint_re_set_one): Call the breakpoint's
+       breakpoint_ops->re_set implementation, if there's one.  Adjust.
+       * breakpoint.h: Forward declare struct bpstats and struct bp_location.
+       (struct bp_location_ops): New type.
+       (struct bp_location): New field `ops'.
+       (struct breakpoint_ops): New `allocate_location', `re_set' and
+       `check_status' fields.  Make `breakpoint_hit''s description match
+       reality.
+       (init_bp_location): Declare.
+       (breakpoint_re_set_default): Declare.
+       (create_ada_exception_breakpoint): Rename to ...
+       (init_ada_exception_breakpoint): ... this.  Add a struct
+       breakpoint parameter, and delete the exp_string, cond_string and
+       cond parameters.
+       (install_breakpoint): Declare.
+       * ada-lang.c: Include exceptions.h.
+       <Ada exceptions description>: Update.
+       (struct ada_catchpoint_location): New type.
+       (ada_catchpoint_location_dtor): New function.
+       (ada_catchpoint_location_ops): New global.
+       (ada_catchpoint): New type.
+       (create_excep_cond_exprs): New function.
+       (dtor_exception, allocate_location_exception, re_set_exception)
+       (should_stop_exception, check_status_exception): New functions.
+       (print_one_exception, print_mention_exception)
+       (print_recreate_exception): Adjust.
+       (dtor_catch_exception, allocate_location_catch_exception)
+       (re_set_catch_exception, check_status_catch_exception): New
+       functions.
+       (catch_exception_breakpoint_ops): Install them.
+       (dtor_catch_exception_unhandled)
+       (allocate_location_catch_exception_unhandled)
+       (re_set_catch_exception_unhandled)
+       (check_status_catch_exception_unhandled): New functions.
+       (catch_exception_unhandled_breakpoint_ops): Install them.
+       (dtor_catch_assert, allocate_location_catch_assert)
+       (re_set_catch_assert, check_status_catch_assert): New functions.
+       (catch_assert_breakpoint_ops): Install them.
+       (ada_exception_catchpoint_p): Delete.
+       (catch_ada_exception_command_split)
+       (ada_exception_catchpoint_cond_string): Rename exp_string
+       parameter to excep_string.  Adjust.
+       (ada_parse_catchpoint_condition): Delete.
+       (ada_exception_sal): Rename the exp_string parameter to
+       excep_string.  Delete the cond_string and cond parameters.
+       Adjust.
+       (ada_decode_exception_location): Rename the exp_string parameter
+       to excep_string.  Delete the cond_string and cond parameters.
+       Adjust.
+       (create_ada_exception_catchpoint): New function.
+       (catch_ada_exception_command, ada_decode_assert_location)
+       (catch_assert_command): Adjust.
+       * ada-lang.h (ada_exception_catchpoint_p): Delete declaration.
+
 2011-06-22  Pedro Alves  <pedro@codesourcery.com>
 
        * ada-lang.c: Include arch-utils.h.
index 05fd75d38598808fdbaf3d25f9b8701a2c86b485..a3234fba0f71a975e929a678dde1a22f6662ddcd 100644 (file)
@@ -62,6 +62,7 @@
 #include "value.h"
 #include "mi/mi-common.h"
 #include "arch-utils.h"
+#include "exceptions.h"
 
 /* Define whether or not the C operator '/' truncates towards zero for
    differently signed operands (truncation direction is undefined in C).
@@ -10395,19 +10396,7 @@ ada_modulus (struct type *type)
    a few times already, and these changes affect the implementation
    of these catchpoints.  In order to be able to support several
    variants of the runtime, we use a sniffer that will determine
-   the runtime variant used by the program being debugged.
-
-   At this time, we do not support the use of conditions on Ada exception
-   catchpoints.  The COND and COND_STRING fields are therefore set
-   to NULL (most of the time, see below).
-   
-   Conditions where EXP_STRING, COND, and COND_STRING are used:
-
-     When a user specifies the name of a specific exception in the case
-     of catchpoints on Ada exceptions, we store the name of that exception
-     in the EXP_STRING.  We then translate this request into an actual
-     condition stored in COND_STRING, and then parse it into an expression
-     stored in COND.  */
+   the runtime variant used by the program being debugged.  */
 
 /* The different types of catchpoints that we introduced for catching
    Ada exceptions.  */
@@ -10744,6 +10733,215 @@ ada_exception_name_addr (enum exception_catchpoint_kind ex,
   return result;
 }
 
+static struct symtab_and_line ada_exception_sal (enum exception_catchpoint_kind,
+                                                char *, char **,
+                                                struct breakpoint_ops **);
+static char *ada_exception_catchpoint_cond_string (const char *excep_string);
+
+/* Ada catchpoints.
+
+   In the case of catchpoints on Ada exceptions, the catchpoint will
+   stop the target on every exception the program throws.  When a user
+   specifies the name of a specific exception, we translate this
+   request into a condition expression (in text form), and then parse
+   it into an expression stored in each of the catchpoint's locations.
+   We then use this condition to check whether the exception that was
+   raised is the one the user is interested in.  If not, then the
+   target is resumed again.  We store the name of the requested
+   exception, in order to be able to re-set the condition expression
+   when symbols change.  */
+
+/* An instance of this type is used to represent an Ada catchpoint
+   breakpoint location.  It includes a "struct bp_location" as a kind
+   of base class; users downcast to "struct bp_location *" when
+   needed.  */
+
+struct ada_catchpoint_location
+{
+  /* The base class.  */
+  struct bp_location base;
+
+  /* The condition that checks whether the exception that was raised
+     is the specific exception the user specified on catchpoint
+     creation.  */
+  struct expression *excep_cond_expr;
+};
+
+/* Implement the DTOR method in the bp_location_ops structure for all
+   Ada exception catchpoint kinds.  */
+
+static void
+ada_catchpoint_location_dtor (struct bp_location *bl)
+{
+  struct ada_catchpoint_location *al = (struct ada_catchpoint_location *) bl;
+
+  xfree (al->excep_cond_expr);
+}
+
+/* The vtable to be used in Ada catchpoint locations.  */
+
+static const struct bp_location_ops ada_catchpoint_location_ops =
+{
+  ada_catchpoint_location_dtor
+};
+
+/* An instance of this type is used to represent an Ada catchpoint.
+   It includes a "struct breakpoint" as a kind of base class; users
+   downcast to "struct breakpoint *" when needed.  */
+
+struct ada_catchpoint
+{
+  /* The base class.  */
+  struct breakpoint base;
+
+  /* The name of the specific exception the user specified.  */
+  char *excep_string;
+};
+
+/* Parse the exception condition string in the context of each of the
+   catchpoint's locations, and store them for later evaluation.  */
+
+static void
+create_excep_cond_exprs (struct ada_catchpoint *c)
+{
+  struct cleanup *old_chain;
+  struct bp_location *bl;
+  char *cond_string;
+
+  /* Nothing to do if there's no specific exception to catch.  */
+  if (c->excep_string == NULL)
+    return;
+
+  /* Same if there are no locations... */
+  if (c->base.loc == NULL)
+    return;
+
+  /* Compute the condition expression in text form, from the specific
+     expection we want to catch.  */
+  cond_string = ada_exception_catchpoint_cond_string (c->excep_string);
+  old_chain = make_cleanup (xfree, cond_string);
+
+  /* Iterate over all the catchpoint's locations, and parse an
+     expression for each.  */
+  for (bl = c->base.loc; bl != NULL; bl = bl->next)
+    {
+      struct ada_catchpoint_location *ada_loc
+       = (struct ada_catchpoint_location *) bl;
+      struct expression *exp = NULL;
+
+      if (!bl->shlib_disabled)
+       {
+         volatile struct gdb_exception e;
+         char *s;
+
+         s = cond_string;
+         TRY_CATCH (e, RETURN_MASK_ERROR)
+           {
+             exp = parse_exp_1 (&s, block_for_pc (bl->address), 0);
+           }
+         if (e.reason < 0)
+           warning (_("failed to reevaluate internal exception condition "
+                      "for catchpoint %d: %s"),
+                    c->base.number, e.message);
+       }
+
+      ada_loc->excep_cond_expr = exp;
+    }
+
+  do_cleanups (old_chain);
+}
+
+/* Implement the DTOR method in the breakpoint_ops structure for all
+   exception catchpoint kinds.  */
+
+static void
+dtor_exception (enum exception_catchpoint_kind ex, struct breakpoint *b)
+{
+  struct ada_catchpoint *c = (struct ada_catchpoint *) b;
+
+  xfree (c->excep_string);
+}
+
+/* Implement the ALLOCATE_LOCATION method in the breakpoint_ops
+   structure for all exception catchpoint kinds.  */
+
+static struct bp_location *
+allocate_location_exception (enum exception_catchpoint_kind ex,
+                            struct breakpoint *self)
+{
+  struct ada_catchpoint_location *loc;
+
+  loc = XNEW (struct ada_catchpoint_location);
+  init_bp_location (&loc->base, &ada_catchpoint_location_ops, self);
+  loc->excep_cond_expr = NULL;
+  return &loc->base;
+}
+
+/* Implement the RE_SET method in the breakpoint_ops structure for all
+   exception catchpoint kinds.  */
+
+static void
+re_set_exception (enum exception_catchpoint_kind ex, struct breakpoint *b)
+{
+  struct ada_catchpoint *c = (struct ada_catchpoint *) b;
+
+  /* Call the base class's method.  This updates the catchpoint's
+     locations.  */
+  breakpoint_re_set_default (b);
+
+  /* Reparse the exception conditional expressions.  One for each
+     location.  */
+  create_excep_cond_exprs (c);
+}
+
+/* Returns true if we should stop for this breakpoint hit.  If the
+   user specified a specific exception, we only want to cause a stop
+   if the program thrown that exception.  */
+
+static int
+should_stop_exception (const struct bp_location *bl)
+{
+  struct ada_catchpoint *c = (struct ada_catchpoint *) bl->owner;
+  const struct ada_catchpoint_location *ada_loc
+    = (const struct ada_catchpoint_location *) bl;
+  volatile struct gdb_exception ex;
+  int stop;
+
+  /* With no specific exception, should always stop.  */
+  if (c->excep_string == NULL)
+    return 1;
+
+  if (ada_loc->excep_cond_expr == NULL)
+    {
+      /* We will have a NULL expression if back when we were creating
+        the expressions, this location's had failed to parse.  */
+      return 1;
+    }
+
+  stop = 1;
+  TRY_CATCH (ex, RETURN_MASK_ALL)
+    {
+      struct value *mark;
+
+      mark = value_mark ();
+      stop = value_true (evaluate_expression (ada_loc->excep_cond_expr));
+      value_free_to_mark (mark);
+    }
+  if (ex.reason < 0)
+    exception_fprintf (gdb_stderr, ex,
+                      _("Error in testing exception condition:\n"));
+  return stop;
+}
+
+/* Implement the CHECK_STATUS method in the breakpoint_ops structure
+   for all exception catchpoint kinds.  */
+
+static void
+check_status_exception (enum exception_catchpoint_kind ex, bpstat bs)
+{
+  bs->stop = should_stop_exception (bs->bp_location_at);
+}
+
 /* Implement the PRINT_IT method in the breakpoint_ops structure
    for all exception catchpoint kinds.  */
 
@@ -10818,6 +11016,7 @@ static void
 print_one_exception (enum exception_catchpoint_kind ex,
                      struct breakpoint *b, struct bp_location **last_loc)
 { 
+  struct ada_catchpoint *c = (struct ada_catchpoint *) b;
   struct value_print_options opts;
 
   get_user_print_options (&opts);
@@ -10832,10 +11031,10 @@ print_one_exception (enum exception_catchpoint_kind ex,
   switch (ex)
     {
       case ex_catch_exception:
-        if (b->exp_string != NULL)
+        if (c->excep_string != NULL)
           {
-            char *msg = xstrprintf (_("`%s' Ada exception"), b->exp_string);
-            
+            char *msg = xstrprintf (_("`%s' Ada exception"), c->excep_string);
+
             ui_out_field_string (uiout, "what", msg);
             xfree (msg);
           }
@@ -10865,12 +11064,14 @@ static void
 print_mention_exception (enum exception_catchpoint_kind ex,
                          struct breakpoint *b)
 {
+  struct ada_catchpoint *c = (struct ada_catchpoint *) b;
+
   switch (ex)
     {
       case ex_catch_exception:
-        if (b->exp_string != NULL)
+        if (c->excep_string != NULL)
           printf_filtered (_("Catchpoint %d: `%s' Ada exception"),
-                           b->number, b->exp_string);
+                           b->number, c->excep_string);
         else
           printf_filtered (_("Catchpoint %d: all Ada exceptions"), b->number);
         
@@ -10898,12 +11099,14 @@ static void
 print_recreate_exception (enum exception_catchpoint_kind ex,
                          struct breakpoint *b, struct ui_file *fp)
 {
+  struct ada_catchpoint *c = (struct ada_catchpoint *) b;
+
   switch (ex)
     {
       case ex_catch_exception:
        fprintf_filtered (fp, "catch exception");
-       if (b->exp_string != NULL)
-         fprintf_filtered (fp, " %s", b->exp_string);
+       if (c->excep_string != NULL)
+         fprintf_filtered (fp, " %s", c->excep_string);
        break;
 
       case ex_catch_exception_unhandled:
@@ -10921,6 +11124,30 @@ print_recreate_exception (enum exception_catchpoint_kind ex,
 
 /* Virtual table for "catch exception" breakpoints.  */
 
+static void
+dtor_catch_exception (struct breakpoint *b)
+{
+  dtor_exception (ex_catch_exception, b);
+}
+
+static struct bp_location *
+allocate_location_catch_exception (struct breakpoint *self)
+{
+  return allocate_location_exception (ex_catch_exception, self);
+}
+
+static void
+re_set_catch_exception (struct breakpoint *b)
+{
+  re_set_exception (ex_catch_exception, b);
+}
+
+static void
+check_status_catch_exception (bpstat bs)
+{
+  check_status_exception (ex_catch_exception, bs);
+}
+
 static enum print_stop_action
 print_it_catch_exception (struct breakpoint *b)
 {
@@ -10947,10 +11174,13 @@ print_recreate_catch_exception (struct breakpoint *b, struct ui_file *fp)
 
 static struct breakpoint_ops catch_exception_breakpoint_ops =
 {
-  NULL, /* dtor */
+  dtor_catch_exception,
+  allocate_location_catch_exception,
+  re_set_catch_exception,
   NULL, /* insert */
   NULL, /* remove */
   NULL, /* breakpoint_hit */
+  check_status_catch_exception,
   NULL, /* resources_needed */
   NULL, /* works_in_software_mode */
   print_it_catch_exception,
@@ -10962,6 +11192,30 @@ static struct breakpoint_ops catch_exception_breakpoint_ops =
 
 /* Virtual table for "catch exception unhandled" breakpoints.  */
 
+static void
+dtor_catch_exception_unhandled (struct breakpoint *b)
+{
+  dtor_exception (ex_catch_exception_unhandled, b);
+}
+
+static struct bp_location *
+allocate_location_catch_exception_unhandled (struct breakpoint *self)
+{
+  return allocate_location_exception (ex_catch_exception_unhandled, self);
+}
+
+static void
+re_set_catch_exception_unhandled (struct breakpoint *b)
+{
+  re_set_exception (ex_catch_exception_unhandled, b);
+}
+
+static void
+check_status_catch_exception_unhandled (bpstat bs)
+{
+  check_status_exception (ex_catch_exception_unhandled, bs);
+}
+
 static enum print_stop_action
 print_it_catch_exception_unhandled (struct breakpoint *b)
 {
@@ -10989,10 +11243,13 @@ print_recreate_catch_exception_unhandled (struct breakpoint *b,
 }
 
 static struct breakpoint_ops catch_exception_unhandled_breakpoint_ops = {
-  NULL, /* dtor */
+  dtor_catch_exception_unhandled,
+  allocate_location_catch_exception_unhandled,
+  re_set_catch_exception_unhandled,
   NULL, /* insert */
   NULL, /* remove */
   NULL, /* breakpoint_hit */
+  check_status_catch_exception_unhandled,
   NULL, /* resources_needed */
   NULL, /* works_in_software_mode */
   print_it_catch_exception_unhandled,
@@ -11004,6 +11261,30 @@ static struct breakpoint_ops catch_exception_unhandled_breakpoint_ops = {
 
 /* Virtual table for "catch assert" breakpoints.  */
 
+static void
+dtor_catch_assert (struct breakpoint *b)
+{
+  dtor_exception (ex_catch_assert, b);
+}
+
+static struct bp_location *
+allocate_location_catch_assert (struct breakpoint *self)
+{
+  return allocate_location_exception (ex_catch_assert, self);
+}
+
+static void
+re_set_catch_assert (struct breakpoint *b)
+{
+  return re_set_exception (ex_catch_assert, b);
+}
+
+static void
+check_status_catch_assert (bpstat bs)
+{
+  check_status_exception (ex_catch_assert, bs);
+}
+
 static enum print_stop_action
 print_it_catch_assert (struct breakpoint *b)
 {
@@ -11029,10 +11310,13 @@ print_recreate_catch_assert (struct breakpoint *b, struct ui_file *fp)
 }
 
 static struct breakpoint_ops catch_assert_breakpoint_ops = {
-  NULL, /* dtor */
+  dtor_catch_assert,
+  allocate_location_catch_assert,
+  re_set_catch_assert,
   NULL, /* insert */
   NULL, /* remove */
   NULL, /* breakpoint_hit */
+  check_status_catch_assert,
   NULL, /* resources_needed */
   NULL, /* works_in_software_mode */
   print_it_catch_assert,
@@ -11042,16 +11326,6 @@ static struct breakpoint_ops catch_assert_breakpoint_ops = {
   print_recreate_catch_assert
 };
 
-/* Return non-zero if B is an Ada exception catchpoint.  */
-
-int
-ada_exception_catchpoint_p (struct breakpoint *b)
-{
-  return (b->ops == &catch_exception_breakpoint_ops
-          || b->ops == &catch_exception_unhandled_breakpoint_ops
-          || b->ops == &catch_assert_breakpoint_ops);
-}
-
 /* Return a newly allocated copy of the first space-separated token
    in ARGSP, and then adjust ARGSP to point immediately after that
    token.
@@ -11094,13 +11368,13 @@ ada_get_next_arg (char **argsp)
 
 /* Split the arguments specified in a "catch exception" command.  
    Set EX to the appropriate catchpoint type.
-   Set EXP_STRING to the name of the specific exception if
+   Set EXCEP_STRING to the name of the specific exception if
    specified by the user.  */
 
 static void
 catch_ada_exception_command_split (char *args,
                                    enum exception_catchpoint_kind *ex,
-                                   char **exp_string)
+                                   char **excep_string)
 {
   struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
   char *exception_name;
@@ -11123,19 +11397,19 @@ catch_ada_exception_command_split (char *args,
     {
       /* Catch all exceptions.  */
       *ex = ex_catch_exception;
-      *exp_string = NULL;
+      *excep_string = NULL;
     }
   else if (strcmp (exception_name, "unhandled") == 0)
     {
       /* Catch unhandled exceptions.  */
       *ex = ex_catch_exception_unhandled;
-      *exp_string = NULL;
+      *excep_string = NULL;
     }
   else
     {
       /* Catch a specific exception.  */
       *ex = ex_catch_exception;
-      *exp_string = exception_name;
+      *excep_string = exception_name;
     }
 }
 
@@ -11196,13 +11470,13 @@ ada_exception_breakpoint_ops (enum exception_catchpoint_kind ex)
    deallocated later.  */
 
 static char *
-ada_exception_catchpoint_cond_string (const char *exp_string)
+ada_exception_catchpoint_cond_string (const char *excep_string)
 {
   int i;
 
   /* The standard exceptions are a special case.  They are defined in
      runtime units that have been compiled without debugging info; if
-     EXP_STRING is the not-fully-qualified name of a standard
+     EXCEP_STRING is the not-fully-qualified name of a standard
      exception (e.g. "constraint_error") then, during the evaluation
      of the condition expression, the symbol lookup on this name would
      *not* return this standard exception.  The catchpoint condition
@@ -11221,44 +11495,28 @@ ada_exception_catchpoint_cond_string (const char *exp_string)
 
   for (i = 0; i < sizeof (standard_exc) / sizeof (char *); i++)
     {
-      if (strcmp (standard_exc [i], exp_string) == 0)
+      if (strcmp (standard_exc [i], excep_string) == 0)
        {
           return xstrprintf ("long_integer (e) = long_integer (&standard.%s)",
-                             exp_string);
+                             excep_string);
        }
     }
-  return xstrprintf ("long_integer (e) = long_integer (&%s)", exp_string);
-}
-
-/* Return the expression corresponding to COND_STRING evaluated at SAL.  */
-
-static struct expression *
-ada_parse_catchpoint_condition (char *cond_string,
-                                struct symtab_and_line sal)
-{
-  return (parse_exp_1 (&cond_string, block_for_pc (sal.pc), 0));
+  return xstrprintf ("long_integer (e) = long_integer (&%s)", excep_string);
 }
 
 /* Return the symtab_and_line that should be used to insert an exception
    catchpoint of the TYPE kind.
 
-   EX_STRING should contain the name of a specific exception
-   that the catchpoint should catch, or NULL otherwise.
+   EXCEP_STRING should contain the name of a specific exception that
+   the catchpoint should catch, or NULL otherwise.
 
-   The idea behind all the remaining parameters is that their names match
-   the name of certain fields in the breakpoint structure that are used to
-   handle exception catchpoints.  This function returns the value to which
-   these fields should be set, depending on the type of catchpoint we need
-   to create.
-   
-   If COND and COND_STRING are both non-NULL, any value they might
-   hold will be free'ed, and then replaced by newly allocated ones.
-   These parameters are left untouched otherwise.  */
+   ADDR_STRING returns the name of the function where the real
+   breakpoint that implements the catchpoints is set, depending on the
+   type of catchpoint we need to create.  */
 
 static struct symtab_and_line
-ada_exception_sal (enum exception_catchpoint_kind ex, char *exp_string,
-                   char **addr_string, char **cond_string,
-                   struct expression **cond, struct breakpoint_ops **ops)
+ada_exception_sal (enum exception_catchpoint_kind ex, char *excep_string,
+                  char **addr_string, struct breakpoint_ops **ops)
 {
   const char *sym_name;
   struct symbol *sym;
@@ -11304,27 +11562,6 @@ ada_exception_sal (enum exception_catchpoint_kind ex, char *exp_string,
 
   *addr_string = xstrdup (sym_name);
 
-  /* Set the COND and COND_STRING (if not NULL).  */
-
-  if (cond_string != NULL && cond != NULL)
-    {
-      if (*cond_string != NULL)
-        {
-          xfree (*cond_string);
-          *cond_string = NULL;
-        }
-      if (*cond != NULL)
-        {
-          xfree (*cond);
-          *cond = NULL;
-        }
-      if (exp_string != NULL)
-        {
-          *cond_string = ada_exception_catchpoint_cond_string (exp_string);
-          *cond = ada_parse_catchpoint_condition (*cond_string, sal);
-        }
-    }
-
   /* Set OPS.  */
   *ops = ada_exception_breakpoint_ops (ex);
 
@@ -11333,7 +11570,6 @@ ada_exception_sal (enum exception_catchpoint_kind ex, char *exp_string,
 
 /* Parse the arguments (ARGS) of the "catch exception" command.
  
-   Set TYPE to the appropriate exception catchpoint type.
    If the user asked the catchpoint to catch only a specific
    exception, then save the exception name in ADDR_STRING.
 
@@ -11342,15 +11578,34 @@ ada_exception_sal (enum exception_catchpoint_kind ex, char *exp_string,
 
 static struct symtab_and_line
 ada_decode_exception_location (char *args, char **addr_string,
-                               char **exp_string, char **cond_string,
-                               struct expression **cond,
+                               char **excep_string,
                                struct breakpoint_ops **ops)
 {
   enum exception_catchpoint_kind ex;
 
-  catch_ada_exception_command_split (args, &ex, exp_string);
-  return ada_exception_sal (ex, *exp_string, addr_string, cond_string,
-                            cond, ops);
+  catch_ada_exception_command_split (args, &ex, excep_string);
+  return ada_exception_sal (ex, *excep_string, addr_string, ops);
+}
+
+/* Create an Ada exception catchpoint.  */
+
+static void
+create_ada_exception_catchpoint (struct gdbarch *gdbarch,
+                                struct symtab_and_line sal,
+                                char *addr_string,
+                                char *excep_string,
+                                struct breakpoint_ops *ops,
+                                int tempflag,
+                                int from_tty)
+{
+  struct ada_catchpoint *c;
+
+  c = XNEW (struct ada_catchpoint);
+  init_ada_exception_breakpoint (&c->base, gdbarch, sal, addr_string,
+                                ops, tempflag, from_tty);
+  c->excep_string = excep_string;
+  create_excep_cond_exprs (c);
+  install_breakpoint (&c->base);
 }
 
 /* Implement the "catch exception" command.  */
@@ -11363,20 +11618,16 @@ catch_ada_exception_command (char *arg, int from_tty,
   int tempflag;
   struct symtab_and_line sal;
   char *addr_string = NULL;
-  char *exp_string = NULL;
-  char *cond_string = NULL;
-  struct expression *cond = NULL;
+  char *excep_string = NULL;
   struct breakpoint_ops *ops = NULL;
 
   tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
 
   if (!arg)
     arg = "";
-  sal = ada_decode_exception_location (arg, &addr_string, &exp_string,
-                                       &cond_string, &cond, &ops);
-  create_ada_exception_breakpoint (gdbarch, sal, addr_string, exp_string,
-                                   cond_string, cond, ops, tempflag,
-                                   from_tty);
+  sal = ada_decode_exception_location (arg, &addr_string, &excep_string, &ops);
+  create_ada_exception_catchpoint (gdbarch, sal, addr_string,
+                                  excep_string, ops, tempflag, from_tty);
 }
 
 static struct symtab_and_line
@@ -11393,8 +11644,7 @@ ada_decode_assert_location (char *args, char **addr_string,
         error (_("Junk at end of arguments."));
     }
 
-  return ada_exception_sal (ex_catch_assert, NULL, addr_string, NULL, NULL,
-                            ops);
+  return ada_exception_sal (ex_catch_assert, NULL, addr_string, ops);
 }
 
 /* Implement the "catch assert" command.  */
@@ -11414,8 +11664,8 @@ catch_assert_command (char *arg, int from_tty,
   if (!arg)
     arg = "";
   sal = ada_decode_assert_location (arg, &addr_string, &ops);
-  create_ada_exception_breakpoint (gdbarch, sal, addr_string, NULL, NULL, NULL,
-                                  ops, tempflag, from_tty);
+  create_ada_exception_catchpoint (gdbarch, sal, addr_string,
+                                  NULL, ops, tempflag, from_tty);
 }
                                 /* Operators */
 /* Information about operators given special treatment in functions
index e0366fcbcc2777c54e7020297ac852afe8ab3fd5..c36305977d00598eff404281edccbb7659f62f73 100644 (file)
@@ -385,6 +385,4 @@ extern void iterate_over_live_ada_tasks
 
 extern int ada_build_task_list (int warn_if_null);
 
-extern int ada_exception_catchpoint_p (struct breakpoint *b);
-  
 #endif
index 714437e8c4b9d1102524e6530dab8c419c6ce869..935cd0338bb5cc54c2521858b2dd030eea6bf894 100644 (file)
@@ -4313,6 +4313,13 @@ bpstat_stop_status (struct address_space *aspace,
 
       b = bs->breakpoint_at;
 
+      if (b->ops != NULL && b->ops->check_status != NULL)
+       {
+         b->ops->check_status (bs);
+         if (!bs->stop)
+           continue;
+       }
+
          if (b->type == bp_thread_event || b->type == bp_overlay_event
              || b->type == bp_longjmp_master
              || b->type == bp_std_terminate_master
@@ -5009,11 +5016,8 @@ print_one_breakpoint_location (struct breakpoint *b,
       ui_out_text (uiout, "\n");
     }
   
-  if (!part_of_multiple && b->cond_string && !ada_exception_catchpoint_p (b))
+  if (!part_of_multiple && b->cond_string)
     {
-      /* We do not print the condition for Ada exception catchpoints
-         because the condition is an internal implementation detail
-         that we do not want to expose to the user.  */
       annotate_field (7);
       if (is_tracepoint (b))
        ui_out_text (uiout, "\ttrace only if ");
@@ -5685,22 +5689,19 @@ adjust_breakpoint_address (struct gdbarch *gdbarch,
     }
 }
 
-/* Allocate a struct bp_location.  */
-
-static struct bp_location *
-allocate_bp_location (struct breakpoint *bpt)
+void
+init_bp_location (struct bp_location *loc, const struct bp_location_ops *ops,
+                 struct breakpoint *owner)
 {
-  struct bp_location *loc;
-
-  loc = xmalloc (sizeof (struct bp_location));
   memset (loc, 0, sizeof (*loc));
 
-  loc->owner = bpt;
+  loc->ops = ops;
+  loc->owner = owner;
   loc->cond = NULL;
   loc->shlib_disabled = 0;
   loc->enabled = 1;
 
-  switch (bpt->type)
+  switch (owner->type)
     {
     case bp_breakpoint:
     case bp_until:
@@ -5745,12 +5746,29 @@ allocate_bp_location (struct breakpoint *bpt)
     }
 
   loc->refc = 1;
+}
+
+/* Allocate a struct bp_location.  */
+
+static struct bp_location *
+allocate_bp_location (struct breakpoint *bpt)
+{
+  struct bp_location *loc;
+
+  if (bpt->ops && bpt->ops->allocate_location)
+    return bpt->ops->allocate_location (bpt);
+
+  loc = xmalloc (sizeof (struct bp_location));
+  init_bp_location (loc, NULL, bpt);
   return loc;
 }
 
 static void
 free_bp_location (struct bp_location *loc)
 {
+  if (loc->ops && loc->ops->dtor)
+    loc->ops->dtor (loc);
+
   if (loc->cond)
     xfree (loc->cond);
 
@@ -5807,10 +5825,12 @@ add_to_breakpoint_chain (struct breakpoint *b)
 static void
 init_raw_breakpoint_without_location (struct breakpoint *b,
                                      struct gdbarch *gdbarch,
-                                     enum bptype bptype)
+                                     enum bptype bptype,
+                                     struct breakpoint_ops *ops)
 {
   memset (b, 0, sizeof (*b));
 
+  b->ops = ops;
   b->type = bptype;
   b->gdbarch = gdbarch;
   b->language = current_language->la_language;
@@ -5822,7 +5842,6 @@ init_raw_breakpoint_without_location (struct breakpoint *b,
   b->ignore_count = 0;
   b->commands = NULL;
   b->frame_id = null_frame_id;
-  b->ops = NULL;
   b->condition_not_parsed = 0;
   b->py_bp_object = NULL;
   b->related_breakpoint = b;
@@ -5839,7 +5858,7 @@ set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
 {
   struct breakpoint *b = XNEW (struct breakpoint);
 
-  init_raw_breakpoint_without_location (b, gdbarch, bptype);
+  init_raw_breakpoint_without_location (b, gdbarch, bptype, NULL);
   add_to_breakpoint_chain (b);
   return b;
 }
@@ -5911,12 +5930,13 @@ get_sal_arch (struct symtab_and_line sal)
 
 static void
 init_raw_breakpoint (struct breakpoint *b, struct gdbarch *gdbarch,
-                    struct symtab_and_line sal, enum bptype bptype)
+                    struct symtab_and_line sal, enum bptype bptype,
+                    struct breakpoint_ops *ops)
 {
   CORE_ADDR adjusted_address;
   struct gdbarch *loc_gdbarch;
 
-  init_raw_breakpoint_without_location (b, gdbarch, bptype);
+  init_raw_breakpoint_without_location (b, gdbarch, bptype, ops);
 
   loc_gdbarch = get_sal_arch (sal);
   if (!loc_gdbarch)
@@ -5978,7 +5998,7 @@ set_raw_breakpoint (struct gdbarch *gdbarch,
 {
   struct breakpoint *b = XNEW (struct breakpoint);
 
-  init_raw_breakpoint (b, gdbarch, sal, bptype);
+  init_raw_breakpoint (b, gdbarch, sal, bptype, NULL);
   add_to_breakpoint_chain (b);
   return b;
 }
@@ -6381,9 +6401,12 @@ print_recreate_catch_fork (struct breakpoint *b, struct ui_file *fp)
 static struct breakpoint_ops catch_fork_breakpoint_ops =
 {
   NULL, /* dtor */
+  NULL, /* allocate_location */
+  NULL, /* re_set */
   insert_catch_fork,
   remove_catch_fork,
   breakpoint_hit_catch_fork,
+  NULL, /* check_status */
   NULL, /* resources_needed */
   NULL, /* works_in_software_mode */
   print_it_catch_fork,
@@ -6486,9 +6509,12 @@ print_recreate_catch_vfork (struct breakpoint *b, struct ui_file *fp)
 static struct breakpoint_ops catch_vfork_breakpoint_ops =
 {
   NULL, /* dtor */
+  NULL, /* allocate_location */
+  NULL, /* re_set */
   insert_catch_vfork,
   remove_catch_vfork,
   breakpoint_hit_catch_vfork,
+  NULL, /* check_status */
   NULL, /* resources_needed */
   NULL, /* works_in_software_mode */
   print_it_catch_vfork,
@@ -6812,9 +6838,12 @@ print_recreate_catch_syscall (struct breakpoint *b, struct ui_file *fp)
 static struct breakpoint_ops catch_syscall_breakpoint_ops =
 {
   dtor_catch_syscall,
+  NULL, /* allocate_location */
+  NULL, /* re_set */
   insert_catch_syscall,
   remove_catch_syscall,
   breakpoint_hit_catch_syscall,
+  NULL, /* check_status */
   NULL, /* resources_needed */
   NULL, /* works_in_software_mode */
   print_it_catch_syscall,
@@ -6845,26 +6874,17 @@ init_catchpoint (struct breakpoint *b,
 {
   struct symtab_and_line sal;
 
-  memset (b, 0, sizeof (*b));
-
   init_sal (&sal);
   sal.pspace = current_program_space;
 
-  init_raw_breakpoint (b, gdbarch, sal, bp_catchpoint);
+  init_raw_breakpoint (b, gdbarch, sal, bp_catchpoint, ops);
 
   b->cond_string = (cond_string == NULL) ? NULL : xstrdup (cond_string);
-  b->thread = -1;
-  b->addr_string = NULL;
-  b->enable_state = bp_enabled;
   b->disposition = tempflag ? disp_del : disp_donttouch;
-  b->ops = ops;
 }
 
-/* Add breakpoint B on the breakpoint list, and notify the user, the
-   target and breakpoint_created observers of its existence.  */
-
-static void
-install_catchpoint (struct breakpoint *b)
+void
+install_breakpoint (struct breakpoint *b)
 {
   add_to_breakpoint_chain (b);
   set_breakpoint_count (breakpoint_count + 1);
@@ -6885,7 +6905,7 @@ create_fork_vfork_event_catchpoint (struct gdbarch *gdbarch,
 
   c->forked_inferior_pid = null_ptid;
 
-  install_catchpoint (&c->base);
+  install_breakpoint (&c->base);
 }
 
 /* Exec catchpoints.  */
@@ -6991,9 +7011,12 @@ print_recreate_catch_exec (struct breakpoint *b, struct ui_file *fp)
 static struct breakpoint_ops catch_exec_breakpoint_ops =
 {
   dtor_catch_exec,
+  NULL, /* allocate_location */
+  NULL, /* re_set */
   insert_catch_exec,
   remove_catch_exec,
   breakpoint_hit_catch_exec,
+  NULL, /* check_status */
   NULL, /* resources_needed */
   NULL, /* works_in_software_mode */
   print_it_catch_exec,
@@ -7014,7 +7037,7 @@ create_syscall_event_catchpoint (int tempflag, VEC(int) *filter,
   init_catchpoint (&c->base, gdbarch, tempflag, NULL, ops);
   c->syscalls_to_be_caught = filter;
 
-  install_catchpoint (&c->base);
+  install_breakpoint (&c->base);
 }
 
 static int
@@ -8616,9 +8639,12 @@ print_recreate_ranged_breakpoint (struct breakpoint *b, struct ui_file *fp)
 static struct breakpoint_ops ranged_breakpoint_ops =
 {
   NULL, /* dtor */
+  NULL, /* allocate_location */
+  NULL, /* re_set */
   NULL, /* insert */
   NULL, /* remove */
   breakpoint_hit_ranged_breakpoint,
+  NULL, /* check_status */
   resources_needed_ranged_breakpoint,
   NULL, /* works_in_software_mode */
   print_it_ranged_breakpoint,
@@ -8942,9 +8968,12 @@ works_in_software_mode_watchpoint (const struct breakpoint *b)
 static struct breakpoint_ops watchpoint_breakpoint_ops =
 {
   NULL, /* dtor */
+  NULL, /* allocate_location */
+  NULL, /* re_set */
   insert_watchpoint,
   remove_watchpoint,
   NULL, /* breakpoint_hit */
+  NULL, /* check_status */
   resources_needed_watchpoint,
   works_in_software_mode_watchpoint,
   NULL, /* print_it */
@@ -9121,9 +9150,12 @@ print_recreate_masked_watchpoint (struct breakpoint *b, struct ui_file *fp)
 static struct breakpoint_ops masked_watchpoint_breakpoint_ops =
 {
   NULL, /* dtor */
+  NULL, /* allocate_location */
+  NULL, /* re_set */
   insert_masked_watchpoint,
   remove_masked_watchpoint,
   NULL, /* breakpoint_hit */
+  NULL, /* check_status */
   resources_needed_masked_watchpoint,
   works_in_software_mode_masked_watchpoint,
   print_it_masked_watchpoint,
@@ -9845,7 +9877,7 @@ catch_exec_command_1 (char *arg, int from_tty,
                   &catch_exec_breakpoint_ops);
   c->exec_pathname = NULL;
 
-  install_catchpoint (&c->base);
+  install_breakpoint (&c->base);
 }
 
 static enum print_stop_action
@@ -9937,9 +9969,12 @@ print_recreate_exception_catchpoint (struct breakpoint *b,
 
 static struct breakpoint_ops gnu_v3_exception_catchpoint_ops = {
   NULL, /* dtor */
+  NULL, /* allocate_location */
+  NULL, /* re_set */
   NULL, /* insert */
   NULL, /* remove */
   NULL, /* breakpoint_hit */
+  NULL, /* check_status */
   NULL, /* resources_needed */
   NULL, /* works_in_software_mode */
   print_it_exception_catchpoint,
@@ -10021,18 +10056,14 @@ catch_throw_command (char *arg, int from_tty, struct cmd_list_element *command)
 }
 
 void
-create_ada_exception_breakpoint (struct gdbarch *gdbarch,
-                                struct symtab_and_line sal,
-                                 char *addr_string,
-                                 char *exp_string,
-                                 char *cond_string,
-                                 struct expression *cond,
-                                 struct breakpoint_ops *ops,
-                                 int tempflag,
-                                 int from_tty)
+init_ada_exception_breakpoint (struct breakpoint *b,
+                              struct gdbarch *gdbarch,
+                              struct symtab_and_line sal,
+                              char *addr_string,
+                              struct breakpoint_ops *ops,
+                              int tempflag,
+                              int from_tty)
 {
-  struct breakpoint *b;
-
   if (from_tty)
     {
       struct gdbarch *loc_gdbarch = get_sal_arch (sal);
@@ -10051,24 +10082,12 @@ create_ada_exception_breakpoint (struct gdbarch *gdbarch,
          enough for now, though.  */
     }
 
-  b = set_raw_breakpoint (gdbarch, sal, bp_breakpoint);
-  set_breakpoint_count (breakpoint_count + 1);
+  init_raw_breakpoint (b, gdbarch, sal, bp_breakpoint, ops);
 
   b->enable_state = bp_enabled;
   b->disposition = tempflag ? disp_del : disp_donttouch;
-  b->number = breakpoint_count;
-  b->ignore_count = 0;
-  b->loc->cond = cond;
   b->addr_string = addr_string;
   b->language = language_ada;
-  b->cond_string = cond_string;
-  b->exp_string = exp_string;
-  b->thread = -1;
-  b->ops = ops;
-
-  mention (b);
-  observer_notify_breakpoint_created (b);
-  update_global_location_list (1);
 }
 
 /* Cleanup function for a syscall filter list.  */
@@ -11402,23 +11421,13 @@ addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
   return sals;
 }
 
-/* Reevaluate a hardware or software breakpoint and recreate its locations.
-   This is necessary after symbols are read (e.g., an executable or DSO
-   was loaded, or the inferior just started).  */
-
-static void
-re_set_breakpoint (struct breakpoint *b)
+void
+breakpoint_re_set_default (struct breakpoint *b)
 {
   int found;
   struct symtabs_and_lines sals, sals_end;
   struct symtabs_and_lines expanded = {0};
   struct symtabs_and_lines expanded_end = {0};
-  struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
-
-  input_radix = b->input_radix;
-  save_current_space_and_thread ();
-  switch_to_program_space_and_thread (b->pspace);
-  set_language (b->language);
 
   sals = addr_string_to_sals (b, b->addr_string, &found);
   if (found)
@@ -11438,7 +11447,21 @@ re_set_breakpoint (struct breakpoint *b)
     }
 
   update_breakpoint_locations (b, expanded, expanded_end);
-  do_cleanups (cleanups);
+}
+
+/* Prepare the global context for a re-set of breakpoint B.  */
+
+static struct cleanup *
+prepare_re_set_context (struct breakpoint *b)
+{
+  struct cleanup *cleanups;
+
+  input_radix = b->input_radix;
+  cleanups = save_current_space_and_thread ();
+  switch_to_program_space_and_thread (b->pspace);
+  set_language (b->language);
+
+  return cleanups;
 }
 
 /* Reset a breakpoint given it's struct breakpoint * BINT.
@@ -11451,6 +11474,17 @@ breakpoint_re_set_one (void *bint)
   /* Get past catch_errs.  */
   struct breakpoint *b = (struct breakpoint *) bint;
 
+  if (b->ops != NULL && b->ops->re_set != NULL)
+    {
+      struct cleanup *cleanups;
+
+      cleanups = prepare_re_set_context (b);
+      b->ops->re_set (b);
+      do_cleanups (cleanups);
+
+      return 0;
+    }
+
   switch (b->type)
     {
     case bp_none:
@@ -11474,7 +11508,13 @@ breakpoint_re_set_one (void *bint)
          return 0;
        }
 
-      re_set_breakpoint (b);
+      {
+       struct cleanup *cleanups;
+
+       cleanups = prepare_re_set_context (b);
+       breakpoint_re_set_default (b);
+       do_cleanups (cleanups);
+      }
       break;
 
     case bp_watchpoint:
index 9dbf23b6ad8b5a34e1a1217e3f0ae71cfea963b8..6fca4791c6e99ab8f6e74e95b78637835b01c3ef 100644 (file)
@@ -30,6 +30,8 @@ struct block;
 struct breakpoint_object;
 struct get_number_or_range_state;
 struct thread_info;
+struct bpstats;
+struct bp_location;
 
 /* This is the maximum number of bytes a breakpoint instruction can
    take.  Feel free to increase it.  It's just used in a few places to
@@ -278,12 +280,26 @@ enum bp_loc_type
   bp_loc_other                 /* Miscellaneous...  */
 };
 
+/* This structure is a collection of function pointers that, if
+   available, will be called instead of performing the default action
+   for this bp_loc_type.  */
+
+struct bp_location_ops
+{
+  /* Destructor.  Releases everything from SELF (but not SELF
+     itself).  */
+  void (*dtor) (struct bp_location *self);
+};
+
 struct bp_location
 {
   /* Chain pointer to the next breakpoint location for
      the same parent breakpoint.  */
   struct bp_location *next;
 
+  /* Methods associated with this location.  */
+  const struct bp_location_ops *ops;
+
   /* The reference count.  */
   int refc;
 
@@ -397,6 +413,14 @@ struct breakpoint_ops
      itself).  */
   void (*dtor) (struct breakpoint *self);
 
+  /* Allocate a location for this breakpoint.  */
+  struct bp_location * (*allocate_location) (struct breakpoint *);
+
+  /* Reevaluate a breakpoint.  This is necessary after symbols change
+     (e.g., an executable or DSO was loaded, or the inferior just
+     started).  */
+  void (*re_set) (struct breakpoint *self);
+
   /* Insert the breakpoint or watchpoint or activate the catchpoint.
      Return 0 for success, 1 if the breakpoint, watchpoint or catchpoint
      type is not supported, -1 for failure.  */
@@ -408,11 +432,16 @@ struct breakpoint_ops
      -1 for failure.  */
   int (*remove_location) (struct bp_location *);
 
-  /* Return non-zero if the debugger should tell the user that this
-     breakpoint was hit.  */
-  int (*breakpoint_hit) (const struct bp_location *, struct address_space *,
+  /* Return true if it the target has stopped due to hitting
+     breakpoint location BL.  This function does not check if we
+     should stop, only if BL explains the stop.  */
+  int (*breakpoint_hit) (const struct bp_location *bl, struct address_space *,
                         CORE_ADDR);
 
+  /* Check internal conditions of the breakpoint referred to by BS.
+     If we should not stop for this breakpoint, set BS->stop to 0.  */
+  void (*check_status) (struct bpstats *bs);
+
   /* Tell how many hardware resources (debug registers) are needed
      for this breakpoint.  If this function is not provided, then
      the breakpoint or watchpoint needs one debug register.  */
@@ -937,6 +966,12 @@ extern int breakpoint_thread_match (struct address_space *,
 
 extern void until_break_command (char *, int, int);
 
+/* Initialize a struct bp_location.  */
+
+extern void init_bp_location (struct bp_location *loc,
+                             const struct bp_location_ops *ops,
+                             struct breakpoint *owner);
+
 extern void update_breakpoint_locations (struct breakpoint *b,
                                         struct symtabs_and_lines sals,
                                         struct symtabs_and_lines sals_end);
@@ -945,6 +980,12 @@ extern void breakpoint_re_set (void);
 
 extern void breakpoint_re_set_thread (struct breakpoint *);
 
+/* The default re_set method, for typical hardware or software
+   breakpoints.  Reevaluate the breakpoint and recreate its
+   locations.  */
+
+extern void breakpoint_re_set_default (struct breakpoint *);
+
 extern struct breakpoint *set_momentary_breakpoint
   (struct gdbarch *, struct symtab_and_line, struct frame_id, enum bptype);
 
@@ -1001,18 +1042,21 @@ extern void
                     void *user_data_catch,
                     void *user_data_tcatch);
 
-/* Create a breakpoint struct for Ada exception catchpoints.  */
+/* Initialize a breakpoint struct for Ada exception catchpoints.  */
 
 extern void
-  create_ada_exception_breakpoint (struct gdbarch *gdbarch,
-                                  struct symtab_and_line sal,
-                                  char *addr_string,
-                                  char *exp_string,
-                                  char *cond_string,
-                                  struct expression *cond,
-                                  struct breakpoint_ops *ops,
-                                  int tempflag,
-                                  int from_tty);
+  init_ada_exception_breakpoint (struct breakpoint *b,
+                                struct gdbarch *gdbarch,
+                                struct symtab_and_line sal,
+                                char *addr_string,
+                                struct breakpoint_ops *ops,
+                                int tempflag,
+                                int from_tty);
+
+/* Add breakpoint B on the breakpoint list, and notify the user, the
+   target and breakpoint_created observers of its existence.  */
+
+extern void install_breakpoint (struct breakpoint *b);
 
 extern int create_breakpoint (struct gdbarch *gdbarch, char *arg,
                              char *cond_string, int thread,