[PATCH] Avoid software breakpoint's instruction shadow inconsistency

Maciej W. Rozycki macro@codesourcery.com
Tue Sep 23 17:08:00 GMT 2014


Hi,

 This change:

commit b775012e845380ed4c7421a1b87caf7bfae39f5f
Author: Luis Machado <luisgpm@br.ibm.com>
Date:   Fri Feb 24 15:10:59 2012 +0000

    2012-02-24  Luis Machado  <lgustavo@codesourcery.com>

    	* remote.c (remote_supports_cond_breakpoints): New forward
    	declaration.
[...]

changed the way breakpoints are inserted and removed such that 
`insert_bp_location' can now be called with the breakpoint being handled 
already in place, while previously the call was only ever made for 
breakpoints that have not been put in place.  This in turn caused an issue 
for software breakpoints and targets for which a breakpoint's 
`placed_address' may not be the same as the original requested address.

 The issue is `insert_bp_location' overwrites the previously adjusted 
value in `placed_address' with the original address, that is only replaced 
back with the correct adjusted address later on when 
`gdbarch_breakpoint_from_pc' is called.  Meanwhile there's a window where 
the value in `placed_address' does not correspond to data stored in 
`shadow_contents', leading to incorrect instruction bytes being supplied 
when `one_breakpoint_xfer_memory' is called to supply the instruction 
overlaid by the breakpoint.

 And this is exactly what happens on the MIPS target with software 
breakpoints placed in microMIPS code.  There not only `placed_address' is 
not the original address because of the ISA bit, but also 
`mips_breakpoint_from_pc' has to read the original instruction to 
determine which one of the two software breakpoint instruction encodings 
to choose.  The 16-bit encoding is used to replace 16-bit instructions and 
similarly the 32-bit one is used with 32-bit instructions, to satisfy 
branch delay slot size requirements.

 The mismatch between `placed_address' and the address data in 
`shadow_contents' has been obtained from leads to the wrong encoding being 
used in some cases, which in the case of a 32-bit software breakpoint 
instruction replacing a 16-bit instruction causes corruption to the 
adjacent following instruction and leads the debug session astray if 
execution reaches there e.g. with a jump.

 To address this problem I propose the change below, that adds a 
`reqstd_address' field to `struct bp_target_info' and leaves 
`placed_address' unchanged once it has been set.  This ensures data in 
`shadow_contents' is always consistent with `placed_address'.

 This approach also has this good side effect that all the places that 
examine the breakpoint's address see a consistent value, either 
`reqstd_address' or `placed_address', as required.  Currently some places 
see either the original or the adjusted address in `placed_address', 
depending on whether they have been called before 
`gdbarch_remote_breakpoint_from_pc' or afterwards.  This is in particular 
true for subsequent calls to `gdbarch_remote_breakpoint_from_pc' itself, 
e.g. from `one_breakpoint_xfer_memory'.  This is also important for places 
like `find_single_step_breakpoint' where a breakpoint's address is 
compared to the raw value of $pc.

 I have regression tested it with the mips-linux-gnu target and the 
following multilibs:

-EB
-EB -msoft-float
-EB -mips16
-EB -mips16 -msoft-float
-EB -mmicromips
-EB -mmicromips -msoft-float
-EB -mabi=n32
-EB -mabi=n32 -msoft-float
-EB -mabi=64
-EB -mabi=64 -msoft-float

and the -EL variants of same with no regressions and removing ~900 
seemingly random failures for each of the little-endian microMIPS 
multilibs.  Obviously in the big-endian case the corrupt `placed_address' 
vs `shadow_contents' state did not cause the wrong breakpoint instruction 
to have been chosen.

 FAOD: I chose `reqstd_address' rather than `requested_address' to avoid 
