From: Pedro Alves Date: Thu, 12 May 2022 18:43:53 +0000 (+0100) Subject: Make breakpoint_address_bits look at the location kind X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6e14e4412b670d093d74b90e5d4adcfaedb76d3f;p=binutils-gdb.git Make breakpoint_address_bits look at the location kind Software watchpoints allocate a special dummy location using software_watchpoint_add_no_memory_location, and then breakpoint_address_bits checks whether the location is that special location to decide whether the location has a meaninful address to print. Introduce a new bp_loc_software_watchpoint location kind, and make breakpoint_address_bits use bl_address_is_meaningful instead, which returns false for bp_loc_other, which is in accordance with we document for bp_location::address: /* (... snip ...) Valid for all types except bp_loc_other. */ CORE_ADDR address = 0; Rename software_watchpoint_add_no_memory_location to add_dummy_location, and simplify it. This will be used by catchpoints too in a following patch. Note that neither "info breakpoints" nor "maint info breakpoints" actually prints the addresses of watchpoints, but I think it would be useful to do so in "maint info breakpoints". This approach let's us implement that in the future. Change-Id: I50e398f66ef618c31ffa662da755eaba6295aed7 --- diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 299358f16d5..0ba2ea2f6b7 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -164,6 +164,8 @@ static std::vector bkpt_probe_decode_location struct event_location *location, struct program_space *search_pspace); +static bool bl_address_is_meaningful (bp_location *loc); + /* update_global_location_list's modes of operation wrt to whether to insert locations now. */ enum ugll_insert_mode @@ -1830,34 +1832,18 @@ extract_bitfield_from_watchpoint_value (struct watchpoint *w, struct value *val) return bit_val; } -/* Allocate a dummy location and add it to B, which must be a software - watchpoint. This is required because even if a software watchpoint - is not watching any memory, bpstat_stop_status requires a location - to be able to report stops. */ +/* Allocate a dummy location and add it to B. This is required + because bpstat_stop_status requires a location to be able to report + stops. */ static void -software_watchpoint_add_no_memory_location (struct breakpoint *b, - struct program_space *pspace) +add_dummy_location (struct breakpoint *b, + struct program_space *pspace) { - gdb_assert (b->type == bp_watchpoint && b->loc == NULL); + gdb_assert (b->loc == NULL); - b->loc = b->allocate_location (); + b->loc = new bp_location (b, bp_loc_other); b->loc->pspace = pspace; - b->loc->address = -1; - b->loc->length = -1; -} - -/* Returns true if B is a software watchpoint that is not watching any - memory (e.g., "watch $pc"). */ - -static bool -is_no_memory_software_watchpoint (struct breakpoint *b) -{ - return (b->type == bp_watchpoint - && b->loc != NULL - && b->loc->next == NULL - && b->loc->address == -1 - && b->loc->length == -1); } /* Assuming that B is a watchpoint: @@ -2197,7 +2183,7 @@ update_watchpoint (struct watchpoint *b, int reparse) else b->type = bp_watchpoint; - loc_type = (b->type == bp_watchpoint? bp_loc_other + loc_type = (b->type == bp_watchpoint? bp_loc_software_watchpoint : bp_loc_hardware_watchpoint); for (bp_location *bl : b->locations ()) bl->loc_type = loc_type; @@ -2208,7 +2194,7 @@ update_watchpoint (struct watchpoint *b, int reparse) bpstat_stop_status requires a location to be able to report stops, so make sure there's at least a dummy one. */ if (b->type == bp_watchpoint && b->loc == NULL) - software_watchpoint_add_no_memory_location (b, frame_pspace); + add_dummy_location (b, frame_pspace); } else if (!within_current_scope) { @@ -3840,11 +3826,12 @@ detach_breakpoints (ptid_t ptid) /* This function must physically remove breakpoints locations from the specified ptid, without modifying the breakpoint - package's state. Locations of type bp_loc_other are only - maintained at GDB side. So, there is no need to remove - these bp_loc_other locations. Moreover, removing these + package's state. Locations of type bp_loc_other and + bp_loc_software_watchpoint are only maintained at GDB side, + so there is no need to remove them. Moreover, removing these would modify the breakpoint package's state. */ - if (bl->loc_type == bp_loc_other) + if (bl->loc_type == bp_loc_other + || bl->loc_type == bp_loc_software_watchpoint) continue; if (bl->inserted) @@ -5798,7 +5785,8 @@ bpstat_what (bpstat *bs_head) { /* Some catchpoints are implemented with breakpoints. For those, we need to step over the breakpoint. */ - if (bs->bp_location_at->loc_type != bp_loc_other) + if (bs->bp_location_at->loc_type == bp_loc_software_breakpoint + || bs->bp_location_at->loc_type == bp_loc_hardware_breakpoint) this_action = BPSTAT_WHAT_SINGLE; } break; @@ -6557,16 +6545,12 @@ breakpoint_address_bits (struct breakpoint *b) { int print_address_bits = 0; - /* Software watchpoints that aren't watching memory don't have an - address to print. */ - if (is_no_memory_software_watchpoint (b)) - return 0; - for (bp_location *loc : b->locations ()) { - int addr_bit; + if (!bl_address_is_meaningful (loc)) + continue; - addr_bit = gdbarch_addr_bit (loc->gdbarch); + int addr_bit = gdbarch_addr_bit (loc->gdbarch); if (addr_bit > print_address_bits) print_address_bits = addr_bit; } @@ -7161,6 +7145,7 @@ bp_location_from_bp_type (bptype type) case bp_access_watchpoint: return bp_loc_hardware_watchpoint; case bp_watchpoint: + return bp_loc_software_watchpoint; case bp_catchpoint: case bp_tracepoint: case bp_fast_tracepoint: diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index a4ead8b4d4e..7375e976dc6 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -314,6 +314,7 @@ enum bp_loc_type { bp_loc_software_breakpoint, bp_loc_hardware_breakpoint, + bp_loc_software_watchpoint, bp_loc_hardware_watchpoint, bp_loc_other /* Miscellaneous... */ };