Home | History | Annotate | Line # | Download | only in nat
aarch64-hw-point.c revision 1.1.1.1.4.2
      1  1.1.1.1.4.2  perseant /* Copyright (C) 2009-2023 Free Software Foundation, Inc.
      2  1.1.1.1.4.2  perseant 
      3  1.1.1.1.4.2  perseant    This file is part of GDB.
      4  1.1.1.1.4.2  perseant 
      5  1.1.1.1.4.2  perseant    This program is free software; you can redistribute it and/or modify
      6  1.1.1.1.4.2  perseant    it under the terms of the GNU General Public License as published by
      7  1.1.1.1.4.2  perseant    the Free Software Foundation; either version 3 of the License, or
      8  1.1.1.1.4.2  perseant    (at your option) any later version.
      9  1.1.1.1.4.2  perseant 
     10  1.1.1.1.4.2  perseant    This program is distributed in the hope that it will be useful,
     11  1.1.1.1.4.2  perseant    but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  1.1.1.1.4.2  perseant    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  1.1.1.1.4.2  perseant    GNU General Public License for more details.
     14  1.1.1.1.4.2  perseant 
     15  1.1.1.1.4.2  perseant    You should have received a copy of the GNU General Public License
     16  1.1.1.1.4.2  perseant    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     17  1.1.1.1.4.2  perseant 
     18  1.1.1.1.4.2  perseant #include "gdbsupport/common-defs.h"
     19  1.1.1.1.4.2  perseant #include "gdbsupport/break-common.h"
     20  1.1.1.1.4.2  perseant #include "gdbsupport/common-regcache.h"
     21  1.1.1.1.4.2  perseant #include "aarch64-hw-point.h"
     22  1.1.1.1.4.2  perseant 
     23  1.1.1.1.4.2  perseant #ifdef __linux__
     24  1.1.1.1.4.2  perseant /* For kernel_supports_any_contiguous_range.  */
     25  1.1.1.1.4.2  perseant #include "aarch64-linux-hw-point.h"
     26  1.1.1.1.4.2  perseant #else
     27  1.1.1.1.4.2  perseant #define	kernel_supports_any_contiguous_range	true
     28  1.1.1.1.4.2  perseant #endif
     29  1.1.1.1.4.2  perseant 
     30  1.1.1.1.4.2  perseant /* Number of hardware breakpoints/watchpoints the target supports.
     31  1.1.1.1.4.2  perseant    They are initialized with values obtained via ptrace.  */
     32  1.1.1.1.4.2  perseant 
     33  1.1.1.1.4.2  perseant int aarch64_num_bp_regs;
     34  1.1.1.1.4.2  perseant int aarch64_num_wp_regs;
     35  1.1.1.1.4.2  perseant 
     36  1.1.1.1.4.2  perseant /* Return starting byte 0..7 incl. of a watchpoint encoded by CTRL.  */
     37  1.1.1.1.4.2  perseant 
     38  1.1.1.1.4.2  perseant unsigned int
     39  1.1.1.1.4.2  perseant aarch64_watchpoint_offset (unsigned int ctrl)
     40  1.1.1.1.4.2  perseant {
     41  1.1.1.1.4.2  perseant   uint8_t mask = DR_CONTROL_MASK (ctrl);
     42  1.1.1.1.4.2  perseant   unsigned retval;
     43  1.1.1.1.4.2  perseant 
     44  1.1.1.1.4.2  perseant   /* Shift out bottom zeros.  */
     45  1.1.1.1.4.2  perseant   for (retval = 0; mask && (mask & 1) == 0; ++retval)
     46  1.1.1.1.4.2  perseant     mask >>= 1;
     47  1.1.1.1.4.2  perseant 
     48  1.1.1.1.4.2  perseant   return retval;
     49  1.1.1.1.4.2  perseant }
     50  1.1.1.1.4.2  perseant 
     51  1.1.1.1.4.2  perseant /* Utility function that returns the length in bytes of a watchpoint
     52  1.1.1.1.4.2  perseant    according to the content of a hardware debug control register CTRL.
     53  1.1.1.1.4.2  perseant    Any contiguous range of bytes in CTRL is supported.  The returned
     54  1.1.1.1.4.2  perseant    value can be between 0..8 (inclusive).  */
     55  1.1.1.1.4.2  perseant 
     56  1.1.1.1.4.2  perseant unsigned int
     57  1.1.1.1.4.2  perseant aarch64_watchpoint_length (unsigned int ctrl)
     58  1.1.1.1.4.2  perseant {
     59  1.1.1.1.4.2  perseant   uint8_t mask = DR_CONTROL_MASK (ctrl);
     60  1.1.1.1.4.2  perseant   unsigned retval;
     61  1.1.1.1.4.2  perseant 
     62  1.1.1.1.4.2  perseant   /* Shift out bottom zeros.  */
     63  1.1.1.1.4.2  perseant   mask >>= aarch64_watchpoint_offset (ctrl);
     64  1.1.1.1.4.2  perseant 
     65  1.1.1.1.4.2  perseant   /* Count bottom ones.  */
     66  1.1.1.1.4.2  perseant   for (retval = 0; (mask & 1) != 0; ++retval)
     67  1.1.1.1.4.2  perseant     mask >>= 1;
     68  1.1.1.1.4.2  perseant 
     69  1.1.1.1.4.2  perseant   if (mask != 0)
     70  1.1.1.1.4.2  perseant     error (_("Unexpected hardware watchpoint length register value 0x%x"),
     71  1.1.1.1.4.2  perseant 	   DR_CONTROL_MASK (ctrl));
     72  1.1.1.1.4.2  perseant 
     73  1.1.1.1.4.2  perseant   return retval;
     74  1.1.1.1.4.2  perseant }
     75  1.1.1.1.4.2  perseant 
     76  1.1.1.1.4.2  perseant /* Given the hardware breakpoint or watchpoint type TYPE and its
     77  1.1.1.1.4.2  perseant    length LEN, return the expected encoding for a hardware
     78  1.1.1.1.4.2  perseant    breakpoint/watchpoint control register.  */
     79  1.1.1.1.4.2  perseant 
     80  1.1.1.1.4.2  perseant static unsigned int
     81  1.1.1.1.4.2  perseant aarch64_point_encode_ctrl_reg (enum target_hw_bp_type type, int offset, int len)
     82  1.1.1.1.4.2  perseant {
     83  1.1.1.1.4.2  perseant   unsigned int ctrl, ttype;
     84  1.1.1.1.4.2  perseant 
     85  1.1.1.1.4.2  perseant   gdb_assert (offset == 0 || kernel_supports_any_contiguous_range);
     86  1.1.1.1.4.2  perseant   gdb_assert (offset + len <= AARCH64_HWP_MAX_LEN_PER_REG);
     87  1.1.1.1.4.2  perseant 
     88  1.1.1.1.4.2  perseant   /* type */
     89  1.1.1.1.4.2  perseant   switch (type)
     90  1.1.1.1.4.2  perseant     {
     91  1.1.1.1.4.2  perseant     case hw_write:
     92  1.1.1.1.4.2  perseant       ttype = 2;
     93  1.1.1.1.4.2  perseant       break;
     94  1.1.1.1.4.2  perseant     case hw_read:
     95  1.1.1.1.4.2  perseant       ttype = 1;
     96  1.1.1.1.4.2  perseant       break;
     97  1.1.1.1.4.2  perseant     case hw_access:
     98  1.1.1.1.4.2  perseant       ttype = 3;
     99  1.1.1.1.4.2  perseant       break;
    100  1.1.1.1.4.2  perseant     case hw_execute:
    101  1.1.1.1.4.2  perseant       ttype = 0;
    102  1.1.1.1.4.2  perseant       break;
    103  1.1.1.1.4.2  perseant     default:
    104  1.1.1.1.4.2  perseant       perror_with_name (_("Unrecognized breakpoint/watchpoint type"));
    105  1.1.1.1.4.2  perseant     }
    106  1.1.1.1.4.2  perseant 
    107  1.1.1.1.4.2  perseant   ctrl = ttype << 3;
    108  1.1.1.1.4.2  perseant 
    109  1.1.1.1.4.2  perseant   /* offset and length bitmask */
    110  1.1.1.1.4.2  perseant   ctrl |= ((1 << len) - 1) << (5 + offset);
    111  1.1.1.1.4.2  perseant   /* enabled at el0 */
    112  1.1.1.1.4.2  perseant   ctrl |= (2 << 1) | 1;
    113  1.1.1.1.4.2  perseant 
    114  1.1.1.1.4.2  perseant   return ctrl;
    115  1.1.1.1.4.2  perseant }
    116  1.1.1.1.4.2  perseant 
    117  1.1.1.1.4.2  perseant /* Addresses to be written to the hardware breakpoint and watchpoint
    118  1.1.1.1.4.2  perseant    value registers need to be aligned; the alignment is 4-byte and
    119  1.1.1.1.4.2  perseant    8-type respectively.  Linux kernel rejects any non-aligned address
    120  1.1.1.1.4.2  perseant    it receives from the related ptrace call.  Furthermore, the kernel
    121  1.1.1.1.4.2  perseant    currently only supports the following Byte Address Select (BAS)
    122  1.1.1.1.4.2  perseant    values: 0x1, 0x3, 0xf and 0xff, which means that for a hardware
    123  1.1.1.1.4.2  perseant    watchpoint to be accepted by the kernel (via ptrace call), its
    124  1.1.1.1.4.2  perseant    valid length can only be 1 byte, 2 bytes, 4 bytes or 8 bytes.
    125  1.1.1.1.4.2  perseant    Despite these limitations, the unaligned watchpoint is supported in
    126  1.1.1.1.4.2  perseant    this port.
    127  1.1.1.1.4.2  perseant 
    128  1.1.1.1.4.2  perseant    Return 0 for any non-compliant ADDR and/or LEN; return 1 otherwise.  */
    129  1.1.1.1.4.2  perseant 
    130  1.1.1.1.4.2  perseant static int
    131  1.1.1.1.4.2  perseant aarch64_point_is_aligned (ptid_t ptid, int is_watchpoint, CORE_ADDR addr,
    132  1.1.1.1.4.2  perseant 			  int len)
    133  1.1.1.1.4.2  perseant {
    134  1.1.1.1.4.2  perseant   unsigned int alignment = 0;
    135  1.1.1.1.4.2  perseant 
    136  1.1.1.1.4.2  perseant   if (is_watchpoint)
    137  1.1.1.1.4.2  perseant     alignment = AARCH64_HWP_ALIGNMENT;
    138  1.1.1.1.4.2  perseant   else
    139  1.1.1.1.4.2  perseant     {
    140  1.1.1.1.4.2  perseant       struct regcache *regcache
    141  1.1.1.1.4.2  perseant 	= get_thread_regcache_for_ptid (ptid);
    142  1.1.1.1.4.2  perseant 
    143  1.1.1.1.4.2  perseant       /* Set alignment to 2 only if the current process is 32-bit,
    144  1.1.1.1.4.2  perseant 	 since thumb instruction can be 2-byte aligned.  Otherwise, set
    145  1.1.1.1.4.2  perseant 	 alignment to AARCH64_HBP_ALIGNMENT.  */
    146  1.1.1.1.4.2  perseant       if (regcache_register_size (regcache, 0) == 8)
    147  1.1.1.1.4.2  perseant 	alignment = AARCH64_HBP_ALIGNMENT;
    148  1.1.1.1.4.2  perseant       else
    149  1.1.1.1.4.2  perseant 	alignment = 2;
    150  1.1.1.1.4.2  perseant     }
    151  1.1.1.1.4.2  perseant 
    152  1.1.1.1.4.2  perseant   if (addr & (alignment - 1))
    153  1.1.1.1.4.2  perseant     return 0;
    154  1.1.1.1.4.2  perseant 
    155  1.1.1.1.4.2  perseant   if ((!kernel_supports_any_contiguous_range
    156  1.1.1.1.4.2  perseant        && len != 8 && len != 4 && len != 2 && len != 1)
    157  1.1.1.1.4.2  perseant       || (kernel_supports_any_contiguous_range
    158  1.1.1.1.4.2  perseant 	  && (len < 1 || len > 8)))
    159  1.1.1.1.4.2  perseant     return 0;
    160  1.1.1.1.4.2  perseant 
    161  1.1.1.1.4.2  perseant   return 1;
    162  1.1.1.1.4.2  perseant }
    163  1.1.1.1.4.2  perseant 
    164  1.1.1.1.4.2  perseant /* Given the (potentially unaligned) watchpoint address in ADDR and
    165  1.1.1.1.4.2  perseant    length in LEN, return the aligned address, offset from that base
    166  1.1.1.1.4.2  perseant    address, and aligned length in *ALIGNED_ADDR_P, *ALIGNED_OFFSET_P
    167  1.1.1.1.4.2  perseant    and *ALIGNED_LEN_P, respectively.  The returned values will be
    168  1.1.1.1.4.2  perseant    valid values to write to the hardware watchpoint value and control
    169  1.1.1.1.4.2  perseant    registers.
    170  1.1.1.1.4.2  perseant 
    171  1.1.1.1.4.2  perseant    The given watchpoint may get truncated if more than one hardware
    172  1.1.1.1.4.2  perseant    register is needed to cover the watched region.  *NEXT_ADDR_P
    173  1.1.1.1.4.2  perseant    and *NEXT_LEN_P, if non-NULL, will return the address and length
    174  1.1.1.1.4.2  perseant    of the remaining part of the watchpoint (which can be processed
    175  1.1.1.1.4.2  perseant    by calling this routine again to generate another aligned address,
    176  1.1.1.1.4.2  perseant    offset and length tuple.
    177  1.1.1.1.4.2  perseant 
    178  1.1.1.1.4.2  perseant    Essentially, unaligned watchpoint is achieved by minimally
    179  1.1.1.1.4.2  perseant    enlarging the watched area to meet the alignment requirement, and
    180  1.1.1.1.4.2  perseant    if necessary, splitting the watchpoint over several hardware
    181  1.1.1.1.4.2  perseant    watchpoint registers.
    182  1.1.1.1.4.2  perseant 
    183  1.1.1.1.4.2  perseant    On kernels that predate the support for Byte Address Select (BAS)
    184  1.1.1.1.4.2  perseant    in the hardware watchpoint control register, the offset from the
    185  1.1.1.1.4.2  perseant    base address is always zero, and so in that case the trade-off is
    186  1.1.1.1.4.2  perseant    that there will be false-positive hits for the read-type or the
    187  1.1.1.1.4.2  perseant    access-type hardware watchpoints; for the write type, which is more
    188  1.1.1.1.4.2  perseant    commonly used, there will be no such issues, as the higher-level
    189  1.1.1.1.4.2  perseant    breakpoint management in gdb always examines the exact watched
    190  1.1.1.1.4.2  perseant    region for any content change, and transparently resumes a thread
    191  1.1.1.1.4.2  perseant    from a watchpoint trap if there is no change to the watched region.
    192  1.1.1.1.4.2  perseant 
    193  1.1.1.1.4.2  perseant    Another limitation is that because the watched region is enlarged,
    194  1.1.1.1.4.2  perseant    the watchpoint fault address discovered by
    195  1.1.1.1.4.2  perseant    aarch64_stopped_data_address may be outside of the original watched
    196  1.1.1.1.4.2  perseant    region, especially when the triggering instruction is accessing a
    197  1.1.1.1.4.2  perseant    larger region.  When the fault address is not within any known
    198  1.1.1.1.4.2  perseant    range, watchpoints_triggered in gdb will get confused, as the
    199  1.1.1.1.4.2  perseant    higher-level watchpoint management is only aware of original
    200  1.1.1.1.4.2  perseant    watched regions, and will think that some unknown watchpoint has
    201  1.1.1.1.4.2  perseant    been triggered.  To prevent such a case,
    202  1.1.1.1.4.2  perseant    aarch64_stopped_data_address implementations in gdb and gdbserver
    203  1.1.1.1.4.2  perseant    try to match the trapped address with a watched region, and return
    204  1.1.1.1.4.2  perseant    an address within the latter. */
    205  1.1.1.1.4.2  perseant 
    206  1.1.1.1.4.2  perseant static void
    207  1.1.1.1.4.2  perseant aarch64_align_watchpoint (CORE_ADDR addr, int len, CORE_ADDR *aligned_addr_p,
    208  1.1.1.1.4.2  perseant 			  int *aligned_offset_p, int *aligned_len_p,
    209  1.1.1.1.4.2  perseant 			  CORE_ADDR *next_addr_p, int *next_len_p,
    210  1.1.1.1.4.2  perseant 			  CORE_ADDR *next_addr_orig_p)
    211  1.1.1.1.4.2  perseant {
    212  1.1.1.1.4.2  perseant   int aligned_len;
    213  1.1.1.1.4.2  perseant   unsigned int offset, aligned_offset;
    214  1.1.1.1.4.2  perseant   CORE_ADDR aligned_addr;
    215  1.1.1.1.4.2  perseant   const unsigned int alignment = AARCH64_HWP_ALIGNMENT;
    216  1.1.1.1.4.2  perseant   const unsigned int max_wp_len = AARCH64_HWP_MAX_LEN_PER_REG;
    217  1.1.1.1.4.2  perseant 
    218  1.1.1.1.4.2  perseant   /* As assumed by the algorithm.  */
    219  1.1.1.1.4.2  perseant   gdb_assert (alignment == max_wp_len);
    220  1.1.1.1.4.2  perseant 
    221  1.1.1.1.4.2  perseant   if (len <= 0)
    222  1.1.1.1.4.2  perseant     return;
    223  1.1.1.1.4.2  perseant 
    224  1.1.1.1.4.2  perseant   /* The address put into the hardware watchpoint value register must
    225  1.1.1.1.4.2  perseant      be aligned.  */
    226  1.1.1.1.4.2  perseant   offset = addr & (alignment - 1);
    227  1.1.1.1.4.2  perseant   aligned_addr = addr - offset;
    228  1.1.1.1.4.2  perseant   aligned_offset
    229  1.1.1.1.4.2  perseant     = kernel_supports_any_contiguous_range ? addr & (alignment - 1) : 0;
    230  1.1.1.1.4.2  perseant 
    231  1.1.1.1.4.2  perseant   gdb_assert (offset >= 0 && offset < alignment);
    232  1.1.1.1.4.2  perseant   gdb_assert (aligned_addr >= 0 && aligned_addr <= addr);
    233  1.1.1.1.4.2  perseant   gdb_assert (offset + len > 0);
    234  1.1.1.1.4.2  perseant 
    235  1.1.1.1.4.2  perseant   if (offset + len >= max_wp_len)
    236  1.1.1.1.4.2  perseant     {
    237  1.1.1.1.4.2  perseant       /* Need more than one watchpoint register; truncate at the
    238  1.1.1.1.4.2  perseant 	 alignment boundary.  */
    239  1.1.1.1.4.2  perseant       aligned_len
    240  1.1.1.1.4.2  perseant 	= max_wp_len - (kernel_supports_any_contiguous_range ? offset : 0);
    241  1.1.1.1.4.2  perseant       len -= (max_wp_len - offset);
    242  1.1.1.1.4.2  perseant       addr += (max_wp_len - offset);
    243  1.1.1.1.4.2  perseant       gdb_assert ((addr & (alignment - 1)) == 0);
    244  1.1.1.1.4.2  perseant     }
    245  1.1.1.1.4.2  perseant   else
    246  1.1.1.1.4.2  perseant     {
    247  1.1.1.1.4.2  perseant       /* Find the smallest valid length that is large enough to
    248  1.1.1.1.4.2  perseant 	 accommodate this watchpoint.  */
    249  1.1.1.1.4.2  perseant       static const unsigned char
    250  1.1.1.1.4.2  perseant 	aligned_len_array[AARCH64_HWP_MAX_LEN_PER_REG] =
    251  1.1.1.1.4.2  perseant 	{ 1, 2, 4, 4, 8, 8, 8, 8 };
    252  1.1.1.1.4.2  perseant 
    253  1.1.1.1.4.2  perseant       aligned_len = (kernel_supports_any_contiguous_range
    254  1.1.1.1.4.2  perseant 		     ? len : aligned_len_array[offset + len - 1]);
    255  1.1.1.1.4.2  perseant       addr += len;
    256  1.1.1.1.4.2  perseant       len = 0;
    257  1.1.1.1.4.2  perseant     }
    258  1.1.1.1.4.2  perseant 
    259  1.1.1.1.4.2  perseant   if (aligned_addr_p)
    260  1.1.1.1.4.2  perseant     *aligned_addr_p = aligned_addr;
    261  1.1.1.1.4.2  perseant   if (aligned_offset_p)
    262  1.1.1.1.4.2  perseant     *aligned_offset_p = aligned_offset;
    263  1.1.1.1.4.2  perseant   if (aligned_len_p)
    264  1.1.1.1.4.2  perseant     *aligned_len_p = aligned_len;
    265  1.1.1.1.4.2  perseant   if (next_addr_p)
    266  1.1.1.1.4.2  perseant     *next_addr_p = addr;
    267  1.1.1.1.4.2  perseant   if (next_len_p)
    268  1.1.1.1.4.2  perseant     *next_len_p = len;
    269  1.1.1.1.4.2  perseant   if (next_addr_orig_p)
    270  1.1.1.1.4.2  perseant     *next_addr_orig_p = align_down (*next_addr_orig_p + alignment, alignment);
    271  1.1.1.1.4.2  perseant }
    272  1.1.1.1.4.2  perseant 
    273  1.1.1.1.4.2  perseant /* Record the insertion of one breakpoint/watchpoint, as represented
    274  1.1.1.1.4.2  perseant    by ADDR and CTRL, in the process' arch-specific data area *STATE.  */
    275  1.1.1.1.4.2  perseant 
    276  1.1.1.1.4.2  perseant static int
    277  1.1.1.1.4.2  perseant aarch64_dr_state_insert_one_point (ptid_t ptid,
    278  1.1.1.1.4.2  perseant 				   struct aarch64_debug_reg_state *state,
    279  1.1.1.1.4.2  perseant 				   enum target_hw_bp_type type,
    280  1.1.1.1.4.2  perseant 				   CORE_ADDR addr, int offset, int len,
    281  1.1.1.1.4.2  perseant 				   CORE_ADDR addr_orig)
    282  1.1.1.1.4.2  perseant {
    283  1.1.1.1.4.2  perseant   int i, idx, num_regs, is_watchpoint;
    284  1.1.1.1.4.2  perseant   unsigned int ctrl, *dr_ctrl_p, *dr_ref_count;
    285  1.1.1.1.4.2  perseant   CORE_ADDR *dr_addr_p, *dr_addr_orig_p;
    286  1.1.1.1.4.2  perseant 
    287  1.1.1.1.4.2  perseant   /* Set up state pointers.  */
    288  1.1.1.1.4.2  perseant   is_watchpoint = (type != hw_execute);
    289  1.1.1.1.4.2  perseant   gdb_assert (aarch64_point_is_aligned (ptid, is_watchpoint, addr, len));
    290  1.1.1.1.4.2  perseant   if (is_watchpoint)
    291  1.1.1.1.4.2  perseant     {
    292  1.1.1.1.4.2  perseant       num_regs = aarch64_num_wp_regs;
    293  1.1.1.1.4.2  perseant       dr_addr_p = state->dr_addr_wp;
    294  1.1.1.1.4.2  perseant       dr_addr_orig_p = state->dr_addr_orig_wp;
    295  1.1.1.1.4.2  perseant       dr_ctrl_p = state->dr_ctrl_wp;
    296  1.1.1.1.4.2  perseant       dr_ref_count = state->dr_ref_count_wp;
    297  1.1.1.1.4.2  perseant     }
    298  1.1.1.1.4.2  perseant   else
    299  1.1.1.1.4.2  perseant     {
    300  1.1.1.1.4.2  perseant       num_regs = aarch64_num_bp_regs;
    301  1.1.1.1.4.2  perseant       dr_addr_p = state->dr_addr_bp;
    302  1.1.1.1.4.2  perseant       dr_addr_orig_p = nullptr;
    303  1.1.1.1.4.2  perseant       dr_ctrl_p = state->dr_ctrl_bp;
    304  1.1.1.1.4.2  perseant       dr_ref_count = state->dr_ref_count_bp;
    305  1.1.1.1.4.2  perseant     }
    306  1.1.1.1.4.2  perseant 
    307  1.1.1.1.4.2  perseant   ctrl = aarch64_point_encode_ctrl_reg (type, offset, len);
    308  1.1.1.1.4.2  perseant 
    309  1.1.1.1.4.2  perseant   /* Find an existing or free register in our cache.  */
    310  1.1.1.1.4.2  perseant   idx = -1;
    311  1.1.1.1.4.2  perseant   for (i = 0; i < num_regs; ++i)
    312  1.1.1.1.4.2  perseant     {
    313  1.1.1.1.4.2  perseant       if ((dr_ctrl_p[i] & 1) == 0)
    314  1.1.1.1.4.2  perseant 	{
    315  1.1.1.1.4.2  perseant 	  gdb_assert (dr_ref_count[i] == 0);
    316  1.1.1.1.4.2  perseant 	  idx = i;
    317  1.1.1.1.4.2  perseant 	  /* no break; continue hunting for an exising one.  */
    318  1.1.1.1.4.2  perseant 	}
    319  1.1.1.1.4.2  perseant       else if (dr_addr_p[i] == addr
    320  1.1.1.1.4.2  perseant 	       && (dr_addr_orig_p == nullptr || dr_addr_orig_p[i] == addr_orig)
    321  1.1.1.1.4.2  perseant 	       && dr_ctrl_p[i] == ctrl)
    322  1.1.1.1.4.2  perseant 	{
    323  1.1.1.1.4.2  perseant 	  gdb_assert (dr_ref_count[i] != 0);
    324  1.1.1.1.4.2  perseant 	  idx = i;
    325  1.1.1.1.4.2  perseant 	  break;
    326  1.1.1.1.4.2  perseant 	}
    327  1.1.1.1.4.2  perseant     }
    328  1.1.1.1.4.2  perseant 
    329  1.1.1.1.4.2  perseant   /* No space.  */
    330  1.1.1.1.4.2  perseant   if (idx == -1)
    331  1.1.1.1.4.2  perseant     return -1;
    332  1.1.1.1.4.2  perseant 
    333  1.1.1.1.4.2  perseant   /* Update our cache.  */
    334  1.1.1.1.4.2  perseant   if ((dr_ctrl_p[idx] & 1) == 0)
    335  1.1.1.1.4.2  perseant     {
    336  1.1.1.1.4.2  perseant       /* new entry */
    337  1.1.1.1.4.2  perseant       dr_addr_p[idx] = addr;
    338  1.1.1.1.4.2  perseant       if (dr_addr_orig_p != nullptr)
    339  1.1.1.1.4.2  perseant 	dr_addr_orig_p[idx] = addr_orig;
    340  1.1.1.1.4.2  perseant       dr_ctrl_p[idx] = ctrl;
    341  1.1.1.1.4.2  perseant       dr_ref_count[idx] = 1;
    342  1.1.1.1.4.2  perseant       /* Notify the change.  */
    343  1.1.1.1.4.2  perseant       aarch64_notify_debug_reg_change (ptid, is_watchpoint, idx);
    344  1.1.1.1.4.2  perseant     }
    345  1.1.1.1.4.2  perseant   else
    346  1.1.1.1.4.2  perseant     {
    347  1.1.1.1.4.2  perseant       /* existing entry */
    348  1.1.1.1.4.2  perseant       dr_ref_count[idx]++;
    349  1.1.1.1.4.2  perseant     }
    350  1.1.1.1.4.2  perseant 
    351  1.1.1.1.4.2  perseant   return 0;
    352  1.1.1.1.4.2  perseant }
    353  1.1.1.1.4.2  perseant 
    354  1.1.1.1.4.2  perseant /* Record the removal of one breakpoint/watchpoint, as represented by
    355  1.1.1.1.4.2  perseant    ADDR and CTRL, in the process' arch-specific data area *STATE.  */
    356  1.1.1.1.4.2  perseant 
    357  1.1.1.1.4.2  perseant static int
    358  1.1.1.1.4.2  perseant aarch64_dr_state_remove_one_point (ptid_t ptid,
    359  1.1.1.1.4.2  perseant 				   struct aarch64_debug_reg_state *state,
    360  1.1.1.1.4.2  perseant 				   enum target_hw_bp_type type,
    361  1.1.1.1.4.2  perseant 				   CORE_ADDR addr, int offset, int len,
    362  1.1.1.1.4.2  perseant 				   CORE_ADDR addr_orig)
    363  1.1.1.1.4.2  perseant {
    364  1.1.1.1.4.2  perseant   int i, num_regs, is_watchpoint;
    365  1.1.1.1.4.2  perseant   unsigned int ctrl, *dr_ctrl_p, *dr_ref_count;
    366  1.1.1.1.4.2  perseant   CORE_ADDR *dr_addr_p, *dr_addr_orig_p;
    367  1.1.1.1.4.2  perseant 
    368  1.1.1.1.4.2  perseant   /* Set up state pointers.  */
    369  1.1.1.1.4.2  perseant   is_watchpoint = (type != hw_execute);
    370  1.1.1.1.4.2  perseant   if (is_watchpoint)
    371  1.1.1.1.4.2  perseant     {
    372  1.1.1.1.4.2  perseant       num_regs = aarch64_num_wp_regs;
    373  1.1.1.1.4.2  perseant       dr_addr_p = state->dr_addr_wp;
    374  1.1.1.1.4.2  perseant       dr_addr_orig_p = state->dr_addr_orig_wp;
    375  1.1.1.1.4.2  perseant       dr_ctrl_p = state->dr_ctrl_wp;
    376  1.1.1.1.4.2  perseant       dr_ref_count = state->dr_ref_count_wp;
    377  1.1.1.1.4.2  perseant     }
    378  1.1.1.1.4.2  perseant   else
    379  1.1.1.1.4.2  perseant     {
    380  1.1.1.1.4.2  perseant       num_regs = aarch64_num_bp_regs;
    381  1.1.1.1.4.2  perseant       dr_addr_p = state->dr_addr_bp;
    382  1.1.1.1.4.2  perseant       dr_addr_orig_p = nullptr;
    383  1.1.1.1.4.2  perseant       dr_ctrl_p = state->dr_ctrl_bp;
    384  1.1.1.1.4.2  perseant       dr_ref_count = state->dr_ref_count_bp;
    385  1.1.1.1.4.2  perseant     }
    386  1.1.1.1.4.2  perseant 
    387  1.1.1.1.4.2  perseant   ctrl = aarch64_point_encode_ctrl_reg (type, offset, len);
    388  1.1.1.1.4.2  perseant 
    389  1.1.1.1.4.2  perseant   /* Find the entry that matches the ADDR and CTRL.  */
    390  1.1.1.1.4.2  perseant   for (i = 0; i < num_regs; ++i)
    391  1.1.1.1.4.2  perseant     if (dr_addr_p[i] == addr
    392  1.1.1.1.4.2  perseant 	&& (dr_addr_orig_p == nullptr || dr_addr_orig_p[i] == addr_orig)
    393  1.1.1.1.4.2  perseant 	&& dr_ctrl_p[i] == ctrl)
    394  1.1.1.1.4.2  perseant       {
    395  1.1.1.1.4.2  perseant 	gdb_assert (dr_ref_count[i] != 0);
    396  1.1.1.1.4.2  perseant 	break;
    397  1.1.1.1.4.2  perseant       }
    398  1.1.1.1.4.2  perseant 
    399  1.1.1.1.4.2  perseant   /* Not found.  */
    400  1.1.1.1.4.2  perseant   if (i == num_regs)
    401  1.1.1.1.4.2  perseant     return -1;
    402  1.1.1.1.4.2  perseant 
    403  1.1.1.1.4.2  perseant   /* Clear our cache.  */
    404  1.1.1.1.4.2  perseant   if (--dr_ref_count[i] == 0)
    405  1.1.1.1.4.2  perseant     {
    406  1.1.1.1.4.2  perseant       /* Clear the enable bit.  */
    407  1.1.1.1.4.2  perseant       ctrl &= ~1;
    408  1.1.1.1.4.2  perseant       dr_addr_p[i] = 0;
    409  1.1.1.1.4.2  perseant       if (dr_addr_orig_p != nullptr)
    410  1.1.1.1.4.2  perseant 	dr_addr_orig_p[i] = 0;
    411  1.1.1.1.4.2  perseant       dr_ctrl_p[i] = ctrl;
    412  1.1.1.1.4.2  perseant       /* Notify the change.  */
    413  1.1.1.1.4.2  perseant       aarch64_notify_debug_reg_change (ptid, is_watchpoint, i);
    414  1.1.1.1.4.2  perseant     }
    415  1.1.1.1.4.2  perseant 
    416  1.1.1.1.4.2  perseant   return 0;
    417  1.1.1.1.4.2  perseant }
    418  1.1.1.1.4.2  perseant 
    419  1.1.1.1.4.2  perseant int
    420  1.1.1.1.4.2  perseant aarch64_handle_breakpoint (enum target_hw_bp_type type, CORE_ADDR addr,
    421  1.1.1.1.4.2  perseant 			   int len, int is_insert, ptid_t ptid,
    422  1.1.1.1.4.2  perseant 			   struct aarch64_debug_reg_state *state)
    423  1.1.1.1.4.2  perseant {
    424  1.1.1.1.4.2  perseant   if (is_insert)
    425  1.1.1.1.4.2  perseant     {
    426  1.1.1.1.4.2  perseant       /* The hardware breakpoint on AArch64 should always be 4-byte
    427  1.1.1.1.4.2  perseant 	 aligned, but on AArch32, it can be 2-byte aligned.  Note that
    428  1.1.1.1.4.2  perseant 	 we only check the alignment on inserting breakpoint because
    429  1.1.1.1.4.2  perseant 	 aarch64_point_is_aligned needs the inferior_ptid inferior's
    430  1.1.1.1.4.2  perseant 	 regcache to decide whether the inferior is 32-bit or 64-bit.
    431  1.1.1.1.4.2  perseant 	 However when GDB follows the parent process and detach breakpoints
    432  1.1.1.1.4.2  perseant 	 from child process, inferior_ptid is the child ptid, but the
    433  1.1.1.1.4.2  perseant 	 child inferior doesn't exist in GDB's view yet.  */
    434  1.1.1.1.4.2  perseant       if (!aarch64_point_is_aligned (ptid, 0 /* is_watchpoint */ , addr, len))
    435  1.1.1.1.4.2  perseant 	return -1;
    436  1.1.1.1.4.2  perseant 
    437  1.1.1.1.4.2  perseant       return aarch64_dr_state_insert_one_point (ptid, state, type, addr, 0, len,
    438  1.1.1.1.4.2  perseant 						-1);
    439  1.1.1.1.4.2  perseant     }
    440  1.1.1.1.4.2  perseant   else
    441  1.1.1.1.4.2  perseant     return aarch64_dr_state_remove_one_point (ptid, state, type, addr, 0, len,
    442  1.1.1.1.4.2  perseant 					      -1);
    443  1.1.1.1.4.2  perseant }
    444  1.1.1.1.4.2  perseant 
    445  1.1.1.1.4.2  perseant /* This is essentially the same as aarch64_handle_breakpoint, apart
    446  1.1.1.1.4.2  perseant    from that it is an aligned watchpoint to be handled.  */
    447  1.1.1.1.4.2  perseant 
    448  1.1.1.1.4.2  perseant static int
    449  1.1.1.1.4.2  perseant aarch64_handle_aligned_watchpoint (enum target_hw_bp_type type,
    450  1.1.1.1.4.2  perseant 				   CORE_ADDR addr, int len, int is_insert,
    451  1.1.1.1.4.2  perseant 				   ptid_t ptid,
    452  1.1.1.1.4.2  perseant 				   struct aarch64_debug_reg_state *state)
    453  1.1.1.1.4.2  perseant {
    454  1.1.1.1.4.2  perseant   if (is_insert)
    455  1.1.1.1.4.2  perseant     return aarch64_dr_state_insert_one_point (ptid, state, type, addr, 0, len,
    456  1.1.1.1.4.2  perseant 					      addr);
    457  1.1.1.1.4.2  perseant   else
    458  1.1.1.1.4.2  perseant     return aarch64_dr_state_remove_one_point (ptid, state, type, addr, 0, len,
    459  1.1.1.1.4.2  perseant 					      addr);
    460  1.1.1.1.4.2  perseant }
    461  1.1.1.1.4.2  perseant 
    462  1.1.1.1.4.2  perseant /* Insert/remove unaligned watchpoint by calling
    463  1.1.1.1.4.2  perseant    aarch64_align_watchpoint repeatedly until the whole watched region,
    464  1.1.1.1.4.2  perseant    as represented by ADDR and LEN, has been properly aligned and ready
    465  1.1.1.1.4.2  perseant    to be written to one or more hardware watchpoint registers.
    466  1.1.1.1.4.2  perseant    IS_INSERT indicates whether this is an insertion or a deletion.
    467  1.1.1.1.4.2  perseant    Return 0 if succeed.  */
    468  1.1.1.1.4.2  perseant 
    469  1.1.1.1.4.2  perseant static int
    470  1.1.1.1.4.2  perseant aarch64_handle_unaligned_watchpoint (enum target_hw_bp_type type,
    471  1.1.1.1.4.2  perseant 				     CORE_ADDR addr, int len, int is_insert,
    472  1.1.1.1.4.2  perseant 				     ptid_t ptid,
    473  1.1.1.1.4.2  perseant 				     struct aarch64_debug_reg_state *state)
    474  1.1.1.1.4.2  perseant {
    475  1.1.1.1.4.2  perseant   CORE_ADDR addr_orig = addr;
    476  1.1.1.1.4.2  perseant 
    477  1.1.1.1.4.2  perseant   while (len > 0)
    478  1.1.1.1.4.2  perseant     {
    479  1.1.1.1.4.2  perseant       CORE_ADDR aligned_addr;
    480  1.1.1.1.4.2  perseant       int aligned_offset, aligned_len, ret;
    481  1.1.1.1.4.2  perseant       CORE_ADDR addr_orig_next = addr_orig;
    482  1.1.1.1.4.2  perseant 
    483  1.1.1.1.4.2  perseant       aarch64_align_watchpoint (addr, len, &aligned_addr, &aligned_offset,
    484  1.1.1.1.4.2  perseant 				&aligned_len, &addr, &len, &addr_orig_next);
    485  1.1.1.1.4.2  perseant 
    486  1.1.1.1.4.2  perseant       if (is_insert)
    487  1.1.1.1.4.2  perseant 	ret = aarch64_dr_state_insert_one_point (ptid, state, type,
    488  1.1.1.1.4.2  perseant 						 aligned_addr, aligned_offset,
    489  1.1.1.1.4.2  perseant 						 aligned_len, addr_orig);
    490  1.1.1.1.4.2  perseant       else
    491  1.1.1.1.4.2  perseant 	ret = aarch64_dr_state_remove_one_point (ptid, state, type,
    492  1.1.1.1.4.2  perseant 						 aligned_addr, aligned_offset,
    493  1.1.1.1.4.2  perseant 						 aligned_len, addr_orig);
    494  1.1.1.1.4.2  perseant 
    495  1.1.1.1.4.2  perseant       if (show_debug_regs)
    496  1.1.1.1.4.2  perseant 	debug_printf ("handle_unaligned_watchpoint: is_insert: %d\n"
    497  1.1.1.1.4.2  perseant 		      "                             "
    498  1.1.1.1.4.2  perseant 		      "aligned_addr: %s, aligned_len: %d\n"
    499  1.1.1.1.4.2  perseant 		      "                                "
    500  1.1.1.1.4.2  perseant 		      "addr_orig: %s\n"
    501  1.1.1.1.4.2  perseant 		      "                                "
    502  1.1.1.1.4.2  perseant 		      "next_addr: %s,    next_len: %d\n"
    503  1.1.1.1.4.2  perseant 		      "                           "
    504  1.1.1.1.4.2  perseant 		      "addr_orig_next: %s\n",
    505  1.1.1.1.4.2  perseant 		      is_insert, core_addr_to_string_nz (aligned_addr),
    506  1.1.1.1.4.2  perseant 		      aligned_len, core_addr_to_string_nz (addr_orig),
    507  1.1.1.1.4.2  perseant 		      core_addr_to_string_nz (addr), len,
    508  1.1.1.1.4.2  perseant 		      core_addr_to_string_nz (addr_orig_next));
    509  1.1.1.1.4.2  perseant 
    510  1.1.1.1.4.2  perseant       addr_orig = addr_orig_next;
    511  1.1.1.1.4.2  perseant 
    512  1.1.1.1.4.2  perseant       if (ret != 0)
    513  1.1.1.1.4.2  perseant 	return ret;
    514  1.1.1.1.4.2  perseant     }
    515  1.1.1.1.4.2  perseant 
    516  1.1.1.1.4.2  perseant   return 0;
    517  1.1.1.1.4.2  perseant }
    518  1.1.1.1.4.2  perseant 
    519  1.1.1.1.4.2  perseant int
    520  1.1.1.1.4.2  perseant aarch64_handle_watchpoint (enum target_hw_bp_type type, CORE_ADDR addr,
    521  1.1.1.1.4.2  perseant 			   int len, int is_insert, ptid_t ptid,
    522  1.1.1.1.4.2  perseant 			   struct aarch64_debug_reg_state *state)
    523  1.1.1.1.4.2  perseant {
    524  1.1.1.1.4.2  perseant   if (aarch64_point_is_aligned (ptid, 1 /* is_watchpoint */ , addr, len))
    525  1.1.1.1.4.2  perseant     return aarch64_handle_aligned_watchpoint (type, addr, len, is_insert, ptid,
    526  1.1.1.1.4.2  perseant 					      state);
    527  1.1.1.1.4.2  perseant   else
    528  1.1.1.1.4.2  perseant     return aarch64_handle_unaligned_watchpoint (type, addr, len, is_insert,
    529  1.1.1.1.4.2  perseant 						ptid, state);
    530  1.1.1.1.4.2  perseant }
    531  1.1.1.1.4.2  perseant 
    532  1.1.1.1.4.2  perseant /* See nat/aarch64-hw-point.h.  */
    533  1.1.1.1.4.2  perseant 
    534  1.1.1.1.4.2  perseant bool
    535  1.1.1.1.4.2  perseant aarch64_any_set_debug_regs_state (aarch64_debug_reg_state *state,
    536  1.1.1.1.4.2  perseant 				  bool watchpoint)
    537  1.1.1.1.4.2  perseant {
    538  1.1.1.1.4.2  perseant   int count = watchpoint ? aarch64_num_wp_regs : aarch64_num_bp_regs;
    539  1.1.1.1.4.2  perseant   if (count == 0)
    540  1.1.1.1.4.2  perseant     return false;
    541  1.1.1.1.4.2  perseant 
    542  1.1.1.1.4.2  perseant   const CORE_ADDR *addr = watchpoint ? state->dr_addr_wp : state->dr_addr_bp;
    543  1.1.1.1.4.2  perseant   const unsigned int *ctrl = watchpoint ? state->dr_ctrl_wp : state->dr_ctrl_bp;
    544  1.1.1.1.4.2  perseant 
    545  1.1.1.1.4.2  perseant   for (int i = 0; i < count; i++)
    546  1.1.1.1.4.2  perseant     if (addr[i] != 0 || ctrl[i] != 0)
    547  1.1.1.1.4.2  perseant       return true;
    548  1.1.1.1.4.2  perseant 
    549  1.1.1.1.4.2  perseant   return false;
    550  1.1.1.1.4.2  perseant }
    551  1.1.1.1.4.2  perseant 
    552  1.1.1.1.4.2  perseant /* Print the values of the cached breakpoint/watchpoint registers.  */
    553  1.1.1.1.4.2  perseant 
    554  1.1.1.1.4.2  perseant void
    555  1.1.1.1.4.2  perseant aarch64_show_debug_reg_state (struct aarch64_debug_reg_state *state,
    556  1.1.1.1.4.2  perseant 			      const char *func, CORE_ADDR addr,
    557  1.1.1.1.4.2  perseant 			      int len, enum target_hw_bp_type type)
    558  1.1.1.1.4.2  perseant {
    559  1.1.1.1.4.2  perseant   int i;
    560  1.1.1.1.4.2  perseant 
    561  1.1.1.1.4.2  perseant   debug_printf ("%s", func);
    562  1.1.1.1.4.2  perseant   if (addr || len)
    563  1.1.1.1.4.2  perseant     debug_printf (" (addr=0x%08lx, len=%d, type=%s)",
    564  1.1.1.1.4.2  perseant 		  (unsigned long) addr, len,
    565  1.1.1.1.4.2  perseant 		  type == hw_write ? "hw-write-watchpoint"
    566  1.1.1.1.4.2  perseant 		  : (type == hw_read ? "hw-read-watchpoint"
    567  1.1.1.1.4.2  perseant 		     : (type == hw_access ? "hw-access-watchpoint"
    568  1.1.1.1.4.2  perseant 			: (type == hw_execute ? "hw-breakpoint"
    569  1.1.1.1.4.2  perseant 			   : "??unknown??"))));
    570  1.1.1.1.4.2  perseant   debug_printf (":\n");
    571  1.1.1.1.4.2  perseant 
    572  1.1.1.1.4.2  perseant   debug_printf ("\tBREAKPOINTs:\n");
    573  1.1.1.1.4.2  perseant   for (i = 0; i < aarch64_num_bp_regs; i++)
    574  1.1.1.1.4.2  perseant     debug_printf ("\tBP%d: addr=%s, ctrl=0x%08x, ref.count=%d\n",
    575  1.1.1.1.4.2  perseant 		  i, core_addr_to_string_nz (state->dr_addr_bp[i]),
    576  1.1.1.1.4.2  perseant 		  state->dr_ctrl_bp[i], state->dr_ref_count_bp[i]);
    577  1.1.1.1.4.2  perseant 
    578  1.1.1.1.4.2  perseant   debug_printf ("\tWATCHPOINTs:\n");
    579  1.1.1.1.4.2  perseant   for (i = 0; i < aarch64_num_wp_regs; i++)
    580  1.1.1.1.4.2  perseant     debug_printf ("\tWP%d: addr=%s (orig=%s), ctrl=0x%08x, ref.count=%d\n",
    581  1.1.1.1.4.2  perseant 		  i, core_addr_to_string_nz (state->dr_addr_wp[i]),
    582  1.1.1.1.4.2  perseant 		  core_addr_to_string_nz (state->dr_addr_orig_wp[i]),
    583  1.1.1.1.4.2  perseant 		  state->dr_ctrl_wp[i], state->dr_ref_count_wp[i]);
    584  1.1.1.1.4.2  perseant }
    585  1.1.1.1.4.2  perseant 
    586  1.1.1.1.4.2  perseant /* Return true if we can watch a memory region that starts address
    587  1.1.1.1.4.2  perseant    ADDR and whose length is LEN in bytes.  */
    588  1.1.1.1.4.2  perseant 
    589  1.1.1.1.4.2  perseant int
    590  1.1.1.1.4.2  perseant aarch64_region_ok_for_watchpoint (CORE_ADDR addr, int len)
    591  1.1.1.1.4.2  perseant {
    592  1.1.1.1.4.2  perseant   CORE_ADDR aligned_addr;
    593  1.1.1.1.4.2  perseant 
    594  1.1.1.1.4.2  perseant   /* Can not set watchpoints for zero or negative lengths.  */
    595  1.1.1.1.4.2  perseant   if (len <= 0)
    596  1.1.1.1.4.2  perseant     return 0;
    597  1.1.1.1.4.2  perseant 
    598  1.1.1.1.4.2  perseant   /* Must have hardware watchpoint debug register(s).  */
    599  1.1.1.1.4.2  perseant   if (aarch64_num_wp_regs == 0)
    600  1.1.1.1.4.2  perseant     return 0;
    601  1.1.1.1.4.2  perseant 
    602  1.1.1.1.4.2  perseant   /* We support unaligned watchpoint address and arbitrary length,
    603  1.1.1.1.4.2  perseant      as long as the size of the whole watched area after alignment
    604  1.1.1.1.4.2  perseant      doesn't exceed size of the total area that all watchpoint debug
    605  1.1.1.1.4.2  perseant      registers can watch cooperatively.
    606  1.1.1.1.4.2  perseant 
    607  1.1.1.1.4.2  perseant      This is a very relaxed rule, but unfortunately there are
    608  1.1.1.1.4.2  perseant      limitations, e.g. false-positive hits, due to limited support of
    609  1.1.1.1.4.2  perseant      hardware debug registers in the kernel.  See comment above
    610  1.1.1.1.4.2  perseant      aarch64_align_watchpoint for more information.  */
    611  1.1.1.1.4.2  perseant 
    612  1.1.1.1.4.2  perseant   aligned_addr = addr & ~(AARCH64_HWP_MAX_LEN_PER_REG - 1);
    613  1.1.1.1.4.2  perseant   if (aligned_addr + aarch64_num_wp_regs * AARCH64_HWP_MAX_LEN_PER_REG
    614  1.1.1.1.4.2  perseant       < addr + len)
    615  1.1.1.1.4.2  perseant     return 0;
    616  1.1.1.1.4.2  perseant 
    617  1.1.1.1.4.2  perseant   /* All tests passed so we are likely to be able to set the watchpoint.
    618  1.1.1.1.4.2  perseant      The reason that it is 'likely' rather than 'must' is because
    619  1.1.1.1.4.2  perseant      we don't check the current usage of the watchpoint registers, and
    620  1.1.1.1.4.2  perseant      there may not be enough registers available for this watchpoint.
    621  1.1.1.1.4.2  perseant      Ideally we should check the cached debug register state, however
    622  1.1.1.1.4.2  perseant      the checking is costly.  */
    623  1.1.1.1.4.2  perseant   return 1;
    624  1.1.1.1.4.2  perseant }
    625