This is the mail archive of the
gdb-patches@sourceware.cygnus.com
mailing list for the GDB project.
Hardware watchpoints for bitfields
- To: gdb-patches at sourceware dot cygnus dot com
- Subject: Hardware watchpoints for bitfields
- From: Eli Zaretskii <eliz at gnu dot org>
- Date: Sat, 6 Nov 1999 10:45:50 -0500
- References: <np3dv6k64w.fsf@zwingli.cygnus.com><19991019235249.917DC1B494@ocean.lucon.org><199910201401.KAA28719@mescaline.gnu.org><npvh82htxn.fsf@zwingli.cygnus.com><199910221200.IAA24556@mescaline.gnu.org><npn1tbnr5f.fsf@zwingli.cygnus.com><199910231048.GAA31392@mescaline.gnu.org><npaep8o97e.fsf@zwingli.cygnus.com><npu2ndmzyh.fsf@zwingli.cygnus.com><199910272007.QAA04553@mescaline.gnu.org> <npk8o8m1ch.fsf@zwingli.cygnus.com>
The following changes let me use hardware watchpoints to watch struct
members which are bitfields:
1999-11-06 Eli Zaretskii <eliz@is.elta.co.il>
* breakpoint.c (insert_breakpoints, remove_breakpoint)
(bpstat_stop_status, can_use_hardware_watchpoint): Don't insert,
remove, or check status of hardware watchpoints for entire structs
and arrays unless the user explicitly asked to watch that struct
or array.
1999-11-03 Eli Zaretskii <eliz@is.elta.co.il>
* values.c (value_primitive_field): Set the offset in struct value
we return when the field is a packed bitfield.
--- gdb/breakpoint.c~6 Sat Nov 6 12:25:52 1999
+++ gdb/breakpoint.c Sat Nov 6 12:25:18 1999
@@ -798,28 +798,38 @@ insert_breakpoints ()
if (VALUE_LVAL (v) == lval_memory
&& ! VALUE_LAZY (v))
{
- CORE_ADDR addr;
- int len, type;
-
- addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
- len = TYPE_LENGTH (VALUE_TYPE (v));
- type = 0;
- if (b->type == bp_read_watchpoint)
- type = 1;
- else if (b->type == bp_access_watchpoint)
- type = 2;
+ struct type *vtype = check_typedef (VALUE_TYPE (v));
- val = target_insert_watchpoint (addr, len, type);
- if (val == -1)
+ /* We only watch structs and arrays if user asked
+ for it explicitly, never if they just happen to
+ appear in the middle of some value chain. */
+ if (v == b->val_chain
+ || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+ && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
{
- /* Don't exit the loop; try to insert every
- value on the value chain. That's because
- we will be removing all the watches below,
- and removing a watchpoint we didn't insert
- could have adverse effects. */
- b->inserted = 0;
+ CORE_ADDR addr;
+ int len, type;
+
+ addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+ len = TYPE_LENGTH (VALUE_TYPE (v));
+ type = 0;
+ if (b->type == bp_read_watchpoint)
+ type = 1;
+ else if (b->type == bp_access_watchpoint)
+ type = 2;
+
+ val = target_insert_watchpoint (addr, len, type);
+ if (val == -1)
+ {
+ /* Don't exit the loop, try to insert every
+ value on the value chain. That's because
+ we will be removing all the watches below,
+ and removing a watchpoint we didn't insert
+ could have adverse effects. */
+ b->inserted = 0;
+ }
+ val = 0;
}
- val = 0;
}
}
/* Failure to insert a watchpoint on any memory value in the
@@ -1139,21 +1149,28 @@ remove_breakpoint (b, is)
if (VALUE_LVAL (v) == lval_memory
&& ! VALUE_LAZY (v))
{
- CORE_ADDR addr;
- int len, type;
+ struct type *vtype = check_typedef (VALUE_TYPE (v));
+
+ if (v == b->val_chain
+ || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+ && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
+ {
+ CORE_ADDR addr;
+ int len, type;
- addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
- len = TYPE_LENGTH (VALUE_TYPE (v));
- type = 0;
- if (b->type == bp_read_watchpoint)
- type = 1;
- else if (b->type == bp_access_watchpoint)
- type = 2;
-
- val = target_remove_watchpoint (addr, len, type);
- if (val == -1)
- b->inserted = 1;
- val = 0;
+ addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+ len = TYPE_LENGTH (VALUE_TYPE (v));
+ type = 0;
+ if (b->type == bp_read_watchpoint)
+ type = 1;
+ else if (b->type == bp_access_watchpoint)
+ type = 2;
+
+ val = target_remove_watchpoint (addr, len, type);
+ if (val == -1)
+ b->inserted = 1;
+ val = 0;
+ }
}
}
/* Failure to remove any of the hardware watchpoints comes here. */
@@ -2212,15 +2229,22 @@ bpstat_stop_status (pc, not_a_breakpoint
{
if (VALUE_LVAL (v) == lval_memory
&& ! VALUE_LAZY (v))
- {
- CORE_ADDR vaddr;
+ {
+ struct type *vtype = check_typedef (VALUE_TYPE (v));
- vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
- /* Exact match not required. Within range is sufficient.
- */
- if (addr >= vaddr
- && addr < vaddr + TYPE_LENGTH (VALUE_TYPE (v)))
- found = 1;
+ if (v == b->val_chain
+ || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+ && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
+ {
+ CORE_ADDR vaddr;
+
+ vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+ /* Exact match not required. Within range is
+ sufficient. */
+ if (addr >= vaddr
+ && addr < vaddr + TYPE_LENGTH (VALUE_TYPE (v)))
+ found = 1;
+ }
}
}
if (found)
@@ -4487,6 +4511,7 @@ can_use_hardware_watchpoint (v)
struct value *v;
{
int found_memory_cnt = 0;
+ struct value *head = v;
/* Did the user specifically forbid us to use hardware watchpoints? */
if (! can_use_hw_watchpoints)
@@ -4524,13 +4549,23 @@ can_use_hardware_watchpoint (v)
{
/* Ahh, memory we actually used! Check if we can cover
it with hardware watchpoints. */
- CORE_ADDR vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
- int len = TYPE_LENGTH (VALUE_TYPE (v));
+ struct type *vtype = check_typedef (VALUE_TYPE (v));
- if (!TARGET_REGION_OK_FOR_HW_WATCHPOINT (vaddr, len))
- return 0;
- else
- found_memory_cnt++;
+ /* We only watch structs and arrays if user asked for it
+ explicitly, never if they just happen to appear in a
+ middle of some value chain. */
+ if (v == head
+ || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
+ && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
+ {
+ CORE_ADDR vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
+ int len = TYPE_LENGTH (vtype);
+
+ if (!TARGET_REGION_OK_FOR_HW_WATCHPOINT (vaddr, len))
+ return 0;
+ else
+ found_memory_cnt++;
+ }
}
}
else if (v->lval != not_lval && v->modifiable == 0)
--- gdb/values.c~0 Mon Jan 18 16:43:00 1999
+++ gdb/values.c Wed Nov 3 22:12:02 1999
@@ -802,6 +802,8 @@ value_primitive_field (arg1, offset, fie
fieldno));
VALUE_BITPOS (v) = TYPE_FIELD_BITPOS (arg_type, fieldno) % 8;
VALUE_BITSIZE (v) = TYPE_FIELD_BITSIZE (arg_type, fieldno);
+ VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset
+ + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
}
else if (fieldno < TYPE_N_BASECLASSES (arg_type))
{