diff options
author | Pedro Alves <palves@redhat.com> | 2011-09-13 16:37:13 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2011-09-13 16:37:13 +0000 |
commit | a1398e0c5690d181307a819fbe9cc4e08e518fbc (patch) | |
tree | be0204b7e0fd60e868b8a8ff10e35ac4a2cecf70 /gdb/breakpoint.c | |
parent | 40b2987463cd3792ba025dc2fbb8a640bb49f45a (diff) | |
download | gdb-a1398e0c5690d181307a819fbe9cc4e08e518fbc.zip gdb-a1398e0c5690d181307a819fbe9cc4e08e518fbc.tar.gz gdb-a1398e0c5690d181307a819fbe9cc4e08e518fbc.tar.bz2 |
2011-09-13 Pedro Alves <pedro@codesourcery.com>
* breakpoint.c (update_watchpoint): Handle the case of the
watchpoint to update not being in the breakpoint list yet.
(hw_watchpoint_use_count): New, factored out from
hw_watchpoint_used_count.
(hw_watchpoint_used_count): Rename to ...
(hw_watchpoint_used_count_others): ... this. Add `except'
parameter. Don't count resources of `except'. Use
hw_watchpoint_use_count.
Diffstat (limited to 'gdb/breakpoint.c')
-rw-r--r-- | gdb/breakpoint.c | 99 |
1 files changed, 75 insertions, 24 deletions
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 8c5b6e5..14c8903 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -176,7 +176,11 @@ static void maintenance_info_breakpoints (char *, int); static int hw_breakpoint_used_count (void); -static int hw_watchpoint_used_count (enum bptype, int *); +static int hw_watchpoint_use_count (struct breakpoint *); + +static int hw_watchpoint_used_count_others (struct breakpoint *except, + enum bptype type, + int *other_type_used); static void hbreak_command (char *, int); @@ -1458,6 +1462,7 @@ update_watchpoint (struct watchpoint *b, int reparse) if (reg_cnt) { int i, target_resources_ok, other_type_used; + enum bptype type; /* Use an exact watchpoint when there's only one memory region to be watched, and only one debug register is needed to watch it. */ @@ -1466,16 +1471,29 @@ update_watchpoint (struct watchpoint *b, int reparse) /* We need to determine how many resources are already used for all other hardware watchpoints plus this one to see if we still have enough resources to also fit - this watchpoint in as well. To guarantee the - hw_watchpoint_used_count call below counts this - watchpoint, make sure that it is marked as a hardware - watchpoint. */ - if (b->base.type == bp_watchpoint) - b->base.type = bp_hardware_watchpoint; - - i = hw_watchpoint_used_count (b->base.type, &other_type_used); - target_resources_ok = target_can_use_hardware_watchpoint - (b->base.type, i, other_type_used); + this watchpoint in as well. */ + + /* If this is a software watchpoint, we try to turn it + to a hardware one -- count resources as if B was of + hardware watchpoint type. */ + type = b->base.type; + if (type == bp_watchpoint) + type = bp_hardware_watchpoint; + + /* This watchpoint may or may not have been placed on + the list yet at this point (it won't be in the list + if we're trying to create it for the first time, + through watch_command), so always account for it + manually. */ + + /* Count resources used by all watchpoints except B. */ + i = hw_watchpoint_used_count_others (&b->base, type, &other_type_used); + + /* Add in the resources needed for B. */ + i += hw_watchpoint_use_count (&b->base); + + target_resources_ok + = target_can_use_hardware_watchpoint (type, i, other_type_used); if (target_resources_ok <= 0) { int sw_mode = b->base.ops->works_in_software_mode (&b->base); @@ -1486,8 +1504,17 @@ update_watchpoint (struct watchpoint *b, int reparse) else if (target_resources_ok < 0 && !sw_mode) error (_("There are not enough available hardware " "resources for this watchpoint.")); - else - b->base.type = bp_watchpoint; + + /* Downgrade to software watchpoint. */ + b->base.type = bp_watchpoint; + } + else + { + /* If this was a software watchpoint, we've just + found we have enough resources to turn it to a + hardware watchpoint. Otherwise, this is a + nop. */ + b->base.type = type; } } else if (!b->base.ops->works_in_software_mode (&b->base)) @@ -6846,28 +6873,52 @@ hw_breakpoint_used_count (void) return i; } +/* Returns the resources B would use if it were a hardware + watchpoint. */ + static int -hw_watchpoint_used_count (enum bptype type, int *other_type_used) +hw_watchpoint_use_count (struct breakpoint *b) { int i = 0; - struct breakpoint *b; struct bp_location *bl; + if (!breakpoint_enabled (b)) + return 0; + + for (bl = b->loc; bl; bl = bl->next) + { + /* Special types of hardware watchpoints may use more than + one register. */ + i += b->ops->resources_needed (bl); + } + + return i; +} + +/* Returns the sum the used resources of all hardware watchpoints of + type TYPE in the breakpoints list. Also returns in OTHER_TYPE_USED + the sum of the used resources of all hardware watchpoints of other + types _not_ TYPE. */ + +static int +hw_watchpoint_used_count_others (struct breakpoint *except, + enum bptype type, int *other_type_used) +{ + int i = 0; + struct breakpoint *b; + *other_type_used = 0; ALL_BREAKPOINTS (b) { + if (b == except) + continue; if (!breakpoint_enabled (b)) continue; - if (b->type == type) - for (bl = b->loc; bl; bl = bl->next) - { - /* Special types of hardware watchpoints may use more than - one register. */ - i += b->ops->resources_needed (bl); - } - else if (is_hardware_watchpoint (b)) - *other_type_used = 1; + if (b->type == type) + i += hw_watchpoint_use_count (b); + else if (is_hardware_watchpoint (b)) + *other_type_used = 1; } return i; |