/* Initialize the hardware breakpoint structure P for a breakpoint or
watchpoint at ADDR to LEN. The type of watchpoint is given in TYPE.
- Returns -1 if TYPE is unsupported, 0 if TYPE represents a breakpoint,
- and 1 if type represents a watchpoint. */
+ Returns -1 if TYPE is unsupported, or -2 if the particular combination
+ of ADDR and LEN cannot be implemented. Otherwise, returns 0 if TYPE
+ represents a breakpoint and 1 if type represents a watchpoint. */
static int
arm_linux_hw_point_initialize (char type, CORE_ADDR addr, int len,
struct arm_linux_hw_breakpoint *p)
break;
default:
/* Unsupported. */
- return -1;
+ return -2;
}
}
else
/* Can not set watchpoints for zero or negative lengths. */
if (len <= 0)
- return -1;
+ return -2;
/* The current ptrace interface can only handle watchpoints that are a
power of 2. */
if ((len & (len - 1)) != 0)
- return -1;
+ return -2;
/* Test that the range [ADDR, ADDR + LEN) fits into the largest address
range covered by a watchpoint. */
aligned_addr = addr & ~(max_wp_length - 1);
if (aligned_addr + max_wp_length < addr + len)
- return -1;
+ return -2;
mask = (1 << len) - 1;
}
if (watch < 0)
{
/* Unsupported. */
- return 1;
+ return watch == -1 ? 1 : -1;
}
if (watch)
proc test_wide_location_1 {} {
global no_hw
+ global gdb_prompt
# This test watches two words on most 32-bit ABIs, and one word on
# most 64-bit ABIs.
# Platforms where the target can't watch such a large region
# should clear hw_expected below.
- if { $no_hw || [target_info exists gdb,no_hardware_watchpoints] } {
+ if { $no_hw || [target_info exists gdb,no_hardware_watchpoints]
+ || [istarget arm*-*-*] } {
set hw_expected 0
} else {
set hw_expected 1
"continue with watch foo2"
} else {
gdb_test "watch foo2" "atchpoint .*: .*" "watch foo2"
- gdb_test "continue" \
- "Continuing.*\[Ww\]atchpoint .*: .*New value = \\\{val = \\\{0, 11\\\}\\\}.*" \
- "continue with watch foo2"
+ set test "continue with watch foo2"
+ gdb_test_multiple "cont" $test {
+ -re "Continuing.*\[Ww\]atchpoint .*: .*New value = \\\{val = \\\{0, 11\\\}\\\}.*$gdb_prompt $" {
+ pass $test
+ }
+ -re "Could not insert hardware breakpoints:.*You may have requested too many hardware breakpoints/watchpoints.*$gdb_prompt $" {
+ # This may happen with remote targets that support
+ # hardware watchpoints. We only find out the
+ # watchpoint was too large, for example, at insert
+ # time. If GDB is ever adjusted to downgrade the
+ # watchpoint automatically in this case, this match
+ # should be removed.
+ pass $test
+ }
+ }
}
gdb_test_no_output "delete \$bpnum" "delete watch foo2"
proc test_wide_location_2 {} {
global no_hw
+ global gdb_prompt
# This test watches four words on most 32-bit ABIs, and two words
# on 64-bit ABIs.
# Platforms where the target can't watch such a large region
# should clear hw_expected below.
- if { $no_hw || [target_info exists gdb,no_hardware_watchpoints] } {
+ if { $no_hw || [target_info exists gdb,no_hardware_watchpoints]
+ || [istarget arm*-*-*] } {
set hw_expected 0
} else {
set hw_expected 1
"continue with watch foo4"
} else {
gdb_test "watch foo4" "atchpoint .*: .*" "watch foo4"
- gdb_test "continue" \
- "Continuing.*\[Ww\]atchpoint .*: .*New value = \\\{val = \\\{0, 0, 0, 33\\\}\\\}.*" \
- "continue with watch foo4"
+ set test "continue with watch foo4"
+ gdb_test_multiple "cont" $test {
+ -re "Continuing.*\[Ww\]atchpoint .*: .*New value = \\\{val = \\\{0, 0, 0, 33\\\}\\\}.*$gdb_prompt $" {
+ pass $test
+ }
+ -re "Could not insert hardware breakpoints:.*You may have requested too many hardware breakpoints/watchpoints.*$gdb_prompt $" {
+ # This may happen with remote targets that support
+ # hardware watchpoints. We only find out the
+ # watchpoint was too large, for example, at insert
+ # time. If GDB is ever adjusted to downgrade the
+ # watchpoint automatically in this case, this match
+ # should be removed.
+ pass $test
+ }
+ }
}
gdb_test_no_output "delete \$bpnum" "delete watch foo4"