1 /* GNU/Linux on ARM native support. 2 Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 3 2010, 2011 Free Software Foundation, Inc. 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 9 the Free Software Foundation; either version 3 of the License, or 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 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #include "defs.h" 21 #include "inferior.h" 22 #include "gdbcore.h" 23 #include "gdb_string.h" 24 #include "regcache.h" 25 #include "target.h" 26 #include "linux-nat.h" 27 #include "target-descriptions.h" 28 #include "auxv.h" 29 #include "observer.h" 30 #include "gdbthread.h" 31 32 #include "arm-tdep.h" 33 #include "arm-linux-tdep.h" 34 35 #include <elf/common.h> 36 #include <sys/user.h> 37 #include <sys/ptrace.h> 38 #include <sys/utsname.h> 39 #include <sys/procfs.h> 40 41 /* Prototypes for supply_gregset etc. */ 42 #include "gregset.h" 43 44 /* Defines ps_err_e, struct ps_prochandle. */ 45 #include "gdb_proc_service.h" 46 47 #include "features/arm-with-iwmmxt.c" 48 #include "features/arm-with-vfpv2.c" 49 #include "features/arm-with-vfpv3.c" 50 #include "features/arm-with-neon.c" 51 52 #ifndef PTRACE_GET_THREAD_AREA 53 #define PTRACE_GET_THREAD_AREA 22 54 #endif 55 56 #ifndef PTRACE_GETWMMXREGS 57 #define PTRACE_GETWMMXREGS 18 58 #define PTRACE_SETWMMXREGS 19 59 #endif 60 61 #ifndef PTRACE_GETVFPREGS 62 #define PTRACE_GETVFPREGS 27 63 #define PTRACE_SETVFPREGS 28 64 #endif 65 66 #ifndef PTRACE_GETHBPREGS 67 #define PTRACE_GETHBPREGS 29 68 #define PTRACE_SETHBPREGS 30 69 #endif 70 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 78 /* A flag for whether the WMMX registers are available. */ 79 static int arm_linux_has_wmmx_registers; 80 81 /* The number of 64-bit VFP registers we have (expect this to be 0, 82 16, or 32). */ 83 static int arm_linux_vfp_register_count; 84 85 extern int arm_apcs_32; 86 87 /* The following variables are used to determine the version of the 88 underlying GNU/Linux operating system. Examples: 89 90 GNU/Linux 2.0.35 GNU/Linux 2.2.12 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 101 static unsigned int os_version, os_major, os_minor, os_release; 102 103 /* On GNU/Linux, threads are implemented as pseudo-processes, in which 104 case we may be tracing more than one process at a time. In that 105 case, inferior_ptid will contain the main process ID and the 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. */ 108 109 int 110 get_thread_id (ptid_t ptid) 111 { 112 int tid = TIDGET (ptid); 113 if (0 == tid) 114 tid = PIDGET (ptid); 115 return tid; 116 } 117 118 #define GET_THREAD_ID(PTID) get_thread_id (PTID) 119 120 /* Get the value of a particular register from the floating point 121 state of the process and store it into regcache. */ 122 123 static void 124 fetch_fpregister (struct regcache *regcache, int regno) 125 { 126 int ret, tid; 127 gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE]; 128 129 /* Get the thread id for the ptrace call. */ 130 tid = GET_THREAD_ID (inferior_ptid); 131 132 /* Read the floating point state. */ 133 ret = ptrace (PT_GETFPREGS, tid, 0, fp); 134 if (ret < 0) 135 { 136 warning (_("Unable to fetch floating point register.")); 137 return; 138 } 139 140 /* Fetch fpsr. */ 141 if (ARM_FPS_REGNUM == regno) 142 regcache_raw_supply (regcache, ARM_FPS_REGNUM, 143 fp + NWFPE_FPSR_OFFSET); 144 145 /* Fetch the floating point register. */ 146 if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM) 147 supply_nwfpe_register (regcache, regno, fp); 148 } 149 150 /* Get the whole floating point state of the process and store it 151 into regcache. */ 152 153 static void 154 fetch_fpregs (struct regcache *regcache) 155 { 156 int ret, regno, tid; 157 gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE]; 158 159 /* Get the thread id for the ptrace call. */ 160 tid = GET_THREAD_ID (inferior_ptid); 161 162 /* Read the floating point state. */ 163 ret = ptrace (PT_GETFPREGS, tid, 0, fp); 164 if (ret < 0) 165 { 166 warning (_("Unable to fetch the floating point registers.")); 167 return; 168 } 169 170 /* Fetch fpsr. */ 171 regcache_raw_supply (regcache, ARM_FPS_REGNUM, 172 fp + NWFPE_FPSR_OFFSET); 173 174 /* Fetch the floating point registers. */ 175 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++) 176 supply_nwfpe_register (regcache, regno, fp); 177 } 178 179 /* Save a particular register into the floating point state of the 180 process using the contents from regcache. */ 181 182 static void 183 store_fpregister (const struct regcache *regcache, int regno) 184 { 185 int ret, tid; 186 gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE]; 187 188 /* Get the thread id for the ptrace call. */ 189 tid = GET_THREAD_ID (inferior_ptid); 190 191 /* Read the floating point state. */ 192 ret = ptrace (PT_GETFPREGS, tid, 0, fp); 193 if (ret < 0) 194 { 195 warning (_("Unable to fetch the floating point registers.")); 196 return; 197 } 198 199 /* Store fpsr. */ 200 if (ARM_FPS_REGNUM == regno 201 && REG_VALID == regcache_register_status (regcache, ARM_FPS_REGNUM)) 202 regcache_raw_collect (regcache, ARM_FPS_REGNUM, fp + NWFPE_FPSR_OFFSET); 203 204 /* Store the floating point register. */ 205 if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM) 206 collect_nwfpe_register (regcache, regno, fp); 207 208 ret = ptrace (PTRACE_SETFPREGS, tid, 0, fp); 209 if (ret < 0) 210 { 211 warning (_("Unable to store floating point register.")); 212 return; 213 } 214 } 215 216 /* Save the whole floating point state of the process using 217 the contents from regcache. */ 218 219 static void 220 store_fpregs (const struct regcache *regcache) 221 { 222 int ret, regno, tid; 223 gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE]; 224 225 /* Get the thread id for the ptrace call. */ 226 tid = GET_THREAD_ID (inferior_ptid); 227 228 /* Read the floating point state. */ 229 ret = ptrace (PT_GETFPREGS, tid, 0, fp); 230 if (ret < 0) 231 { 232 warning (_("Unable to fetch the floating point registers.")); 233 return; 234 } 235 236 /* Store fpsr. */ 237 if (REG_VALID == regcache_register_status (regcache, ARM_FPS_REGNUM)) 238 regcache_raw_collect (regcache, ARM_FPS_REGNUM, fp + NWFPE_FPSR_OFFSET); 239 240 /* Store the floating point registers. */ 241 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++) 242 if (REG_VALID == regcache_register_status (regcache, regno)) 243 collect_nwfpe_register (regcache, regno, fp); 244 245 ret = ptrace (PTRACE_SETFPREGS, tid, 0, fp); 246 if (ret < 0) 247 { 248 warning (_("Unable to store floating point registers.")); 249 return; 250 } 251 } 252 253 /* Fetch a general register of the process and store into 254 regcache. */ 255 256 static void 257 fetch_register (struct regcache *regcache, int regno) 258 { 259 int ret, tid; 260 elf_gregset_t regs; 261 262 /* Get the thread id for the ptrace call. */ 263 tid = GET_THREAD_ID (inferior_ptid); 264 265 ret = ptrace (PTRACE_GETREGS, tid, 0, ®s); 266 if (ret < 0) 267 { 268 warning (_("Unable to fetch general register.")); 269 return; 270 } 271 272 if (regno >= ARM_A1_REGNUM && regno < ARM_PC_REGNUM) 273 regcache_raw_supply (regcache, regno, (char *) ®s[regno]); 274 275 if (ARM_PS_REGNUM == regno) 276 { 277 if (arm_apcs_32) 278 regcache_raw_supply (regcache, ARM_PS_REGNUM, 279 (char *) ®s[ARM_CPSR_GREGNUM]); 280 else 281 regcache_raw_supply (regcache, ARM_PS_REGNUM, 282 (char *) ®s[ARM_PC_REGNUM]); 283 } 284 285 if (ARM_PC_REGNUM == regno) 286 { 287 regs[ARM_PC_REGNUM] = gdbarch_addr_bits_remove 288 (get_regcache_arch (regcache), 289 regs[ARM_PC_REGNUM]); 290 regcache_raw_supply (regcache, ARM_PC_REGNUM, 291 (char *) ®s[ARM_PC_REGNUM]); 292 } 293 } 294 295 /* Fetch all general registers of the process and store into 296 regcache. */ 297 298 static void 299 fetch_regs (struct regcache *regcache) 300 { 301 int ret, regno, tid; 302 elf_gregset_t regs; 303 304 /* Get the thread id for the ptrace call. */ 305 tid = GET_THREAD_ID (inferior_ptid); 306 307 ret = ptrace (PTRACE_GETREGS, tid, 0, ®s); 308 if (ret < 0) 309 { 310 warning (_("Unable to fetch general registers.")); 311 return; 312 } 313 314 for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++) 315 regcache_raw_supply (regcache, regno, (char *) ®s[regno]); 316 317 if (arm_apcs_32) 318 regcache_raw_supply (regcache, ARM_PS_REGNUM, 319 (char *) ®s[ARM_CPSR_GREGNUM]); 320 else 321 regcache_raw_supply (regcache, ARM_PS_REGNUM, 322 (char *) ®s[ARM_PC_REGNUM]); 323 324 regs[ARM_PC_REGNUM] = gdbarch_addr_bits_remove 325 (get_regcache_arch (regcache), regs[ARM_PC_REGNUM]); 326 regcache_raw_supply (regcache, ARM_PC_REGNUM, 327 (char *) ®s[ARM_PC_REGNUM]); 328 } 329 330 /* Store all general registers of the process from the values in 331 regcache. */ 332 333 static void 334 store_register (const struct regcache *regcache, int regno) 335 { 336 int ret, tid; 337 elf_gregset_t regs; 338 339 if (REG_VALID != regcache_register_status (regcache, regno)) 340 return; 341 342 /* Get the thread id for the ptrace call. */ 343 tid = GET_THREAD_ID (inferior_ptid); 344 345 /* Get the general registers from the process. */ 346 ret = ptrace (PTRACE_GETREGS, tid, 0, ®s); 347 if (ret < 0) 348 { 349 warning (_("Unable to fetch general registers.")); 350 return; 351 } 352 353 if (regno >= ARM_A1_REGNUM && regno <= ARM_PC_REGNUM) 354 regcache_raw_collect (regcache, regno, (char *) ®s[regno]); 355 else if (arm_apcs_32 && regno == ARM_PS_REGNUM) 356 regcache_raw_collect (regcache, regno, 357 (char *) ®s[ARM_CPSR_GREGNUM]); 358 else if (!arm_apcs_32 && regno == ARM_PS_REGNUM) 359 regcache_raw_collect (regcache, ARM_PC_REGNUM, 360 (char *) ®s[ARM_PC_REGNUM]); 361 362 ret = ptrace (PTRACE_SETREGS, tid, 0, ®s); 363 if (ret < 0) 364 { 365 warning (_("Unable to store general register.")); 366 return; 367 } 368 } 369 370 static void 371 store_regs (const struct regcache *regcache) 372 { 373 int ret, regno, tid; 374 elf_gregset_t regs; 375 376 /* Get the thread id for the ptrace call. */ 377 tid = GET_THREAD_ID (inferior_ptid); 378 379 /* Fetch the general registers. */ 380 ret = ptrace (PTRACE_GETREGS, tid, 0, ®s); 381 if (ret < 0) 382 { 383 warning (_("Unable to fetch general registers.")); 384 return; 385 } 386 387 for (regno = ARM_A1_REGNUM; regno <= ARM_PC_REGNUM; regno++) 388 { 389 if (REG_VALID == regcache_register_status (regcache, regno)) 390 regcache_raw_collect (regcache, regno, (char *) ®s[regno]); 391 } 392 393 if (arm_apcs_32 && REG_VALID == regcache_register_status (regcache, ARM_PS_REGNUM)) 394 regcache_raw_collect (regcache, ARM_PS_REGNUM, 395 (char *) ®s[ARM_CPSR_GREGNUM]); 396 397 ret = ptrace (PTRACE_SETREGS, tid, 0, ®s); 398 399 if (ret < 0) 400 { 401 warning (_("Unable to store general registers.")); 402 return; 403 } 404 } 405 406 /* Fetch all WMMX registers of the process and store into 407 regcache. */ 408 409 #define IWMMXT_REGS_SIZE (16 * 8 + 6 * 4) 410 411 static void 412 fetch_wmmx_regs (struct regcache *regcache) 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++) 428 regcache_raw_supply (regcache, regno + ARM_WR0_REGNUM, 429 ®buf[regno * 8]); 430 431 for (regno = 0; regno < 2; regno++) 432 regcache_raw_supply (regcache, regno + ARM_WCSSF_REGNUM, 433 ®buf[16 * 8 + regno * 4]); 434 435 for (regno = 0; regno < 4; regno++) 436 regcache_raw_supply (regcache, regno + ARM_WCGR0_REGNUM, 437 ®buf[16 * 8 + 2 * 4 + regno * 4]); 438 } 439 440 static void 441 store_wmmx_regs (const struct regcache *regcache) 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++) 457 if (REG_VALID == regcache_register_status (regcache, 458 regno + ARM_WR0_REGNUM)) 459 regcache_raw_collect (regcache, regno + ARM_WR0_REGNUM, 460 ®buf[regno * 8]); 461 462 for (regno = 0; regno < 2; regno++) 463 if (REG_VALID == regcache_register_status (regcache, 464 regno + ARM_WCSSF_REGNUM)) 465 regcache_raw_collect (regcache, regno + ARM_WCSSF_REGNUM, 466 ®buf[16 * 8 + regno * 4]); 467 468 for (regno = 0; regno < 4; regno++) 469 if (REG_VALID == regcache_register_status (regcache, 470 regno + ARM_WCGR0_REGNUM)) 471 regcache_raw_collect (regcache, regno + ARM_WCGR0_REGNUM, 472 ®buf[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 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 488 static void 489 fetch_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 512 static void 513 store_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 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 548 static void 549 arm_linux_fetch_inferior_registers (struct target_ops *ops, 550 struct regcache *regcache, int regno) 551 { 552 if (-1 == regno) 553 { 554 fetch_regs (regcache); 555 fetch_fpregs (regcache); 556 if (arm_linux_has_wmmx_registers) 557 fetch_wmmx_regs (regcache); 558 if (arm_linux_vfp_register_count > 0) 559 fetch_vfp_regs (regcache); 560 } 561 else 562 { 563 if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM) 564 fetch_register (regcache, regno); 565 else if (regno >= ARM_F0_REGNUM && regno <= ARM_FPS_REGNUM) 566 fetch_fpregister (regcache, regno); 567 else if (arm_linux_has_wmmx_registers 568 && regno >= ARM_WR0_REGNUM && regno <= ARM_WCGR7_REGNUM) 569 fetch_wmmx_regs (regcache); 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); 574 } 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 581 static void 582 arm_linux_store_inferior_registers (struct target_ops *ops, 583 struct regcache *regcache, int regno) 584 { 585 if (-1 == regno) 586 { 587 store_regs (regcache); 588 store_fpregs (regcache); 589 if (arm_linux_has_wmmx_registers) 590 store_wmmx_regs (regcache); 591 if (arm_linux_vfp_register_count > 0) 592 store_vfp_regs (regcache); 593 } 594 else 595 { 596 if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM) 597 store_register (regcache, regno); 598 else if ((regno >= ARM_F0_REGNUM) && (regno <= ARM_FPS_REGNUM)) 599 store_fpregister (regcache, regno); 600 else if (arm_linux_has_wmmx_registers 601 && regno >= ARM_WR0_REGNUM && regno <= ARM_WCGR7_REGNUM) 602 store_wmmx_regs (regcache); 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); 607 } 608 } 609 610 /* Wrapper functions for the standard regset handling, used by 611 thread debugging. */ 612 613 void 614 fill_gregset (const struct regcache *regcache, 615 gdb_gregset_t *gregsetp, int regno) 616 { 617 arm_linux_collect_gregset (NULL, regcache, regno, gregsetp, 0); 618 } 619 620 void 621 supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp) 622 { 623 arm_linux_supply_gregset (NULL, regcache, -1, gregsetp, 0); 624 } 625 626 void 627 fill_fpregset (const struct regcache *regcache, 628 gdb_fpregset_t *fpregsetp, int regno) 629 { 630 arm_linux_collect_nwfpe (NULL, regcache, regno, fpregsetp, 0); 631 } 632 633 /* Fill GDB's register array with the floating-point register values 634 in *fpregsetp. */ 635 636 void 637 supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp) 638 { 639 arm_linux_supply_nwfpe (NULL, regcache, -1, fpregsetp, 0); 640 } 641 642 /* Fetch the thread-local storage pointer for libthread_db. */ 643 644 ps_err_e 645 ps_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 659 static unsigned int 660 get_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 { 669 warning (_("Unable to determine GNU/Linux version.")); 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 684 static const struct target_desc * 685 arm_linux_read_description (struct target_ops *ops) 686 { 687 CORE_ADDR arm_hwcap = 0; 688 arm_linux_has_wmmx_registers = 0; 689 arm_linux_vfp_register_count = 0; 690 691 if (target_auxv_search (ops, AT_HWCAP, &arm_hwcap) != 1) 692 { 693 return NULL; 694 } 695 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; 747 } 748 749 /* Information describing the hardware breakpoint capabilities. */ 750 struct 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. */ 761 static const struct arm_linux_hwbp_cap * 762 arm_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? */ 794 static int 795 arm_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? */ 802 static int 803 arm_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. */ 811 static int 812 arm_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. */ 832 typedef 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. */ 841 typedef unsigned int arm_hwbp_control_t; 842 843 /* Structure used to keep track of hardware break-/watch-points. */ 844 struct 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 */ 873 typedef 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; 882 DEF_VEC_P (arm_linux_thread_points_p); 883 884 /* Vector of hardware breakpoints for each thread. */ 885 VEC(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. */ 890 static struct arm_linux_thread_points * 891 arm_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 */ 922 static arm_hwbp_control_t 923 arm_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? */ 935 static int 936 arm_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. */ 942 static arm_hwbp_control_t 943 arm_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. */ 950 static void 951 arm_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. */ 971 static arm_hwbp_type 972 arm_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. */ 984 static void 985 arm_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? */ 1002 static int 1003 arm_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. */ 1011 static void 1012 arm_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. */ 1055 static void 1056 arm_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. */ 1094 static int 1095 arm_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. */ 1113 static int 1114 arm_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? */ 1133 static int 1134 arm_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. */ 1165 static int 1166 arm_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. */ 1184 static int 1185 arm_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. */ 1203 static int 1204 arm_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? */ 1228 static int 1229 arm_linux_stopped_by_watchpoint (void) 1230 { 1231 CORE_ADDR addr; 1232 return arm_linux_stopped_data_address (¤t_target, &addr); 1233 } 1234 1235 static int 1236 arm_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. */ 1245 static void 1246 arm_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. */ 1275 static void 1276 arm_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 1307 void _initialize_arm_linux_nat (void); 1308 1309 void 1310 _initialize_arm_linux_nat (void) 1311 { 1312 struct target_ops *t; 1313 1314 os_version = get_linux_version (&os_major, &os_minor, &os_release); 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 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 1334 t->to_read_description = arm_linux_read_description; 1335 1336 /* Register the target. */ 1337 linux_nat_add_target (t); 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); 1342 } 1343