2011-12-16 Phil Muldoon <pmuldoon@redhat.com>
[deliverable/binutils-gdb.git] / gdb / arm-linux-nat.c
CommitLineData
ed9a39eb 1/* GNU/Linux on ARM native support.
4c38e0a4 2 Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009,
7b6bb8da 3 2010, 2011 Free Software Foundation, Inc.
ed9a39eb
JM
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
ed9a39eb
JM
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
ed9a39eb
JM
19
20#include "defs.h"
21#include "inferior.h"
22#include "gdbcore.h"
23#include "gdb_string.h"
4e052eda 24#include "regcache.h"
10d6c8cd
DJ
25#include "target.h"
26#include "linux-nat.h"
05a4558a 27#include "target-descriptions.h"
3b273a55 28#include "auxv.h"
e3039479
UW
29#include "observer.h"
30#include "gdbthread.h"
ed9a39eb 31
aeb98c60 32#include "arm-tdep.h"
cb587d83 33#include "arm-linux-tdep.h"
aeb98c60 34
3b273a55 35#include <elf/common.h>
ed9a39eb
JM
36#include <sys/user.h>
37#include <sys/ptrace.h>
38#include <sys/utsname.h>
41c49b06 39#include <sys/procfs.h>
ed9a39eb 40
0963b4bd 41/* Prototypes for supply_gregset etc. */
c60c0f5f
MS
42#include "gregset.h"
43
9308fc88
DJ
44/* Defines ps_err_e, struct ps_prochandle. */
45#include "gdb_proc_service.h"
46
47#ifndef PTRACE_GET_THREAD_AREA
48#define PTRACE_GET_THREAD_AREA 22
49#endif
50
05a4558a
DJ
51#ifndef PTRACE_GETWMMXREGS
52#define PTRACE_GETWMMXREGS 18
53#define PTRACE_SETWMMXREGS 19
54#endif
55
3b273a55
RE
56#ifndef PTRACE_GETVFPREGS
57#define PTRACE_GETVFPREGS 27
58#define PTRACE_SETVFPREGS 28
59#endif
60
e3039479
UW
61#ifndef PTRACE_GETHBPREGS
62#define PTRACE_GETHBPREGS 29
63#define PTRACE_SETHBPREGS 30
64#endif
65
05a4558a
DJ
66/* A flag for whether the WMMX registers are available. */
67static int arm_linux_has_wmmx_registers;
68
3b273a55 69/* The number of 64-bit VFP registers we have (expect this to be 0,
0963b4bd 70 16, or 32). */
3b273a55
RE
71static int arm_linux_vfp_register_count;
72
ed9a39eb
JM
73extern int arm_apcs_32;
74
fdf39c9a 75/* On GNU/Linux, threads are implemented as pseudo-processes, in which
41c49b06 76 case we may be tracing more than one process at a time. In that
39f77062 77 case, inferior_ptid will contain the main process ID and the
fdf39c9a
RE
78 individual thread (process) ID. get_thread_id () is used to get
79 the thread id if it's available, and the process id otherwise. */
41c49b06
SB
80
81int
39f77062 82get_thread_id (ptid_t ptid)
41c49b06 83{
39f77062
KB
84 int tid = TIDGET (ptid);
85 if (0 == tid)
86 tid = PIDGET (ptid);
41c49b06
SB
87 return tid;
88}
3b273a55 89
05a4558a 90#define GET_THREAD_ID(PTID) get_thread_id (PTID)
41c49b06 91
41c49b06 92/* Get the value of a particular register from the floating point
c6b92abd 93 state of the process and store it into regcache. */
41c49b06
SB
94
95static void
56be3814 96fetch_fpregister (struct regcache *regcache, int regno)
41c49b06
SB
97{
98 int ret, tid;
cb587d83 99 gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE];
41c49b06
SB
100
101 /* Get the thread id for the ptrace call. */
39f77062 102 tid = GET_THREAD_ID (inferior_ptid);
41c49b06
SB
103
104 /* Read the floating point state. */
cb587d83 105 ret = ptrace (PT_GETFPREGS, tid, 0, fp);
41c49b06
SB
106 if (ret < 0)
107 {
edefbb7c 108 warning (_("Unable to fetch floating point register."));
41c49b06
SB
109 return;
110 }
111
112 /* Fetch fpsr. */
34e8f22d 113 if (ARM_FPS_REGNUM == regno)
56be3814 114 regcache_raw_supply (regcache, ARM_FPS_REGNUM,
cb587d83 115 fp + NWFPE_FPSR_OFFSET);
41c49b06
SB
116
117 /* Fetch the floating point register. */
34e8f22d 118 if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM)
56be3814 119 supply_nwfpe_register (regcache, regno, fp);
41c49b06
SB
120}
121
122/* Get the whole floating point state of the process and store it
c6b92abd 123 into regcache. */
ed9a39eb
JM
124
125static void
56be3814 126fetch_fpregs (struct regcache *regcache)
ed9a39eb 127{
41c49b06 128 int ret, regno, tid;
cb587d83 129 gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE];
ed9a39eb 130
41c49b06 131 /* Get the thread id for the ptrace call. */
39f77062 132 tid = GET_THREAD_ID (inferior_ptid);
41c49b06 133
ed9a39eb 134 /* Read the floating point state. */
cb587d83 135 ret = ptrace (PT_GETFPREGS, tid, 0, fp);
ed9a39eb
JM
136 if (ret < 0)
137 {
edefbb7c 138 warning (_("Unable to fetch the floating point registers."));
ed9a39eb
JM
139 return;
140 }
141
142 /* Fetch fpsr. */
56be3814 143 regcache_raw_supply (regcache, ARM_FPS_REGNUM,
cb587d83 144 fp + NWFPE_FPSR_OFFSET);
ed9a39eb
JM
145
146 /* Fetch the floating point registers. */
34e8f22d 147 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
56be3814 148 supply_nwfpe_register (regcache, regno, fp);
ed9a39eb
JM
149}
150
41c49b06 151/* Save a particular register into the floating point state of the
c6b92abd 152 process using the contents from regcache. */
41c49b06
SB
153
154static void
56be3814 155store_fpregister (const struct regcache *regcache, int regno)
41c49b06
SB
156{
157 int ret, tid;
cb587d83 158 gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE];
41c49b06
SB
159
160 /* Get the thread id for the ptrace call. */
39f77062 161 tid = GET_THREAD_ID (inferior_ptid);
41c49b06
SB
162
163 /* Read the floating point state. */
cb587d83 164 ret = ptrace (PT_GETFPREGS, tid, 0, fp);
41c49b06
SB
165 if (ret < 0)
166 {
edefbb7c 167 warning (_("Unable to fetch the floating point registers."));
41c49b06
SB
168 return;
169 }
170
171 /* Store fpsr. */
672c9795
YQ
172 if (ARM_FPS_REGNUM == regno
173 && REG_VALID == regcache_register_status (regcache, ARM_FPS_REGNUM))
56be3814 174 regcache_raw_collect (regcache, ARM_FPS_REGNUM, fp + NWFPE_FPSR_OFFSET);
41c49b06
SB
175
176 /* Store the floating point register. */
34e8f22d 177 if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM)
56be3814 178 collect_nwfpe_register (regcache, regno, fp);
41c49b06 179
cb587d83 180 ret = ptrace (PTRACE_SETFPREGS, tid, 0, fp);
41c49b06
SB
181 if (ret < 0)
182 {
edefbb7c 183 warning (_("Unable to store floating point register."));
41c49b06
SB
184 return;
185 }
186}
187
ed9a39eb 188/* Save the whole floating point state of the process using
c6b92abd 189 the contents from regcache. */
ed9a39eb
JM
190
191static void
56be3814 192store_fpregs (const struct regcache *regcache)
ed9a39eb 193{
41c49b06 194 int ret, regno, tid;
cb587d83 195 gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE];
ed9a39eb 196
41c49b06 197 /* Get the thread id for the ptrace call. */
39f77062 198 tid = GET_THREAD_ID (inferior_ptid);
41c49b06
SB
199
200 /* Read the floating point state. */
cb587d83 201 ret = ptrace (PT_GETFPREGS, tid, 0, fp);
41c49b06
SB
202 if (ret < 0)
203 {
edefbb7c 204 warning (_("Unable to fetch the floating point registers."));
41c49b06
SB
205 return;
206 }
207
ed9a39eb 208 /* Store fpsr. */
672c9795 209 if (REG_VALID == regcache_register_status (regcache, ARM_FPS_REGNUM))
56be3814 210 regcache_raw_collect (regcache, ARM_FPS_REGNUM, fp + NWFPE_FPSR_OFFSET);
ed9a39eb
JM
211
212 /* Store the floating point registers. */
34e8f22d 213 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
672c9795 214 if (REG_VALID == regcache_register_status (regcache, regno))
56be3814 215 collect_nwfpe_register (regcache, regno, fp);
ed9a39eb 216
cb587d83 217 ret = ptrace (PTRACE_SETFPREGS, tid, 0, fp);
ed9a39eb
JM
218 if (ret < 0)
219 {
edefbb7c 220 warning (_("Unable to store floating point registers."));
ed9a39eb
JM
221 return;
222 }
223}
224
41c49b06 225/* Fetch a general register of the process and store into
c6b92abd 226 regcache. */
41c49b06
SB
227
228static void
56be3814 229fetch_register (struct regcache *regcache, int regno)
41c49b06
SB
230{
231 int ret, tid;
c2152441 232 elf_gregset_t regs;
41c49b06
SB
233
234 /* Get the thread id for the ptrace call. */
39f77062 235 tid = GET_THREAD_ID (inferior_ptid);
41c49b06
SB
236
237 ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
238 if (ret < 0)
239 {
edefbb7c 240 warning (_("Unable to fetch general register."));
41c49b06
SB
241 return;
242 }
243
34e8f22d 244 if (regno >= ARM_A1_REGNUM && regno < ARM_PC_REGNUM)
56be3814 245 regcache_raw_supply (regcache, regno, (char *) &regs[regno]);
41c49b06 246
34e8f22d 247 if (ARM_PS_REGNUM == regno)
41c49b06
SB
248 {
249 if (arm_apcs_32)
56be3814 250 regcache_raw_supply (regcache, ARM_PS_REGNUM,
17c12639 251 (char *) &regs[ARM_CPSR_GREGNUM]);
41c49b06 252 else
56be3814 253 regcache_raw_supply (regcache, ARM_PS_REGNUM,
23a6d369 254 (char *) &regs[ARM_PC_REGNUM]);
41c49b06
SB
255 }
256
34e8f22d 257 if (ARM_PC_REGNUM == regno)
41c49b06 258 {
bf6ae464 259 regs[ARM_PC_REGNUM] = gdbarch_addr_bits_remove
08790784
UW
260 (get_regcache_arch (regcache),
261 regs[ARM_PC_REGNUM]);
56be3814 262 regcache_raw_supply (regcache, ARM_PC_REGNUM,
23a6d369 263 (char *) &regs[ARM_PC_REGNUM]);
41c49b06
SB
264 }
265}
266
ed9a39eb 267/* Fetch all general registers of the process and store into
c6b92abd 268 regcache. */
ed9a39eb
JM
269
270static void
56be3814 271fetch_regs (struct regcache *regcache)
ed9a39eb 272{
41c49b06 273 int ret, regno, tid;
c2152441 274 elf_gregset_t regs;
ed9a39eb 275
41c49b06 276 /* Get the thread id for the ptrace call. */
39f77062 277 tid = GET_THREAD_ID (inferior_ptid);
41c49b06
SB
278
279 ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
ed9a39eb
JM
280 if (ret < 0)
281 {
edefbb7c 282 warning (_("Unable to fetch general registers."));
ed9a39eb
JM
283 return;
284 }
285
34e8f22d 286 for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
56be3814 287 regcache_raw_supply (regcache, regno, (char *) &regs[regno]);
ed9a39eb
JM
288
289 if (arm_apcs_32)
56be3814 290 regcache_raw_supply (regcache, ARM_PS_REGNUM,
17c12639 291 (char *) &regs[ARM_CPSR_GREGNUM]);
ed9a39eb 292 else
56be3814 293 regcache_raw_supply (regcache, ARM_PS_REGNUM,
23a6d369 294 (char *) &regs[ARM_PC_REGNUM]);
ed9a39eb 295
bf6ae464 296 regs[ARM_PC_REGNUM] = gdbarch_addr_bits_remove
08790784 297 (get_regcache_arch (regcache), regs[ARM_PC_REGNUM]);
56be3814 298 regcache_raw_supply (regcache, ARM_PC_REGNUM,
23a6d369 299 (char *) &regs[ARM_PC_REGNUM]);
ed9a39eb
JM
300}
301
302/* Store all general registers of the process from the values in
c6b92abd 303 regcache. */
ed9a39eb 304
41c49b06 305static void
56be3814 306store_register (const struct regcache *regcache, int regno)
41c49b06
SB
307{
308 int ret, tid;
c2152441 309 elf_gregset_t regs;
41c49b06 310
672c9795 311 if (REG_VALID != regcache_register_status (regcache, regno))
41c49b06
SB
312 return;
313
314 /* Get the thread id for the ptrace call. */
39f77062 315 tid = GET_THREAD_ID (inferior_ptid);
41c49b06
SB
316
317 /* Get the general registers from the process. */
318 ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
319 if (ret < 0)
320 {
edefbb7c 321 warning (_("Unable to fetch general registers."));
41c49b06
SB
322 return;
323 }
324
34e8f22d 325 if (regno >= ARM_A1_REGNUM && regno <= ARM_PC_REGNUM)
56be3814 326 regcache_raw_collect (regcache, regno, (char *) &regs[regno]);
adb8a87c 327 else if (arm_apcs_32 && regno == ARM_PS_REGNUM)
56be3814 328 regcache_raw_collect (regcache, regno,
17c12639 329 (char *) &regs[ARM_CPSR_GREGNUM]);
adb8a87c 330 else if (!arm_apcs_32 && regno == ARM_PS_REGNUM)
56be3814 331 regcache_raw_collect (regcache, ARM_PC_REGNUM,
adb8a87c 332 (char *) &regs[ARM_PC_REGNUM]);
41c49b06
SB
333
334 ret = ptrace (PTRACE_SETREGS, tid, 0, &regs);
335 if (ret < 0)
336 {
edefbb7c 337 warning (_("Unable to store general register."));
41c49b06
SB
338 return;
339 }
340}
341
ed9a39eb 342static void
56be3814 343store_regs (const struct regcache *regcache)
ed9a39eb 344{
41c49b06 345 int ret, regno, tid;
c2152441 346 elf_gregset_t regs;
ed9a39eb 347
41c49b06 348 /* Get the thread id for the ptrace call. */
39f77062 349 tid = GET_THREAD_ID (inferior_ptid);
41c49b06
SB
350
351 /* Fetch the general registers. */
352 ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
ed9a39eb
JM
353 if (ret < 0)
354 {
edefbb7c 355 warning (_("Unable to fetch general registers."));
ed9a39eb
JM
356 return;
357 }
358
34e8f22d 359 for (regno = ARM_A1_REGNUM; regno <= ARM_PC_REGNUM; regno++)
ed9a39eb 360 {
672c9795 361 if (REG_VALID == regcache_register_status (regcache, regno))
56be3814 362 regcache_raw_collect (regcache, regno, (char *) &regs[regno]);
ed9a39eb
JM
363 }
364
672c9795 365 if (arm_apcs_32 && REG_VALID == regcache_register_status (regcache, ARM_PS_REGNUM))
56be3814 366 regcache_raw_collect (regcache, ARM_PS_REGNUM,
17c12639 367 (char *) &regs[ARM_CPSR_GREGNUM]);
adb8a87c 368
41c49b06 369 ret = ptrace (PTRACE_SETREGS, tid, 0, &regs);
ed9a39eb
JM
370
371 if (ret < 0)
372 {
edefbb7c 373 warning (_("Unable to store general registers."));
ed9a39eb
JM
374 return;
375 }
376}
377
05a4558a
DJ
378/* Fetch all WMMX registers of the process and store into
379 regcache. */
380
381#define IWMMXT_REGS_SIZE (16 * 8 + 6 * 4)
382
383static void
56be3814 384fetch_wmmx_regs (struct regcache *regcache)
05a4558a
DJ
385{
386 char regbuf[IWMMXT_REGS_SIZE];
387 int ret, regno, tid;
388
389 /* Get the thread id for the ptrace call. */
390 tid = GET_THREAD_ID (inferior_ptid);
391
392 ret = ptrace (PTRACE_GETWMMXREGS, tid, 0, regbuf);
393 if (ret < 0)
394 {
395 warning (_("Unable to fetch WMMX registers."));
396 return;
397 }
398
399 for (regno = 0; regno < 16; regno++)
56be3814 400 regcache_raw_supply (regcache, regno + ARM_WR0_REGNUM,
05a4558a
DJ
401 &regbuf[regno * 8]);
402
403 for (regno = 0; regno < 2; regno++)
56be3814 404 regcache_raw_supply (regcache, regno + ARM_WCSSF_REGNUM,
05a4558a
DJ
405 &regbuf[16 * 8 + regno * 4]);
406
407 for (regno = 0; regno < 4; regno++)
56be3814 408 regcache_raw_supply (regcache, regno + ARM_WCGR0_REGNUM,
05a4558a
DJ
409 &regbuf[16 * 8 + 2 * 4 + regno * 4]);
410}
411
412static void
56be3814 413store_wmmx_regs (const struct regcache *regcache)
05a4558a
DJ
414{
415 char regbuf[IWMMXT_REGS_SIZE];
416 int ret, regno, tid;
417
418 /* Get the thread id for the ptrace call. */
419 tid = GET_THREAD_ID (inferior_ptid);
420
421 ret = ptrace (PTRACE_GETWMMXREGS, tid, 0, regbuf);
422 if (ret < 0)
423 {
424 warning (_("Unable to fetch WMMX registers."));
425 return;
426 }
427
428 for (regno = 0; regno < 16; regno++)
672c9795
YQ
429 if (REG_VALID == regcache_register_status (regcache,
430 regno + ARM_WR0_REGNUM))
56be3814 431 regcache_raw_collect (regcache, regno + ARM_WR0_REGNUM,
05a4558a
DJ
432 &regbuf[regno * 8]);
433
434 for (regno = 0; regno < 2; regno++)
672c9795
YQ
435 if (REG_VALID == regcache_register_status (regcache,
436 regno + ARM_WCSSF_REGNUM))
56be3814 437 regcache_raw_collect (regcache, regno + ARM_WCSSF_REGNUM,
05a4558a
DJ
438 &regbuf[16 * 8 + regno * 4]);
439
440 for (regno = 0; regno < 4; regno++)
672c9795
YQ
441 if (REG_VALID == regcache_register_status (regcache,
442 regno + ARM_WCGR0_REGNUM))
56be3814 443 regcache_raw_collect (regcache, regno + ARM_WCGR0_REGNUM,
05a4558a
DJ
444 &regbuf[16 * 8 + 2 * 4 + regno * 4]);
445
446 ret = ptrace (PTRACE_SETWMMXREGS, tid, 0, regbuf);
447
448 if (ret < 0)
449 {
450 warning (_("Unable to store WMMX registers."));
451 return;
452 }
453}
454
3b273a55
RE
455/* Fetch and store VFP Registers. The kernel object has space for 32
456 64-bit registers, and the FPSCR. This is even when on a VFPv2 or
457 VFPv3D16 target. */
458#define VFP_REGS_SIZE (32 * 8 + 4)
459
460static void
461fetch_vfp_regs (struct regcache *regcache)
462{
463 char regbuf[VFP_REGS_SIZE];
464 int ret, regno, tid;
465
466 /* Get the thread id for the ptrace call. */
467 tid = GET_THREAD_ID (inferior_ptid);
468
469 ret = ptrace (PTRACE_GETVFPREGS, tid, 0, regbuf);
470 if (ret < 0)
471 {
472 warning (_("Unable to fetch VFP registers."));
473 return;
474 }
475
476 for (regno = 0; regno < arm_linux_vfp_register_count; regno++)
477 regcache_raw_supply (regcache, regno + ARM_D0_REGNUM,
478 (char *) regbuf + regno * 8);
479
480 regcache_raw_supply (regcache, ARM_FPSCR_REGNUM,
481 (char *) regbuf + 32 * 8);
482}
483
484static void
485store_vfp_regs (const struct regcache *regcache)
486{
487 char regbuf[VFP_REGS_SIZE];
488 int ret, regno, tid;
489
490 /* Get the thread id for the ptrace call. */
491 tid = GET_THREAD_ID (inferior_ptid);
492
493 ret = ptrace (PTRACE_GETVFPREGS, tid, 0, regbuf);
494 if (ret < 0)
495 {
496 warning (_("Unable to fetch VFP registers (for update)."));
497 return;
498 }
499
500 for (regno = 0; regno < arm_linux_vfp_register_count; regno++)
501 regcache_raw_collect (regcache, regno + ARM_D0_REGNUM,
502 (char *) regbuf + regno * 8);
503
504 regcache_raw_collect (regcache, ARM_FPSCR_REGNUM,
505 (char *) regbuf + 32 * 8);
506
507 ret = ptrace (PTRACE_SETVFPREGS, tid, 0, regbuf);
508
509 if (ret < 0)
510 {
511 warning (_("Unable to store VFP registers."));
512 return;
513 }
514}
515
ed9a39eb
JM
516/* Fetch registers from the child process. Fetch all registers if
517 regno == -1, otherwise fetch all general registers or all floating
518 point registers depending upon the value of regno. */
519
10d6c8cd 520static void
28439f5e
PA
521arm_linux_fetch_inferior_registers (struct target_ops *ops,
522 struct regcache *regcache, int regno)
ed9a39eb 523{
41c49b06
SB
524 if (-1 == regno)
525 {
56be3814
UW
526 fetch_regs (regcache);
527 fetch_fpregs (regcache);
05a4558a 528 if (arm_linux_has_wmmx_registers)
56be3814 529 fetch_wmmx_regs (regcache);
3b273a55
RE
530 if (arm_linux_vfp_register_count > 0)
531 fetch_vfp_regs (regcache);
41c49b06
SB
532 }
533 else
534 {
05a4558a 535 if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM)
56be3814 536 fetch_register (regcache, regno);
05a4558a 537 else if (regno >= ARM_F0_REGNUM && regno <= ARM_FPS_REGNUM)
56be3814 538 fetch_fpregister (regcache, regno);
05a4558a
DJ
539 else if (arm_linux_has_wmmx_registers
540 && regno >= ARM_WR0_REGNUM && regno <= ARM_WCGR7_REGNUM)
56be3814 541 fetch_wmmx_regs (regcache);
3b273a55
RE
542 else if (arm_linux_vfp_register_count > 0
543 && regno >= ARM_D0_REGNUM
544 && regno <= ARM_D0_REGNUM + arm_linux_vfp_register_count)
545 fetch_vfp_regs (regcache);
41c49b06 546 }
ed9a39eb
JM
547}
548
549/* Store registers back into the inferior. Store all registers if
550 regno == -1, otherwise store all general registers or all floating
551 point registers depending upon the value of regno. */
552
10d6c8cd 553static void
28439f5e
PA
554arm_linux_store_inferior_registers (struct target_ops *ops,
555 struct regcache *regcache, int regno)
ed9a39eb 556{
41c49b06
SB
557 if (-1 == regno)
558 {
56be3814
UW
559 store_regs (regcache);
560 store_fpregs (regcache);
05a4558a 561 if (arm_linux_has_wmmx_registers)
56be3814 562 store_wmmx_regs (regcache);
3b273a55
RE
563 if (arm_linux_vfp_register_count > 0)
564 store_vfp_regs (regcache);
41c49b06
SB
565 }
566 else
567 {
05a4558a 568 if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM)
56be3814 569 store_register (regcache, regno);
05a4558a 570 else if ((regno >= ARM_F0_REGNUM) && (regno <= ARM_FPS_REGNUM))
56be3814 571 store_fpregister (regcache, regno);
05a4558a
DJ
572 else if (arm_linux_has_wmmx_registers
573 && regno >= ARM_WR0_REGNUM && regno <= ARM_WCGR7_REGNUM)
56be3814 574 store_wmmx_regs (regcache);
3b273a55
RE
575 else if (arm_linux_vfp_register_count > 0
576 && regno >= ARM_D0_REGNUM
577 && regno <= ARM_D0_REGNUM + arm_linux_vfp_register_count)
578 store_vfp_regs (regcache);
41c49b06 579 }
ed9a39eb
JM
580}
581
cb587d83
DJ
582/* Wrapper functions for the standard regset handling, used by
583 thread debugging. */
41c49b06
SB
584
585void
7f7fe91e
UW
586fill_gregset (const struct regcache *regcache,
587 gdb_gregset_t *gregsetp, int regno)
41c49b06 588{
7f7fe91e 589 arm_linux_collect_gregset (NULL, regcache, regno, gregsetp, 0);
41c49b06
SB
590}
591
41c49b06 592void
7f7fe91e 593supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
41c49b06 594{
7f7fe91e 595 arm_linux_supply_gregset (NULL, regcache, -1, gregsetp, 0);
41c49b06
SB
596}
597
41c49b06 598void
7f7fe91e
UW
599fill_fpregset (const struct regcache *regcache,
600 gdb_fpregset_t *fpregsetp, int regno)
41c49b06 601{
7f7fe91e 602 arm_linux_collect_nwfpe (NULL, regcache, regno, fpregsetp, 0);
41c49b06
SB
603}
604
605/* Fill GDB's register array with the floating-point register values
606 in *fpregsetp. */
607
608void
7f7fe91e 609supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
ed9a39eb 610{
7f7fe91e 611 arm_linux_supply_nwfpe (NULL, regcache, -1, fpregsetp, 0);
ed9a39eb
JM
612}
613
9308fc88
DJ
614/* Fetch the thread-local storage pointer for libthread_db. */
615
616ps_err_e
617ps_get_thread_area (const struct ps_prochandle *ph,
618 lwpid_t lwpid, int idx, void **base)
619{
620 if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
621 return PS_ERR;
622
623 /* IDX is the bias from the thread pointer to the beginning of the
624 thread descriptor. It has to be subtracted due to implementation
625 quirks in libthread_db. */
626 *base = (void *) ((char *)*base - idx);
627
628 return PS_OK;
629}
630
81adfced
DJ
631static const struct target_desc *
632arm_linux_read_description (struct target_ops *ops)
05a4558a 633{
3b273a55
RE
634 CORE_ADDR arm_hwcap = 0;
635 arm_linux_has_wmmx_registers = 0;
636 arm_linux_vfp_register_count = 0;
05a4558a 637
3b273a55
RE
638 if (target_auxv_search (ops, AT_HWCAP, &arm_hwcap) != 1)
639 {
640 return NULL;
641 }
81adfced 642
3b273a55
RE
643 if (arm_hwcap & HWCAP_IWMMXT)
644 {
645 arm_linux_has_wmmx_registers = 1;
3b273a55
RE
646 return tdesc_arm_with_iwmmxt;
647 }
648
649 if (arm_hwcap & HWCAP_VFP)
650 {
651 int pid;
652 char *buf;
653 const struct target_desc * result = NULL;
654
655 /* NEON implies VFPv3-D32 or no-VFP unit. Say that we only support
656 Neon with VFPv3-D32. */
657 if (arm_hwcap & HWCAP_NEON)
658 {
659 arm_linux_vfp_register_count = 32;
3b273a55
RE
660 result = tdesc_arm_with_neon;
661 }
662 else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPv3D16)) == HWCAP_VFPv3)
663 {
664 arm_linux_vfp_register_count = 32;
3b273a55
RE
665 result = tdesc_arm_with_vfpv3;
666 }
667 else
668 {
669 arm_linux_vfp_register_count = 16;
3b273a55
RE
670 result = tdesc_arm_with_vfpv2;
671 }
672
673 /* Now make sure that the kernel supports reading these
674 registers. Support was added in 2.6.30. */
675 pid = GET_LWP (inferior_ptid);
676 errno = 0;
677 buf = alloca (VFP_REGS_SIZE);
678 if (ptrace (PTRACE_GETVFPREGS, pid, 0, buf) < 0
679 && errno == EIO)
680 result = NULL;
681
682 return result;
683 }
684
685 return NULL;
05a4558a
DJ
686}
687
e3039479
UW
688/* Information describing the hardware breakpoint capabilities. */
689struct arm_linux_hwbp_cap
690{
691 gdb_byte arch;
692 gdb_byte max_wp_length;
693 gdb_byte wp_count;
694 gdb_byte bp_count;
695};
696
697/* Get hold of the Hardware Breakpoint information for the target we are
698 attached to. Returns NULL if the kernel doesn't support Hardware
699 breakpoints at all, or a pointer to the information structure. */
700static const struct arm_linux_hwbp_cap *
701arm_linux_get_hwbp_cap (void)
702{
703 /* The info structure we return. */
704 static struct arm_linux_hwbp_cap info;
705
706 /* Is INFO in a good state? -1 means that no attempt has been made to
707 initialize INFO; 0 means an attempt has been made, but it failed; 1
708 means INFO is in an initialized state. */
709 static int available = -1;
710
711 if (available == -1)
712 {
713 int tid;
714 unsigned int val;
715
716 tid = GET_THREAD_ID (inferior_ptid);
717 if (ptrace (PTRACE_GETHBPREGS, tid, 0, &val) < 0)
718 available = 0;
719 else
720 {
721 info.arch = (gdb_byte)((val >> 24) & 0xff);
722 info.max_wp_length = (gdb_byte)((val >> 16) & 0xff);
723 info.wp_count = (gdb_byte)((val >> 8) & 0xff);
724 info.bp_count = (gdb_byte)(val & 0xff);
725 available = (info.arch != 0);
726 }
727 }
728
729 return available == 1 ? &info : NULL;
730}
731
732/* How many hardware breakpoints are available? */
733static int
734arm_linux_get_hw_breakpoint_count (void)
735{
736 const struct arm_linux_hwbp_cap *cap = arm_linux_get_hwbp_cap ();
737 return cap != NULL ? cap->bp_count : 0;
738}
739
740/* How many hardware watchpoints are available? */
741static int
742arm_linux_get_hw_watchpoint_count (void)
743{
744 const struct arm_linux_hwbp_cap *cap = arm_linux_get_hwbp_cap ();
745 return cap != NULL ? cap->wp_count : 0;
746}
747
748/* Have we got a free break-/watch-point available for use? Returns -1 if
749 there is not an appropriate resource available, otherwise returns 1. */
750static int
751arm_linux_can_use_hw_breakpoint (int type, int cnt, int ot)
752{
753 if (type == bp_hardware_watchpoint || type == bp_read_watchpoint
754 || type == bp_access_watchpoint || type == bp_watchpoint)
755 {
756 if (cnt + ot > arm_linux_get_hw_watchpoint_count ())
757 return -1;
758 }
759 else if (type == bp_hardware_breakpoint)
760 {
761 if (cnt > arm_linux_get_hw_breakpoint_count ())
762 return -1;
763 }
764 else
765 gdb_assert (FALSE);
766
767 return 1;
768}
769
770/* Enum describing the different types of ARM hardware break-/watch-points. */
771typedef enum
772{
773 arm_hwbp_break = 0,
774 arm_hwbp_load = 1,
775 arm_hwbp_store = 2,
776 arm_hwbp_access = 3
777} arm_hwbp_type;
778
779/* Type describing an ARM Hardware Breakpoint Control register value. */
780typedef unsigned int arm_hwbp_control_t;
781
782/* Structure used to keep track of hardware break-/watch-points. */
783struct arm_linux_hw_breakpoint
784{
785 /* Address to break on, or being watched. */
786 unsigned int address;
787 /* Control register for break-/watch- point. */
788 arm_hwbp_control_t control;
789};
790
791/* Structure containing arrays of the break and watch points which are have
792 active in each thread.
793
794 The Linux ptrace interface to hardware break-/watch-points presents the
795 values in a vector centred around 0 (which is used fo generic information).
796 Positive indicies refer to breakpoint addresses/control registers, negative
797 indices to watchpoint addresses/control registers.
798
799 The Linux vector is indexed as follows:
800 -((i << 1) + 2): Control register for watchpoint i.
801 -((i << 1) + 1): Address register for watchpoint i.
802 0: Information register.
803 ((i << 1) + 1): Address register for breakpoint i.
804 ((i << 1) + 2): Control register for breakpoint i.
805
806 This structure is used as a per-thread cache of the state stored by the
807 kernel, so that we don't need to keep calling into the kernel to find a
808 free breakpoint.
809
810 We treat break-/watch-points with their enable bit clear as being deleted.
811 */
812typedef struct arm_linux_thread_points
813{
814 /* Thread ID. */
815 int tid;
816 /* Breakpoints for thread. */
817 struct arm_linux_hw_breakpoint *bpts;
818 /* Watchpoint for threads. */
819 struct arm_linux_hw_breakpoint *wpts;
820} *arm_linux_thread_points_p;
821DEF_VEC_P (arm_linux_thread_points_p);
822
823/* Vector of hardware breakpoints for each thread. */
824VEC(arm_linux_thread_points_p) *arm_threads = NULL;
825
826/* Find the list of hardware break-/watch-points for a thread with id TID.
827 If no list exists for TID we return NULL if ALLOC_NEW is 0, otherwise we
828 create a new list and return that. */
829static struct arm_linux_thread_points *
830arm_linux_find_breakpoints_by_tid (int tid, int alloc_new)
831{
832 int i;
833 struct arm_linux_thread_points *t;
834
835 for (i = 0; VEC_iterate (arm_linux_thread_points_p, arm_threads, i, t); ++i)
836 {
837 if (t->tid == tid)
838 return t;
839 }
840
841 t = NULL;
842
843 if (alloc_new)
844 {
845 t = xmalloc (sizeof (struct arm_linux_thread_points));
846 t->tid = tid;
847 t->bpts = xzalloc (arm_linux_get_hw_breakpoint_count ()
848 * sizeof (struct arm_linux_hw_breakpoint));
849 t->wpts = xzalloc (arm_linux_get_hw_watchpoint_count ()
850 * sizeof (struct arm_linux_hw_breakpoint));
851 VEC_safe_push (arm_linux_thread_points_p, arm_threads, t);
852 }
853
854 return t;
855}
856
857/* Initialize an ARM hardware break-/watch-point control register value.
858 BYTE_ADDRESS_SELECT is the mask of bytes to trigger on; HWBP_TYPE is the
859 type of break-/watch-point; ENABLE indicates whether the point is enabled.
860 */
861static arm_hwbp_control_t
862arm_hwbp_control_initialize (unsigned byte_address_select,
863 arm_hwbp_type hwbp_type,
864 int enable)
865{
866 gdb_assert ((byte_address_select & ~0xffU) == 0);
867 gdb_assert (hwbp_type != arm_hwbp_break
868 || ((byte_address_select & 0xfU) != 0));
869
870 return (byte_address_select << 5) | (hwbp_type << 3) | (3 << 1) | enable;
871}
872
873/* Does the breakpoint control value CONTROL have the enable bit set? */
874static int
875arm_hwbp_control_is_enabled (arm_hwbp_control_t control)
876{
877 return control & 0x1;
878}
879
880/* Change a breakpoint control word so that it is in the disabled state. */
881static arm_hwbp_control_t
882arm_hwbp_control_disable (arm_hwbp_control_t control)
883{
884 return control & ~0x1;
885}
886
887/* Initialise the hardware breakpoint structure P. The breakpoint will be
888 enabled, and will point to the placed address of BP_TGT. */
889static void
890arm_linux_hw_breakpoint_initialize (struct gdbarch *gdbarch,
891 struct bp_target_info *bp_tgt,
892 struct arm_linux_hw_breakpoint *p)
893{
894 unsigned mask;
895 CORE_ADDR address = bp_tgt->placed_address;
896
897 /* We have to create a mask for the control register which says which bits
898 of the word pointed to by address to break on. */
899 if (arm_pc_is_thumb (gdbarch, address))
900 mask = 0x3 << (address & 2);
901 else
902 mask = 0xf;
903
904 p->address = (unsigned int) (address & ~3);
905 p->control = arm_hwbp_control_initialize (mask, arm_hwbp_break, 1);
906}
907
908/* Get the ARM hardware breakpoint type from the RW value we're given when
909 asked to set a watchpoint. */
910static arm_hwbp_type
911arm_linux_get_hwbp_type (int rw)
912{
913 if (rw == hw_read)
914 return arm_hwbp_load;
915 else if (rw == hw_write)
916 return arm_hwbp_store;
917 else
918 return arm_hwbp_access;
919}
920
921/* Initialize the hardware breakpoint structure P for a watchpoint at ADDR
922 to LEN. The type of watchpoint is given in RW. */
923static void
924arm_linux_hw_watchpoint_initialize (CORE_ADDR addr, int len, int rw,
925 struct arm_linux_hw_breakpoint *p)
926{
927 const struct arm_linux_hwbp_cap *cap = arm_linux_get_hwbp_cap ();
928 unsigned mask;
929
930 gdb_assert (cap != NULL);
931 gdb_assert (cap->max_wp_length != 0);
932
933 mask = (1 << len) - 1;
934
935 p->address = (unsigned int) addr;
936 p->control = arm_hwbp_control_initialize (mask,
937 arm_linux_get_hwbp_type (rw), 1);
938}
939
940/* Are two break-/watch-points equal? */
941static int
942arm_linux_hw_breakpoint_equal (const struct arm_linux_hw_breakpoint *p1,
943 const struct arm_linux_hw_breakpoint *p2)
944{
945 return p1->address == p2->address && p1->control == p2->control;
946}
947
948/* Insert the hardware breakpoint (WATCHPOINT = 0) or watchpoint (WATCHPOINT
949 =1) BPT for thread TID. */
950static void
951arm_linux_insert_hw_breakpoint1 (const struct arm_linux_hw_breakpoint* bpt,
952 int tid, int watchpoint)
953{
954 struct arm_linux_thread_points *t = arm_linux_find_breakpoints_by_tid (tid, 1);
955 gdb_byte count, i;
956 struct arm_linux_hw_breakpoint* bpts;
957 int dir;
958
959 gdb_assert (t != NULL);
960
961 if (watchpoint)
962 {
963 count = arm_linux_get_hw_watchpoint_count ();
964 bpts = t->wpts;
965 dir = -1;
966 }
967 else
968 {
969 count = arm_linux_get_hw_breakpoint_count ();
970 bpts = t->bpts;
971 dir = 1;
972 }
973
974 for (i = 0; i < count; ++i)
975 if (!arm_hwbp_control_is_enabled (bpts[i].control))
976 {
977 errno = 0;
978 if (ptrace (PTRACE_SETHBPREGS, tid, dir * ((i << 1) + 1),
979 &bpt->address) < 0)
980 perror_with_name (_("Unexpected error setting breakpoint address"));
981 if (ptrace (PTRACE_SETHBPREGS, tid, dir * ((i << 1) + 2),
982 &bpt->control) < 0)
983 perror_with_name (_("Unexpected error setting breakpoint"));
984
985 memcpy (bpts + i, bpt, sizeof (struct arm_linux_hw_breakpoint));
986 break;
987 }
988
989 gdb_assert (i != count);
990}
991
992/* Remove the hardware breakpoint (WATCHPOINT = 0) or watchpoint
993 (WATCHPOINT = 1) BPT for thread TID. */
994static void
995arm_linux_remove_hw_breakpoint1 (const struct arm_linux_hw_breakpoint *bpt,
996 int tid, int watchpoint)
997{
998 struct arm_linux_thread_points *t = arm_linux_find_breakpoints_by_tid (tid, 0);
999 gdb_byte count, i;
1000 struct arm_linux_hw_breakpoint *bpts;
1001 int dir;
1002
1003 gdb_assert (t != NULL);
1004
1005 if (watchpoint)
1006 {
1007 count = arm_linux_get_hw_watchpoint_count ();
1008 bpts = t->wpts;
1009 dir = -1;
1010 }
1011 else
1012 {
1013 count = arm_linux_get_hw_breakpoint_count ();
1014 bpts = t->bpts;
1015 dir = 1;
1016 }
1017
1018 for (i = 0; i < count; ++i)
1019 if (arm_linux_hw_breakpoint_equal (bpt, bpts + i))
1020 {
1021 errno = 0;
1022 bpts[i].control = arm_hwbp_control_disable (bpts[i].control);
1023 if (ptrace (PTRACE_SETHBPREGS, tid, dir * ((i << 1) + 2),
1024 &bpts[i].control) < 0)
1025 perror_with_name (_("Unexpected error clearing breakpoint"));
1026 break;
1027 }
1028
1029 gdb_assert (i != count);
1030}
1031
1032/* Insert a Hardware breakpoint. */
1033static int
1034arm_linux_insert_hw_breakpoint (struct gdbarch *gdbarch,
1035 struct bp_target_info *bp_tgt)
1036{
e3039479
UW
1037 struct lwp_info *lp;
1038 struct arm_linux_hw_breakpoint p;
1039
1040 if (arm_linux_get_hw_breakpoint_count () == 0)
1041 return -1;
1042
1043 arm_linux_hw_breakpoint_initialize (gdbarch, bp_tgt, &p);
4c38200f
PA
1044 ALL_LWPS (lp)
1045 arm_linux_insert_hw_breakpoint1 (&p, TIDGET (lp->ptid), 0);
e3039479
UW
1046
1047 return 0;
1048}
1049
1050/* Remove a hardware breakpoint. */
1051static int
1052arm_linux_remove_hw_breakpoint (struct gdbarch *gdbarch,
1053 struct bp_target_info *bp_tgt)
1054{
e3039479
UW
1055 struct lwp_info *lp;
1056 struct arm_linux_hw_breakpoint p;
1057
1058 if (arm_linux_get_hw_breakpoint_count () == 0)
1059 return -1;
1060
1061 arm_linux_hw_breakpoint_initialize (gdbarch, bp_tgt, &p);
4c38200f
PA
1062 ALL_LWPS (lp)
1063 arm_linux_remove_hw_breakpoint1 (&p, TIDGET (lp->ptid), 0);
e3039479
UW
1064
1065 return 0;
1066}
1067
1068/* Are we able to use a hardware watchpoint for the LEN bytes starting at
1069 ADDR? */
1070static int
1071arm_linux_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
1072{
1073 const struct arm_linux_hwbp_cap *cap = arm_linux_get_hwbp_cap ();
1074 CORE_ADDR max_wp_length, aligned_addr;
1075
1076 /* Can not set watchpoints for zero or negative lengths. */
1077 if (len <= 0)
1078 return 0;
1079
1080 /* Need to be able to use the ptrace interface. */
1081 if (cap == NULL || cap->wp_count == 0)
1082 return 0;
1083
1084 /* Test that the range [ADDR, ADDR + LEN) fits into the largest address
1085 range covered by a watchpoint. */
1086 max_wp_length = (CORE_ADDR)cap->max_wp_length;
1087 aligned_addr = addr & ~(max_wp_length - 1);
1088
1089 if (aligned_addr + max_wp_length < addr + len)
1090 return 0;
1091
1092 /* The current ptrace interface can only handle watchpoints that are a
1093 power of 2. */
1094 if ((len & (len - 1)) != 0)
1095 return 0;
1096
1097 /* All tests passed so we must be able to set a watchpoint. */
1098 return 1;
1099}
1100
1101/* Insert a Hardware breakpoint. */
1102static int
1103arm_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
1104 struct expression *cond)
1105{
e3039479
UW
1106 struct lwp_info *lp;
1107 struct arm_linux_hw_breakpoint p;
1108
1109 if (arm_linux_get_hw_watchpoint_count () == 0)
1110 return -1;
1111
1112 arm_linux_hw_watchpoint_initialize (addr, len, rw, &p);
4c38200f
PA
1113 ALL_LWPS (lp)
1114 arm_linux_insert_hw_breakpoint1 (&p, TIDGET (lp->ptid), 1);
e3039479
UW
1115
1116 return 0;
1117}
1118
1119/* Remove a hardware breakpoint. */
1120static int
1121arm_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw,
1122 struct expression *cond)
1123{
e3039479
UW
1124 struct lwp_info *lp;
1125 struct arm_linux_hw_breakpoint p;
1126
1127 if (arm_linux_get_hw_watchpoint_count () == 0)
1128 return -1;
1129
1130 arm_linux_hw_watchpoint_initialize (addr, len, rw, &p);
4c38200f
PA
1131 ALL_LWPS (lp)
1132 arm_linux_remove_hw_breakpoint1 (&p, TIDGET (lp->ptid), 1);
e3039479
UW
1133
1134 return 0;
1135}
1136
1137/* What was the data address the target was stopped on accessing. */
1138static int
1139arm_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
1140{
1141 struct siginfo *siginfo_p = linux_nat_get_siginfo (inferior_ptid);
1142 int slot = siginfo_p->si_errno;
1143
1144 /* This must be a hardware breakpoint. */
1145 if (siginfo_p->si_signo != SIGTRAP
1146 || (siginfo_p->si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
1147 return 0;
1148
1149 /* We must be able to set hardware watchpoints. */
1150 if (arm_linux_get_hw_watchpoint_count () == 0)
1151 return 0;
1152
1153 /* If we are in a positive slot then we're looking at a breakpoint and not
1154 a watchpoint. */
1155 if (slot >= 0)
1156 return 0;
1157
1158 *addr_p = (CORE_ADDR) (uintptr_t) siginfo_p->si_addr;
1159 return 1;
1160}
1161
1162/* Has the target been stopped by hitting a watchpoint? */
1163static int
1164arm_linux_stopped_by_watchpoint (void)
1165{
1166 CORE_ADDR addr;
1167 return arm_linux_stopped_data_address (&current_target, &addr);
1168}
1169
1170static int
1171arm_linux_watchpoint_addr_within_range (struct target_ops *target,
1172 CORE_ADDR addr,
1173 CORE_ADDR start, int length)
1174{
1175 return start <= addr && start + length - 1 >= addr;
1176}
1177
1178/* Handle thread creation. We need to copy the breakpoints and watchpoints
1179 in the parent thread to the child thread. */
1180static void
7b50312a 1181arm_linux_new_thread (struct lwp_info *lp)
e3039479 1182{
7b50312a 1183 int tid = TIDGET (lp->ptid);
e3039479
UW
1184 const struct arm_linux_hwbp_cap *info = arm_linux_get_hwbp_cap ();
1185
1186 if (info != NULL)
1187 {
1188 int i;
1189 struct arm_linux_thread_points *p;
1190 struct arm_linux_hw_breakpoint *bpts;
1191
1192 if (VEC_empty (arm_linux_thread_points_p, arm_threads))
1193 return;
1194
1195 /* Get a list of breakpoints from any thread. */
1196 p = VEC_last (arm_linux_thread_points_p, arm_threads);
1197
1198 /* Copy that thread's breakpoints and watchpoints to the new thread. */
1199 for (i = 0; i < info->bp_count; i++)
1200 if (arm_hwbp_control_is_enabled (p->bpts[i].control))
1201 arm_linux_insert_hw_breakpoint1 (p->bpts + i, tid, 0);
1202 for (i = 0; i < info->wp_count; i++)
1203 if (arm_hwbp_control_is_enabled (p->wpts[i].control))
1204 arm_linux_insert_hw_breakpoint1 (p->wpts + i, tid, 1);
1205 }
1206}
1207
1208/* Handle thread exit. Tidy up the memory that has been allocated for the
1209 thread. */
1210static void
1211arm_linux_thread_exit (struct thread_info *tp, int silent)
1212{
1213 const struct arm_linux_hwbp_cap *info = arm_linux_get_hwbp_cap ();
1214
1215 if (info != NULL)
1216 {
1217 int i;
1218 int tid = TIDGET (tp->ptid);
1219 struct arm_linux_thread_points *t = NULL, *p;
1220
1221 for (i = 0;
1222 VEC_iterate (arm_linux_thread_points_p, arm_threads, i, p); i++)
1223 {
1224 if (p->tid == tid)
1225 {
1226 t = p;
1227 break;
1228 }
1229 }
1230
1231 if (t == NULL)
1232 return;
1233
1234 VEC_unordered_remove (arm_linux_thread_points_p, arm_threads, i);
1235
1236 xfree (t->bpts);
1237 xfree (t->wpts);
1238 xfree (t);
1239 }
1240}
1241
10d6c8cd
DJ
1242void _initialize_arm_linux_nat (void);
1243
ed9a39eb
JM
1244void
1245_initialize_arm_linux_nat (void)
1246{
10d6c8cd
DJ
1247 struct target_ops *t;
1248
10d6c8cd
DJ
1249 /* Fill in the generic GNU/Linux methods. */
1250 t = linux_target ();
1251
1252 /* Add our register access methods. */
1253 t->to_fetch_registers = arm_linux_fetch_inferior_registers;
1254 t->to_store_registers = arm_linux_store_inferior_registers;
1255
e3039479
UW
1256 /* Add our hardware breakpoint and watchpoint implementation. */
1257 t->to_can_use_hw_breakpoint = arm_linux_can_use_hw_breakpoint;
1258 t->to_insert_hw_breakpoint = arm_linux_insert_hw_breakpoint;
1259 t->to_remove_hw_breakpoint = arm_linux_remove_hw_breakpoint;
1260 t->to_region_ok_for_hw_watchpoint = arm_linux_region_ok_for_hw_watchpoint;
1261 t->to_insert_watchpoint = arm_linux_insert_watchpoint;
1262 t->to_remove_watchpoint = arm_linux_remove_watchpoint;
1263 t->to_stopped_by_watchpoint = arm_linux_stopped_by_watchpoint;
1264 t->to_stopped_data_address = arm_linux_stopped_data_address;
1265 t->to_watchpoint_addr_within_range = arm_linux_watchpoint_addr_within_range;
1266
81adfced 1267 t->to_read_description = arm_linux_read_description;
05a4558a 1268
10d6c8cd 1269 /* Register the target. */
f973ed9c 1270 linux_nat_add_target (t);
e3039479
UW
1271
1272 /* Handle thread creation and exit */
1273 observer_attach_thread_exit (arm_linux_thread_exit);
1274 linux_nat_set_new_thread (t, arm_linux_new_thread);
ed9a39eb 1275}
This page took 0.741532 seconds and 4 git commands to generate.