|
|
bb9a89c |
gdb/
|
|
|
bb9a89c |
2008-10-28 Jan Kratochvil <jan.kratochvil@redhat.com>
|
|
|
bb9a89c |
|
|
|
bb9a89c |
Fix automatic restoration of breakpoints memory for ia64.
|
|
|
bb9a89c |
* ia64-tdep.c (ia64_memory_insert_breakpoint): New comment part for
|
|
|
bb9a89c |
SHADOW_CONTENTS content. Remova variable instr. New variable cleanup.
|
|
|
bb9a89c |
Force automatic breakpoints restoration. PLACED_SIZE and SHADOW_LEN
|
|
|
bb9a89c |
are now set larger, to BUNDLE_LEN - 2.
|
|
|
bb9a89c |
(ia64_memory_remove_breakpoint): Rename variables bundle to bundle_mem
|
|
|
bb9a89c |
and instr to instr_saved. New variables bundle_saved and
|
|
|
bb9a89c |
instr_breakpoint. Comment new reasons why we need to disable automatic
|
|
|
bb9a89c |
restoration of breakpoints. Assert PLACED_SIZE and SHADOW_LEN. New
|
|
|
bb9a89c |
check of the original memory content.
|
|
|
bb9a89c |
(ia64_breakpoint_from_pc): Array breakpoint extended to BUNDLE_LEN.
|
|
|
bb9a89c |
Sanity check the PCPTR parameter SLOTNUM value. New #if check on
|
|
|
bb9a89c |
BREAKPOINT_MAX vs. BUNDLE_LEN. Increase LENPTR to BUNDLE_LEN - 2.
|
|
|
bb9a89c |
|
|
|
bb9a89c |
gdb/testsuite/
|
|
|
bb9a89c |
2008-10-28 Jan Kratochvil <jan.kratochvil@redhat.com>
|
|
|
bb9a89c |
|
|
|
bb9a89c |
* gdb.base/breakpoint-shadow.exp, gdb.base/breakpoint-shadow.c: New.
|
|
|
bb9a89c |
|
|
|
bb9a89c |
[ RHEL-5 disable of `set breakpoint always-inserted'. ]
|
|
|
bb9a89c |
|
|
|
bb9a89c |
--- ./gdb/ia64-tdep.c 11 Sep 2008 14:23:15 -0000 1.184
|
|
|
bb9a89c |
+++ ./gdb/ia64-tdep.c 28 Oct 2008 10:28:41 -0000
|
|
|
bb9a89c |
@@ -545,7 +545,21 @@ fetch_instruction (CORE_ADDR addr, instr
|
|
|
bb9a89c |
simulators. So I changed the pattern slightly to do "break.i 0x080001"
|
|
|
bb9a89c |
instead. But that didn't work either (I later found out that this
|
|
|
bb9a89c |
pattern was used by the simulator that I was using.) So I ended up
|
|
|
bb9a89c |
- using the pattern seen below. */
|
|
|
bb9a89c |
+ using the pattern seen below.
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+ SHADOW_CONTENTS has byte-based addressing (PLACED_ADDRESS and SHADOW_LEN)
|
|
|
bb9a89c |
+ while we need bit-based addressing as the instructions length is 41 bits and
|
|
|
bb9a89c |
+ we must not modify/corrupt the adjacent ones in the same bundle.
|
|
|
bb9a89c |
+ Fortunately we may store larger memory incl. the adjacent bits with the
|
|
|
bb9a89c |
+ original memory content (not the possibly already stored breakpoints there).
|
|
|
bb9a89c |
+ We need to be careful in ia64_memory_remove_breakpoint to always restore
|
|
|
bb9a89c |
+ only the specific bits of this instruction ignoring any adjacent stored
|
|
|
bb9a89c |
+ bits.
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+ We use the original addressing with the low nibble 0..2 which gets
|
|
|
bb9a89c |
+ incorrectly interpreted by the generic GDB code as the byte offset of
|
|
|
bb9a89c |
+ SHADOW_CONTENTS. We store whole BUNDLE_LEN bytes just without these two
|
|
|
bb9a89c |
+ possibly skipped bytes. */
|
|
|
bb9a89c |
|
|
|
bb9a89c |
#if 0
|
|
|
bb9a89c |
#define IA64_BREAKPOINT 0x00002000040LL
|
|
|
bb9a89c |
@@ -559,15 +573,21 @@ ia64_memory_insert_breakpoint (struct gd
|
|
|
bb9a89c |
CORE_ADDR addr = bp_tgt->placed_address;
|
|
|
bb9a89c |
char bundle[BUNDLE_LEN];
|
|
|
bb9a89c |
int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER;
|
|
|
bb9a89c |
- long long instr;
|
|
|
bb9a89c |
int val;
|
|
|
bb9a89c |
int template;
|
|
|
bb9a89c |
+ struct cleanup *cleanup;
|
|
|
bb9a89c |
|
|
|
bb9a89c |
if (slotnum > 2)
|
|
|
bb9a89c |
error (_("Can't insert breakpoint for slot numbers greater than 2."));
|
|
|
bb9a89c |
|
|
|
bb9a89c |
addr &= ~0x0f;
|
|
|
bb9a89c |
|
|
|
bb9a89c |
+ /* Enable the automatic memory restoration from breakpoints while
|
|
|
bb9a89c |
+ we read our instruction bundle. Otherwise, we could store into
|
|
|
bb9a89c |
+ SHADOW_CONTENTS an already stored breakpoint at the same location.
|
|
|
bb9a89c |
+ In practice it is already being prevented by the DUPLICATE field and
|
|
|
bb9a89c |
+ update_global_location_list. */
|
|
|
bb9a89c |
+ cleanup = make_show_memory_breakpoints_cleanup (0);
|
|
|
bb9a89c |
val = target_read_memory (addr, bundle, BUNDLE_LEN);
|
|
|
bb9a89c |
|
|
|
bb9a89c |
/* Check for L type instruction in 2nd slot, if present then
|
|
|
bb9a89c |
@@ -578,13 +598,18 @@ ia64_memory_insert_breakpoint (struct gd
|
|
|
bb9a89c |
slotnum = 2;
|
|
|
bb9a89c |
}
|
|
|
bb9a89c |
|
|
|
bb9a89c |
- instr = slotN_contents (bundle, slotnum);
|
|
|
bb9a89c |
- memcpy (bp_tgt->shadow_contents, &instr, sizeof (instr));
|
|
|
bb9a89c |
- bp_tgt->placed_size = bp_tgt->shadow_len = sizeof (instr);
|
|
|
bb9a89c |
+ /* Slot number 2 may skip at most 2 bytes at the beginning. */
|
|
|
bb9a89c |
+ bp_tgt->placed_size = bp_tgt->shadow_len = BUNDLE_LEN - 2;
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+ /* Store the whole bundle, except for the initial skipped bytes by the slot
|
|
|
bb9a89c |
+ number interpreted as bytes offset in PLACED_ADDRESS. */
|
|
|
bb9a89c |
+ memcpy (bp_tgt->shadow_contents, bundle + slotnum, bp_tgt->shadow_len);
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
replace_slotN_contents (bundle, IA64_BREAKPOINT, slotnum);
|
|
|
bb9a89c |
if (val == 0)
|
|
|
bb9a89c |
- target_write_memory (addr, bundle, BUNDLE_LEN);
|
|
|
bb9a89c |
+ target_write_memory (addr + slotnum, bundle + slotnum, bp_tgt->shadow_len);
|
|
|
bb9a89c |
|
|
|
bb9a89c |
+ do_cleanups (cleanup);
|
|
|
bb9a89c |
return val;
|
|
|
bb9a89c |
}
|
|
|
bb9a89c |
|
|
|
bb9a89c |
@@ -593,9 +618,9 @@ ia64_memory_remove_breakpoint (struct gd
|
|
|
bb9a89c |
struct bp_target_info *bp_tgt)
|
|
|
bb9a89c |
{
|
|
|
bb9a89c |
CORE_ADDR addr = bp_tgt->placed_address;
|
|
|
bb9a89c |
- char bundle[BUNDLE_LEN];
|
|
|
bb9a89c |
+ char bundle_mem[BUNDLE_LEN], bundle_saved[BUNDLE_LEN];
|
|
|
bb9a89c |
int slotnum = (addr & 0x0f) / SLOT_MULTIPLIER;
|
|
|
bb9a89c |
- long long instr;
|
|
|
bb9a89c |
+ long long instr_breakpoint, instr_saved;
|
|
|
bb9a89c |
int val;
|
|
|
bb9a89c |
int template;
|
|
|
bb9a89c |
struct cleanup *cleanup;
|
|
|
bb9a89c |
@@ -604,23 +629,39 @@ ia64_memory_remove_breakpoint (struct gd
|
|
|
bb9a89c |
|
|
|
bb9a89c |
/* Disable the automatic memory restoration from breakpoints while
|
|
|
bb9a89c |
we read our instruction bundle. Otherwise, the general restoration
|
|
|
bb9a89c |
- mechanism kicks in and ends up corrupting our bundle, because it
|
|
|
bb9a89c |
- is not aware of the concept of instruction bundles. */
|
|
|
bb9a89c |
+ mechanism kicks in and we would possibly remove parts of the adjacent
|
|
|
bb9a89c |
+ placed breakpoints. It is due to our SHADOW_CONTENTS overlapping the real
|
|
|
bb9a89c |
+ breakpoint instruction bits region. */
|
|
|
bb9a89c |
cleanup = make_show_memory_breakpoints_cleanup (1);
|
|
|
bb9a89c |
- val = target_read_memory (addr, bundle, BUNDLE_LEN);
|
|
|
bb9a89c |
+ val = target_read_memory (addr, bundle_mem, BUNDLE_LEN);
|
|
|
bb9a89c |
|
|
|
bb9a89c |
/* Check for L type instruction in 2nd slot, if present then
|
|
|
bb9a89c |
bump up the slot number to the 3rd slot */
|
|
|
bb9a89c |
- template = extract_bit_field (bundle, 0, 5);
|
|
|
bb9a89c |
+ template = extract_bit_field (bundle_mem, 0, 5);
|
|
|
bb9a89c |
if (slotnum == 1 && template_encoding_table[template][1] == L)
|
|
|
bb9a89c |
{
|
|
|
bb9a89c |
slotnum = 2;
|
|
|
bb9a89c |
}
|
|
|
bb9a89c |
|
|
|
bb9a89c |
- memcpy (&instr, bp_tgt->shadow_contents, sizeof instr);
|
|
|
bb9a89c |
- replace_slotN_contents (bundle, instr, slotnum);
|
|
|
bb9a89c |
+ gdb_assert (bp_tgt->placed_size == BUNDLE_LEN - 2);
|
|
|
bb9a89c |
+ gdb_assert (bp_tgt->placed_size == bp_tgt->shadow_len);
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+ instr_breakpoint = slotN_contents (bundle_mem, slotnum);
|
|
|
bb9a89c |
+ if (instr_breakpoint != IA64_BREAKPOINT)
|
|
|
bb9a89c |
+ warning (_("Breakpoint removal cannot find the placed breakpoint at %s"),
|
|
|
bb9a89c |
+ paddr_nz (bp_tgt->placed_address));
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+ /* Extract the original saved instruction from SLOTNUM normalizing its
|
|
|
bb9a89c |
+ bit-shift for INSTR_SAVED. */
|
|
|
bb9a89c |
+ memcpy (bundle_saved, bundle_mem, BUNDLE_LEN);
|
|
|
bb9a89c |
+ memcpy (bundle_saved + slotnum, bp_tgt->shadow_contents, bp_tgt->shadow_len);
|
|
|
bb9a89c |
+ instr_saved = slotN_contents (bundle_saved, slotnum);
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+ /* In BUNDLE_MEM be careful to modify only the bits belonging to SLOTNUM and
|
|
|
bb9a89c |
+ never any other possibly also stored in SHADOW_CONTENTS. */
|
|
|
bb9a89c |
+ replace_slotN_contents (bundle_mem, instr_saved, slotnum);
|
|
|
bb9a89c |
if (val == 0)
|
|
|
bb9a89c |
- target_write_memory (addr, bundle, BUNDLE_LEN);
|
|
|
bb9a89c |
+ target_write_memory (addr, bundle_mem, BUNDLE_LEN);
|
|
|
bb9a89c |
|
|
|
bb9a89c |
do_cleanups (cleanup);
|
|
|
bb9a89c |
return val;
|
|
|
bb9a89c |
@@ -631,12 +672,18 @@ ia64_memory_remove_breakpoint (struct gd
|
|
|
bb9a89c |
const unsigned char *
|
|
|
bb9a89c |
ia64_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr)
|
|
|
bb9a89c |
{
|
|
|
bb9a89c |
- static unsigned char breakpoint[] =
|
|
|
bb9a89c |
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
|
|
bb9a89c |
- *lenptr = sizeof (breakpoint);
|
|
|
bb9a89c |
-#if 0
|
|
|
bb9a89c |
- *pcptr &= ~0x0f;
|
|
|
bb9a89c |
+ static unsigned char breakpoint[BUNDLE_LEN];
|
|
|
bb9a89c |
+ int slotnum = (int) (*pcptr & 0x0f) / SLOT_MULTIPLIER;
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+ if (slotnum > 2)
|
|
|
bb9a89c |
+ error (_("Can't insert breakpoint for slot numbers greater than 2."));
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+#if BREAKPOINT_MAX < BUNDLE_LEN
|
|
|
bb9a89c |
+# error "BREAKPOINT_MAX < BUNDLE_LEN"
|
|
|
bb9a89c |
#endif
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+ *lenptr = BUNDLE_LEN - 2;
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
return breakpoint;
|
|
|
bb9a89c |
}
|
|
|
bb9a89c |
|
|
|
bb9a89c |
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
|
|
bb9a89c |
+++ ./gdb/testsuite/gdb.base/breakpoint-shadow.c 28 Oct 2008 10:28:41 -0000
|
|
|
bb9a89c |
@@ -0,0 +1,27 @@
|
|
|
bb9a89c |
+/* This testcase is part of GDB, the GNU debugger.
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+ Copyright 2008 Free Software Foundation, Inc.
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+ This program is free software; you can redistribute it and/or modify
|
|
|
bb9a89c |
+ it under the terms of the GNU General Public License as published by
|
|
|
bb9a89c |
+ the Free Software Foundation; either version 3 of the License, or
|
|
|
bb9a89c |
+ (at your option) any later version.
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+ This program is distributed in the hope that it will be useful,
|
|
|
bb9a89c |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
bb9a89c |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
bb9a89c |
+ GNU General Public License for more details.
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+ You should have received a copy of the GNU General Public License
|
|
|
bb9a89c |
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+int
|
|
|
bb9a89c |
+main (void)
|
|
|
bb9a89c |
+{
|
|
|
bb9a89c |
+ volatile int i;
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+ i = 1; /* break-first */
|
|
|
bb9a89c |
+ i = 2; /* break-second */
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+ return 0;
|
|
|
bb9a89c |
+}
|
|
|
bb9a89c |
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
|
|
bb9a89c |
+++ ./gdb/testsuite/gdb.base/breakpoint-shadow.exp 28 Oct 2008 10:28:41 -0000
|
|
|
bb9a89c |
@@ -0,0 +1,65 @@
|
|
|
bb9a89c |
+# Copyright 2008 Free Software Foundation, Inc.
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+# This program is free software; you can redistribute it and/or modify
|
|
|
bb9a89c |
+# it under the terms of the GNU General Public License as published by
|
|
|
bb9a89c |
+# the Free Software Foundation; either version 3 of the License, or
|
|
|
bb9a89c |
+# (at your option) any later version.
|
|
|
bb9a89c |
+#
|
|
|
bb9a89c |
+# This program is distributed in the hope that it will be useful,
|
|
|
bb9a89c |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
bb9a89c |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
bb9a89c |
+# GNU General Public License for more details.
|
|
|
bb9a89c |
+#
|
|
|
bb9a89c |
+# You should have received a copy of the GNU General Public License
|
|
|
bb9a89c |
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+set testfile breakpoint-shadow
|
|
|
bb9a89c |
+set srcfile ${testfile}.c
|
|
|
bb9a89c |
+set binfile ${objdir}/${subdir}/${testfile}
|
|
|
bb9a89c |
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
|
|
|
bb9a89c |
+ untested "Couldn't compile test program"
|
|
|
bb9a89c |
+ return -1
|
|
|
bb9a89c |
+}
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+gdb_exit
|
|
|
bb9a89c |
+gdb_start
|
|
|
bb9a89c |
+gdb_reinitialize_dir $srcdir/$subdir
|
|
|
bb9a89c |
+gdb_load ${binfile}
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+# We need to start the inferior to place the breakpoints in the memory at all.
|
|
|
bb9a89c |
+if { [gdb_start_cmd] < 0 } {
|
|
|
bb9a89c |
+ untested start
|
|
|
bb9a89c |
+ return -1
|
|
|
bb9a89c |
+}
|
|
|
bb9a89c |
+gdb_test "" "main \\(\\) at .*" "start"
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+# The default "auto" mode removes all the breakpoints when we stop (and not
|
|
|
bb9a89c |
+# running the nonstop mode). We would not be able to test the shadow.
|
|
|
bb9a89c |
+#RHEL-5:
|
|
|
bb9a89c |
+#gdb_test "set breakpoint always-inserted on"
|
|
|
bb9a89c |
+#gdb_test "show breakpoint always-inserted" "Always inserted breakpoint mode is on."
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+set match "\nDump of assembler code for function main:\r\n(.*)End of assembler dump.\r\n$gdb_prompt $"
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+set test "disassembly without breakpoints"
|
|
|
bb9a89c |
+gdb_test_multiple "disass main" $test {
|
|
|
bb9a89c |
+ -re $match {
|
|
|
bb9a89c |
+ set orig $expect_out(1,string)
|
|
|
bb9a89c |
+ pass $test
|
|
|
bb9a89c |
+ }
|
|
|
bb9a89c |
+}
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+gdb_test "b [gdb_get_line_number "break-first"]" "Breakpoint \[0-9\] at .*" "First breakpoint placed"
|
|
|
bb9a89c |
+gdb_test "b [gdb_get_line_number "break-second"]" "Breakpoint \[0-9\] at .*" "Second breakpoint placed"
|
|
|
bb9a89c |
+
|
|
|
bb9a89c |
+set test "disassembly with breakpoints"
|
|
|
bb9a89c |
+gdb_test_multiple "disass main" $test {
|
|
|
bb9a89c |
+ -re $match {
|
|
|
bb9a89c |
+ set got $expect_out(1,string)
|
|
|
bb9a89c |
+ if [string equal -nocase $orig $got] {
|
|
|
bb9a89c |
+ pass $test
|
|
|
bb9a89c |
+ } else {
|
|
|
bb9a89c |
+ fail $test
|
|
|
bb9a89c |
+ }
|
|
|
bb9a89c |
+ }
|
|
|
bb9a89c |
+}
|