Commit | Line | Data |
---|---|---|
75c9abc6 | 1 | /* Native-dependent code for GNU/Linux on MIPS processors. |
a094c6fb | 2 | |
0fb0cc75 | 3 | Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 |
dc60ece8 | 4 | Free Software Foundation, Inc. |
2aa830e4 DJ |
5 | |
6 | This file is part of GDB. | |
7 | ||
8 | This program is free software; you can redistribute it and/or modify | |
9 | it under the terms of the GNU General Public License as published by | |
a9762ec7 | 10 | the Free Software Foundation; either version 3 of the License, or |
2aa830e4 DJ |
11 | (at your option) any later version. |
12 | ||
13 | This program is distributed in the hope that it will be useful, | |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
a9762ec7 | 19 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
2aa830e4 DJ |
20 | |
21 | #include "defs.h" | |
b9412953 DD |
22 | #include "command.h" |
23 | #include "gdbcmd.h" | |
24 | #include "gdb_assert.h" | |
d37eb719 | 25 | #include "inferior.h" |
6b753f60 | 26 | #include "mips-tdep.h" |
10d6c8cd | 27 | #include "target.h" |
28f5035f | 28 | #include "regcache.h" |
10d6c8cd | 29 | #include "linux-nat.h" |
d37eb719 | 30 | #include "mips-linux-tdep.h" |
822b6570 | 31 | #include "target-descriptions.h" |
2aa830e4 | 32 | |
dc60ece8 | 33 | #include "gdb_proc_service.h" |
3e00823e | 34 | #include "gregset.h" |
dc60ece8 | 35 | |
822b6570 | 36 | #include <sgidefs.h> |
d37eb719 DJ |
37 | #include <sys/ptrace.h> |
38 | ||
81adfced DJ |
39 | #include "features/mips-linux.c" |
40 | #include "features/mips64-linux.c" | |
41 | ||
dc60ece8 DJ |
42 | #ifndef PTRACE_GET_THREAD_AREA |
43 | #define PTRACE_GET_THREAD_AREA 25 | |
44 | #endif | |
45 | ||
d37eb719 DJ |
46 | /* Assume that we have PTRACE_GETREGS et al. support. If we do not, |
47 | we'll clear this and use PTRACE_PEEKUSER instead. */ | |
48 | static int have_ptrace_regsets = 1; | |
49 | ||
b9412953 DD |
50 | /* Whether or not to print the mirrored debug registers. */ |
51 | ||
52 | static int maint_show_dr; | |
53 | ||
d37eb719 DJ |
54 | /* Saved function pointers to fetch and store a single register using |
55 | PTRACE_PEEKUSER and PTRACE_POKEUSER. */ | |
56 | ||
b9412953 DD |
57 | static void (*super_fetch_registers) (struct target_ops *, |
58 | struct regcache *, int); | |
59 | static void (*super_store_registers) (struct target_ops *, | |
60 | struct regcache *, int); | |
61 | ||
62 | static void (*super_close) (int); | |
d37eb719 | 63 | |
dda0c97e | 64 | /* Map gdb internal register number to ptrace ``address''. |
7714d83a UW |
65 | These ``addresses'' are normally defined in <asm/ptrace.h>. |
66 | ||
67 | ptrace does not provide a way to read (or set) MIPS_PS_REGNUM, | |
68 | and there's no point in reading or setting MIPS_ZERO_REGNUM. | |
69 | We also can not set BADVADDR, CAUSE, or FCRIR via ptrace(). */ | |
dda0c97e UW |
70 | |
71 | static CORE_ADDR | |
7714d83a | 72 | mips_linux_register_addr (struct gdbarch *gdbarch, int regno, int store) |
dda0c97e | 73 | { |
7714d83a | 74 | CORE_ADDR regaddr; |
dda0c97e | 75 | |
2eb4d78b | 76 | if (regno < 0 || regno >= gdbarch_num_regs (gdbarch)) |
dda0c97e UW |
77 | error (_("Bogon register number %d."), regno); |
78 | ||
7714d83a | 79 | if (regno > MIPS_ZERO_REGNUM && regno < MIPS_ZERO_REGNUM + 32) |
dda0c97e | 80 | regaddr = regno; |
7714d83a UW |
81 | else if ((regno >= mips_regnum (gdbarch)->fp0) |
82 | && (regno < mips_regnum (gdbarch)->fp0 + 32)) | |
83 | regaddr = FPR_BASE + (regno - mips_regnum (gdbarch)->fp0); | |
84 | else if (regno == mips_regnum (gdbarch)->pc) | |
dda0c97e | 85 | regaddr = PC; |
7714d83a UW |
86 | else if (regno == mips_regnum (gdbarch)->cause) |
87 | regaddr = store? (CORE_ADDR) -1 : CAUSE; | |
88 | else if (regno == mips_regnum (gdbarch)->badvaddr) | |
89 | regaddr = store? (CORE_ADDR) -1 : BADVADDR; | |
90 | else if (regno == mips_regnum (gdbarch)->lo) | |
dda0c97e | 91 | regaddr = MMLO; |
7714d83a | 92 | else if (regno == mips_regnum (gdbarch)->hi) |
dda0c97e | 93 | regaddr = MMHI; |
7714d83a | 94 | else if (regno == mips_regnum (gdbarch)->fp_control_status) |
dda0c97e | 95 | regaddr = FPC_CSR; |
7714d83a UW |
96 | else if (regno == mips_regnum (gdbarch)->fp_implementation_revision) |
97 | regaddr = store? (CORE_ADDR) -1 : FPC_EIR; | |
822b6570 DJ |
98 | else if (mips_linux_restart_reg_p (gdbarch) && regno == MIPS_RESTART_REGNUM) |
99 | regaddr = 0; | |
dda0c97e | 100 | else |
7714d83a | 101 | regaddr = (CORE_ADDR) -1; |
dda0c97e UW |
102 | |
103 | return regaddr; | |
104 | } | |
105 | ||
106 | static CORE_ADDR | |
7714d83a | 107 | mips64_linux_register_addr (struct gdbarch *gdbarch, int regno, int store) |
dda0c97e | 108 | { |
7714d83a | 109 | CORE_ADDR regaddr; |
dda0c97e | 110 | |
2eb4d78b | 111 | if (regno < 0 || regno >= gdbarch_num_regs (gdbarch)) |
dda0c97e UW |
112 | error (_("Bogon register number %d."), regno); |
113 | ||
7714d83a | 114 | if (regno > MIPS_ZERO_REGNUM && regno < MIPS_ZERO_REGNUM + 32) |
dda0c97e | 115 | regaddr = regno; |
7714d83a UW |
116 | else if ((regno >= mips_regnum (gdbarch)->fp0) |
117 | && (regno < mips_regnum (gdbarch)->fp0 + 32)) | |
2eb4d78b | 118 | regaddr = MIPS64_FPR_BASE + (regno - gdbarch_fp0_regnum (gdbarch)); |
7714d83a | 119 | else if (regno == mips_regnum (gdbarch)->pc) |
dda0c97e | 120 | regaddr = MIPS64_PC; |
7714d83a UW |
121 | else if (regno == mips_regnum (gdbarch)->cause) |
122 | regaddr = store? (CORE_ADDR) -1 : MIPS64_CAUSE; | |
123 | else if (regno == mips_regnum (gdbarch)->badvaddr) | |
124 | regaddr = store? (CORE_ADDR) -1 : MIPS64_BADVADDR; | |
125 | else if (regno == mips_regnum (gdbarch)->lo) | |
dda0c97e | 126 | regaddr = MIPS64_MMLO; |
7714d83a | 127 | else if (regno == mips_regnum (gdbarch)->hi) |
dda0c97e | 128 | regaddr = MIPS64_MMHI; |
7714d83a | 129 | else if (regno == mips_regnum (gdbarch)->fp_control_status) |
dda0c97e | 130 | regaddr = MIPS64_FPC_CSR; |
7714d83a UW |
131 | else if (regno == mips_regnum (gdbarch)->fp_implementation_revision) |
132 | regaddr = store? (CORE_ADDR) -1 : MIPS64_FPC_EIR; | |
822b6570 DJ |
133 | else if (mips_linux_restart_reg_p (gdbarch) && regno == MIPS_RESTART_REGNUM) |
134 | regaddr = 0; | |
dda0c97e | 135 | else |
7714d83a | 136 | regaddr = (CORE_ADDR) -1; |
dda0c97e UW |
137 | |
138 | return regaddr; | |
139 | } | |
140 | ||
dc60ece8 DJ |
141 | /* Fetch the thread-local storage pointer for libthread_db. */ |
142 | ||
143 | ps_err_e | |
144 | ps_get_thread_area (const struct ps_prochandle *ph, | |
145 | lwpid_t lwpid, int idx, void **base) | |
146 | { | |
147 | if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0) | |
148 | return PS_ERR; | |
149 | ||
150 | /* IDX is the bias from the thread pointer to the beginning of the | |
151 | thread descriptor. It has to be subtracted due to implementation | |
152 | quirks in libthread_db. */ | |
153 | *base = (void *) ((char *)*base - idx); | |
154 | ||
155 | return PS_OK; | |
156 | } | |
157 | ||
3e00823e UW |
158 | /* Wrapper functions. These are only used by libthread_db. */ |
159 | ||
160 | void | |
7f7fe91e | 161 | supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp) |
3e00823e | 162 | { |
2eb4d78b | 163 | if (mips_isa_regsize (get_regcache_arch (regcache)) == 4) |
7f7fe91e | 164 | mips_supply_gregset (regcache, (const mips_elf_gregset_t *) gregsetp); |
3e00823e | 165 | else |
7f7fe91e | 166 | mips64_supply_gregset (regcache, (const mips64_elf_gregset_t *) gregsetp); |
3e00823e UW |
167 | } |
168 | ||
169 | void | |
7f7fe91e UW |
170 | fill_gregset (const struct regcache *regcache, |
171 | gdb_gregset_t *gregsetp, int regno) | |
3e00823e | 172 | { |
2eb4d78b | 173 | if (mips_isa_regsize (get_regcache_arch (regcache)) == 4) |
7f7fe91e | 174 | mips_fill_gregset (regcache, (mips_elf_gregset_t *) gregsetp, regno); |
3e00823e | 175 | else |
7f7fe91e | 176 | mips64_fill_gregset (regcache, (mips64_elf_gregset_t *) gregsetp, regno); |
3e00823e UW |
177 | } |
178 | ||
179 | void | |
7f7fe91e | 180 | supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp) |
3e00823e | 181 | { |
2eb4d78b | 182 | if (mips_isa_regsize (get_regcache_arch (regcache)) == 4) |
7f7fe91e | 183 | mips_supply_fpregset (regcache, (const mips_elf_fpregset_t *) fpregsetp); |
3e00823e | 184 | else |
7f7fe91e | 185 | mips64_supply_fpregset (regcache, (const mips64_elf_fpregset_t *) fpregsetp); |
3e00823e UW |
186 | } |
187 | ||
188 | void | |
7f7fe91e UW |
189 | fill_fpregset (const struct regcache *regcache, |
190 | gdb_fpregset_t *fpregsetp, int regno) | |
3e00823e | 191 | { |
2eb4d78b | 192 | if (mips_isa_regsize (get_regcache_arch (regcache)) == 4) |
7f7fe91e | 193 | mips_fill_fpregset (regcache, (mips_elf_fpregset_t *) fpregsetp, regno); |
3e00823e | 194 | else |
7f7fe91e | 195 | mips64_fill_fpregset (regcache, (mips64_elf_fpregset_t *) fpregsetp, regno); |
3e00823e UW |
196 | } |
197 | ||
198 | ||
d37eb719 DJ |
199 | /* Fetch REGNO (or all registers if REGNO == -1) from the target |
200 | using PTRACE_GETREGS et al. */ | |
201 | ||
202 | static void | |
56be3814 | 203 | mips64_linux_regsets_fetch_registers (struct regcache *regcache, int regno) |
d37eb719 | 204 | { |
2eb4d78b | 205 | struct gdbarch *gdbarch = get_regcache_arch (regcache); |
d37eb719 DJ |
206 | int is_fp; |
207 | int tid; | |
208 | ||
2eb4d78b UW |
209 | if (regno >= mips_regnum (gdbarch)->fp0 |
210 | && regno <= mips_regnum (gdbarch)->fp0 + 32) | |
d37eb719 | 211 | is_fp = 1; |
2eb4d78b | 212 | else if (regno == mips_regnum (gdbarch)->fp_control_status) |
d37eb719 | 213 | is_fp = 1; |
2eb4d78b | 214 | else if (regno == mips_regnum (gdbarch)->fp_implementation_revision) |
d37eb719 DJ |
215 | is_fp = 1; |
216 | else | |
217 | is_fp = 0; | |
218 | ||
219 | tid = ptid_get_lwp (inferior_ptid); | |
220 | if (tid == 0) | |
221 | tid = ptid_get_pid (inferior_ptid); | |
222 | ||
223 | if (regno == -1 || !is_fp) | |
224 | { | |
225 | mips64_elf_gregset_t regs; | |
226 | ||
227 | if (ptrace (PTRACE_GETREGS, tid, 0L, (PTRACE_TYPE_ARG3) ®s) == -1) | |
228 | { | |
229 | if (errno == EIO) | |
230 | { | |
231 | have_ptrace_regsets = 0; | |
232 | return; | |
233 | } | |
234 | perror_with_name (_("Couldn't get registers")); | |
235 | } | |
236 | ||
56be3814 | 237 | mips64_supply_gregset (regcache, |
28f5035f | 238 | (const mips64_elf_gregset_t *) ®s); |
d37eb719 DJ |
239 | } |
240 | ||
241 | if (regno == -1 || is_fp) | |
242 | { | |
243 | mips64_elf_fpregset_t fp_regs; | |
244 | ||
245 | if (ptrace (PTRACE_GETFPREGS, tid, 0L, | |
246 | (PTRACE_TYPE_ARG3) &fp_regs) == -1) | |
247 | { | |
248 | if (errno == EIO) | |
249 | { | |
250 | have_ptrace_regsets = 0; | |
251 | return; | |
252 | } | |
253 | perror_with_name (_("Couldn't get FP registers")); | |
254 | } | |
255 | ||
56be3814 | 256 | mips64_supply_fpregset (regcache, |
28f5035f | 257 | (const mips64_elf_fpregset_t *) &fp_regs); |
d37eb719 DJ |
258 | } |
259 | } | |
260 | ||
261 | /* Store REGNO (or all registers if REGNO == -1) to the target | |
262 | using PTRACE_SETREGS et al. */ | |
263 | ||
264 | static void | |
56be3814 | 265 | mips64_linux_regsets_store_registers (const struct regcache *regcache, int regno) |
d37eb719 | 266 | { |
2eb4d78b | 267 | struct gdbarch *gdbarch = get_regcache_arch (regcache); |
d37eb719 DJ |
268 | int is_fp; |
269 | int tid; | |
270 | ||
2eb4d78b UW |
271 | if (regno >= mips_regnum (gdbarch)->fp0 |
272 | && regno <= mips_regnum (gdbarch)->fp0 + 32) | |
d37eb719 | 273 | is_fp = 1; |
2eb4d78b | 274 | else if (regno == mips_regnum (gdbarch)->fp_control_status) |
d37eb719 | 275 | is_fp = 1; |
2eb4d78b | 276 | else if (regno == mips_regnum (gdbarch)->fp_implementation_revision) |
d37eb719 DJ |
277 | is_fp = 1; |
278 | else | |
279 | is_fp = 0; | |
280 | ||
281 | tid = ptid_get_lwp (inferior_ptid); | |
282 | if (tid == 0) | |
283 | tid = ptid_get_pid (inferior_ptid); | |
284 | ||
285 | if (regno == -1 || !is_fp) | |
286 | { | |
287 | mips64_elf_gregset_t regs; | |
288 | ||
289 | if (ptrace (PTRACE_GETREGS, tid, 0L, (PTRACE_TYPE_ARG3) ®s) == -1) | |
290 | perror_with_name (_("Couldn't get registers")); | |
291 | ||
56be3814 | 292 | mips64_fill_gregset (regcache, ®s, regno); |
d37eb719 DJ |
293 | |
294 | if (ptrace (PTRACE_SETREGS, tid, 0L, (PTRACE_TYPE_ARG3) ®s) == -1) | |
295 | perror_with_name (_("Couldn't set registers")); | |
296 | } | |
297 | ||
298 | if (regno == -1 || is_fp) | |
299 | { | |
300 | mips64_elf_fpregset_t fp_regs; | |
301 | ||
302 | if (ptrace (PTRACE_GETFPREGS, tid, 0L, | |
303 | (PTRACE_TYPE_ARG3) &fp_regs) == -1) | |
304 | perror_with_name (_("Couldn't get FP registers")); | |
305 | ||
56be3814 | 306 | mips64_fill_fpregset (regcache, &fp_regs, regno); |
d37eb719 DJ |
307 | |
308 | if (ptrace (PTRACE_SETFPREGS, tid, 0L, | |
309 | (PTRACE_TYPE_ARG3) &fp_regs) == -1) | |
310 | perror_with_name (_("Couldn't set FP registers")); | |
311 | } | |
312 | } | |
313 | ||
314 | /* Fetch REGNO (or all registers if REGNO == -1) from the target | |
315 | using any working method. */ | |
316 | ||
317 | static void | |
28439f5e PA |
318 | mips64_linux_fetch_registers (struct target_ops *ops, |
319 | struct regcache *regcache, int regnum) | |
d37eb719 DJ |
320 | { |
321 | /* Unless we already know that PTRACE_GETREGS does not work, try it. */ | |
322 | if (have_ptrace_regsets) | |
56be3814 | 323 | mips64_linux_regsets_fetch_registers (regcache, regnum); |
d37eb719 DJ |
324 | |
325 | /* If we know, or just found out, that PTRACE_GETREGS does not work, fall | |
326 | back to PTRACE_PEEKUSER. */ | |
327 | if (!have_ptrace_regsets) | |
a0740d21 | 328 | super_fetch_registers (ops, regcache, regnum); |
d37eb719 DJ |
329 | } |
330 | ||
331 | /* Store REGNO (or all registers if REGNO == -1) to the target | |
332 | using any working method. */ | |
333 | ||
334 | static void | |
28439f5e PA |
335 | mips64_linux_store_registers (struct target_ops *ops, |
336 | struct regcache *regcache, int regnum) | |
d37eb719 DJ |
337 | { |
338 | /* Unless we already know that PTRACE_GETREGS does not work, try it. */ | |
339 | if (have_ptrace_regsets) | |
56be3814 | 340 | mips64_linux_regsets_store_registers (regcache, regnum); |
d37eb719 DJ |
341 | |
342 | /* If we know, or just found out, that PTRACE_GETREGS does not work, fall | |
343 | back to PTRACE_PEEKUSER. */ | |
344 | if (!have_ptrace_regsets) | |
a0740d21 | 345 | super_store_registers (ops, regcache, regnum); |
d37eb719 DJ |
346 | } |
347 | ||
910122bf UW |
348 | /* Return the address in the core dump or inferior of register |
349 | REGNO. */ | |
350 | ||
351 | static CORE_ADDR | |
7714d83a | 352 | mips_linux_register_u_offset (struct gdbarch *gdbarch, int regno, int store_p) |
910122bf | 353 | { |
7714d83a UW |
354 | if (mips_abi_regsize (gdbarch) == 8) |
355 | return mips64_linux_register_addr (gdbarch, regno, store_p); | |
dda0c97e | 356 | else |
7714d83a | 357 | return mips_linux_register_addr (gdbarch, regno, store_p); |
910122bf UW |
358 | } |
359 | ||
81adfced DJ |
360 | static const struct target_desc * |
361 | mips_linux_read_description (struct target_ops *ops) | |
822b6570 | 362 | { |
81adfced DJ |
363 | /* Report that target registers are a size we know for sure |
364 | that we can get from ptrace. */ | |
365 | if (_MIPS_SIM == _ABIO32) | |
366 | return tdesc_mips_linux; | |
367 | else | |
368 | return tdesc_mips64_linux; | |
822b6570 DJ |
369 | } |
370 | ||
b9412953 DD |
371 | #ifndef PTRACE_GET_WATCH_REGS |
372 | # define PTRACE_GET_WATCH_REGS 0xd0 | |
373 | #endif | |
374 | ||
375 | #ifndef PTRACE_SET_WATCH_REGS | |
376 | # define PTRACE_SET_WATCH_REGS 0xd1 | |
377 | #endif | |
378 | ||
379 | #define W_BIT 0 | |
380 | #define R_BIT 1 | |
381 | #define I_BIT 2 | |
382 | ||
383 | #define W_MASK (1 << W_BIT) | |
384 | #define R_MASK (1 << R_BIT) | |
385 | #define I_MASK (1 << I_BIT) | |
386 | ||
387 | #define IRW_MASK (I_MASK | R_MASK | W_MASK) | |
388 | ||
389 | enum pt_watch_style { | |
390 | pt_watch_style_mips32, | |
391 | pt_watch_style_mips64 | |
392 | }; | |
393 | ||
394 | #define MAX_DEBUG_REGISTER 8 | |
395 | ||
396 | /* A value of zero in a watchlo indicates that it is available. */ | |
397 | ||
398 | struct mips32_watch_regs | |
399 | { | |
400 | uint32_t watchlo[MAX_DEBUG_REGISTER]; | |
401 | /* Lower 16 bits of watchhi. */ | |
402 | uint16_t watchhi[MAX_DEBUG_REGISTER]; | |
403 | /* Valid mask and I R W bits. | |
404 | * bit 0 -- 1 if W bit is usable. | |
405 | * bit 1 -- 1 if R bit is usable. | |
406 | * bit 2 -- 1 if I bit is usable. | |
407 | * bits 3 - 11 -- Valid watchhi mask bits. | |
408 | */ | |
409 | uint16_t watch_masks[MAX_DEBUG_REGISTER]; | |
410 | /* The number of valid watch register pairs. */ | |
411 | uint32_t num_valid; | |
412 | /* There is confusion across gcc versions about structure alignment, | |
413 | so we force 8 byte alignment for these structures so they match | |
414 | the kernel even if it was build with a different gcc version. */ | |
415 | } __attribute__ ((aligned (8))); | |
416 | ||
417 | struct mips64_watch_regs | |
418 | { | |
419 | uint64_t watchlo[MAX_DEBUG_REGISTER]; | |
420 | uint16_t watchhi[MAX_DEBUG_REGISTER]; | |
421 | uint16_t watch_masks[MAX_DEBUG_REGISTER]; | |
422 | uint32_t num_valid; | |
423 | } __attribute__ ((aligned (8))); | |
424 | ||
425 | struct pt_watch_regs | |
426 | { | |
427 | enum pt_watch_style style; | |
428 | union | |
429 | { | |
430 | struct mips32_watch_regs mips32; | |
431 | struct mips64_watch_regs mips64; | |
432 | }; | |
433 | }; | |
434 | ||
435 | /* -1 if the kernel and/or CPU do not support watch registers. | |
436 | 1 if watch_readback is valid and we can read style, num_valid | |
437 | and the masks. | |
438 | 0 if we need to read the watch_readback. */ | |
439 | ||
440 | static int watch_readback_valid; | |
441 | ||
442 | /* Cached watch register read values. */ | |
443 | ||
444 | static struct pt_watch_regs watch_readback; | |
445 | ||
446 | /* We keep list of all watchpoints we should install and calculate the | |
447 | watch register values each time the list changes. This allows for | |
448 | easy sharing of watch registers for more than one watchpoint. */ | |
449 | ||
450 | struct mips_watchpoint | |
451 | { | |
452 | CORE_ADDR addr; | |
453 | int len; | |
454 | int type; | |
455 | struct mips_watchpoint *next; | |
456 | }; | |
457 | ||
458 | static struct mips_watchpoint *current_watches; | |
459 | ||
460 | /* The current set of watch register values for writing the | |
461 | registers. */ | |
462 | ||
463 | static struct pt_watch_regs watch_mirror; | |
464 | ||
465 | /* Assuming usable watch registers, return the irw_mask. */ | |
466 | ||
467 | static uint32_t | |
468 | get_irw_mask (struct pt_watch_regs *regs, int set) | |
469 | { | |
470 | switch (regs->style) | |
471 | { | |
472 | case pt_watch_style_mips32: | |
473 | return regs->mips32.watch_masks[set] & IRW_MASK; | |
474 | case pt_watch_style_mips64: | |
475 | return regs->mips64.watch_masks[set] & IRW_MASK; | |
476 | default: | |
477 | internal_error (__FILE__, __LINE__, | |
478 | _("Unrecognized watch register style")); | |
479 | } | |
480 | } | |
481 | ||
482 | /* Assuming usable watch registers, return the reg_mask. */ | |
483 | ||
484 | static uint32_t | |
485 | get_reg_mask (struct pt_watch_regs *regs, int set) | |
486 | { | |
487 | switch (regs->style) | |
488 | { | |
489 | case pt_watch_style_mips32: | |
490 | return regs->mips32.watch_masks[set] & ~IRW_MASK; | |
491 | case pt_watch_style_mips64: | |
492 | return regs->mips64.watch_masks[set] & ~IRW_MASK; | |
493 | default: | |
494 | internal_error (__FILE__, __LINE__, | |
495 | _("Unrecognized watch register style")); | |
496 | } | |
497 | } | |
498 | ||
499 | /* Assuming usable watch registers, return the num_valid. */ | |
500 | ||
501 | static uint32_t | |
502 | get_num_valid (struct pt_watch_regs *regs) | |
503 | { | |
504 | switch (regs->style) | |
505 | { | |
506 | case pt_watch_style_mips32: | |
507 | return regs->mips32.num_valid; | |
508 | case pt_watch_style_mips64: | |
509 | return regs->mips64.num_valid; | |
510 | default: | |
511 | internal_error (__FILE__, __LINE__, | |
512 | _("Unrecognized watch register style")); | |
513 | } | |
514 | } | |
515 | ||
516 | /* Assuming usable watch registers, return the watchlo. */ | |
517 | ||
518 | static CORE_ADDR | |
519 | get_watchlo (struct pt_watch_regs *regs, int set) | |
520 | { | |
521 | switch (regs->style) | |
522 | { | |
523 | case pt_watch_style_mips32: | |
524 | return regs->mips32.watchlo[set]; | |
525 | case pt_watch_style_mips64: | |
526 | return regs->mips64.watchlo[set]; | |
527 | default: | |
528 | internal_error (__FILE__, __LINE__, | |
529 | _("Unrecognized watch register style")); | |
530 | } | |
531 | } | |
532 | ||
533 | /* Assuming usable watch registers, set a watchlo value. */ | |
534 | ||
535 | static void | |
536 | set_watchlo (struct pt_watch_regs *regs, int set, CORE_ADDR value) | |
537 | { | |
538 | switch (regs->style) | |
539 | { | |
540 | case pt_watch_style_mips32: | |
541 | /* The cast will never throw away bits as 64 bit addresses can | |
542 | never be used on a 32 bit kernel. */ | |
543 | regs->mips32.watchlo[set] = (uint32_t)value; | |
544 | break; | |
545 | case pt_watch_style_mips64: | |
546 | regs->mips64.watchlo[set] = value; | |
547 | break; | |
548 | default: | |
549 | internal_error (__FILE__, __LINE__, | |
550 | _("Unrecognized watch register style")); | |
551 | } | |
552 | } | |
553 | ||
554 | /* Assuming usable watch registers, return the watchhi. */ | |
555 | ||
556 | static uint32_t | |
557 | get_watchhi (struct pt_watch_regs *regs, int n) | |
558 | { | |
559 | switch (regs->style) | |
560 | { | |
561 | case pt_watch_style_mips32: | |
562 | return regs->mips32.watchhi[n]; | |
563 | case pt_watch_style_mips64: | |
564 | return regs->mips64.watchhi[n]; | |
565 | default: | |
566 | internal_error (__FILE__, __LINE__, | |
567 | _("Unrecognized watch register style")); | |
568 | } | |
569 | } | |
570 | ||
571 | /* Assuming usable watch registers, set a watchhi value. */ | |
572 | ||
573 | static void | |
574 | set_watchhi (struct pt_watch_regs *regs, int n, uint16_t value) | |
575 | { | |
576 | switch (regs->style) | |
577 | { | |
578 | case pt_watch_style_mips32: | |
579 | regs->mips32.watchhi[n] = value; | |
580 | break; | |
581 | case pt_watch_style_mips64: | |
582 | regs->mips64.watchhi[n] = value; | |
583 | break; | |
584 | default: | |
585 | internal_error (__FILE__, __LINE__, | |
586 | _("Unrecognized watch register style")); | |
587 | } | |
588 | } | |
589 | ||
590 | static void | |
591 | mips_show_dr (const char *func, CORE_ADDR addr, | |
592 | int len, enum target_hw_bp_type type) | |
593 | { | |
594 | int i; | |
595 | ||
596 | puts_unfiltered (func); | |
597 | if (addr || len) | |
5af949e3 UW |
598 | printf_unfiltered (" (addr=%s, len=%d, type=%s)", |
599 | paddress (target_gdbarch, addr), len, | |
b9412953 DD |
600 | type == hw_write ? "data-write" |
601 | : (type == hw_read ? "data-read" | |
602 | : (type == hw_access ? "data-read/write" | |
603 | : (type == hw_execute ? "instruction-execute" | |
604 | : "??unknown??")))); | |
605 | puts_unfiltered (":\n"); | |
606 | ||
607 | for (i = 0; i < MAX_DEBUG_REGISTER; i++) | |
5af949e3 UW |
608 | printf_unfiltered ("\tDR%d: lo=%s, hi=%s\n", i, |
609 | paddress (target_gdbarch, | |
610 | get_watchlo (&watch_mirror, i)), | |
611 | paddress (target_gdbarch, | |
612 | get_watchhi (&watch_mirror, i))); | |
b9412953 DD |
613 | } |
614 | ||
615 | /* Return 1 if watch registers are usable. Cached information is used | |
616 | unless force is true. */ | |
617 | ||
618 | static int | |
619 | mips_linux_read_watch_registers (int force) | |
620 | { | |
621 | int tid; | |
622 | ||
623 | if (force || watch_readback_valid == 0) | |
624 | { | |
625 | tid = ptid_get_lwp (inferior_ptid); | |
626 | if (ptrace (PTRACE_GET_WATCH_REGS, tid, &watch_readback) == -1) | |
627 | { | |
628 | watch_readback_valid = -1; | |
629 | return 0; | |
630 | } | |
631 | switch (watch_readback.style) | |
632 | { | |
633 | case pt_watch_style_mips32: | |
634 | if (watch_readback.mips32.num_valid == 0) | |
635 | { | |
636 | watch_readback_valid = -1; | |
637 | return 0; | |
638 | } | |
639 | break; | |
640 | case pt_watch_style_mips64: | |
641 | if (watch_readback.mips64.num_valid == 0) | |
642 | { | |
643 | watch_readback_valid = -1; | |
644 | return 0; | |
645 | } | |
646 | break; | |
647 | default: | |
648 | watch_readback_valid = -1; | |
649 | return 0; | |
650 | } | |
651 | /* Watch registers appear to be usable. */ | |
652 | watch_readback_valid = 1; | |
653 | } | |
654 | return (watch_readback_valid == 1) ? 1 : 0; | |
655 | } | |
656 | ||
657 | /* Convert GDB's type to an IRW mask. */ | |
658 | ||
659 | static unsigned | |
660 | type_to_irw (int type) | |
661 | { | |
662 | switch (type) | |
663 | { | |
664 | case hw_write: | |
665 | return W_MASK; | |
666 | case hw_read: | |
667 | return R_MASK; | |
668 | case hw_access: | |
669 | return (W_MASK | R_MASK); | |
670 | default: | |
671 | return 0; | |
672 | } | |
673 | } | |
674 | ||
675 | /* Target to_can_use_hw_breakpoint implementation. Return 1 if we can | |
676 | handle the specified watch type. */ | |
677 | ||
678 | static int | |
679 | mips_linux_can_use_hw_breakpoint (int type, int cnt, int ot) | |
680 | { | |
681 | int i; | |
682 | uint32_t wanted_mask, irw_mask; | |
683 | ||
684 | if (!mips_linux_read_watch_registers (0)) | |
685 | return 0; | |
686 | ||
687 | switch (type) | |
688 | { | |
689 | case bp_hardware_watchpoint: | |
690 | wanted_mask = W_MASK; | |
691 | break; | |
692 | case bp_read_watchpoint: | |
693 | wanted_mask = R_MASK; | |
694 | break; | |
695 | case bp_access_watchpoint: | |
696 | wanted_mask = R_MASK | W_MASK; | |
697 | break; | |
698 | default: | |
699 | return 0; | |
700 | } | |
701 | ||
702 | for (i = 0; i < get_num_valid (&watch_readback) && cnt; i++) | |
703 | { | |
704 | irw_mask = get_irw_mask (&watch_readback, i); | |
705 | if ((irw_mask & wanted_mask) == wanted_mask) | |
706 | cnt--; | |
707 | } | |
708 | return (cnt == 0) ? 1 : 0; | |
709 | } | |
710 | ||
711 | /* Target to_stopped_by_watchpoint implementation. Return 1 if | |
712 | stopped by watchpoint. The watchhi R and W bits indicate the watch | |
713 | register triggered. */ | |
714 | ||
715 | static int | |
716 | mips_linux_stopped_by_watchpoint (void) | |
717 | { | |
718 | int n; | |
719 | int num_valid; | |
720 | ||
721 | if (!mips_linux_read_watch_registers (1)) | |
722 | return 0; | |
723 | ||
724 | num_valid = get_num_valid (&watch_readback); | |
725 | ||
726 | for (n = 0; n < MAX_DEBUG_REGISTER && n < num_valid; n++) | |
727 | if (get_watchhi (&watch_readback, n) & (R_MASK | W_MASK)) | |
728 | return 1; | |
729 | ||
730 | return 0; | |
731 | } | |
732 | ||
733 | /* Target to_stopped_data_address implementation. Set the address | |
734 | where the watch triggered (if known). Return 1 if the address was | |
735 | known. */ | |
736 | ||
737 | static int | |
738 | mips_linux_stopped_data_address (struct target_ops *t, CORE_ADDR *paddr) | |
739 | { | |
740 | /* On mips we don't know the low order 3 bits of the data address, | |
741 | so we must return false. */ | |
742 | return 0; | |
743 | } | |
744 | ||
745 | /* Set any low order bits in mask that are not set. */ | |
746 | ||
747 | static CORE_ADDR | |
748 | fill_mask (CORE_ADDR mask) | |
749 | { | |
750 | CORE_ADDR f = 1; | |
751 | while (f && f < mask) | |
752 | { | |
753 | mask |= f; | |
754 | f <<= 1; | |
755 | } | |
756 | return mask; | |
757 | } | |
758 | ||
759 | /* Try to add a single watch to the specified registers. Return 1 on | |
760 | success, 0 on failure. */ | |
761 | ||
762 | static int | |
763 | try_one_watch (struct pt_watch_regs *regs, CORE_ADDR addr, | |
764 | int len, unsigned irw) | |
765 | { | |
766 | CORE_ADDR base_addr, last_byte, break_addr, segment_len; | |
767 | CORE_ADDR mask_bits, t_low, t_low_end; | |
768 | uint16_t t_hi; | |
769 | int i, free_watches; | |
770 | struct pt_watch_regs regs_copy; | |
771 | ||
772 | if (len <= 0) | |
773 | return 0; | |
774 | ||
775 | last_byte = addr + len - 1; | |
776 | mask_bits = fill_mask (addr ^ last_byte) | IRW_MASK; | |
777 | base_addr = addr & ~mask_bits; | |
778 | ||
779 | /* Check to see if it is covered by current registers. */ | |
780 | for (i = 0; i < get_num_valid (regs); i++) | |
781 | { | |
782 | t_low = get_watchlo (regs, i); | |
783 | if (t_low != 0 && irw == ((unsigned)t_low & irw)) | |
784 | { | |
785 | t_hi = get_watchhi (regs, i) | IRW_MASK; | |
786 | t_low &= ~(CORE_ADDR)t_hi; | |
787 | if (addr >= t_low && last_byte <= (t_low + t_hi)) | |
788 | return 1; | |
789 | } | |
790 | } | |
791 | /* Try to find an empty register. */ | |
792 | free_watches = 0; | |
793 | for (i = 0; i < get_num_valid (regs); i++) | |
794 | { | |
795 | t_low = get_watchlo (regs, i); | |
796 | if (t_low == 0 && irw == (get_irw_mask (regs, i) & irw)) | |
797 | { | |
798 | if (mask_bits <= (get_reg_mask (regs, i) | IRW_MASK)) | |
799 | { | |
800 | /* It fits, we'll take it. */ | |
801 | set_watchlo (regs, i, base_addr | irw); | |
802 | set_watchhi (regs, i, mask_bits & ~IRW_MASK); | |
803 | return 1; | |
804 | } | |
805 | else | |
806 | { | |
807 | /* It doesn't fit, but has the proper IRW capabilities. */ | |
808 | free_watches++; | |
809 | } | |
810 | } | |
811 | } | |
812 | if (free_watches > 1) | |
813 | { | |
814 | /* Try to split it across several registers. */ | |
815 | regs_copy = *regs; | |
816 | for (i = 0; i < get_num_valid (®s_copy); i++) | |
817 | { | |
818 | t_low = get_watchlo (®s_copy, i); | |
819 | t_hi = get_reg_mask (®s_copy, i) | IRW_MASK; | |
820 | if (t_low == 0 && irw == (t_hi & irw)) | |
821 | { | |
822 | t_low = addr & ~(CORE_ADDR)t_hi; | |
823 | break_addr = t_low + t_hi + 1; | |
824 | if (break_addr >= addr + len) | |
825 | segment_len = len; | |
826 | else | |
827 | segment_len = break_addr - addr; | |
828 | mask_bits = fill_mask (addr ^ (addr + segment_len - 1)); | |
829 | set_watchlo (®s_copy, i, (addr & ~mask_bits) | irw); | |
830 | set_watchhi (®s_copy, i, mask_bits & ~IRW_MASK); | |
831 | if (break_addr >= addr + len) | |
832 | { | |
833 | *regs = regs_copy; | |
834 | return 1; | |
835 | } | |
836 | len = addr + len - break_addr; | |
837 | addr = break_addr; | |
838 | } | |
839 | } | |
840 | } | |
841 | /* It didn't fit anywhere, we failed. */ | |
842 | return 0; | |
843 | } | |
844 | ||
845 | /* Target to_region_ok_for_hw_watchpoint implementation. Return 1 if | |
846 | the specified region can be covered by the watch registers. */ | |
847 | ||
848 | static int | |
849 | mips_linux_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) | |
850 | { | |
851 | struct pt_watch_regs dummy_regs; | |
852 | int i; | |
853 | ||
854 | if (!mips_linux_read_watch_registers (0)) | |
855 | return 0; | |
856 | ||
857 | dummy_regs = watch_readback; | |
858 | /* Clear them out. */ | |
859 | for (i = 0; i < get_num_valid (&dummy_regs); i++) | |
860 | set_watchlo (&dummy_regs, i, 0); | |
861 | return try_one_watch (&dummy_regs, addr, len, 0); | |
862 | } | |
863 | ||
864 | ||
865 | /* Write the mirrored watch register values for each thread. */ | |
866 | ||
867 | static int | |
868 | write_watchpoint_regs (void) | |
869 | { | |
870 | struct lwp_info *lp; | |
871 | ptid_t ptid; | |
872 | int tid; | |
873 | ||
874 | ALL_LWPS (lp, ptid) | |
875 | { | |
876 | tid = ptid_get_lwp (ptid); | |
877 | if (ptrace (PTRACE_SET_WATCH_REGS, tid, &watch_mirror) == -1) | |
878 | perror_with_name (_("Couldn't write debug register")); | |
879 | } | |
880 | return 0; | |
881 | } | |
882 | ||
883 | /* linux_nat new_thread implementation. Write the mirrored watch | |
884 | register values for the new thread. */ | |
885 | ||
886 | static void | |
887 | mips_linux_new_thread (ptid_t ptid) | |
888 | { | |
889 | int tid; | |
890 | ||
891 | if (!mips_linux_read_watch_registers (0)) | |
892 | return; | |
893 | ||
894 | tid = ptid_get_lwp (ptid); | |
895 | if (ptrace (PTRACE_SET_WATCH_REGS, tid, &watch_mirror) == -1) | |
896 | perror_with_name (_("Couldn't write debug register")); | |
897 | } | |
898 | ||
899 | /* Fill in the watch registers with the currently cached watches. */ | |
900 | ||
901 | static void | |
902 | populate_regs_from_watches (struct pt_watch_regs *regs) | |
903 | { | |
904 | struct mips_watchpoint *w; | |
905 | int i; | |
906 | ||
907 | /* Clear them out. */ | |
908 | for (i = 0; i < get_num_valid (regs); i++) | |
909 | { | |
910 | set_watchlo (regs, i, 0); | |
911 | set_watchhi (regs, i, 0); | |
912 | } | |
913 | ||
914 | w = current_watches; | |
915 | while (w) | |
916 | { | |
917 | i = try_one_watch (regs, w->addr, w->len, type_to_irw (w->type)); | |
918 | /* They must all fit, because we previously calculated that they | |
919 | would. */ | |
920 | gdb_assert (i); | |
921 | w = w->next; | |
922 | } | |
923 | } | |
924 | ||
925 | /* Target to_insert_watchpoint implementation. Try to insert a new | |
926 | watch. Return zero on success. */ | |
927 | ||
928 | static int | |
929 | mips_linux_insert_watchpoint (CORE_ADDR addr, int len, int type) | |
930 | { | |
931 | struct pt_watch_regs regs; | |
932 | struct mips_watchpoint *new_watch; | |
933 | struct mips_watchpoint **pw; | |
934 | ||
935 | int i; | |
936 | int retval; | |
937 | ||
938 | if (!mips_linux_read_watch_registers (0)) | |
939 | return -1; | |
940 | ||
941 | if (len <= 0) | |
942 | return -1; | |
943 | ||
944 | regs = watch_readback; | |
945 | /* Add the current watches. */ | |
946 | populate_regs_from_watches (®s); | |
947 | ||
948 | /* Now try to add the new watch. */ | |
949 | if (!try_one_watch (®s, addr, len, type_to_irw (type))) | |
950 | return -1; | |
951 | ||
952 | /* It fit. Stick it on the end of the list. */ | |
953 | new_watch = (struct mips_watchpoint *) | |
954 | xmalloc (sizeof (struct mips_watchpoint)); | |
955 | new_watch->addr = addr; | |
956 | new_watch->len = len; | |
957 | new_watch->type = type; | |
958 | new_watch->next = NULL; | |
959 | ||
960 | pw = ¤t_watches; | |
961 | while (*pw != NULL) | |
962 | pw = &(*pw)->next; | |
963 | *pw = new_watch; | |
964 | ||
965 | watch_mirror = regs; | |
966 | retval = write_watchpoint_regs (); | |
967 | ||
968 | if (maint_show_dr) | |
969 | mips_show_dr ("insert_watchpoint", addr, len, type); | |
970 | ||
971 | return retval; | |
972 | } | |
973 | ||
974 | /* Target to_remove_watchpoint implementation. Try to remove a watch. | |
975 | Return zero on success. */ | |
976 | ||
977 | static int | |
978 | mips_linux_remove_watchpoint (CORE_ADDR addr, int len, int type) | |
979 | { | |
980 | int retval; | |
981 | int deleted_one; | |
982 | ||
983 | struct mips_watchpoint **pw; | |
984 | struct mips_watchpoint *w; | |
985 | ||
986 | /* Search for a known watch that matches. Then unlink and free | |
987 | it. */ | |
988 | deleted_one = 0; | |
989 | pw = ¤t_watches; | |
990 | while ((w = *pw)) | |
991 | { | |
992 | if (w->addr == addr && w->len == len && w->type == type) | |
993 | { | |
994 | *pw = w->next; | |
995 | xfree (w); | |
996 | deleted_one = 1; | |
997 | break; | |
998 | } | |
999 | pw = &(w->next); | |
1000 | } | |
1001 | ||
1002 | if (!deleted_one) | |
1003 | return -1; /* We don't know about it, fail doing nothing. */ | |
1004 | ||
1005 | /* At this point watch_readback is known to be valid because we | |
1006 | could not have added the watch without reading it. */ | |
1007 | gdb_assert (watch_readback_valid == 1); | |
1008 | ||
1009 | watch_mirror = watch_readback; | |
1010 | populate_regs_from_watches (&watch_mirror); | |
1011 | ||
1012 | retval = write_watchpoint_regs (); | |
1013 | ||
1014 | if (maint_show_dr) | |
1015 | mips_show_dr ("remove_watchpoint", addr, len, type); | |
1016 | ||
1017 | return retval; | |
1018 | } | |
1019 | ||
1020 | /* Target to_close implementation. Free any watches and call the | |
1021 | super implementation. */ | |
1022 | ||
1023 | static void | |
1024 | mips_linux_close (int quitting) | |
1025 | { | |
1026 | struct mips_watchpoint *w; | |
1027 | struct mips_watchpoint *nw; | |
1028 | ||
1029 | /* Clean out the current_watches list. */ | |
1030 | w = current_watches; | |
1031 | while (w) | |
1032 | { | |
1033 | nw = w->next; | |
1034 | xfree (w); | |
1035 | w = nw; | |
1036 | } | |
1037 | current_watches = NULL; | |
1038 | ||
1039 | if (super_close) | |
1040 | super_close (quitting); | |
1041 | } | |
1042 | ||
10d6c8cd DJ |
1043 | void _initialize_mips_linux_nat (void); |
1044 | ||
1045 | void | |
1046 | _initialize_mips_linux_nat (void) | |
1047 | { | |
b9412953 DD |
1048 | struct target_ops *t; |
1049 | ||
cbe54154 PA |
1050 | add_setshow_boolean_cmd ("show-debug-regs", class_maintenance, |
1051 | &maint_show_dr, _("\ | |
1052 | Set whether to show variables that mirror the mips debug registers."), _("\ | |
1053 | Show whether to show variables that mirror the mips debug registers."), _("\ | |
b9412953 DD |
1054 | Use \"on\" to enable, \"off\" to disable.\n\ |
1055 | If enabled, the debug registers values are shown when GDB inserts\n\ | |
1056 | or removes a hardware breakpoint or watchpoint, and when the inferior\n\ | |
1057 | triggers a breakpoint or watchpoint."), | |
cbe54154 PA |
1058 | NULL, |
1059 | NULL, | |
1060 | &maintenance_set_cmdlist, | |
1061 | &maintenance_show_cmdlist); | |
b9412953 DD |
1062 | |
1063 | t = linux_trad_target (mips_linux_register_u_offset); | |
1064 | ||
1065 | super_close = t->to_close; | |
1066 | t->to_close = mips_linux_close; | |
d37eb719 DJ |
1067 | |
1068 | super_fetch_registers = t->to_fetch_registers; | |
1069 | super_store_registers = t->to_store_registers; | |
1070 | ||
1071 | t->to_fetch_registers = mips64_linux_fetch_registers; | |
1072 | t->to_store_registers = mips64_linux_store_registers; | |
1073 | ||
b9412953 DD |
1074 | t->to_can_use_hw_breakpoint = mips_linux_can_use_hw_breakpoint; |
1075 | t->to_remove_watchpoint = mips_linux_remove_watchpoint; | |
1076 | t->to_insert_watchpoint = mips_linux_insert_watchpoint; | |
1077 | t->to_stopped_by_watchpoint = mips_linux_stopped_by_watchpoint; | |
1078 | t->to_stopped_data_address = mips_linux_stopped_data_address; | |
1079 | t->to_region_ok_for_hw_watchpoint = mips_linux_region_ok_for_hw_watchpoint; | |
1080 | ||
81adfced | 1081 | t->to_read_description = mips_linux_read_description; |
822b6570 | 1082 | |
f973ed9c | 1083 | linux_nat_add_target (t); |
b9412953 | 1084 | linux_nat_set_new_thread (t, mips_linux_new_thread); |
81adfced DJ |
1085 | |
1086 | /* Initialize the standard target descriptions. */ | |
1087 | initialize_tdesc_mips_linux (); | |
1088 | initialize_tdesc_mips64_linux (); | |
10d6c8cd | 1089 | } |