Add a vtable-based breakpoint ops
authorTom Tromey <tom@tromey.com>
Sat, 15 Jan 2022 01:42:13 +0000 (18:42 -0700)
committerTom Tromey <tom@tromey.com>
Fri, 29 Apr 2022 22:14:30 +0000 (16:14 -0600)
This adds methods to struct breakpoint.  Each method has a similar
signature to a corresponding function in breakpoint_ops, with the
exceptions of create_sals_from_location and create_breakpoints_sal,
which can't be virtual methods on breakpoint -- they are only used
during the construction of breakpoints.

Then, this adds a new vtable_breakpoint_ops structure and populates it
with functions that simply forward a call from breakpoint_ops to the
corresponding virtual method.  These are all done with lambdas,
because they are just a stepping stone -- by the end of the series,
this structure will be deleted.

gdb/breakpoint.c
gdb/breakpoint.h

index de1c09e6c443080d4342d30765fe7374836d8bb0..90f87b6352fe369451c2d8863c8e5d39596c481b 100644 (file)
@@ -11493,6 +11493,12 @@ base_breakpoint_allocate_location (struct breakpoint *self)
   return new bp_location (self);
 }
 
+struct bp_location *
+breakpoint::allocate_location ()
+{
+  return new bp_location (this);
+}
+
 static void
 base_breakpoint_re_set (struct breakpoint *b)
 {
@@ -11508,6 +11514,12 @@ base_breakpoint_insert_location (struct bp_location *bl)
   internal_error_pure_virtual_called ();
 }
 
+int
+breakpoint::insert_location (struct bp_location *bl)
+{
+  internal_error_pure_virtual_called ();
+}
+
 static int
 base_breakpoint_remove_location (struct bp_location *bl,
                                 enum remove_bp_reason reason)
@@ -11515,6 +11527,13 @@ base_breakpoint_remove_location (struct bp_location *bl,
   internal_error_pure_virtual_called ();
 }
 
+int
+breakpoint::remove_location (struct bp_location *bl,
+                            enum remove_bp_reason reason)
+{
+  internal_error_pure_virtual_called ();
+}
+
 static int
 base_breakpoint_breakpoint_hit (const struct bp_location *bl,
                                const address_space *aspace,
@@ -11524,6 +11543,15 @@ base_breakpoint_breakpoint_hit (const struct bp_location *bl,
   internal_error_pure_virtual_called ();
 }
 
+int
+breakpoint::breakpoint_hit (const struct bp_location *bl,
+                           const address_space *aspace,
+                           CORE_ADDR bp_addr,
+                           const target_waitstatus &ws)
+{
+  internal_error_pure_virtual_called ();
+}
+
 static void
 base_breakpoint_check_status (bpstat *bs)
 {
@@ -11539,6 +11567,12 @@ base_breakpoint_works_in_software_mode (const struct breakpoint *b)
   internal_error_pure_virtual_called ();
 }
 
+int
+breakpoint::works_in_software_mode () const
+{
+  internal_error_pure_virtual_called ();
+}
+
 /* A "resources_needed" breakpoint_ops method that just internal
    errors.  */
 
@@ -11548,12 +11582,24 @@ base_breakpoint_resources_needed (const struct bp_location *bl)
   internal_error_pure_virtual_called ();
 }
 
+int
+breakpoint::resources_needed (const struct bp_location *bl)
+{
+  internal_error_pure_virtual_called ();
+}
+
 static enum print_stop_action
 base_breakpoint_print_it (bpstat *bs)
 {
   internal_error_pure_virtual_called ();
 }
 
+enum print_stop_action
+breakpoint::print_it (bpstat *bs)
+{
+  internal_error_pure_virtual_called ();
+}
+
 static bool
 base_breakpoint_print_one (struct breakpoint *, struct bp_location **)
 {
@@ -11573,12 +11619,24 @@ base_breakpoint_print_mention (struct breakpoint *b)
   internal_error_pure_virtual_called ();
 }
 
+void
+breakpoint::print_mention ()
+{
+  internal_error_pure_virtual_called ();
+}
+
 static void
 base_breakpoint_print_recreate (struct breakpoint *b, struct ui_file *fp)
 {
   internal_error_pure_virtual_called ();
 }
 
+void
+breakpoint::print_recreate (struct ui_file *fp)
+{
+  internal_error_pure_virtual_called ();
+}
+
 static void
 base_breakpoint_create_sals_from_location
   (struct event_location *location,
@@ -11612,6 +11670,13 @@ base_breakpoint_decode_location (struct breakpoint *b,
   internal_error_pure_virtual_called ();
 }
 
+std::vector<symtab_and_line>
+breakpoint::decode_location (struct event_location *location,
+                            struct program_space *search_pspace)
+{
+  internal_error_pure_virtual_called ();
+}
+
 /* The default 'explains_signal' method.  */
 
 static int
@@ -11650,6 +11715,51 @@ struct breakpoint_ops base_breakpoint_ops =
   base_breakpoint_after_condition_true,
 };
 
