| 1 | /* Copyright (C) 2009-2015 Free Software Foundation, Inc. |
| 2 | Contributed by ARM Ltd. |
| 3 | |
| 4 | This file is part of GDB. |
| 5 | |
| 6 | This program is free software; you can redistribute it and/or modify |
| 7 | it under the terms of the GNU General Public License as published by |
| 8 | the Free Software Foundation; either version 3 of the License, or |
| 9 | (at your option) any later version. |
| 10 | |
| 11 | This program is distributed in the hope that it will be useful, |
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | GNU General Public License for more details. |
| 15 | |
| 16 | You should have received a copy of the GNU General Public License |
| 17 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| 18 | |
| 19 | #ifndef AARCH64_LINUX_HW_POINT_H |
| 20 | #define AARCH64_LINUX_HW_POINT_H 1 |
| 21 | |
| 22 | /* Macro definitions, data structures, and code for the hardware |
| 23 | breakpoint and hardware watchpoint support follow. We use the |
| 24 | following abbreviations throughout the code: |
| 25 | |
| 26 | hw - hardware |
| 27 | bp - breakpoint |
| 28 | wp - watchpoint */ |
| 29 | |
| 30 | /* Maximum number of hardware breakpoint and watchpoint registers. |
| 31 | Neither of these values may exceed the width of dr_changed_t |
| 32 | measured in bits. */ |
| 33 | |
| 34 | #define AARCH64_HBP_MAX_NUM 16 |
| 35 | #define AARCH64_HWP_MAX_NUM 16 |
| 36 | |
| 37 | /* Alignment requirement in bytes for addresses written to |
| 38 | hardware breakpoint and watchpoint value registers. |
| 39 | |
| 40 | A ptrace call attempting to set an address that does not meet the |
| 41 | alignment criteria will fail. Limited support has been provided in |
| 42 | this port for unaligned watchpoints, such that from a GDB user |
| 43 | perspective, an unaligned watchpoint may be requested. |
| 44 | |
| 45 | This is achieved by minimally enlarging the watched area to meet the |
| 46 | alignment requirement, and if necessary, splitting the watchpoint |
| 47 | over several hardware watchpoint registers. */ |
| 48 | |
| 49 | #define AARCH64_HBP_ALIGNMENT 4 |
| 50 | #define AARCH64_HWP_ALIGNMENT 8 |
| 51 | |
| 52 | /* The maximum length of a memory region that can be watched by one |
| 53 | hardware watchpoint register. */ |
| 54 | |
| 55 | #define AARCH64_HWP_MAX_LEN_PER_REG 8 |
| 56 | |
| 57 | /* ptrace hardware breakpoint resource info is formatted as follows: |
| 58 | |
| 59 | 31 24 16 8 0 |
| 60 | +---------------+--------------+---------------+---------------+ |
| 61 | | RESERVED | RESERVED | DEBUG_ARCH | NUM_SLOTS | |
| 62 | +---------------+--------------+---------------+---------------+ */ |
| 63 | |
| 64 | |
| 65 | /* Macros to extract fields from the hardware debug information word. */ |
| 66 | #define AARCH64_DEBUG_NUM_SLOTS(x) ((x) & 0xff) |
| 67 | #define AARCH64_DEBUG_ARCH(x) (((x) >> 8) & 0xff) |
| 68 | |
| 69 | /* Macro for the expected version of the ARMv8-A debug architecture. */ |
| 70 | #define AARCH64_DEBUG_ARCH_V8 0x6 |
| 71 | |
| 72 | /* ptrace expects control registers to be formatted as follows: |
| 73 | |
| 74 | 31 13 5 3 1 0 |
| 75 | +--------------------------------+----------+------+------+----+ |
| 76 | | RESERVED (SBZ) | LENGTH | TYPE | PRIV | EN | |
| 77 | +--------------------------------+----------+------+------+----+ |
| 78 | |
| 79 | The TYPE field is ignored for breakpoints. */ |
| 80 | |
| 81 | #define DR_CONTROL_ENABLED(ctrl) (((ctrl) & 0x1) == 1) |
| 82 | #define DR_CONTROL_LENGTH(ctrl) (((ctrl) >> 5) & 0xff) |
| 83 | |
| 84 | /* Each bit of a variable of this type is used to indicate whether a |
| 85 | hardware breakpoint or watchpoint setting has been changed since |
| 86 | the last update. |
| 87 | |
| 88 | Bit N corresponds to the Nth hardware breakpoint or watchpoint |
| 89 | setting which is managed in aarch64_debug_reg_state, where N is |
| 90 | valid between 0 and the total number of the hardware breakpoint or |
| 91 | watchpoint debug registers minus 1. |
| 92 | |
| 93 | When bit N is 1, the corresponding breakpoint or watchpoint setting |
| 94 | has changed, and therefore the corresponding hardware debug |
| 95 | register needs to be updated via the ptrace interface. |
| 96 | |
| 97 | In the per-thread arch-specific data area, we define two such |
| 98 | variables for per-thread hardware breakpoint and watchpoint |
| 99 | settings respectively. |
| 100 | |
| 101 | This type is part of the mechanism which helps reduce the number of |
| 102 | ptrace calls to the kernel, i.e. avoid asking the kernel to write |
| 103 | to the debug registers with unchanged values. */ |
| 104 | |
| 105 | typedef ULONGEST dr_changed_t; |
| 106 | |
| 107 | /* Set each of the lower M bits of X to 1; assert X is wide enough. */ |
| 108 | |
| 109 | #define DR_MARK_ALL_CHANGED(x, m) \ |
| 110 | do \ |
| 111 | { \ |
| 112 | gdb_assert (sizeof ((x)) * 8 >= (m)); \ |
| 113 | (x) = (((dr_changed_t)1 << (m)) - 1); \ |
| 114 | } while (0) |
| 115 | |
| 116 | #define DR_MARK_N_CHANGED(x, n) \ |
| 117 | do \ |
| 118 | { \ |
| 119 | (x) |= ((dr_changed_t)1 << (n)); \ |
| 120 | } while (0) |
| 121 | |
| 122 | #define DR_CLEAR_CHANGED(x) \ |
| 123 | do \ |
| 124 | { \ |
| 125 | (x) = 0; \ |
| 126 | } while (0) |
| 127 | |
| 128 | #define DR_HAS_CHANGED(x) ((x) != 0) |
| 129 | #define DR_N_HAS_CHANGED(x, n) ((x) & ((dr_changed_t)1 << (n))) |
| 130 | |
| 131 | /* Structure for managing the hardware breakpoint/watchpoint resources. |
| 132 | DR_ADDR_* stores the address, DR_CTRL_* stores the control register |
| 133 | content, and DR_REF_COUNT_* counts the numbers of references to the |
| 134 | corresponding bp/wp, by which way the limited hardware resources |
| 135 | are not wasted on duplicated bp/wp settings (though so far gdb has |
| 136 | done a good job by not sending duplicated bp/wp requests). */ |
| 137 | |
| 138 | struct aarch64_debug_reg_state |
| 139 | { |
| 140 | /* hardware breakpoint */ |
| 141 | CORE_ADDR dr_addr_bp[AARCH64_HBP_MAX_NUM]; |
| 142 | unsigned int dr_ctrl_bp[AARCH64_HBP_MAX_NUM]; |
| 143 | unsigned int dr_ref_count_bp[AARCH64_HBP_MAX_NUM]; |
| 144 | |
| 145 | /* hardware watchpoint */ |
| 146 | CORE_ADDR dr_addr_wp[AARCH64_HWP_MAX_NUM]; |
| 147 | unsigned int dr_ctrl_wp[AARCH64_HWP_MAX_NUM]; |
| 148 | unsigned int dr_ref_count_wp[AARCH64_HWP_MAX_NUM]; |
| 149 | }; |
| 150 | |
| 151 | /* Per-thread arch-specific data we want to keep. */ |
| 152 | |
| 153 | struct arch_lwp_info |
| 154 | { |
| 155 | /* When bit N is 1, it indicates the Nth hardware breakpoint or |
| 156 | watchpoint register pair needs to be updated when the thread is |
| 157 | resumed; see aarch64_linux_prepare_to_resume. */ |
| 158 | dr_changed_t dr_changed_bp; |
| 159 | dr_changed_t dr_changed_wp; |
| 160 | }; |
| 161 | |
| 162 | extern int aarch64_num_bp_regs; |
| 163 | extern int aarch64_num_wp_regs; |
| 164 | |
| 165 | unsigned int aarch64_watchpoint_length (unsigned int ctrl); |
| 166 | |
| 167 | int aarch64_handle_breakpoint (enum target_hw_bp_type type, CORE_ADDR addr, |
| 168 | int len, int is_insert, |
| 169 | struct aarch64_debug_reg_state *state); |
| 170 | int aarch64_handle_watchpoint (enum target_hw_bp_type type, CORE_ADDR addr, |
| 171 | int len, int is_insert, |
| 172 | struct aarch64_debug_reg_state *state); |
| 173 | |
| 174 | void aarch64_linux_set_debug_regs (const struct aarch64_debug_reg_state *state, |
| 175 | int tid, int watchpoint); |
| 176 | |
| 177 | void aarch64_show_debug_reg_state (struct aarch64_debug_reg_state *state, |
| 178 | const char *func, CORE_ADDR addr, |
| 179 | int len, enum target_hw_bp_type type); |
| 180 | |
| 181 | void aarch64_linux_get_debug_reg_capacity (int tid); |
| 182 | |
| 183 | #endif /* AARCH64_LINUX_HW_POINT_H */ |