public inbox for gdb-cvs@sourceware.org
help / color / mirror / Atom feed
* [binutils-gdb] Add a vtable-based breakpoint ops
@ 2022-04-29 22:22 Tom Tromey
  0 siblings, 0 replies; only message in thread
From: Tom Tromey @ 2022-04-29 22:22 UTC (permalink / raw)
  To: gdb-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4c6a92b11dd1aff9b071a245a21b61e6b25c8dec

commit 4c6a92b11dd1aff9b071a245a21b61e6b25c8dec
Author: Tom Tromey <tom@tromey.com>
Date:   Fri Jan 14 18:42:13 2022 -0700

    Add a vtable-based breakpoint ops
    
    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.

Diff:
---
 gdb/breakpoint.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/breakpoint.h | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 223 insertions(+)

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index de1c09e6c44..90f87b6352f 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -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
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index 455a1b4b5ca..ceeabb0d2fd 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -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);


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-04-29 22:22 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-29 22:22 [binutils-gdb] Add a vtable-based breakpoint ops Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).