gdb/
authorJan Kratochvil <jan.kratochvil@redhat.com>
Tue, 8 Sep 2009 17:39:22 +0000 (17:39 +0000)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Tue, 8 Sep 2009 17:39:22 +0000 (17:39 +0000)
Fix ia64 shadowing of breakpoints in multiple slots of a single bundle.
* ia64-tdep.c (ia64_memory_insert_breakpoint): New call
of make_show_memory_breakpoints_cleanup with parameter 0.  Move the
reading of SHADOW_CONTENTS to this memory state point of code.  Update
comment for the memory re-read.

gdb/testsuite/
* gdb.base/breakpoint-shadow.exp (Second breakpoint placed): Initialize
$bpt2address.
(Second breakpoint address is valid on ia64)
(Third breakpoint on ia64 in the Second breakpoint's bundle): New.

gdb/ChangeLog
gdb/ia64-tdep.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/breakpoint-shadow.exp

index 94cfea7..d84702d 100644 (file)
@@ -1,3 +1,11 @@
+2009-09-08  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       Fix ia64 shadowing of breakpoints in multiple slots of a single bundle.
+       * ia64-tdep.c (ia64_memory_insert_breakpoint): New call
+       of make_show_memory_breakpoints_cleanup with parameter 0.  Move the
+       reading of SHADOW_CONTENTS to this memory state point of code.  Update
+       comment for the memory re-read.
+
 2009-09-07  Michael Snyder  <msnyder@vmware.com>
 
        * record.c: Minor comment and white space fix-ups.
index 8b93db4..29601bd 100644 (file)
@@ -622,27 +622,37 @@ ia64_memory_insert_breakpoint (struct gdbarch *gdbarch,
 
   addr &= ~0x0f;
 
-  /* Disable the automatic memory restoration from breakpoints while
-     we read our instruction bundle.  Otherwise, the general restoration
-     mechanism kicks in and we would possibly remove parts of the adjacent
+  /* Enable the automatic memory restoration from breakpoints while
+     we read our instruction bundle for the purpose of SHADOW_CONTENTS.
+     Otherwise, we could possibly store into the shadow parts of the adjacent
      placed breakpoints.  It is due to our SHADOW_CONTENTS overlapping the real
      breakpoint instruction bits region.  */
-  cleanup = make_show_memory_breakpoints_cleanup (1);
+  cleanup = make_show_memory_breakpoints_cleanup (0);
   val = target_read_memory (addr, bundle, BUNDLE_LEN);
 
-  /* Check for L type instruction in slot 1, if present then bump up the slot
-     number to the slot 2.  */
-  template = extract_bit_field (bundle, 0, 5);
-  if (slotnum == 1 && template_encoding_table[template][slotnum] == L)
-    slotnum = 2;
-
   /* Slot number 2 may skip at most 2 bytes at the beginning.  */
-  bp_tgt->placed_size = bp_tgt->shadow_len = BUNDLE_LEN - 2;
+  bp_tgt->shadow_len = BUNDLE_LEN - 2;
 
   /* Store the whole bundle, except for the initial skipped bytes by the slot
      number interpreted as bytes offset in PLACED_ADDRESS.  */
   memcpy (bp_tgt->shadow_contents, bundle + slotnum, bp_tgt->shadow_len);
 
+  /* Re-read the same bundle as above except that, this time, read it in order
+     to compute the new bundle inside which we will be inserting the
+     breakpoint.  Therefore, disable the automatic memory restoration from
+     breakpoints while we read our instruction bundle.  Otherwise, the general
+     restoration mechanism kicks in and we would possibly remove parts of the
+     adjacent placed breakpoints.  It is due to our SHADOW_CONTENTS overlapping
+     the real breakpoint instruction bits region.  */
+  make_show_memory_breakpoints_cleanup (1);
+  val |= target_read_memory (addr, bundle, BUNDLE_LEN);
+
+  /* Check for L type instruction in slot 1, if present then bump up the slot
+     number to the slot 2.  */
+  template = extract_bit_field (bundle, 0, 5);
+  if (slotnum == 1 && template_encoding_table[template][slotnum] == L)
+    slotnum = 2;
+
   /* Breakpoints already present in the code will get deteacted and not get
      reinserted by bp_loc_is_permanent.  Multiple breakpoints at the same
      location cannot induce the internal error as they are optimized into
@@ -654,6 +664,8 @@ ia64_memory_insert_breakpoint (struct gdbarch *gdbarch,
                    paddress (gdbarch, bp_tgt->placed_address));
   replace_slotN_contents (bundle, IA64_BREAKPOINT, slotnum);
 
+  bp_tgt->placed_size = bp_tgt->shadow_len;
+
   if (val == 0)
     val = target_write_memory (addr + slotnum, bundle + slotnum,
                               bp_tgt->shadow_len);
index 824dfb7..f6ffeb9 100644 (file)
@@ -1,3 +1,10 @@
+2009-09-08  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       * gdb.base/breakpoint-shadow.exp (Second breakpoint placed): Initialize
+       $bpt2address.
+       (Second breakpoint address is valid on ia64)
+       (Third breakpoint on ia64 in the Second breakpoint's bundle): New.
+
 2009-09-03  Joseph Myers  <joseph@codesourcery.com>
 
        * gdb.base/ending-run.exp: Restrict regular expression matching
index fcc50dd..7da032f 100644 (file)
@@ -48,7 +48,29 @@ gdb_test_multiple "disass main" $test {
 }
 
 gdb_test "b [gdb_get_line_number "break-first"]" "Breakpoint \[0-9\] at .*" "First breakpoint placed"
-gdb_test "b [gdb_get_line_number "break-second"]" "Breakpoint \[0-9\] at .*" "Second breakpoint placed"
+set test "Second breakpoint placed"
+gdb_test_multiple "b [gdb_get_line_number "break-second"]" $test {
+    -re "Breakpoint \[0-9\] at (0x\[0-9a-f\]*):.*" {
+       pass $test
+       set bpt2address $expect_out(1,string)
+    }
+}
+
+if [istarget "ia64-*-*"] then {
+    # Unoptimized code should not use the 3rd slot for the first instruction of
+    # a source line.  This is important for our test, because we want both
+    # breakpoints ("Second breakpoint" and the following one) to be in the same
+    # bundle.
+
+    set test "Second breakpoint address is valid on ia64"
+    if [string match "*\[01\]" $bpt2address] {
+       pass $test
+
+       gdb_test "b *($bpt2address + 1)" "Breakpoint \[0-9\] at .*" "Third breakpoint on ia64 in the Second breakpoint's bundle"
+    } else {
+       unresolved $test
+    }
+}
 
 set test "disassembly with breakpoints"
 gdb_test_multiple "disass main" $test {