From 4c6a92b11dd1aff9b071a245a21b61e6b25c8dec Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 14 Jan 2022 18:42:13 -0700 Subject: [PATCH] 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. --- 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 +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 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); -- 2.30.2