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.
This commit is contained in:
Tom Tromey 2022-01-14 18:42:13 -07:00
parent c01e038bd2
commit 4c6a92b11d
2 changed files with 223 additions and 0 deletions

View 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

View 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);