This is the mail archive of the 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]
Other format: [Raw text]

[ARM, commit, RFA 7.5] Fix HW breakpoints on unaligned addresses


the new hbreak2.exp tests are failing on ARM.  It turns out that when
attempting to set a HW breakpoint on an address that is not aligned
to 4 bytes (on Thumb), the kernel rejects GDB's ptrace calls as invalid.

After some discussion with Will Deacon (who implemented the kernel side
of this interface), we've decided to fix this on the GDB side:  GDB
tries to align the address to 4 bytes and uses the "byte address select"
feature to specify only the two upper bytes in that range.  However,
the kernel interface does not (yet) support this use of the BAS field.
On the other hand, the kernel *does* support just specifying the
unaligned address in the address field, and setting up the BAS field
for a normal 2-byte access.  (This use is not supported by the hardware,
but will get fixed up by the kernel.)

Since this alternative way is supported by all existing kernels (that
support the HW breakpoint ptrace interface), and will remain supported
in the future (even once kernels may start supporting more general
use of the BAS field), we can fix this simply by changing GDB to use
that alternative.

The patch below implements this in both GDB and gdbserver.  Tested on
arm-linux-gnueabi (Cortex-A9), fixes the hbreak2 regressions.

Committed to mainline.

Joel, would this be OK for the 7.5 branch at this point?

In general, what's the timeline for 7.5?  I've noticed a couple of
other test case regressions when testing the branch on ARM, s390,
and Cell ...



	* arm-linux-nat.c (arm_linux_hw_breakpoint_initialize): Do not
	attempt to 4-byte-align HW breakpoint addresses for Thumb.


	* linux-arm-low.c (arm_linux_hw_point_initialize): Do not attempt
	to 4-byte-align HW breakpoint addresses for Thumb.

Index: gdb/arm-linux-nat.c
RCS file: /cvs/src/src/gdb/arm-linux-nat.c,v
retrieving revision 1.55
diff -u -p -r1.55 arm-linux-nat.c
--- gdb/arm-linux-nat.c	6 Jul 2012 16:49:43 -0000	1.55
+++ gdb/arm-linux-nat.c	30 Jul 2012 15:00:33 -0000
@@ -896,11 +896,17 @@ arm_linux_hw_breakpoint_initialize (stru
   /* We have to create a mask for the control register which says which bits
      of the word pointed to by address to break on.  */
   if (arm_pc_is_thumb (gdbarch, address))
-    mask = 0x3 << (address & 2);
+    {
+      mask = 0x3;
+      address &= ~1;
+    }
-    mask = 0xf;
+    {
+      mask = 0xf;
+      address &= ~3;
+    }
-  p->address = (unsigned int) (address & ~3);
+  p->address = (unsigned int) address;
   p->control = arm_hwbp_control_initialize (mask, arm_hwbp_break, 1);
Index: gdb/gdbserver/linux-arm-low.c
RCS file: /cvs/src/src/gdb/gdbserver/linux-arm-low.c,v
retrieving revision 1.34
diff -u -p -r1.34 linux-arm-low.c
--- gdb/gdbserver/linux-arm-low.c	24 Apr 2012 15:03:43 -0000	1.34
+++ gdb/gdbserver/linux-arm-low.c	30 Jul 2012 15:00:33 -0000
@@ -474,17 +474,17 @@ arm_linux_hw_point_initialize (char type
 	case 2:	 /* 16-bit Thumb mode breakpoint */
 	case 3:  /* 32-bit Thumb mode breakpoint */
-	  mask = 0x3 << (addr & 2);
+	  mask = 0x3;
+	  addr &= ~1;
 	case 4:  /* 32-bit ARM mode breakpoint */
 	  mask = 0xf;
+	  addr &= ~3;
 	  /* Unsupported. */
 	  return -1;
-      addr &= ~3;
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE

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