This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Hardware watchpoints for bitfields



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))
     {

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]