summaryrefslogtreecommitdiff
path: root/gdb/gdbtypes.c
diff options
context:
space:
mode:
authorThiago Jung Bauermann <bauerman@br.ibm.com>2011-01-11 19:23:01 +0000
committerThiago Jung Bauermann <bauerman@br.ibm.com>2011-01-11 19:23:01 +0000
commita5df084452a0c35f114f019854983a8cf7fdc1e4 (patch)
tree95005755e5fe747572eca003e47c892a2b4f021a /gdb/gdbtypes.c
parentc2e02cfa56813570cca008cd86491918abcdd4b8 (diff)
downloadgdb-a5df084452a0c35f114f019854983a8cf7fdc1e4.tar.gz
2011-01-11 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com>
Thiago Jung Bauermann <bauerman@br.ibm.com> Implement support for PowerPC BookE ranged watchpoints. gdb/ * breakpoint.h (struct breakpoint_ops) <resources_needed>: New method. Initialize to NULL in all existing breakpoint_ops instances. (struct breakpoint) <exact>: New field. (target_exact_watchpoints): Declare external global. * breakpoint.c (target_exact_watchpoints): New global flag. (update_watchpoint): Set b->type to bp_hardware_watchpoint and b->enable_state to bp_enabled before calling hw_watchpoint_used_count. (hw_watchpoint_used_count): Iterate over all bp_locations in a watchpoint. Call breakpoint's breakpoint_ops.resources_needed if available. (insert_watchpoint, remove_watchpoint): Use fixed length of 1 byte if the watchpoint is exact. (resources_needed_watchpoint): New function. (watchpoint_breakpoint_ops): Add resources_needed_watchpoint. (watch_command_1): Set b->exact if the user asked for an exact watchpoint and one can be set. (can_use_hardware_watchpoint): Add exact_watchpoints argument. Pass fixed length of 1 to target_region_ok_for_hw_watchpoint if the user asks for an exact watchpoint and one can be set. Return number of needed debug registers to watch the expression. * gdbtypes.c (is_scalar_type): New function, based on valprint.c:scalar_type_p. (is_scalar_type_recursive): New function. * gdbtypes.h (is_scalar_type_recursive): Declare. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Always handle regions when ranged watchpoints are available. (create_watchpoint_request): New function. (ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint): Use create_watchpoint_request. * rs6000-tdep.c (show_powerpc_exact_watchpoints): New function. (_initialize_rs6000_tdep): Add `exact-watchpoints' boolean to the `set powerpc' and `show powerpc' commands. * target.h (struct target_ops) <to_region_ok_for_hw_watchpoint>: Mention documentation comment in the target macro. (target_region_ok_for_hw_watchpoint): Document return value. gdb/doc/ * gdb.texinfo (PowerPC Embedded): Document ranged watchpoints and the "set powerpc exact-watchpoints" flag.
Diffstat (limited to 'gdb/gdbtypes.c')
-rw-r--r--gdb/gdbtypes.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 94ae1792f77..a01f326e8d3 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -1955,6 +1955,68 @@ is_integral_type (struct type *t)
|| (TYPE_CODE (t) == TYPE_CODE_BOOL)));
}
+/* Return true if TYPE is scalar. */
+
+static int
+is_scalar_type (struct type *type)
+{
+ CHECK_TYPEDEF (type);
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_SET:
+ case TYPE_CODE_STRING:
+ case TYPE_CODE_BITSTRING:
+ return 0;
+ default:
+ return 1;
+ }
+}
+
+/* Return true if T is scalar, or a composite type which in practice has
+ the memory layout of a scalar type. E.g., an array or struct with only one
+ scalar element inside it, or a union with only scalar elements. */
+
+int
+is_scalar_type_recursive (struct type *t)
+{
+ CHECK_TYPEDEF (t);
+
+ if (is_scalar_type (t))
+ return 1;
+ /* Are we dealing with an array or string of known dimensions? */
+ else if ((TYPE_CODE (t) == TYPE_CODE_ARRAY
+ || TYPE_CODE (t) == TYPE_CODE_STRING) && TYPE_NFIELDS (t) == 1
+ && TYPE_CODE (TYPE_INDEX_TYPE (t)) == TYPE_CODE_RANGE)
+ {
+ LONGEST low_bound, high_bound;
+ struct type *elt_type = check_typedef (TYPE_TARGET_TYPE (t));
+
+ get_discrete_bounds (TYPE_INDEX_TYPE (t), &low_bound, &high_bound);
+
+ return high_bound == low_bound && is_scalar_type_recursive (elt_type);
+ }
+ /* Are we dealing with a struct with one element? */
+ else if (TYPE_CODE (t) == TYPE_CODE_STRUCT && TYPE_NFIELDS (t) == 1)
+ return is_scalar_type_recursive (TYPE_FIELD_TYPE (t, 0));
+ else if (TYPE_CODE (t) == TYPE_CODE_UNION)
+ {
+ int i, n = TYPE_NFIELDS (t);
+
+ /* If all elements of the union are scalar, then the union is scalar. */
+ for (i = 0; i < n; i++)
+ if (!is_scalar_type_recursive (TYPE_FIELD_TYPE (t, i)))
+ return 0;
+
+ return 1;
+ }
+
+ return 0;
+}
+
/* A helper function which returns true if types A and B represent the
"same" class type. This is true if the types have the same main
type, or the same name. */