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
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);
}
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 {