Avoid software breakpoint's instruction shadow inconsistency
authorMaciej W. Rozycki <macro@codesourcery.com>
Fri, 3 Oct 2014 11:44:58 +0000 (12:44 +0100)
committerMaciej W. Rozycki <macro@codesourcery.com>
Fri, 3 Oct 2014 11:54:34 +0000 (12:54 +0100)
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.  In this case not only
`placed_address' is not the original address because of the ISA bit, but
`mips_breakpoint_from_pc' has to read the original instruction to
determine which one of the two software breakpoint instruction encodings
to choose as well.  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 made 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.

* 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.

17 files changed:
gdb/ChangeLog
gdb/aarch64-linux-nat.c
gdb/arm-linux-nat.c
gdb/breakpoint.c
gdb/breakpoint.h
gdb/ia64-tdep.c
gdb/m32r-tdep.c
gdb/mem-break.c
gdb/microblaze-linux-tdep.c
gdb/monitor.c
gdb/nto-procfs.c
gdb/ppc-linux-nat.c
gdb/ppc-linux-tdep.c
gdb/remote-m32r-sdi.c
gdb/remote-mips.c
gdb/remote.c
gdb/x86-nat.c

index e4004fe4a648c81c769c0f447571c607134c2457..757cc690f22fd48c3702a39115c0c238af1b8a9a 100644 (file)
@@ -1,3 +1,43 @@
+2014-10-03  Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * 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.
+
 2014-10-03  Luis Machado  <lgustavo@codesourcery.com>
 
        * valops.c (value_assign): Check for bit field assignments
index 1c1832f0b6f0c322bf7d028365bc5db8f9032235..48a6378dcc5933ce65dd08d5c6d8fbd78958fb31 100644 (file)
@@ -1183,7 +1183,7 @@ aarch64_handle_breakpoint (int type, CORE_ADDR addr, int len, int is_insert)
     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 (struct target_ops *self,
                                    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 96c67a87dd02fca78df836333e8459b0b2f98357..b9b99966bb45d41bace5a3524e34ecc612851cda 100644 (file)
@@ -975,7 +975,7 @@ arm_linux_hw_breakpoint_initialize (struct gdbarch *gdbarch,
                                    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 7da88b0a49896e6681c06279d00b2c0367695a1f..e2170b4e80309e85e27929723321a0e6ed30de9f 100644 (file)
@@ -1544,8 +1544,8 @@ one_breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
   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,
@@ -1553,7 +1553,7 @@ one_breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
 
       /* 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.  */
@@ -2601,7 +2601,7 @@ insert_bp_location (struct bp_location *bl,
      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;
 
@@ -2642,7 +2642,7 @@ insert_bp_location (struct bp_location *bl,
             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)
            {
@@ -2722,7 +2722,7 @@ insert_bp_location (struct bp_location *bl,
                                                             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)
@@ -13301,6 +13301,7 @@ bp_target_info_copy_insertion_state (struct bp_target_info *dest,
 {
   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;
 }
 
@@ -13319,7 +13320,7 @@ bkpt_insert_location (struct bp_location *bl)
       /* 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];
@@ -13341,7 +13342,7 @@ bkpt_remove_location (struct bp_location *bl)
     {
       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
@@ -15364,7 +15365,7 @@ deprecated_insert_raw_breakpoint (struct gdbarch *gdbarch,
   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
@@ -15401,7 +15402,7 @@ deprecated_remove_raw_breakpoint (struct gdbarch *gdbarch, void *bp)
 {
   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;
 
@@ -15543,7 +15544,7 @@ find_single_step_breakpoint (struct address_space *aspace,
       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 d65405f855958010dac81612d102f1801929aaf8..b611057a15d1883076530e66a54cfa562dc98196 100644 (file)
@@ -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 776a8beebcd805ebbd35bb27c7c64ad99f8a3c0f..85f2b9af25dab15cdbc8d1e0d20e9c41541ad8b4 100644 (file)
@@ -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 067ff99c7468e60357fb6d8283bccd23fdaa6bd0..5b6af4b8e8b1a4f92a497a8ab26103c159951df8 100644 (file)
@@ -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 095b81f137014d526583704914df1c7e383d9b0c..f772f56b0c11ee26d74b0cc7426b495669483dbc 100644 (file)
@@ -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 8d360eb7e40cc7ee3ed2d00bad64e1fccd504006..d5334cb527096000220fe0d21b12fa9e6ef839cd 100644 (file)
@@ -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 b880ff2ead970e5082dfc011da263dd48c485f70..f7e331b73cc4337eeb3354e38b69d291bddca19e 100644 (file)
@@ -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 7903210d12f3f2aec793f76fee8b08138790f2b9..7a96cc9d9eafb2520c83656bf92cb029973163eb 100644 (file)
@@ -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 0d0393615a19556948e1cd1b76104eac25f44362..496c4e7a91d09b0c16b6564327826c24f3f83750 100644 (file)
@@ -1690,7 +1690,7 @@ ppc_linux_insert_hw_breakpoint (struct target_ops *self,
   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 4d7d051d0c53cea2a4e9b1bd2dace9df164fe267..d232f7f37905d27d459891dc9bbf4e5421365b57 100644 (file)
@@ -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 3d6b0c679fde59839250b5ebf0c087c88b79eaca..d1d07c2d64d555490288b21c3f422297bdc7170e 100644 (file)
@@ -1172,7 +1172,7 @@ m32r_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 ib_breakpoints;
   unsigned char buf[13];
   int i, c;
index 19ac30f978a0da02eed49901d7db2d47999a5fba..9e4039d91938364bec57f22cf23476b6d72e0cb3 100644 (file)
@@ -2375,8 +2375,11 @@ mips_insert_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
                        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 41ea0129e33c1de71b1392ad6b16500269b4d1f1..3d55e41d9fc4a74c79585fdb9ace9a3dc2b66a49 100644 (file)
@@ -8076,7 +8076,7 @@ remote_insert_breakpoint (struct target_ops *ops,
 
   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;
@@ -8348,16 +8348,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;
@@ -8375,9 +8375,9 @@ remote_insert_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch,
   *(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);
@@ -8401,6 +8401,8 @@ remote_insert_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch,
     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 a016e6037fda1ddbe90c6a9e14d8c35b13078cd2..00274d31af3931cefec18de60de96460bbd79ead 100644 (file)
@@ -211,7 +211,7 @@ x86_stopped_by_watchpoint (struct target_ops *ops)
   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_ops *self, struct gdbarch *gdbarch,
   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;
 }