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