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