From b554e4bd5309b7a5bdfd36ab20c4c8f3edcb88d5 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Tue, 8 Sep 2009 17:39:22 +0000 Subject: gdb/ 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/ia64-tdep.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'gdb/ia64-tdep.c') 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); -- cgit v1.1