+struct breakpoint_ops vtable_breakpoint_ops =
+{
+  [] (struct breakpoint *b) { return b->allocate_location (); },
+  [] (struct breakpoint *b) { b->re_set (); },
+  [] (struct bp_location *l)
+  {
+    return l->owner->insert_location (l);
+  },
+  [] (struct bp_location *l, enum remove_bp_reason reason)
+  {
+    return l->owner->remove_location (l, reason);
+  },
+  [] (const struct bp_location *bl,
+      const address_space *aspace,
+      CORE_ADDR bp_addr,
+      const target_waitstatus &ws)
+  {
+    return bl->owner->breakpoint_hit (bl, aspace, bp_addr, ws);
+  },
+  [] (struct bpstat *bs) { bs->breakpoint_at->check_status (bs); },
+  [] (const struct bp_location *bl)
+  { return bl->owner->resources_needed (bl); },
+  [] (const struct breakpoint *b)
+  { return b->works_in_software_mode (); },
+  [] (struct bpstat *bs)
+  { return bs->breakpoint_at->print_it (bs); },
+  [] (struct breakpoint *b, struct bp_location **bl)
+  { return b->print_one (bl); },
+  [] (const struct breakpoint *b, struct ui_out *out)
+  { b->print_one_detail (out); },
+  [] (struct breakpoint *b) { b->print_mention (); },
+  [] (struct breakpoint *b, struct ui_file *fp)
+  { b->print_recreate (fp); },
+  create_sals_from_location_default,
+  create_breakpoints_sal_default,
+  [] (struct breakpoint *b,
+      struct event_location *location,
+      struct program_space *search_pspace)
+  { return b->decode_location (location, search_pspace); },
+  [] (struct breakpoint *b, enum gdb_signal s)
+  { return b->explains_signal (s); },
+  [] (struct bpstat *bs)
+  { bs->breakpoint_at->after_condition_true (bs); }
+};
+
 /* Default breakpoint_ops methods.  */
 
 static void
index 455a1b4b5cabb8b894c6ae598ae43db539719421..ceeabb0d2fd5db7b9e3b0c3709e603bc031fcc82 100644 (file)
@@ -723,6 +723,118 @@ struct breakpoint
 {
   virtual ~breakpoint () = default;
 
+  /* Allocate a location for this breakpoint.  */
+  virtual struct bp_location *allocate_location ();
+
+  /* Reevaluate a breakpoint.  This is necessary after symbols change
+     (e.g., an executable or DSO was loaded, or the inferior just
+     started).  */
+  virtual void re_set ()
+  {
+    /* Nothing to re-set.  */
+  }
+
+  /* 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.  */
+  virtual int insert_location (struct bp_location *);
+
+  /* Remove the breakpoint/catchpoint that was previously inserted
+     with the "insert" method above.  Return 0 for success, 1 if the
+     breakpoint, watchpoint or catchpoint type is not supported,
+     -1 for failure.  */
+  virtual int remove_location (struct bp_location *,
+                              enum remove_bp_reason reason);
+
+  /* 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.  ASPACE is the address
+     space in which the event occurred, BP_ADDR is the address at
+     which the inferior stopped, and WS is the target_waitstatus
+     describing the event.  */
+  virtual int breakpoint_hit (const struct bp_location *bl,
+                             const address_space *aspace,
+                             CORE_ADDR bp_addr,
+                             const target_waitstatus &ws);
+
+  /* Check internal conditions of the breakpoint referred to by BS.
+     If we should not stop for this breakpoint, set BS->stop to 0.  */
+  virtual void check_status (struct bpstat *bs)
+  {
+    /* Always stop.  */
+  }
+
+  /* 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.  */
+  virtual int resources_needed (const struct bp_location *);
+
+  /* Tell whether we can downgrade from a hardware watchpoint to a software
+     one.  If not, the user will not be able to enable the watchpoint when
+     there are not enough hardware resources available.  */
+  virtual int works_in_software_mode () const;
+
+  /* The normal print routine for this breakpoint, called when we
+     hit it.  */
+  virtual enum print_stop_action print_it (struct bpstat *bs);
+
+  /* Display information about this breakpoint, for "info
+     breakpoints".  Returns false if this method should use the
+     default behavior.  */
+  virtual bool print_one (struct bp_location **)
+  {
+    return false;
+  }
+
+  /* Display extra information about this breakpoint, below the normal
+     breakpoint description in "info breakpoints".
+
+     In the example below, the "address range" line was printed
+     by print_one_detail_ranged_breakpoint.
+
+     (gdb) info breakpoints
+     Num     Type           Disp Enb Address    What
+     2       hw breakpoint  keep y              in main at test-watch.c:70
+            address range: [0x10000458, 0x100004c7]
+
+   */
+  virtual void print_one_detail (struct ui_out *) const
+  {
+    /* Nothing.  */
+  }
+
+  /* Display information about this breakpoint after setting it
+     (roughly speaking; this is called from "mention").  */
+  virtual void print_mention ();
+
+  /* Print to FP the CLI command that recreates this breakpoint.  */
+  virtual void print_recreate (struct ui_file *fp);
+
+  /* Given the location (second parameter), this method decodes it and
+     returns the SAL locations related to it.  For ordinary
+     breakpoints, it calls `decode_line_full'.  If SEARCH_PSPACE is
+     not NULL, symbol search is restricted to just that program space.
+
+     This function is called inside `location_to_sals'.  */
+  virtual std::vector<symtab_and_line> decode_location
+    (struct event_location *location,
+     struct program_space *search_pspace);
+
+  /* Return true if this breakpoint explains a signal.  See
+     bpstat_explains_signal.  */
+  virtual int explains_signal (enum gdb_signal)
+  {
+    return 1;
+  }
+
+  /* Called after evaluating the breakpoint's condition,
+     and only if it evaluated true.  */
+  virtual void after_condition_true (struct bpstat *bs)
+  {
+    /* Nothing to do.  */
+  }
+
+
   /* Return a range of this breakpoint's locations.  */
   bp_location_range locations ();
 
@@ -1335,6 +1447,7 @@ extern struct breakpoint_ops base_breakpoint_ops;
 extern struct breakpoint_ops bkpt_breakpoint_ops;
 extern struct breakpoint_ops tracepoint_breakpoint_ops;
 extern struct breakpoint_ops dprintf_breakpoint_ops;
+extern struct breakpoint_ops vtable_breakpoint_ops;
 
 extern void initialize_breakpoint_ops (void);