1/* Copyright (C) 2009-2020 Free Software Foundation, Inc. 2 3 This file is part of GDB. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 18#include "gdbsupport/common-defs.h" 19#include "nat/gdb_ptrace.h" 20#include "mips-linux-watch.h" 21 22/* Assuming usable watch registers REGS, return the irw_mask of 23 register N. */ 24 25uint32_t 26mips_linux_watch_get_irw_mask (struct pt_watch_regs *regs, int n) 27{ 28 switch (regs->style) 29 { 30 case pt_watch_style_mips32: 31 return regs->mips32.watch_masks[n] & IRW_MASK; 32 case pt_watch_style_mips64: 33 return regs->mips64.watch_masks[n] & IRW_MASK; 34 default: 35 internal_error (__FILE__, __LINE__, 36 _("Unrecognized watch register style")); 37 } 38} 39 40/* Assuming usable watch registers REGS, return the reg_mask of 41 register N. */ 42 43static uint32_t 44get_reg_mask (struct pt_watch_regs *regs, int n) 45{ 46 switch (regs->style) 47 { 48 case pt_watch_style_mips32: 49 return regs->mips32.watch_masks[n] & ~IRW_MASK; 50 case pt_watch_style_mips64: 51 return regs->mips64.watch_masks[n] & ~IRW_MASK; 52 default: 53 internal_error (__FILE__, __LINE__, 54 _("Unrecognized watch register style")); 55 } 56} 57 58/* Assuming usable watch registers REGS, return the num_valid. */ 59 60uint32_t 61mips_linux_watch_get_num_valid (struct pt_watch_regs *regs) 62{ 63 switch (regs->style) 64 { 65 case pt_watch_style_mips32: 66 return regs->mips32.num_valid; 67 case pt_watch_style_mips64: 68 return regs->mips64.num_valid; 69 default: 70 internal_error (__FILE__, __LINE__, 71 _("Unrecognized watch register style")); 72 } 73} 74 75/* Assuming usable watch registers REGS, return the watchlo of 76 register N. */ 77 78CORE_ADDR 79mips_linux_watch_get_watchlo (struct pt_watch_regs *regs, int n) 80{ 81 switch (regs->style) 82 { 83 case pt_watch_style_mips32: 84 return regs->mips32.watchlo[n]; 85 case pt_watch_style_mips64: 86 return regs->mips64.watchlo[n]; 87 default: 88 internal_error (__FILE__, __LINE__, 89 _("Unrecognized watch register style")); 90 } 91} 92 93/* Assuming usable watch registers REGS, set watchlo of register N to 94 VALUE. */ 95 96void 97mips_linux_watch_set_watchlo (struct pt_watch_regs *regs, int n, 98 CORE_ADDR value) 99{ 100 switch (regs->style) 101 { 102 case pt_watch_style_mips32: 103 /* The cast will never throw away bits as 64 bit addresses can 104 never be used on a 32 bit kernel. */ 105 regs->mips32.watchlo[n] = (uint32_t) value; 106 break; 107 case pt_watch_style_mips64: 108 regs->mips64.watchlo[n] = value; 109 break; 110 default: 111 internal_error (__FILE__, __LINE__, 112 _("Unrecognized watch register style")); 113 } 114} 115 116/* Assuming usable watch registers REGS, return the watchhi of 117 register N. */ 118 119uint32_t 120mips_linux_watch_get_watchhi (struct pt_watch_regs *regs, int n) 121{ 122 switch (regs->style) 123 { 124 case pt_watch_style_mips32: 125 return regs->mips32.watchhi[n]; 126 case pt_watch_style_mips64: 127 return regs->mips64.watchhi[n]; 128 default: 129 internal_error (__FILE__, __LINE__, 130 _("Unrecognized watch register style")); 131 } 132} 133 134/* Assuming usable watch registers REGS, set watchhi of register N to 135 VALUE. */ 136 137void 138mips_linux_watch_set_watchhi (struct pt_watch_regs *regs, int n, 139 uint16_t value) 140{ 141 switch (regs->style) 142 { 143 case pt_watch_style_mips32: 144 regs->mips32.watchhi[n] = value; 145 break; 146 case pt_watch_style_mips64: 147 regs->mips64.watchhi[n] = value; 148 break; 149 default: 150 internal_error (__FILE__, __LINE__, 151 _("Unrecognized watch register style")); 152 } 153} 154 155/* Read the watch registers of process LWPID and store it in 156 WATCH_READBACK. Save true to *WATCH_READBACK_VALID if watch 157 registers are valid. Return 1 if watch registers are usable. 158 Cached information is used unless FORCE is true. */ 159 160int 161mips_linux_read_watch_registers (long lwpid, 162 struct pt_watch_regs *watch_readback, 163 int *watch_readback_valid, int force) 164{ 165 if (force || *watch_readback_valid == 0) 166 { 167 if (ptrace (PTRACE_GET_WATCH_REGS, lwpid, watch_readback, NULL) == -1) 168 { 169 *watch_readback_valid = -1; 170 return 0; 171 } 172 switch (watch_readback->style) 173 { 174 case pt_watch_style_mips32: 175 if (watch_readback->mips32.num_valid == 0) 176 { 177 *watch_readback_valid = -1; 178 return 0; 179 } 180 break; 181 case pt_watch_style_mips64: 182 if (watch_readback->mips64.num_valid == 0) 183 { 184 *watch_readback_valid = -1; 185 return 0; 186 } 187 break; 188 default: 189 *watch_readback_valid = -1; 190 return 0; 191 } 192 /* Watch registers appear to be usable. */ 193 *watch_readback_valid = 1; 194 } 195 return (*watch_readback_valid == 1) ? 1 : 0; 196} 197 198/* Convert GDB's TYPE to an IRW mask. */ 199 200uint32_t 201mips_linux_watch_type_to_irw (enum target_hw_bp_type type) 202{ 203 switch (type) 204 { 205 case hw_write: 206 return W_MASK; 207 case hw_read: 208 return R_MASK; 209 case hw_access: 210 return (W_MASK | R_MASK); 211 default: 212 return 0; 213 } 214} 215 216/* Set any low order bits in MASK that are not set. */ 217 218static CORE_ADDR 219fill_mask (CORE_ADDR mask) 220{ 221 CORE_ADDR f = 1; 222 223 while (f && f < mask) 224 { 225 mask |= f; 226 f <<= 1; 227 } 228 return mask; 229} 230 231/* Try to add a single watch to the specified registers REGS. The 232 address of added watch is ADDR, the length is LEN, and the mask 233 is IRW. Return 1 on success, 0 on failure. */ 234 235int 236mips_linux_watch_try_one_watch (struct pt_watch_regs *regs, 237 CORE_ADDR addr, int len, uint32_t irw) 238{ 239 CORE_ADDR base_addr, last_byte, break_addr, segment_len; 240 CORE_ADDR mask_bits, t_low; 241 uint16_t t_hi; 242 int i, free_watches; 243 struct pt_watch_regs regs_copy; 244 245 if (len <= 0) 246 return 0; 247 248 last_byte = addr + len - 1; 249 mask_bits = fill_mask (addr ^ last_byte) | IRW_MASK; 250 base_addr = addr & ~mask_bits; 251 252 /* Check to see if it is covered by current registers. */ 253 for (i = 0; i < mips_linux_watch_get_num_valid (regs); i++) 254 { 255 t_low = mips_linux_watch_get_watchlo (regs, i); 256 if (t_low != 0 && irw == ((uint32_t) t_low & irw)) 257 { 258 t_hi = mips_linux_watch_get_watchhi (regs, i) | IRW_MASK; 259 t_low &= ~(CORE_ADDR) t_hi; 260 if (addr >= t_low && last_byte <= (t_low + t_hi)) 261 return 1; 262 } 263 } 264 /* Try to find an empty register. */ 265 free_watches = 0; 266 for (i = 0; i < mips_linux_watch_get_num_valid (regs); i++) 267 { 268 t_low = mips_linux_watch_get_watchlo (regs, i); 269 if (t_low == 0 270 && irw == (mips_linux_watch_get_irw_mask (regs, i) & irw)) 271 { 272 if (mask_bits <= (get_reg_mask (regs, i) | IRW_MASK)) 273 { 274 /* It fits, we'll take it. */ 275 mips_linux_watch_set_watchlo (regs, i, base_addr | irw); 276 mips_linux_watch_set_watchhi (regs, i, mask_bits & ~IRW_MASK); 277 return 1; 278 } 279 else 280 { 281 /* It doesn't fit, but has the proper IRW capabilities. */ 282 free_watches++; 283 } 284 } 285 } 286 if (free_watches > 1) 287 { 288 /* Try to split it across several registers. */ 289 regs_copy = *regs; 290 for (i = 0; i < mips_linux_watch_get_num_valid (®s_copy); i++) 291 { 292 t_low = mips_linux_watch_get_watchlo (®s_copy, i); 293 t_hi = get_reg_mask (®s_copy, i) | IRW_MASK; 294 if (t_low == 0 && irw == (t_hi & irw)) 295 { 296 t_low = addr & ~(CORE_ADDR) t_hi; 297 break_addr = t_low + t_hi + 1; 298 if (break_addr >= addr + len) 299 segment_len = len; 300 else 301 segment_len = break_addr - addr; 302 mask_bits = fill_mask (addr ^ (addr + segment_len - 1)); 303 mips_linux_watch_set_watchlo (®s_copy, i, 304 (addr & ~mask_bits) | irw); 305 mips_linux_watch_set_watchhi (®s_copy, i, 306 mask_bits & ~IRW_MASK); 307 if (break_addr >= addr + len) 308 { 309 *regs = regs_copy; 310 return 1; 311 } 312 len = addr + len - break_addr; 313 addr = break_addr; 314 } 315 } 316 } 317 /* It didn't fit anywhere, we failed. */ 318 return 0; 319} 320 321/* Fill in the watch registers REGS with the currently cached 322 watches CURRENT_WATCHES. */ 323 324void 325mips_linux_watch_populate_regs (struct mips_watchpoint *current_watches, 326 struct pt_watch_regs *regs) 327{ 328 struct mips_watchpoint *w; 329 int i; 330 331 /* Clear them out. */ 332 for (i = 0; i < mips_linux_watch_get_num_valid (regs); i++) 333 { 334 mips_linux_watch_set_watchlo (regs, i, 0); 335 mips_linux_watch_set_watchhi (regs, i, 0); 336 } 337 338 w = current_watches; 339 while (w) 340 { 341 uint32_t irw = mips_linux_watch_type_to_irw (w->type); 342 343 i = mips_linux_watch_try_one_watch (regs, w->addr, w->len, irw); 344 /* They must all fit, because we previously calculated that they 345 would. */ 346 gdb_assert (i); 347 w = w->next; 348 } 349} 350