aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/ia64-tdep.c34
-rw-r--r--gdb/testsuite/ChangeLog7
-rw-r--r--gdb/testsuite/gdb.base/breakpoint-shadow.exp24
4 files changed, 61 insertions, 12 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 94cfea7..d84702d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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.
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index 8b93db4..29601bd 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -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);
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 824dfb7..f6ffeb9 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -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
diff --git a/gdb/testsuite/gdb.base/breakpoint-shadow.exp b/gdb/testsuite/gdb.base/breakpoint-shadow.exp
index fcc50dd..7da032f 100644
--- a/gdb/testsuite/gdb.base/breakpoint-shadow.exp
+++ b/gdb/testsuite/gdb.base/breakpoint-shadow.exp
@@ -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 {