aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog19
-rw-r--r--gdb/breakpoint.c5
-rw-r--r--gdb/doc/ChangeLog5
-rw-r--r--gdb/doc/gdbint.texinfo13
-rw-r--r--gdb/ppc-linux-nat.c11
-rw-r--r--gdb/target.c37
-rw-r--r--gdb/target.h5
7 files changed, 89 insertions, 6 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 5efa58e..8b51c3b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,20 @@
+2008-05-02 Andreas Schwab <schwab@suse.de>
+
+ * target.h (struct target_ops): Add
+ to_watchpoint_addr_within_range.
+ (target_watchpoint_addr_within_range): New function.
+ * target.c (update_current_target): Inherit
+ to_watchpoint_addr_within_range, defaulting to
+ default_watchpoint_addr_within_range.
+ (default_watchpoint_addr_within_range): New function.
+ (debug_to_watchpoint_addr_within_range): New function.
+ (setup_target_debug): Set to_watchpoint_addr_within_range.
+ * ppc-linux-nat.c (ppc_linux_watchpoint_addr_within_range):
+ New function.
+ (_initialize_ppc_linux_nat): Set to_watchpoint_addr_within_range.
+ * breakpoint.c (watchpoints_triggered): Use
+ target_watchpoint_addr_within_range.
+
2008-05-01 Pedro Alves <pedro@codesourcery.com>
* configure.tgt: Add i[34567]86-*-dicos* and x86_64-*-dicos*.
@@ -32,7 +49,7 @@
(print_one_exception_catchpoint): Print <PENDING> if no loc available.
(handle_gnu_v3_exceptions): Call generic breakpoint code to insert
catch and throw catchpoints.
-
+
2008-05-01 Aleksandar Riswtovski <aristovski@qnx.com>
PR gdb/2343
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 9dc2ca2..11d9187 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -2616,8 +2616,9 @@ watchpoints_triggered (struct target_waitstatus *ws)
for (loc = b->loc; loc; loc = loc->next)
/* Exact match not required. Within range is
sufficient. */
- if (addr >= loc->address
- && addr < loc->address + loc->length)
+ if (target_watchpoint_addr_within_range (&current_target,
+ addr, loc->address,
+ loc->length))
{
b->watchpoint_triggered = watch_triggered_yes;
break;
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 2285c83..2b5b662 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@
+2008-05-02 Andreas Schwab <schwab@suse.de>
+
+ * gdbint.texinfo (Algorithms): Describe
+ target_watchpoint_addr_within_range.
+
2008-04-30 Daniel Jacobowitz <dan@codesourcery.com>
* gdbint.texinfo (Stack Frames): New chapter.
diff --git a/gdb/doc/gdbint.texinfo b/gdb/doc/gdbint.texinfo
index 39cb031..d020f5b 100644
--- a/gdb/doc/gdbint.texinfo
+++ b/gdb/doc/gdbint.texinfo
@@ -9,7 +9,7 @@
@ifinfo
This file documents the internals of the GNU debugger @value{GDBN}.
Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006
+ 2002, 2003, 2004, 2005, 2006, 2008
Free Software Foundation, Inc.
Contributed by Cygnus Solutions. Written by John Gilmore.
Second Edition by Stan Shebs.
@@ -711,10 +711,19 @@ target's watchpoint indication is sticky, i.e., stays set after
resuming, this method should clear it. For instance, the x86 debug
control register has sticky triggered flags.
+@findex target_watchpoint_addr_within_range
+@item target_watchpoint_addr_within_range (@var{target}, @var{addr}, @var{start}, @var{length})
+Check whether @var{addr} (as returned by @code{target_stopped_data_address})
+lies within the hardware-defined watchpoint region described by
+@var{start} and @var{length}. This only needs to be provided if the
+granularity of a watchpoint is greater than one byte, i.e., if the
+watchpoint can also trigger on nearby addresses outside of the watched
+region.
+
@findex HAVE_STEPPABLE_WATCHPOINT
@item HAVE_STEPPABLE_WATCHPOINT
If defined to a non-zero value, it is not necessary to disable a
-watchpoint to step over it. Like @code{gdbarch_have_nonsteppable_watchpoint},
+watchpoint to step over it. Like @code{gdbarch_have_nonsteppable_watchpoint},
this is usually set when watchpoints trigger at the instruction
which will perform an interesting read or write. It should be
set if there is a temporary disable bit which allows the processor
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index 53bc4ae..5486588 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -889,6 +889,16 @@ ppc_linux_stopped_by_watchpoint (void)
return ppc_linux_stopped_data_address (&current_target, &addr);
}
+static int
+ppc_linux_watchpoint_addr_within_range (struct target_ops *target,
+ CORE_ADDR addr,
+ CORE_ADDR start, int length)
+{
+ addr &= ~7;
+ /* Check whether [start, start+length-1] intersects [addr, addr+7]. */
+ return start <= addr + 7 && start + length - 1 >= addr;
+}
+
static void
ppc_linux_store_inferior_registers (struct regcache *regcache, int regno)
{
@@ -997,6 +1007,7 @@ _initialize_ppc_linux_nat (void)
t->to_remove_watchpoint = ppc_linux_remove_watchpoint;
t->to_stopped_by_watchpoint = ppc_linux_stopped_by_watchpoint;
t->to_stopped_data_address = ppc_linux_stopped_data_address;
+ t->to_watchpoint_addr_within_range = ppc_linux_watchpoint_addr_within_range;
t->to_read_description = ppc_linux_read_description;
diff --git a/gdb/target.c b/gdb/target.c
index 944d601..a8f1afb 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -49,6 +49,9 @@ static void kill_or_be_killed (int);
static void default_terminal_info (char *, int);
+static int default_watchpoint_addr_within_range (struct target_ops *,
+ CORE_ADDR, CORE_ADDR, int);
+
static int default_region_ok_for_hw_watchpoint (CORE_ADDR, int);
static int nosymbol (char *, CORE_ADDR *);
@@ -131,6 +134,9 @@ static int debug_to_stopped_by_watchpoint (void);
static int debug_to_stopped_data_address (struct target_ops *, CORE_ADDR *);
+static int debug_to_watchpoint_addr_within_range (struct target_ops *,
+ CORE_ADDR, CORE_ADDR, int);
+
static int debug_to_region_ok_for_hw_watchpoint (CORE_ADDR, int);
static void debug_to_terminal_init (void);
@@ -416,9 +422,10 @@ update_current_target (void)
INHERIT (to_insert_watchpoint, t);
INHERIT (to_remove_watchpoint, t);
INHERIT (to_stopped_data_address, t);
- INHERIT (to_stopped_by_watchpoint, t);
INHERIT (to_have_steppable_watchpoint, t);
INHERIT (to_have_continuable_watchpoint, t);
+ INHERIT (to_stopped_by_watchpoint, t);
+ INHERIT (to_watchpoint_addr_within_range, t);
INHERIT (to_region_ok_for_hw_watchpoint, t);
INHERIT (to_terminal_init, t);
INHERIT (to_terminal_inferior, t);
@@ -544,6 +551,8 @@ update_current_target (void)
de_fault (to_stopped_data_address,
(int (*) (struct target_ops *, CORE_ADDR *))
return_zero);
+ de_fault (to_watchpoint_addr_within_range,
+ default_watchpoint_addr_within_range);
de_fault (to_region_ok_for_hw_watchpoint,
default_region_ok_for_hw_watchpoint);
de_fault (to_terminal_init,
@@ -1881,6 +1890,14 @@ default_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
}
static int
+default_watchpoint_addr_within_range (struct target_ops *target,
+ CORE_ADDR addr,
+ CORE_ADDR start, int length)
+{
+ return addr >= start && addr < start + length;
+}
+
+static int
return_zero (void)
{
return 0;
@@ -2448,6 +2465,23 @@ debug_to_stopped_data_address (struct target_ops *target, CORE_ADDR *addr)
}
static int
+debug_to_watchpoint_addr_within_range (struct target_ops *target,
+ CORE_ADDR addr,
+ CORE_ADDR start, int length)
+{
+ int retval;
+
+ retval = debug_target.to_watchpoint_addr_within_range (target, addr,
+ start, length);
+
+ fprintf_filtered (gdb_stdlog,
+ "target_watchpoint_addr_within_range (0x%lx, 0x%lx, %d) = %d\n",
+ (unsigned long) addr, (unsigned long) start, length,
+ retval);
+ return retval;
+}
+
+static int
debug_to_insert_hw_breakpoint (struct bp_target_info *bp_tgt)
{
int retval;
@@ -2790,6 +2824,7 @@ setup_target_debug (void)
current_target.to_remove_watchpoint = debug_to_remove_watchpoint;
current_target.to_stopped_by_watchpoint = debug_to_stopped_by_watchpoint;
current_target.to_stopped_data_address = debug_to_stopped_data_address;
+ current_target.to_watchpoint_addr_within_range = debug_to_watchpoint_addr_within_range;
current_target.to_region_ok_for_hw_watchpoint = debug_to_region_ok_for_hw_watchpoint;
current_target.to_terminal_init = debug_to_terminal_init;
current_target.to_terminal_inferior = debug_to_terminal_inferior;
diff --git a/gdb/target.h b/gdb/target.h
index 84cd008..8e7d112 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -367,6 +367,8 @@ struct target_ops
int to_have_steppable_watchpoint;
int to_have_continuable_watchpoint;
int (*to_stopped_data_address) (struct target_ops *, CORE_ADDR *);
+ int (*to_watchpoint_addr_within_range) (struct target_ops *,
+ CORE_ADDR, CORE_ADDR, int);
int (*to_region_ok_for_hw_watchpoint) (CORE_ADDR, int);
void (*to_terminal_init) (void);
void (*to_terminal_inferior) (void);
@@ -1093,6 +1095,9 @@ extern int target_stopped_data_address_p (struct target_ops *);
#define target_stopped_data_address_p(CURRENT_TARGET) (1)
#endif
+#define target_watchpoint_addr_within_range(target, addr, start, length) \
+ (*target.to_watchpoint_addr_within_range) (target, addr, start, length)
+
extern const struct target_desc *target_read_description (struct target_ops *);
/* Command logging facility. */