GDB (API)
|
00001 /* Copyright (C) 2009-2013 Free Software Foundation, Inc. 00002 00003 This file is part of GDB. 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 3 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00017 00018 #include <sys/ptrace.h> 00019 #include "mips-linux-watch.h" 00020 #include "gdb_assert.h" 00021 00022 /* Assuming usable watch registers REGS, return the irw_mask of 00023 register N. */ 00024 00025 uint32_t 00026 mips_linux_watch_get_irw_mask (struct pt_watch_regs *regs, int n) 00027 { 00028 switch (regs->style) 00029 { 00030 case pt_watch_style_mips32: 00031 return regs->mips32.watch_masks[n] & IRW_MASK; 00032 case pt_watch_style_mips64: 00033 return regs->mips64.watch_masks[n] & IRW_MASK; 00034 default: 00035 internal_error (__FILE__, __LINE__, 00036 _("Unrecognized watch register style")); 00037 } 00038 } 00039 00040 /* Assuming usable watch registers REGS, return the reg_mask of 00041 register N. */ 00042 00043 static uint32_t 00044 get_reg_mask (struct pt_watch_regs *regs, int n) 00045 { 00046 switch (regs->style) 00047 { 00048 case pt_watch_style_mips32: 00049 return regs->mips32.watch_masks[n] & ~IRW_MASK; 00050 case pt_watch_style_mips64: 00051 return regs->mips64.watch_masks[n] & ~IRW_MASK; 00052 default: 00053 internal_error (__FILE__, __LINE__, 00054 _("Unrecognized watch register style")); 00055 } 00056 } 00057 00058 /* Assuming usable watch registers REGS, return the num_valid. */ 00059 00060 uint32_t 00061 mips_linux_watch_get_num_valid (struct pt_watch_regs *regs) 00062 { 00063 switch (regs->style) 00064 { 00065 case pt_watch_style_mips32: 00066 return regs->mips32.num_valid; 00067 case pt_watch_style_mips64: 00068 return regs->mips64.num_valid; 00069 default: 00070 internal_error (__FILE__, __LINE__, 00071 _("Unrecognized watch register style")); 00072 } 00073 } 00074 00075 /* Assuming usable watch registers REGS, return the watchlo of 00076 register N. */ 00077 00078 CORE_ADDR 00079 mips_linux_watch_get_watchlo (struct pt_watch_regs *regs, int n) 00080 { 00081 switch (regs->style) 00082 { 00083 case pt_watch_style_mips32: 00084 return regs->mips32.watchlo[n]; 00085 case pt_watch_style_mips64: 00086 return regs->mips64.watchlo[n]; 00087 default: 00088 internal_error (__FILE__, __LINE__, 00089 _("Unrecognized watch register style")); 00090 } 00091 } 00092 00093 /* Assuming usable watch registers REGS, set watchlo of register N to 00094 VALUE. */ 00095 00096 void 00097 mips_linux_watch_set_watchlo (struct pt_watch_regs *regs, int n, 00098 CORE_ADDR value) 00099 { 00100 switch (regs->style) 00101 { 00102 case pt_watch_style_mips32: 00103 /* The cast will never throw away bits as 64 bit addresses can 00104 never be used on a 32 bit kernel. */ 00105 regs->mips32.watchlo[n] = (uint32_t) value; 00106 break; 00107 case pt_watch_style_mips64: 00108 regs->mips64.watchlo[n] = value; 00109 break; 00110 default: 00111 internal_error (__FILE__, __LINE__, 00112 _("Unrecognized watch register style")); 00113 } 00114 } 00115 00116 /* Assuming usable watch registers REGS, return the watchhi of 00117 register N. */ 00118 00119 uint32_t 00120 mips_linux_watch_get_watchhi (struct pt_watch_regs *regs, int n) 00121 { 00122 switch (regs->style) 00123 { 00124 case pt_watch_style_mips32: 00125 return regs->mips32.watchhi[n]; 00126 case pt_watch_style_mips64: 00127 return regs->mips64.watchhi[n]; 00128 default: 00129 internal_error (__FILE__, __LINE__, 00130 _("Unrecognized watch register style")); 00131 } 00132 } 00133 00134 /* Assuming usable watch registers REGS, set watchhi of register N to 00135 VALUE. */ 00136 00137 void 00138 mips_linux_watch_set_watchhi (struct pt_watch_regs *regs, int n, 00139 uint16_t value) 00140 { 00141 switch (regs->style) 00142 { 00143 case pt_watch_style_mips32: 00144 regs->mips32.watchhi[n] = value; 00145 break; 00146 case pt_watch_style_mips64: 00147 regs->mips64.watchhi[n] = value; 00148 break; 00149 default: 00150 internal_error (__FILE__, __LINE__, 00151 _("Unrecognized watch register style")); 00152 } 00153 } 00154 00155 /* Read the watch registers of process LWPID and store it in 00156 WATCH_READBACK. Save true to *WATCH_READBACK_VALID if watch 00157 registers are valid. Return 1 if watch registers are usable. 00158 Cached information is used unless FORCE is true. */ 00159 00160 int 00161 mips_linux_read_watch_registers (long lwpid, 00162 struct pt_watch_regs *watch_readback, 00163 int *watch_readback_valid, int force) 00164 { 00165 if (force || *watch_readback_valid == 0) 00166 { 00167 if (ptrace (PTRACE_GET_WATCH_REGS, lwpid, watch_readback) == -1) 00168 { 00169 *watch_readback_valid = -1; 00170 return 0; 00171 } 00172 switch (watch_readback->style) 00173 { 00174 case pt_watch_style_mips32: 00175 if (watch_readback->mips32.num_valid == 0) 00176 { 00177 *watch_readback_valid = -1; 00178 return 0; 00179 } 00180 break; 00181 case pt_watch_style_mips64: 00182 if (watch_readback->mips64.num_valid == 0) 00183 { 00184 *watch_readback_valid = -1; 00185 return 0; 00186 } 00187 break; 00188 default: 00189 *watch_readback_valid = -1; 00190 return 0; 00191 } 00192 /* Watch registers appear to be usable. */ 00193 *watch_readback_valid = 1; 00194 } 00195 return (*watch_readback_valid == 1) ? 1 : 0; 00196 } 00197 00198 /* Convert GDB's TYPE to an IRW mask. */ 00199 00200 uint32_t 00201 mips_linux_watch_type_to_irw (int type) 00202 { 00203 switch (type) 00204 { 00205 case hw_write: 00206 return W_MASK; 00207 case hw_read: 00208 return R_MASK; 00209 case hw_access: 00210 return (W_MASK | R_MASK); 00211 default: 00212 return 0; 00213 } 00214 } 00215 00216 /* Set any low order bits in MASK that are not set. */ 00217 00218 static CORE_ADDR 00219 fill_mask (CORE_ADDR mask) 00220 { 00221 CORE_ADDR f = 1; 00222 00223 while (f && f < mask) 00224 { 00225 mask |= f; 00226 f <<= 1; 00227 } 00228 return mask; 00229 } 00230 00231 /* Try to add a single watch to the specified registers REGS. The 00232 address of added watch is ADDR, the length is LEN, and the mask 00233 is IRW. Return 1 on success, 0 on failure. */ 00234 00235 int 00236 mips_linux_watch_try_one_watch (struct pt_watch_regs *regs, 00237 CORE_ADDR addr, int len, uint32_t irw) 00238 { 00239 CORE_ADDR base_addr, last_byte, break_addr, segment_len; 00240 CORE_ADDR mask_bits, t_low; 00241 uint16_t t_hi; 00242 int i, free_watches; 00243 struct pt_watch_regs regs_copy; 00244 00245 if (len <= 0) 00246 return 0; 00247 00248 last_byte = addr + len - 1; 00249 mask_bits = fill_mask (addr ^ last_byte) | IRW_MASK; 00250 base_addr = addr & ~mask_bits; 00251 00252 /* Check to see if it is covered by current registers. */ 00253 for (i = 0; i < mips_linux_watch_get_num_valid (regs); i++) 00254 { 00255 t_low = mips_linux_watch_get_watchlo (regs, i); 00256 if (t_low != 0 && irw == ((uint32_t) t_low & irw)) 00257 { 00258 t_hi = mips_linux_watch_get_watchhi (regs, i) | IRW_MASK; 00259 t_low &= ~(CORE_ADDR) t_hi; 00260 if (addr >= t_low && last_byte <= (t_low + t_hi)) 00261 return 1; 00262 } 00263 } 00264 /* Try to find an empty register. */ 00265 free_watches = 0; 00266 for (i = 0; i < mips_linux_watch_get_num_valid (regs); i++) 00267 { 00268 t_low = mips_linux_watch_get_watchlo (regs, i); 00269 if (t_low == 0 00270 && irw == (mips_linux_watch_get_irw_mask (regs, i) & irw)) 00271 { 00272 if (mask_bits <= (get_reg_mask (regs, i) | IRW_MASK)) 00273 { 00274 /* It fits, we'll take it. */ 00275 mips_linux_watch_set_watchlo (regs, i, base_addr | irw); 00276 mips_linux_watch_set_watchhi (regs, i, mask_bits & ~IRW_MASK); 00277 return 1; 00278 } 00279 else 00280 { 00281 /* It doesn't fit, but has the proper IRW capabilities. */ 00282 free_watches++; 00283 } 00284 } 00285 } 00286 if (free_watches > 1) 00287 { 00288 /* Try to split it across several registers. */ 00289 regs_copy = *regs; 00290 for (i = 0; i < mips_linux_watch_get_num_valid (®s_copy); i++) 00291 { 00292 t_low = mips_linux_watch_get_watchlo (®s_copy, i); 00293 t_hi = get_reg_mask (®s_copy, i) | IRW_MASK; 00294 if (t_low == 0 && irw == (t_hi & irw)) 00295 { 00296 t_low = addr & ~(CORE_ADDR) t_hi; 00297 break_addr = t_low + t_hi + 1; 00298 if (break_addr >= addr + len) 00299 segment_len = len; 00300 else 00301 segment_len = break_addr - addr; 00302 mask_bits = fill_mask (addr ^ (addr + segment_len - 1)); 00303 mips_linux_watch_set_watchlo (®s_copy, i, 00304 (addr & ~mask_bits) | irw); 00305 mips_linux_watch_set_watchhi (®s_copy, i, 00306 mask_bits & ~IRW_MASK); 00307 if (break_addr >= addr + len) 00308 { 00309 *regs = regs_copy; 00310 return 1; 00311 } 00312 len = addr + len - break_addr; 00313 addr = break_addr; 00314 } 00315 } 00316 } 00317 /* It didn't fit anywhere, we failed. */ 00318 return 0; 00319 } 00320 00321 /* Fill in the watch registers REGS with the currently cached 00322 watches CURRENT_WATCHES. */ 00323 00324 void 00325 mips_linux_watch_populate_regs (struct mips_watchpoint *current_watches, 00326 struct pt_watch_regs *regs) 00327 { 00328 struct mips_watchpoint *w; 00329 int i; 00330 00331 /* Clear them out. */ 00332 for (i = 0; i < mips_linux_watch_get_num_valid (regs); i++) 00333 { 00334 mips_linux_watch_set_watchlo (regs, i, 0); 00335 mips_linux_watch_set_watchhi (regs, i, 0); 00336 } 00337 00338 w = current_watches; 00339 while (w) 00340 { 00341 uint32_t irw = mips_linux_watch_type_to_irw (w->type); 00342 00343 i = mips_linux_watch_try_one_watch (regs, w->addr, w->len, irw); 00344 /* They must all fit, because we previously calculated that they 00345 would. */ 00346 gdb_assert (i); 00347 w = w->next; 00348 } 00349 }