diff options
author | Thiago Jung Bauermann <bauerman@br.ibm.com> | 2010-07-07 16:15:18 +0000 |
---|---|---|
committer | Thiago Jung Bauermann <bauerman@br.ibm.com> | 2010-07-07 16:15:18 +0000 |
commit | 0cf6dd1543299e30c82397ef49d00b32af911a63 (patch) | |
tree | ae3f26f11acc891e1092331af2f955cc80b05896 /gdb/breakpoint.c | |
parent | 6bd31874685a739404578403651d7b1ad5d20a3e (diff) | |
download | gdb-0cf6dd1543299e30c82397ef49d00b32af911a63.zip gdb-0cf6dd1543299e30c82397ef49d00b32af911a63.tar.gz gdb-0cf6dd1543299e30c82397ef49d00b32af911a63.tar.bz2 |
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com>gdb_7_2-branchpoint
Thiago Jung Bauermann <bauerman@br.ibm.com>
Support for hw accelerated condition watchpoints in booke powerpc.
* breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value
and move to eval.c. Change callers.
(insert_bp_location): Pass watchpoint condition in
target_insert_watchpoint.
(remove_breakpoint_1) Pass watchpoint condition in
target_remove_watchpoint.
(watchpoint_locations_match): Call
target_can_accel_watchpoint_condition.
* eval.c: Include wrapper.h.
(fetch_subexp_value): Moved from breakpoint.c.
* ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint):
Formatting fix.
(can_use_watchpoint_cond_accel): New function.
(calculate_dvc): Likewise.
(num_memory_accesses): Likewise.
(check_condition): Likewise.
(ppc_linux_can_accel_watchpoint_condition): Likewise
(ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel,
check_condition and calculate_dvc.
(ppc_linux_remove_watchpoint): Likewise.
(_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to
ppc_linux_can_accel_watchpoint_condition
* target.c (debug_to_insert_watchpoint): Add argument for watchpoint
condition.
(debug_to_remove_watchpoint): Likewise.
(debug_to_can_accel_watchpoint_condition): New function.
(update_current_target): Set to_can_accel_watchpoint_condition.
(setup_target_debug): Set to_can_accel_watchpoint_condition.
* target.h: Add opaque declaration for struct expression.
(struct target_ops) <to_insert_watchpoint>,
<to_remove_watchpoint>: Add new arguments to pass the watchpoint
<to_can_accel_watchpoint_condition>: New member.
condition. Update all callers and implementations.
(target_can_accel_watchpoint_condition): New macro.
* value.c (free_value_chain): New function.
* value.h (fetch_subexp_value): New prototype.
(free_value_chain): Likewise.
Diffstat (limited to 'gdb/breakpoint.c')
-rw-r--r-- | gdb/breakpoint.c | 112 |
1 files changed, 27 insertions, 85 deletions
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 3c93c4b..4affe0a 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -1234,84 +1234,6 @@ is_watchpoint (const struct breakpoint *bpt) || bpt->type == bp_watchpoint); } -/* Find the current value of a watchpoint on EXP. Return the value in - *VALP and *RESULTP and the chain of intermediate and final values - in *VAL_CHAIN. RESULTP and VAL_CHAIN may be NULL if the caller does - not need them. - - If a memory error occurs while evaluating the expression, *RESULTP will - be set to NULL. *RESULTP may be a lazy value, if the result could - not be read from memory. It is used to determine whether a value - is user-specified (we should watch the whole value) or intermediate - (we should watch only the bit used to locate the final value). - - If the final value, or any intermediate value, could not be read - from memory, *VALP will be set to NULL. *VAL_CHAIN will still be - set to any referenced values. *VALP will never be a lazy value. - This is the value which we store in struct breakpoint. - - If VAL_CHAIN is non-NULL, *VAL_CHAIN will be released from the - value chain. The caller must free the values individually. If - VAL_CHAIN is NULL, all generated values will be left on the value - chain. */ - -static void -fetch_watchpoint_value (struct expression *exp, struct value **valp, - struct value **resultp, struct value **val_chain) -{ - struct value *mark, *new_mark, *result; - volatile struct gdb_exception ex; - - *valp = NULL; - if (resultp) - *resultp = NULL; - if (val_chain) - *val_chain = NULL; - - /* Evaluate the expression. */ - mark = value_mark (); - result = NULL; - - TRY_CATCH (ex, RETURN_MASK_ALL) - { - result = evaluate_expression (exp); - } - if (ex.reason < 0) - { - /* Ignore memory errors, we want watchpoints pointing at - inaccessible memory to still be created; otherwise, throw the - error to some higher catcher. */ - switch (ex.error) - { - case MEMORY_ERROR: - break; - default: - throw_exception (ex); - break; - } - } - - new_mark = value_mark (); - if (mark == new_mark) - return; - if (resultp) - *resultp = result; - - /* Make sure it's not lazy, so that after the target stops again we - have a non-lazy previous value to compare with. */ - if (result != NULL - && (!value_lazy (result) || gdb_value_fetch_lazy (result))) - *valp = result; - - if (val_chain) - { - /* Return the chain of intermediate values. We use this to - decide which addresses to watch. */ - *val_chain = new_mark; - value_release_to_mark (mark); - } -} - /* Assuming that B is a watchpoint: returns true if the current thread and its running state are safe to evaluate or update watchpoint B. Watchpoints on local expressions need to be evaluated in the @@ -1469,10 +1391,11 @@ update_watchpoint (struct breakpoint *b, int reparse) } else if (within_current_scope && b->exp) { + int pc = 0; struct value *val_chain, *v, *result, *next; struct program_space *frame_pspace; - fetch_watchpoint_value (b->exp, &v, &result, &val_chain); + fetch_subexp_value (b->exp, &pc, &v, &result, &val_chain); /* Avoid setting b->val if it's already set. The meaning of b->val is 'the last value' user saw, and we should update @@ -1828,7 +1751,8 @@ Note: automatically using hardware breakpoints for read-only addresses.\n")); { val = target_insert_watchpoint (bpt->address, bpt->length, - bpt->watchpoint_type); + bpt->watchpoint_type, + bpt->owner->cond_exp); /* If trying to set a read-watchpoint, and it turns out it's not supported, try emulating one with an access watchpoint. */ @@ -1856,7 +1780,8 @@ Note: automatically using hardware breakpoints for read-only addresses.\n")); { val = target_insert_watchpoint (bpt->address, bpt->length, - hw_access); + hw_access, + bpt->owner->cond_exp); if (val == 0) bpt->watchpoint_type = hw_access; } @@ -2525,8 +2450,8 @@ remove_breakpoint_1 (struct bp_location *b, insertion_state_t is) else if (b->loc_type == bp_loc_hardware_watchpoint) { b->inserted = (is == mark_inserted); - val = target_remove_watchpoint (b->address, b->length, - b->watchpoint_type); + val = target_remove_watchpoint (b->address, b->length, + b->watchpoint_type, b->owner->cond_exp); /* Failure to remove any of the hardware watchpoints comes here. */ if ((is == mark_uninserted) && (b->inserted)) @@ -3679,10 +3604,11 @@ watchpoint_check (void *p) call free_all_values. We can't call free_all_values because we might be in the middle of evaluating a function call. */ + int pc = 0; struct value *mark = value_mark (); struct value *new_val; - fetch_watchpoint_value (b->exp, &new_val, NULL, NULL); + fetch_subexp_value (b->exp, &pc, &new_val, NULL, NULL); /* We use value_equal_contents instead of value_equal because the latter coerces an array to a pointer, thus comparing just the address of the @@ -5262,6 +5188,21 @@ watchpoint_locations_match (struct bp_location *loc1, struct bp_location *loc2) gdb_assert (loc1->owner != NULL); gdb_assert (loc2->owner != NULL); + /* If the target can evaluate the condition expression in hardware, then we + we need to insert both watchpoints even if they are at the same place. + Otherwise the watchpoint will only trigger when the condition of whichever + watchpoint was inserted evaluates to true, not giving a chance for GDB to + check the condition of the other watchpoint. */ + if ((loc1->owner->cond_exp + && target_can_accel_watchpoint_condition (loc1->address, loc1->length, + loc1->watchpoint_type, + loc1->owner->cond_exp)) + || (loc2->owner->cond_exp + && target_can_accel_watchpoint_condition (loc2->address, loc2->length, + loc2->watchpoint_type, + loc2->owner->cond_exp))) + return 0; + /* Note that this checks the owner's type, not the location's. In case the target does not support read watchpoints, but does support access watchpoints, we'll have bp_read_watchpoint @@ -8057,6 +7998,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty) enum bptype bp_type; int mem_cnt = 0; int thread = -1; + int pc = 0; /* Make sure that we actually have parameters to parse. */ if (arg != NULL && arg[0] != '\0') @@ -8143,7 +8085,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty) exp_valid_block = innermost_block; mark = value_mark (); - fetch_watchpoint_value (exp, &val, NULL, NULL); + fetch_subexp_value (exp, &pc, &val, NULL, NULL); if (val != NULL) release_value (val); |