aboutsummaryrefslogtreecommitdiff
path: root/gdb/eval.c
diff options
context:
space:
mode:
authorThiago Jung Bauermann <bauerman@br.ibm.com>2010-07-07 16:15:18 +0000
committerThiago Jung Bauermann <bauerman@br.ibm.com>2010-07-07 16:15:18 +0000
commit0cf6dd1543299e30c82397ef49d00b32af911a63 (patch)
treeae3f26f11acc891e1092331af2f955cc80b05896 /gdb/eval.c
parent6bd31874685a739404578403651d7b1ad5d20a3e (diff)
downloadgdb-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/eval.c')
-rw-r--r--gdb/eval.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/gdb/eval.c b/gdb/eval.c
index 9a60616..ff17c34 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -43,6 +43,7 @@
#include "gdb_obstack.h"
#include "objfiles.h"
#include "python/python.h"
+#include "wrapper.h"
#include "gdb_assert.h"
@@ -186,6 +187,84 @@ evaluate_subexpression_type (struct expression *exp, int subexp)
return evaluate_subexp (NULL_TYPE, exp, &subexp, EVAL_AVOID_SIDE_EFFECTS);
}
+/* 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. */
+
+void
+fetch_subexp_value (struct expression *exp, int *pc, 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_subexp (NULL_TYPE, exp, pc, EVAL_NORMAL);
+ }
+ 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);
+ }
+}
+
/* Extract a field operation from an expression. If the subexpression
of EXP starting at *SUBEXP is not a structure dereference
operation, return NULL. Otherwise, return the name of the