having to wrap overlong lines, the name of the new member has the same 
length as `placed_address' and I think is as clear with some of its vowels 
removed as it would be with them retained.

2014-09-23  Maciej W. Rozycki  <macro@codesourcery.com>

	gdb/
	* breakpoint.h (bp_target_info): Add `reqstd_address' member,
	update comments.
	* breakpoint.c (one_breakpoint_xfer_memory): Use `reqstd_address' 
	for the breakpoint's address.  Don't preinitialize `placed_size'.
	(insert_bp_location): Set `reqstd_address' rather than 
	`placed_address'.
	(bp_target_info_copy_insertion_state): Also copy `placed_address'.
	(bkpt_insert_location): Use `reqstd_address' for the breakpoint's 
	address.
	(bkpt_remove_location): Likewise.
	(deprecated_insert_raw_breakpoint): Likewise.
	(deprecated_remove_raw_breakpoint): Likewise.
	(find_single_step_breakpoint): Likewise.
	* mem-break.c (default_memory_insert_breakpoint): Use 
	`reqstd_address' for the breakpoint's address.  Don't set 
	`placed_address' or `placed_size' if breakpoint contents couldn't
	have been determined.
	* remote.c (remote_insert_breakpoint): Use `reqstd_address' for 
	the breakpoint's address.
	(remote_insert_hw_breakpoint): Likewise.  Don't set 
	`placed_address' or `placed_size' if breakpoint couldn't have been 
	set.
	* aarch64-linux-nat.c (aarch64_linux_insert_hw_breakpoint): Use
	`reqstd_address' for the breakpoint's address.
	* arm-linux-nat.c (arm_linux_hw_breakpoint_initialize): Likewise.
	* ia64-tdep.c (ia64_memory_insert_breakpoint): Likewise.
	* m32r-tdep.c (m32r_memory_insert_breakpoint): Likewise.
	* microblaze-linux-tdep.c 
	(microblaze_linux_memory_remove_breakpoint): Likewise.
	* monitor.c (monitor_insert_breakpoint): Likewise.
	* nto-procfs.c (procfs_insert_breakpoint): Likewise.
	(procfs_insert_hw_breakpoint): Likewise.
	* ppc-linux-nat.c (ppc_linux_insert_hw_breakpoint): Likewise.
	* ppc-linux-tdep.c (ppc_linux_memory_remove_breakpoint): Likewise.
	* remote-m32r-sdi.c (m32r_insert_breakpoint): Likewise.
	* remote-mips.c (mips_insert_breakpoint): Likewise.
	* x86-nat.c (x86_insert_hw_breakpoint): Likewise.

  Maciej

gdb-bp-update-inserted.diff
Index: gdb-fsf-trunk-quilt/gdb/aarch64-linux-nat.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/aarch64-linux-nat.c	2014-09-18 05:44:50.727603472 +0100
+++ gdb-fsf-trunk-quilt/gdb/aarch64-linux-nat.c	2014-09-18 05:45:20.737876353 +0100
@@ -1183,7 +1183,7 @@ aarch64_handle_breakpoint (int type, COR
     return aarch64_dr_state_remove_one_point (state, type, addr, len);
 }
 
-/* Insert a hardware-assisted breakpoint at BP_TGT->placed_address.
+/* Insert a hardware-assisted breakpoint at BP_TGT->reqstd_address.
    Return 0 on success, -1 on failure.  */
 
 static int
@@ -1192,7 +1192,7 @@ aarch64_linux_insert_hw_breakpoint (stru
 				    struct bp_target_info *bp_tgt)
 {
   int ret;
-  CORE_ADDR addr = bp_tgt->placed_address;
+  CORE_ADDR addr = bp_tgt->placed_address = bp_tgt->reqstd_address;
   const int len = 4;
   const int type = hw_execute;
 
Index: gdb-fsf-trunk-quilt/gdb/arm-linux-nat.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/arm-linux-nat.c	2014-09-18 05:44:50.727603472 +0100
+++ gdb-fsf-trunk-quilt/gdb/arm-linux-nat.c	2014-09-18 05:45:20.737876353 +0100
@@ -975,7 +975,7 @@ arm_linux_hw_breakpoint_initialize (stru
 				    struct arm_linux_hw_breakpoint *p)
 {
   unsigned mask;
-  CORE_ADDR address = bp_tgt->placed_address;
+  CORE_ADDR address = bp_tgt->placed_address = bp_tgt->reqstd_address;
 
   /* We have to create a mask for the control register which says which bits
      of the word pointed to by address to break on.  */
Index: gdb-fsf-trunk-quilt/gdb/breakpoint.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/breakpoint.c	2014-09-18 05:44:50.727603472 +0100
+++ gdb-fsf-trunk-quilt/gdb/breakpoint.c	2014-09-18 05:45:20.737876353 +0100
@@ -1495,8 +1495,8 @@ one_breakpoint_xfer_memory (gdb_byte *re
   else
     {
       const unsigned char *bp;
-      CORE_ADDR placed_address = target_info->placed_address;
-      int placed_size = target_info->placed_size;
+      CORE_ADDR addr = target_info->reqstd_address;
+      int placed_size;
 
       /* Update the shadow with what we want to write to memory.  */
       memcpy (target_info->shadow_contents + bptoffset,
@@ -1504,7 +1504,7 @@ one_breakpoint_xfer_memory (gdb_byte *re
 
       /* Determine appropriate breakpoint contents and size for this
 	 address.  */
-      bp = gdbarch_breakpoint_from_pc (gdbarch, &placed_address, &placed_size);
+      bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &placed_size);
 
       /* Update the final write buffer with this inserted
 	 breakpoint's INSN.  */
@@ -2543,7 +2543,7 @@ insert_bp_location (struct bp_location *
      we have a breakpoint inserted at that address and thus
      read the breakpoint instead of returning the data saved in
      the breakpoint location's shadow contents.  */
-  bl->target_info.placed_address = bl->address;
+  bl->target_info.reqstd_address = bl->address;
   bl->target_info.placed_address_space = bl->pspace->aspace;
   bl->target_info.length = bl->length;
 
@@ -2584,7 +2584,7 @@ insert_bp_location (struct bp_location *
 	     program, but it's not going to work anyway with current
 	     gdb.  */
 	  struct mem_region *mr 
-	    = lookup_mem_region (bl->target_info.placed_address);
+	    = lookup_mem_region (bl->target_info.reqstd_address);
 	  
 	  if (mr)
 	    {
@@ -2658,7 +2658,7 @@ insert_bp_location (struct bp_location *
 							     bl->section);
 		  /* Set a software (trap) breakpoint at the LMA.  */
 		  bl->overlay_target_info = bl->target_info;
-		  bl->overlay_target_info.placed_address = addr;
+		  bl->overlay_target_info.reqstd_address = addr;
 
 		  /* No overlay handling: just set the breakpoint.  */
 		  TRY_CATCH (e, RETURN_MASK_ALL)
@@ -13242,6 +13242,7 @@ bp_target_info_copy_insertion_state (str
 {
   dest->shadow_len = src->shadow_len;
   memcpy (dest->shadow_contents, src->shadow_contents, src->shadow_len);
+  dest->placed_address = src->placed_address;
   dest->placed_size = src->placed_size;
 }
 
@@ -13260,7 +13261,7 @@ bkpt_insert_location (struct bp_location
       /* There is no need to insert a breakpoint if an unconditional
 	 raw/sss breakpoint is already inserted at that location.  */
       sss_slot = find_single_step_breakpoint (bp_tgt->placed_address_space,
-					      bp_tgt->placed_address);
+					      bp_tgt->reqstd_address);
       if (sss_slot >= 0)
 	{
 	  struct bp_target_info *sss_bp_tgt = single_step_breakpoints[sss_slot];
@@ -13282,7 +13283,7 @@ bkpt_remove_location (struct bp_location
     {
       struct bp_target_info *bp_tgt = &bl->target_info;
       struct address_space *aspace = bp_tgt->placed_address_space;
-      CORE_ADDR address = bp_tgt->placed_address;
+      CORE_ADDR address = bp_tgt->reqstd_address;
 
       /* Only remove the breakpoint if there is no raw/sss breakpoint
 	 still inserted at this location.  Otherwise, we would be
@@ -15305,7 +15306,7 @@ deprecated_insert_raw_breakpoint (struct
   bp_tgt = XCNEW (struct bp_target_info);
 
   bp_tgt->placed_address_space = aspace;
-  bp_tgt->placed_address = pc;
+  bp_tgt->reqstd_address = pc;
 
   /* If an unconditional non-raw breakpoint is already inserted at
      that location, there's no need to insert another.  However, with
@@ -15342,7 +15343,7 @@ deprecated_remove_raw_breakpoint (struct
 {
   struct bp_target_info *bp_tgt = bp;
   struct address_space *aspace = bp_tgt->placed_address_space;
-  CORE_ADDR address = bp_tgt->placed_address;
+  CORE_ADDR address = bp_tgt->reqstd_address;
   struct bp_location *bl;
   int ret;
 
@@ -15484,7 +15485,7 @@ find_single_step_breakpoint (struct addr
       struct bp_target_info *bp_tgt = single_step_breakpoints[i];
       if (bp_tgt
 	  && breakpoint_address_match (bp_tgt->placed_address_space,
-				       bp_tgt->placed_address,
+				       bp_tgt->reqstd_address,
 				       aspace, pc))
 	return i;
     }
Index: gdb-fsf-trunk-quilt/gdb/breakpoint.h
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/breakpoint.h	2014-09-18 05:44:50.727603472 +0100
+++ gdb-fsf-trunk-quilt/gdb/breakpoint.h	2014-09-18 05:45:20.737876353 +0100
@@ -235,13 +235,16 @@ struct bp_target_info
   /* Address space at which the breakpoint was placed.  */
   struct address_space *placed_address_space;
 
-  /* Address at which the breakpoint was placed.  This is normally the
-     same as ADDRESS from the bp_location, except when adjustment
-     happens in gdbarch_breakpoint_from_pc.  The most common form of
-     adjustment is stripping an alternate ISA marker from the PC which
-     is used to determine the type of breakpoint to insert.  */
+  /* Address at which the breakpoint was placed.  This is normally
+     the same as REQUESTED_ADDRESS, except when adjustment happens in
+     gdbarch_breakpoint_from_pc.  The most common form of adjustment
+     is stripping an alternate ISA marker from the PC which is used
+     to determine the type of breakpoint to insert.  */
   CORE_ADDR placed_address;
 
+  /* Address at which the breakpoint was requested.  */
+  CORE_ADDR reqstd_address;
+
   /* If this is a ranged breakpoint, then this field contains the
      length of the range that will be watched for execution.  */
   int length;
Index: gdb-fsf-trunk-quilt/gdb/ia64-tdep.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/ia64-tdep.c	2014-09-18 05:44:50.727603472 +0100
+++ gdb-fsf-trunk-quilt/gdb/ia64-tdep.c	2014-09-18 05:45:20.737876353 +0100
@@ -637,7 +637,7 @@ static int
 ia64_memory_insert_breakpoint (struct gdbarch *gdbarch,
 			       struct bp_target_info *bp_tgt)
 {
-  CORE_ADDR addr = bp_tgt->placed_address;
+  CORE_ADDR addr = bp_tgt->placed_address = bp_tgt->reqstd_address;
   gdb_byte bundle[BUNDLE_LEN];
   int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER, shadow_slotnum;
   long long instr_breakpoint;
Index: gdb-fsf-trunk-quilt/gdb/m32r-tdep.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/m32r-tdep.c	2014-09-18 05:44:50.727603472 +0100
+++ gdb-fsf-trunk-quilt/gdb/m32r-tdep.c	2014-09-18 05:45:20.737876353 +0100
@@ -79,7 +79,7 @@ static int
 m32r_memory_insert_breakpoint (struct gdbarch *gdbarch,
 			       struct bp_target_info *bp_tgt)
 {
-  CORE_ADDR addr = bp_tgt->placed_address;
+  CORE_ADDR addr = bp_tgt->placed_address = bp_tgt->reqstd_address;
   int val;
   gdb_byte buf[4];
   gdb_byte contents_cache[4];
Index: gdb-fsf-trunk-quilt/gdb/mem-break.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/mem-break.c	2014-09-18 05:44:50.727603472 +0100
+++ gdb-fsf-trunk-quilt/gdb/mem-break.c	2014-09-18 05:45:20.737876353 +0100
@@ -37,27 +37,29 @@ int
 default_memory_insert_breakpoint (struct gdbarch *gdbarch,
 				  struct bp_target_info *bp_tgt)
 {
-  int val;
+  CORE_ADDR addr = bp_tgt->reqstd_address;
   const unsigned char *bp;
   gdb_byte *readbuf;
+  int bplen;
+  int val;
 
   /* Determine appropriate breakpoint contents and size for this address.  */
-  bp = gdbarch_breakpoint_from_pc
-       (gdbarch, &bp_tgt->placed_address, &bp_tgt->placed_size);
+  bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
   if (bp == NULL)
     error (_("Software breakpoints not implemented for this target."));
 
+  bp_tgt->placed_address = addr;
+  bp_tgt->placed_size = bplen;
+
   /* Save the memory contents in the shadow_contents buffer and then
      write the breakpoint instruction.  */
-  bp_tgt->shadow_len = bp_tgt->placed_size;
-  readbuf = alloca (bp_tgt->placed_size);
-  val = target_read_memory (bp_tgt->placed_address, readbuf,
-			    bp_tgt->placed_size);
+  bp_tgt->shadow_len = bplen;
+  readbuf = alloca (bplen);
+  val = target_read_memory (addr, readbuf, bplen);
   if (val == 0)
     {
-      memcpy (bp_tgt->shadow_contents, readbuf, bp_tgt->placed_size);
-      val = target_write_raw_memory (bp_tgt->placed_address, bp,
-				     bp_tgt->placed_size);
+      memcpy (bp_tgt->shadow_contents, readbuf, bplen);
+      val = target_write_raw_memory (addr, bp, bplen);
     }
 
   return val;
Index: gdb-fsf-trunk-quilt/gdb/microblaze-linux-tdep.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/microblaze-linux-tdep.c	2014-09-18 05:44:50.727603472 +0100
+++ gdb-fsf-trunk-quilt/gdb/microblaze-linux-tdep.c	2014-09-18 05:45:20.737876353 +0100
@@ -41,7 +41,7 @@ static int
 microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch, 
 					   struct bp_target_info *bp_tgt)
 {
-  CORE_ADDR addr = bp_tgt->placed_address;
+  CORE_ADDR addr = bp_tgt->reqstd_address;
   const gdb_byte *bp;
   int val;
   int bplen;
Index: gdb-fsf-trunk-quilt/gdb/monitor.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/monitor.c	2014-09-18 05:44:50.727603472 +0100
+++ gdb-fsf-trunk-quilt/gdb/monitor.c	2014-09-18 05:45:20.737876353 +0100
@@ -2103,7 +2103,7 @@ static int
 monitor_insert_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
 			   struct bp_target_info *bp_tgt)
 {
-  CORE_ADDR addr = bp_tgt->placed_address;
+  CORE_ADDR addr = bp_tgt->placed_address = bp_tgt->reqstd_address;
   int i;
   int bplen;
 
Index: gdb-fsf-trunk-quilt/gdb/nto-procfs.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/nto-procfs.c	2014-09-18 05:44:50.727603472 +0100
+++ gdb-fsf-trunk-quilt/gdb/nto-procfs.c	2014-09-18 05:45:20.737876353 +0100
@@ -928,6 +928,7 @@ static int
 procfs_insert_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
 			  struct bp_target_info *bp_tgt)
 {
+  bp_tgt->placed_address = bp_tgt->reqstd_address;
   return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, 0);
 }
 
@@ -942,6 +943,7 @@ static int
 procfs_insert_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch,
 			     struct bp_target_info *bp_tgt)
 {
+  bp_tgt->placed_address = bp_tgt->reqstd_address;
   return procfs_breakpoint (bp_tgt->placed_address,
 			    _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0);
 }
Index: gdb-fsf-trunk-quilt/gdb/ppc-linux-nat.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/ppc-linux-nat.c	2014-09-18 05:44:50.727603472 +0100
+++ gdb-fsf-trunk-quilt/gdb/ppc-linux-nat.c	2014-09-18 05:45:20.737876353 +0100
@@ -1690,7 +1690,7 @@ ppc_linux_insert_hw_breakpoint (struct t
   p.version = PPC_DEBUG_CURRENT_VERSION;
   p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
   p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
-  p.addr = (uint64_t) bp_tgt->placed_address;
+  p.addr = (uint64_t) (bp_tgt->placed_address = bp_tgt->reqstd_address);
   p.condition_value = 0;
 
   if (bp_tgt->length)
Index: gdb-fsf-trunk-quilt/gdb/ppc-linux-tdep.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/ppc-linux-tdep.c	2014-09-18 05:44:50.727603472 +0100
+++ gdb-fsf-trunk-quilt/gdb/ppc-linux-tdep.c	2014-09-18 05:45:20.737876353 +0100
@@ -211,7 +211,7 @@ static int
 ppc_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
 				    struct bp_target_info *bp_tgt)
 {
-  CORE_ADDR addr = bp_tgt->placed_address;
+  CORE_ADDR addr = bp_tgt->reqstd_address;
   const unsigned char *bp;
   int val;
   int bplen;
Index: gdb-fsf-trunk-quilt/gdb/remote-m32r-sdi.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/remote-m32r-sdi.c	2014-09-18 05:44:50.727603472 +0100
+++ gdb-fsf-trunk-quilt/gdb/remote-m32r-sdi.c	2014-09-18 05:45:20.737876353 +0100
@@ -1172,7 +1172,7 @@ m32r_insert_breakpoint (struct target_op
 			struct gdbarch *gdbarch,
 			struct bp_target_info *bp_tgt)
 {
-  CORE_ADDR addr = bp_tgt->placed_address;
+  CORE_ADDR addr = bp_tgt->placed_address = bp_tgt->reqstd_address;
   int ib_breakpoints;
   unsigned char buf[13];
   int i, c;
Index: gdb-fsf-trunk-quilt/gdb/remote-mips.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/remote-mips.c	2014-09-18 05:44:50.727603472 +0100
+++ gdb-fsf-trunk-quilt/gdb/remote-mips.c	2014-09-18 05:45:20.737876353 +0100
@@ -2375,8 +2375,11 @@ mips_insert_breakpoint (struct target_op
 			struct bp_target_info *bp_tgt)
 {
   if (monitor_supports_breakpoints)
-    return mips_set_breakpoint (bp_tgt->placed_address, MIPS_INSN32_SIZE,
-				BREAK_FETCH);
+    {
+      bp_tgt->placed_address = bp_tgt->reqstd_address;
+      return mips_set_breakpoint (bp_tgt->placed_address, MIPS_INSN32_SIZE,
+				  BREAK_FETCH);
+    }
   else
     return memory_insert_breakpoint (ops, gdbarch, bp_tgt);
 }
Index: gdb-fsf-trunk-quilt/gdb/remote.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/remote.c	2014-09-18 05:44:50.727603472 +0100
+++ gdb-fsf-trunk-quilt/gdb/remote.c	2014-09-18 05:45:20.737876353 +0100
@@ -8079,7 +8079,7 @@ remote_insert_breakpoint (struct target_
 
   if (packet_support (PACKET_Z0) != PACKET_DISABLE)
     {
-      CORE_ADDR addr = bp_tgt->placed_address;
+      CORE_ADDR addr = bp_tgt->reqstd_address;
       struct remote_state *rs;
       char *p, *endbuf;
       int bpsize;
@@ -8351,16 +8351,16 @@ static int
 remote_insert_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch,
 			     struct bp_target_info *bp_tgt)
 {
-  CORE_ADDR addr;
+  CORE_ADDR addr = bp_tgt->reqstd_address;
   struct remote_state *rs;
   char *p, *endbuf;
   char *message;
+  int bpsize;
 
   /* The length field should be set to the size of a breakpoint
      instruction, even though we aren't inserting one ourselves.  */
 
-  gdbarch_remote_breakpoint_from_pc
-    (gdbarch, &bp_tgt->placed_address, &bp_tgt->placed_size);
+  gdbarch_remote_breakpoint_from_pc (gdbarch, &addr, &bpsize);
 
   if (packet_support (PACKET_Z1) == PACKET_DISABLE)
     return -1;
@@ -8378,9 +8378,9 @@ remote_insert_hw_breakpoint (struct targ
   *(p++) = '1';
   *(p++) = ',';
 
-  addr = remote_address_masked (bp_tgt->placed_address);
+  addr = remote_address_masked (addr);
   p += hexnumstr (p, (ULONGEST) addr);
-  xsnprintf (p, endbuf - p, ",%x", bp_tgt->placed_size);
+  xsnprintf (p, endbuf - p, ",%x", bpsize);
 
   if (remote_supports_cond_breakpoints (self))
     remote_add_target_side_condition (gdbarch, bp_tgt, p, endbuf);
@@ -8404,6 +8404,8 @@ remote_insert_hw_breakpoint (struct targ
     case PACKET_UNKNOWN:
       return -1;
     case PACKET_OK:
+      bp_tgt->placed_address = addr;
+      bp_tgt->placed_size = bpsize;
       return 0;
     }
   internal_error (__FILE__, __LINE__,
Index: gdb-fsf-trunk-quilt/gdb/x86-nat.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/x86-nat.c	2014-09-18 05:44:50.727603472 +0100
+++ gdb-fsf-trunk-quilt/gdb/x86-nat.c	2014-09-18 05:45:20.737876353 +0100
@@ -211,7 +211,7 @@ x86_stopped_by_watchpoint (struct target
   return x86_dr_stopped_by_watchpoint (state);
 }
 
-/* Insert a hardware-assisted breakpoint at BP_TGT->placed_address.
+/* Insert a hardware-assisted breakpoint at BP_TGT->reqstd_address.
    Return 0 on success, EBUSY on failure.  */
 
 static int
@@ -221,6 +221,7 @@ x86_insert_hw_breakpoint (struct target_
   struct x86_debug_reg_state *state
     = x86_debug_reg_state (ptid_get_pid (inferior_ptid));
 
+  bp_tgt->placed_address = bp_tgt->reqstd_address;
   return x86_dr_insert_watchpoint (state, hw_execute,
 				   bp_tgt->placed_address, 1) ? EBUSY : 0;
 }



More information about the Gdb-patches mailing list