GDB (API)
|
00001 /* GNU/Linux on ARM native support. 00002 Copyright (C) 1999-2013 Free Software Foundation, Inc. 00003 00004 This file is part of GDB. 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00018 00019 #include "defs.h" 00020 #include "inferior.h" 00021 #include "gdbcore.h" 00022 #include "gdb_string.h" 00023 #include "regcache.h" 00024 #include "target.h" 00025 #include "linux-nat.h" 00026 #include "target-descriptions.h" 00027 #include "auxv.h" 00028 #include "observer.h" 00029 #include "gdbthread.h" 00030 00031 #include "arm-tdep.h" 00032 #include "arm-linux-tdep.h" 00033 00034 #include <elf/common.h> 00035 #include <sys/user.h> 00036 #include <sys/ptrace.h> 00037 #include <sys/utsname.h> 00038 #include <sys/procfs.h> 00039 00040 /* Prototypes for supply_gregset etc. */ 00041 #include "gregset.h" 00042 00043 /* Defines ps_err_e, struct ps_prochandle. */ 00044 #include "gdb_proc_service.h" 00045 00046 #ifndef PTRACE_GET_THREAD_AREA 00047 #define PTRACE_GET_THREAD_AREA 22 00048 #endif 00049 00050 #ifndef PTRACE_GETWMMXREGS 00051 #define PTRACE_GETWMMXREGS 18 00052 #define PTRACE_SETWMMXREGS 19 00053 #endif 00054 00055 #ifndef PTRACE_GETVFPREGS 00056 #define PTRACE_GETVFPREGS 27 00057 #define PTRACE_SETVFPREGS 28 00058 #endif 00059 00060 #ifndef PTRACE_GETHBPREGS 00061 #define PTRACE_GETHBPREGS 29 00062 #define PTRACE_SETHBPREGS 30 00063 #endif 00064 00065 /* A flag for whether the WMMX registers are available. */ 00066 static int arm_linux_has_wmmx_registers; 00067 00068 /* The number of 64-bit VFP registers we have (expect this to be 0, 00069 16, or 32). */ 00070 static int arm_linux_vfp_register_count; 00071 00072 extern int arm_apcs_32; 00073 00074 /* On GNU/Linux, threads are implemented as pseudo-processes, in which 00075 case we may be tracing more than one process at a time. In that 00076 case, inferior_ptid will contain the main process ID and the 00077 individual thread (process) ID. get_thread_id () is used to get 00078 the thread id if it's available, and the process id otherwise. */ 00079 00080 static int 00081 get_thread_id (ptid_t ptid) 00082 { 00083 int tid = ptid_get_lwp (ptid); 00084 if (0 == tid) 00085 tid = ptid_get_pid (ptid); 00086 return tid; 00087 } 00088 00089 #define GET_THREAD_ID(PTID) get_thread_id (PTID) 00090 00091 /* Get the value of a particular register from the floating point 00092 state of the process and store it into regcache. */ 00093 00094 static void 00095 fetch_fpregister (struct regcache *regcache, int regno) 00096 { 00097 int ret, tid; 00098 gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE]; 00099 00100 /* Get the thread id for the ptrace call. */ 00101 tid = GET_THREAD_ID (inferior_ptid); 00102 00103 /* Read the floating point state. */ 00104 ret = ptrace (PT_GETFPREGS, tid, 0, fp); 00105 if (ret < 0) 00106 { 00107 warning (_("Unable to fetch floating point register.")); 00108 return; 00109 } 00110 00111 /* Fetch fpsr. */ 00112 if (ARM_FPS_REGNUM == regno) 00113 regcache_raw_supply (regcache, ARM_FPS_REGNUM, 00114 fp + NWFPE_FPSR_OFFSET); 00115 00116 /* Fetch the floating point register. */ 00117 if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM) 00118 supply_nwfpe_register (regcache, regno, fp); 00119 } 00120 00121 /* Get the whole floating point state of the process and store it 00122 into regcache. */ 00123 00124 static void 00125 fetch_fpregs (struct regcache *regcache) 00126 { 00127 int ret, regno, tid; 00128 gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE]; 00129 00130 /* Get the thread id for the ptrace call. */ 00131 tid = GET_THREAD_ID (inferior_ptid); 00132 00133 /* Read the floating point state. */ 00134 ret = ptrace (PT_GETFPREGS, tid, 0, fp); 00135 if (ret < 0) 00136 { 00137 warning (_("Unable to fetch the floating point registers.")); 00138 return; 00139 } 00140 00141 /* Fetch fpsr. */ 00142 regcache_raw_supply (regcache, ARM_FPS_REGNUM, 00143 fp + NWFPE_FPSR_OFFSET); 00144 00145 /* Fetch the floating point registers. */ 00146 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++) 00147 supply_nwfpe_register (regcache, regno, fp); 00148 } 00149 00150 /* Save a particular register into the floating point state of the 00151 process using the contents from regcache. */ 00152 00153 static void 00154 store_fpregister (const struct regcache *regcache, int regno) 00155 { 00156 int ret, tid; 00157 gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE]; 00158 00159 /* Get the thread id for the ptrace call. */ 00160 tid = GET_THREAD_ID (inferior_ptid); 00161 00162 /* Read the floating point state. */ 00163 ret = ptrace (PT_GETFPREGS, tid, 0, fp); 00164 if (ret < 0) 00165 { 00166 warning (_("Unable to fetch the floating point registers.")); 00167 return; 00168 } 00169 00170 /* Store fpsr. */ 00171 if (ARM_FPS_REGNUM == regno 00172 && REG_VALID == regcache_register_status (regcache, ARM_FPS_REGNUM)) 00173 regcache_raw_collect (regcache, ARM_FPS_REGNUM, fp + NWFPE_FPSR_OFFSET); 00174 00175 /* Store the floating point register. */ 00176 if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM) 00177 collect_nwfpe_register (regcache, regno, fp); 00178 00179 ret = ptrace (PTRACE_SETFPREGS, tid, 0, fp); 00180 if (ret < 0) 00181 { 00182 warning (_("Unable to store floating point register.")); 00183 return; 00184 } 00185 } 00186 00187 /* Save the whole floating point state of the process using 00188 the contents from regcache. */ 00189 00190 static void 00191 store_fpregs (const struct regcache *regcache) 00192 { 00193 int ret, regno, tid; 00194 gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE]; 00195 00196 /* Get the thread id for the ptrace call. */ 00197 tid = GET_THREAD_ID (inferior_ptid); 00198 00199 /* Read the floating point state. */ 00200 ret = ptrace (PT_GETFPREGS, tid, 0, fp); 00201 if (ret < 0) 00202 { 00203 warning (_("Unable to fetch the floating point registers.")); 00204 return; 00205 } 00206 00207 /* Store fpsr. */ 00208 if (REG_VALID == regcache_register_status (regcache, ARM_FPS_REGNUM)) 00209 regcache_raw_collect (regcache, ARM_FPS_REGNUM, fp + NWFPE_FPSR_OFFSET); 00210 00211 /* Store the floating point registers. */ 00212 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++) 00213 if (REG_VALID == regcache_register_status (regcache, regno)) 00214 collect_nwfpe_register (regcache, regno, fp); 00215 00216 ret = ptrace (PTRACE_SETFPREGS, tid, 0, fp); 00217 if (ret < 0) 00218 { 00219 warning (_("Unable to store floating point registers.")); 00220 return; 00221 } 00222 } 00223 00224 /* Fetch a general register of the process and store into 00225 regcache. */ 00226 00227 static void 00228 fetch_register (struct regcache *regcache, int regno) 00229 { 00230 int ret, tid; 00231 elf_gregset_t regs; 00232 00233 /* Get the thread id for the ptrace call. */ 00234 tid = GET_THREAD_ID (inferior_ptid); 00235 00236 ret = ptrace (PTRACE_GETREGS, tid, 0, ®s); 00237 if (ret < 0) 00238 { 00239 warning (_("Unable to fetch general register.")); 00240 return; 00241 } 00242 00243 if (regno >= ARM_A1_REGNUM && regno < ARM_PC_REGNUM) 00244 regcache_raw_supply (regcache, regno, (char *) ®s[regno]); 00245 00246 if (ARM_PS_REGNUM == regno) 00247 { 00248 if (arm_apcs_32) 00249 regcache_raw_supply (regcache, ARM_PS_REGNUM, 00250 (char *) ®s[ARM_CPSR_GREGNUM]); 00251 else 00252 regcache_raw_supply (regcache, ARM_PS_REGNUM, 00253 (char *) ®s[ARM_PC_REGNUM]); 00254 } 00255 00256 if (ARM_PC_REGNUM == regno) 00257 { 00258 regs[ARM_PC_REGNUM] = gdbarch_addr_bits_remove 00259 (get_regcache_arch (regcache), 00260 regs[ARM_PC_REGNUM]); 00261 regcache_raw_supply (regcache, ARM_PC_REGNUM, 00262 (char *) ®s[ARM_PC_REGNUM]); 00263 } 00264 } 00265 00266 /* Fetch all general registers of the process and store into 00267 regcache. */ 00268 00269 static void 00270 fetch_regs (struct regcache *regcache) 00271 { 00272 int ret, regno, tid; 00273 elf_gregset_t regs; 00274 00275 /* Get the thread id for the ptrace call. */ 00276 tid = GET_THREAD_ID (inferior_ptid); 00277 00278 ret = ptrace (PTRACE_GETREGS, tid, 0, ®s); 00279 if (ret < 0) 00280 { 00281 warning (_("Unable to fetch general registers.")); 00282 return; 00283 } 00284 00285 for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++) 00286 regcache_raw_supply (regcache, regno, (char *) ®s[regno]); 00287 00288 if (arm_apcs_32) 00289 regcache_raw_supply (regcache, ARM_PS_REGNUM, 00290 (char *) ®s[ARM_CPSR_GREGNUM]); 00291 else 00292 regcache_raw_supply (regcache, ARM_PS_REGNUM, 00293 (char *) ®s[ARM_PC_REGNUM]); 00294 00295 regs[ARM_PC_REGNUM] = gdbarch_addr_bits_remove 00296 (get_regcache_arch (regcache), regs[ARM_PC_REGNUM]); 00297 regcache_raw_supply (regcache, ARM_PC_REGNUM, 00298 (char *) ®s[ARM_PC_REGNUM]); 00299 } 00300 00301 /* Store all general registers of the process from the values in 00302 regcache. */ 00303 00304 static void 00305 store_register (const struct regcache *regcache, int regno) 00306 { 00307 int ret, tid; 00308 elf_gregset_t regs; 00309 00310 if (REG_VALID != regcache_register_status (regcache, regno)) 00311 return; 00312 00313 /* Get the thread id for the ptrace call. */ 00314 tid = GET_THREAD_ID (inferior_ptid); 00315 00316 /* Get the general registers from the process. */ 00317 ret = ptrace (PTRACE_GETREGS, tid, 0, ®s); 00318 if (ret < 0) 00319 { 00320 warning (_("Unable to fetch general registers.")); 00321 return; 00322 } 00323 00324 if (regno >= ARM_A1_REGNUM && regno <= ARM_PC_REGNUM) 00325 regcache_raw_collect (regcache, regno, (char *) ®s[regno]); 00326 else if (arm_apcs_32 && regno == ARM_PS_REGNUM) 00327 regcache_raw_collect (regcache, regno, 00328 (char *) ®s[ARM_CPSR_GREGNUM]); 00329 else if (!arm_apcs_32 && regno == ARM_PS_REGNUM) 00330 regcache_raw_collect (regcache, ARM_PC_REGNUM, 00331 (char *) ®s[ARM_PC_REGNUM]); 00332 00333 ret = ptrace (PTRACE_SETREGS, tid, 0, ®s); 00334 if (ret < 0) 00335 { 00336 warning (_("Unable to store general register.")); 00337 return; 00338 } 00339 } 00340 00341 static void 00342 store_regs (const struct regcache *regcache) 00343 { 00344 int ret, regno, tid; 00345 elf_gregset_t regs; 00346 00347 /* Get the thread id for the ptrace call. */ 00348 tid = GET_THREAD_ID (inferior_ptid); 00349 00350 /* Fetch the general registers. */ 00351 ret = ptrace (PTRACE_GETREGS, tid, 0, ®s); 00352 if (ret < 0) 00353 { 00354 warning (_("Unable to fetch general registers.")); 00355 return; 00356 } 00357 00358 for (regno = ARM_A1_REGNUM; regno <= ARM_PC_REGNUM; regno++) 00359 { 00360 if (REG_VALID == regcache_register_status (regcache, regno)) 00361 regcache_raw_collect (regcache, regno, (char *) ®s[regno]); 00362 } 00363 00364 if (arm_apcs_32 && REG_VALID == regcache_register_status (regcache, ARM_PS_REGNUM)) 00365 regcache_raw_collect (regcache, ARM_PS_REGNUM, 00366 (char *) ®s[ARM_CPSR_GREGNUM]); 00367 00368 ret = ptrace (PTRACE_SETREGS, tid, 0, ®s); 00369 00370 if (ret < 0) 00371 { 00372 warning (_("Unable to store general registers.")); 00373 return; 00374 } 00375 } 00376 00377 /* Fetch all WMMX registers of the process and store into 00378 regcache. */ 00379 00380 #define IWMMXT_REGS_SIZE (16 * 8 + 6 * 4) 00381 00382 static void 00383 fetch_wmmx_regs (struct regcache *regcache) 00384 { 00385 char regbuf[IWMMXT_REGS_SIZE]; 00386 int ret, regno, tid; 00387 00388 /* Get the thread id for the ptrace call. */ 00389 tid = GET_THREAD_ID (inferior_ptid); 00390 00391 ret = ptrace (PTRACE_GETWMMXREGS, tid, 0, regbuf); 00392 if (ret < 0) 00393 { 00394 warning (_("Unable to fetch WMMX registers.")); 00395 return; 00396 } 00397 00398 for (regno = 0; regno < 16; regno++) 00399 regcache_raw_supply (regcache, regno + ARM_WR0_REGNUM, 00400 ®buf[regno * 8]); 00401 00402 for (regno = 0; regno < 2; regno++) 00403 regcache_raw_supply (regcache, regno + ARM_WCSSF_REGNUM, 00404 ®buf[16 * 8 + regno * 4]); 00405 00406 for (regno = 0; regno < 4; regno++) 00407 regcache_raw_supply (regcache, regno + ARM_WCGR0_REGNUM, 00408 ®buf[16 * 8 + 2 * 4 + regno * 4]); 00409 } 00410 00411 static void 00412 store_wmmx_regs (const struct regcache *regcache) 00413 { 00414 char regbuf[IWMMXT_REGS_SIZE]; 00415 int ret, regno, tid; 00416 00417 /* Get the thread id for the ptrace call. */ 00418 tid = GET_THREAD_ID (inferior_ptid); 00419 00420 ret = ptrace (PTRACE_GETWMMXREGS, tid, 0, regbuf); 00421 if (ret < 0) 00422 { 00423 warning (_("Unable to fetch WMMX registers.")); 00424 return; 00425 } 00426 00427 for (regno = 0; regno < 16; regno++) 00428 if (REG_VALID == regcache_register_status (regcache, 00429 regno + ARM_WR0_REGNUM)) 00430 regcache_raw_collect (regcache, regno + ARM_WR0_REGNUM, 00431 ®buf[regno * 8]); 00432 00433 for (regno = 0; regno < 2; regno++) 00434 if (REG_VALID == regcache_register_status (regcache, 00435 regno + ARM_WCSSF_REGNUM)) 00436 regcache_raw_collect (regcache, regno + ARM_WCSSF_REGNUM, 00437 ®buf[16 * 8 + regno * 4]); 00438 00439 for (regno = 0; regno < 4; regno++) 00440 if (REG_VALID == regcache_register_status (regcache, 00441 regno + ARM_WCGR0_REGNUM)) 00442 regcache_raw_collect (regcache, regno + ARM_WCGR0_REGNUM, 00443 ®buf[16 * 8 + 2 * 4 + regno * 4]); 00444 00445 ret = ptrace (PTRACE_SETWMMXREGS, tid, 0, regbuf); 00446 00447 if (ret < 0) 00448 { 00449 warning (_("Unable to store WMMX registers.")); 00450 return; 00451 } 00452 } 00453 00454 /* Fetch and store VFP Registers. The kernel object has space for 32 00455 64-bit registers, and the FPSCR. This is even when on a VFPv2 or 00456 VFPv3D16 target. */ 00457 #define VFP_REGS_SIZE (32 * 8 + 4) 00458 00459 static void 00460 fetch_vfp_regs (struct regcache *regcache) 00461 { 00462 char regbuf[VFP_REGS_SIZE]; 00463 int ret, regno, tid; 00464 00465 /* Get the thread id for the ptrace call. */ 00466 tid = GET_THREAD_ID (inferior_ptid); 00467 00468 ret = ptrace (PTRACE_GETVFPREGS, tid, 0, regbuf); 00469 if (ret < 0) 00470 { 00471 warning (_("Unable to fetch VFP registers.")); 00472 return; 00473 } 00474 00475 for (regno = 0; regno < arm_linux_vfp_register_count; regno++) 00476 regcache_raw_supply (regcache, regno + ARM_D0_REGNUM, 00477 (char *) regbuf + regno * 8); 00478 00479 regcache_raw_supply (regcache, ARM_FPSCR_REGNUM, 00480 (char *) regbuf + 32 * 8); 00481 } 00482 00483 static void 00484 store_vfp_regs (const struct regcache *regcache) 00485 { 00486 char regbuf[VFP_REGS_SIZE]; 00487 int ret, regno, tid; 00488 00489 /* Get the thread id for the ptrace call. */ 00490 tid = GET_THREAD_ID (inferior_ptid); 00491 00492 ret = ptrace (PTRACE_GETVFPREGS, tid, 0, regbuf); 00493 if (ret < 0) 00494 { 00495 warning (_("Unable to fetch VFP registers (for update).")); 00496 return; 00497 } 00498 00499 for (regno = 0; regno < arm_linux_vfp_register_count; regno++) 00500 regcache_raw_collect (regcache, regno + ARM_D0_REGNUM, 00501 (char *) regbuf + regno * 8); 00502 00503 regcache_raw_collect (regcache, ARM_FPSCR_REGNUM, 00504 (char *) regbuf + 32 * 8); 00505 00506 ret = ptrace (PTRACE_SETVFPREGS, tid, 0, regbuf); 00507 00508 if (ret < 0) 00509 { 00510 warning (_("Unable to store VFP registers.")); 00511 return; 00512 } 00513 } 00514 00515 /* Fetch registers from the child process. Fetch all registers if 00516 regno == -1, otherwise fetch all general registers or all floating 00517 point registers depending upon the value of regno. */ 00518 00519 static void 00520 arm_linux_fetch_inferior_registers (struct target_ops *ops, 00521 struct regcache *regcache, int regno) 00522 { 00523 if (-1 == regno) 00524 { 00525 fetch_regs (regcache); 00526 fetch_fpregs (regcache); 00527 if (arm_linux_has_wmmx_registers) 00528 fetch_wmmx_regs (regcache); 00529 if (arm_linux_vfp_register_count > 0) 00530 fetch_vfp_regs (regcache); 00531 } 00532 else 00533 { 00534 if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM) 00535 fetch_register (regcache, regno); 00536 else if (regno >= ARM_F0_REGNUM && regno <= ARM_FPS_REGNUM) 00537 fetch_fpregister (regcache, regno); 00538 else if (arm_linux_has_wmmx_registers 00539 && regno >= ARM_WR0_REGNUM && regno <= ARM_WCGR7_REGNUM) 00540 fetch_wmmx_regs (regcache); 00541 else if (arm_linux_vfp_register_count > 0 00542 && regno >= ARM_D0_REGNUM 00543 && regno <= ARM_D0_REGNUM + arm_linux_vfp_register_count) 00544 fetch_vfp_regs (regcache); 00545 } 00546 } 00547 00548 /* Store registers back into the inferior. Store all registers if 00549 regno == -1, otherwise store all general registers or all floating 00550 point registers depending upon the value of regno. */ 00551 00552 static void 00553 arm_linux_store_inferior_registers (struct target_ops *ops, 00554 struct regcache *regcache, int regno) 00555 { 00556 if (-1 == regno) 00557 { 00558 store_regs (regcache); 00559 store_fpregs (regcache); 00560 if (arm_linux_has_wmmx_registers) 00561 store_wmmx_regs (regcache); 00562 if (arm_linux_vfp_register_count > 0) 00563 store_vfp_regs (regcache); 00564 } 00565 else 00566 { 00567 if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM) 00568 store_register (regcache, regno); 00569 else if ((regno >= ARM_F0_REGNUM) && (regno <= ARM_FPS_REGNUM)) 00570 store_fpregister (regcache, regno); 00571 else if (arm_linux_has_wmmx_registers 00572 && regno >= ARM_WR0_REGNUM && regno <= ARM_WCGR7_REGNUM) 00573 store_wmmx_regs (regcache); 00574 else if (arm_linux_vfp_register_count > 0 00575 && regno >= ARM_D0_REGNUM 00576 && regno <= ARM_D0_REGNUM + arm_linux_vfp_register_count) 00577 store_vfp_regs (regcache); 00578 } 00579 } 00580 00581 /* Wrapper functions for the standard regset handling, used by 00582 thread debugging. */ 00583 00584 void 00585 fill_gregset (const struct regcache *regcache, 00586 gdb_gregset_t *gregsetp, int regno) 00587 { 00588 arm_linux_collect_gregset (NULL, regcache, regno, gregsetp, 0); 00589 } 00590 00591 void 00592 supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp) 00593 { 00594 arm_linux_supply_gregset (NULL, regcache, -1, gregsetp, 0); 00595 } 00596 00597 void 00598 fill_fpregset (const struct regcache *regcache, 00599 gdb_fpregset_t *fpregsetp, int regno) 00600 { 00601 arm_linux_collect_nwfpe (NULL, regcache, regno, fpregsetp, 0); 00602 } 00603 00604 /* Fill GDB's register array with the floating-point register values 00605 in *fpregsetp. */ 00606 00607 void 00608 supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp) 00609 { 00610 arm_linux_supply_nwfpe (NULL, regcache, -1, fpregsetp, 0); 00611 } 00612 00613 /* Fetch the thread-local storage pointer for libthread_db. */ 00614 00615 ps_err_e 00616 ps_get_thread_area (const struct ps_prochandle *ph, 00617 lwpid_t lwpid, int idx, void **base) 00618 { 00619 if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0) 00620 return PS_ERR; 00621 00622 /* IDX is the bias from the thread pointer to the beginning of the 00623 thread descriptor. It has to be subtracted due to implementation 00624 quirks in libthread_db. */ 00625 *base = (void *) ((char *)*base - idx); 00626 00627 return PS_OK; 00628 } 00629 00630 static const struct target_desc * 00631 arm_linux_read_description (struct target_ops *ops) 00632 { 00633 CORE_ADDR arm_hwcap = 0; 00634 arm_linux_has_wmmx_registers = 0; 00635 arm_linux_vfp_register_count = 0; 00636 00637 if (target_auxv_search (ops, AT_HWCAP, &arm_hwcap) != 1) 00638 { 00639 return NULL; 00640 } 00641 00642 if (arm_hwcap & HWCAP_IWMMXT) 00643 { 00644 arm_linux_has_wmmx_registers = 1; 00645 return tdesc_arm_with_iwmmxt; 00646 } 00647 00648 if (arm_hwcap & HWCAP_VFP) 00649 { 00650 int pid; 00651 char *buf; 00652 const struct target_desc * result = NULL; 00653 00654 /* NEON implies VFPv3-D32 or no-VFP unit. Say that we only support 00655 Neon with VFPv3-D32. */ 00656 if (arm_hwcap & HWCAP_NEON) 00657 { 00658 arm_linux_vfp_register_count = 32; 00659 result = tdesc_arm_with_neon; 00660 } 00661 else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPv3D16)) == HWCAP_VFPv3) 00662 { 00663 arm_linux_vfp_register_count = 32; 00664 result = tdesc_arm_with_vfpv3; 00665 } 00666 else 00667 { 00668 arm_linux_vfp_register_count = 16; 00669 result = tdesc_arm_with_vfpv2; 00670 } 00671 00672 /* Now make sure that the kernel supports reading these 00673 registers. Support was added in 2.6.30. */ 00674 pid = ptid_get_lwp (inferior_ptid); 00675 errno = 0; 00676 buf = alloca (VFP_REGS_SIZE); 00677 if (ptrace (PTRACE_GETVFPREGS, pid, 0, buf) < 0 00678 && errno == EIO) 00679 result = NULL; 00680 00681 return result; 00682 } 00683 00684 return NULL; 00685 } 00686 00687 /* Information describing the hardware breakpoint capabilities. */ 00688 struct arm_linux_hwbp_cap 00689 { 00690 gdb_byte arch; 00691 gdb_byte max_wp_length; 00692 gdb_byte wp_count; 00693 gdb_byte bp_count; 00694 }; 00695 00696 /* Get hold of the Hardware Breakpoint information for the target we are 00697 attached to. Returns NULL if the kernel doesn't support Hardware 00698 breakpoints at all, or a pointer to the information structure. */ 00699 static const struct arm_linux_hwbp_cap * 00700 arm_linux_get_hwbp_cap (void) 00701 { 00702 /* The info structure we return. */ 00703 static struct arm_linux_hwbp_cap info; 00704 00705 /* Is INFO in a good state? -1 means that no attempt has been made to 00706 initialize INFO; 0 means an attempt has been made, but it failed; 1 00707 means INFO is in an initialized state. */ 00708 static int available = -1; 00709 00710 if (available == -1) 00711 { 00712 int tid; 00713 unsigned int val; 00714 00715 tid = GET_THREAD_ID (inferior_ptid); 00716 if (ptrace (PTRACE_GETHBPREGS, tid, 0, &val) < 0) 00717 available = 0; 00718 else 00719 { 00720 info.arch = (gdb_byte)((val >> 24) & 0xff); 00721 info.max_wp_length = (gdb_byte)((val >> 16) & 0xff); 00722 info.wp_count = (gdb_byte)((val >> 8) & 0xff); 00723 info.bp_count = (gdb_byte)(val & 0xff); 00724 available = (info.arch != 0); 00725 } 00726 } 00727 00728 return available == 1 ? &info : NULL; 00729 } 00730 00731 /* How many hardware breakpoints are available? */ 00732 static int 00733 arm_linux_get_hw_breakpoint_count (void) 00734 { 00735 const struct arm_linux_hwbp_cap *cap = arm_linux_get_hwbp_cap (); 00736 return cap != NULL ? cap->bp_count : 0; 00737 } 00738 00739 /* How many hardware watchpoints are available? */ 00740 static int 00741 arm_linux_get_hw_watchpoint_count (void) 00742 { 00743 const struct arm_linux_hwbp_cap *cap = arm_linux_get_hwbp_cap (); 00744 return cap != NULL ? cap->wp_count : 0; 00745 } 00746 00747 /* Have we got a free break-/watch-point available for use? Returns -1 if 00748 there is not an appropriate resource available, otherwise returns 1. */ 00749 static int 00750 arm_linux_can_use_hw_breakpoint (int type, int cnt, int ot) 00751 { 00752 if (type == bp_hardware_watchpoint || type == bp_read_watchpoint 00753 || type == bp_access_watchpoint || type == bp_watchpoint) 00754 { 00755 if (cnt + ot > arm_linux_get_hw_watchpoint_count ()) 00756 return -1; 00757 } 00758 else if (type == bp_hardware_breakpoint) 00759 { 00760 if (cnt > arm_linux_get_hw_breakpoint_count ()) 00761 return -1; 00762 } 00763 else 00764 gdb_assert (FALSE); 00765 00766 return 1; 00767 } 00768 00769 /* Enum describing the different types of ARM hardware break-/watch-points. */ 00770 typedef enum 00771 { 00772 arm_hwbp_break = 0, 00773 arm_hwbp_load = 1, 00774 arm_hwbp_store = 2, 00775 arm_hwbp_access = 3 00776 } arm_hwbp_type; 00777 00778 /* Type describing an ARM Hardware Breakpoint Control register value. */ 00779 typedef unsigned int arm_hwbp_control_t; 00780 00781 /* Structure used to keep track of hardware break-/watch-points. */ 00782 struct arm_linux_hw_breakpoint 00783 { 00784 /* Address to break on, or being watched. */ 00785 unsigned int address; 00786 /* Control register for break-/watch- point. */ 00787 arm_hwbp_control_t control; 00788 }; 00789 00790 /* Structure containing arrays of the break and watch points which are have 00791 active in each thread. 00792 00793 The Linux ptrace interface to hardware break-/watch-points presents the 00794 values in a vector centred around 0 (which is used fo generic information). 00795 Positive indicies refer to breakpoint addresses/control registers, negative 00796 indices to watchpoint addresses/control registers. 00797 00798 The Linux vector is indexed as follows: 00799 -((i << 1) + 2): Control register for watchpoint i. 00800 -((i << 1) + 1): Address register for watchpoint i. 00801 0: Information register. 00802 ((i << 1) + 1): Address register for breakpoint i. 00803 ((i << 1) + 2): Control register for breakpoint i. 00804 00805 This structure is used as a per-thread cache of the state stored by the 00806 kernel, so that we don't need to keep calling into the kernel to find a 00807 free breakpoint. 00808 00809 We treat break-/watch-points with their enable bit clear as being deleted. 00810 */ 00811 typedef struct arm_linux_thread_points 00812 { 00813 /* Thread ID. */ 00814 int tid; 00815 /* Breakpoints for thread. */ 00816 struct arm_linux_hw_breakpoint *bpts; 00817 /* Watchpoint for threads. */ 00818 struct arm_linux_hw_breakpoint *wpts; 00819 } *arm_linux_thread_points_p; 00820 DEF_VEC_P (arm_linux_thread_points_p); 00821 00822 /* Vector of hardware breakpoints for each thread. */ 00823 VEC(arm_linux_thread_points_p) *arm_threads = NULL; 00824 00825 /* Find the list of hardware break-/watch-points for a thread with id TID. 00826 If no list exists for TID we return NULL if ALLOC_NEW is 0, otherwise we 00827 create a new list and return that. */ 00828 static struct arm_linux_thread_points * 00829 arm_linux_find_breakpoints_by_tid (int tid, int alloc_new) 00830 { 00831 int i; 00832 struct arm_linux_thread_points *t; 00833 00834 for (i = 0; VEC_iterate (arm_linux_thread_points_p, arm_threads, i, t); ++i) 00835 { 00836 if (t->tid == tid) 00837 return t; 00838 } 00839 00840 t = NULL; 00841 00842 if (alloc_new) 00843 { 00844 t = xmalloc (sizeof (struct arm_linux_thread_points)); 00845 t->tid = tid; 00846 t->bpts = xzalloc (arm_linux_get_hw_breakpoint_count () 00847 * sizeof (struct arm_linux_hw_breakpoint)); 00848 t->wpts = xzalloc (arm_linux_get_hw_watchpoint_count () 00849 * sizeof (struct arm_linux_hw_breakpoint)); 00850 VEC_safe_push (arm_linux_thread_points_p, arm_threads, t); 00851 } 00852 00853 return t; 00854 } 00855 00856 /* Initialize an ARM hardware break-/watch-point control register value. 00857 BYTE_ADDRESS_SELECT is the mask of bytes to trigger on; HWBP_TYPE is the 00858 type of break-/watch-point; ENABLE indicates whether the point is enabled. 00859 */ 00860 static arm_hwbp_control_t 00861 arm_hwbp_control_initialize (unsigned byte_address_select, 00862 arm_hwbp_type hwbp_type, 00863 int enable) 00864 { 00865 gdb_assert ((byte_address_select & ~0xffU) == 0); 00866 gdb_assert (hwbp_type != arm_hwbp_break 00867 || ((byte_address_select & 0xfU) != 0)); 00868 00869 return (byte_address_select << 5) | (hwbp_type << 3) | (3 << 1) | enable; 00870 } 00871 00872 /* Does the breakpoint control value CONTROL have the enable bit set? */ 00873 static int 00874 arm_hwbp_control_is_enabled (arm_hwbp_control_t control) 00875 { 00876 return control & 0x1; 00877 } 00878 00879 /* Change a breakpoint control word so that it is in the disabled state. */ 00880 static arm_hwbp_control_t 00881 arm_hwbp_control_disable (arm_hwbp_control_t control) 00882 { 00883 return control & ~0x1; 00884 } 00885 00886 /* Initialise the hardware breakpoint structure P. The breakpoint will be 00887 enabled, and will point to the placed address of BP_TGT. */ 00888 static void 00889 arm_linux_hw_breakpoint_initialize (struct gdbarch *gdbarch, 00890 struct bp_target_info *bp_tgt, 00891 struct arm_linux_hw_breakpoint *p) 00892 { 00893 unsigned mask; 00894 CORE_ADDR address = bp_tgt->placed_address; 00895 00896 /* We have to create a mask for the control register which says which bits 00897 of the word pointed to by address to break on. */ 00898 if (arm_pc_is_thumb (gdbarch, address)) 00899 { 00900 mask = 0x3; 00901 address &= ~1; 00902 } 00903 else 00904 { 00905 mask = 0xf; 00906 address &= ~3; 00907 } 00908 00909 p->address = (unsigned int) address; 00910 p->control = arm_hwbp_control_initialize (mask, arm_hwbp_break, 1); 00911 } 00912 00913 /* Get the ARM hardware breakpoint type from the RW value we're given when 00914 asked to set a watchpoint. */ 00915 static arm_hwbp_type 00916 arm_linux_get_hwbp_type (int rw) 00917 { 00918 if (rw == hw_read) 00919 return arm_hwbp_load; 00920 else if (rw == hw_write) 00921 return arm_hwbp_store; 00922 else 00923 return arm_hwbp_access; 00924 } 00925 00926 /* Initialize the hardware breakpoint structure P for a watchpoint at ADDR 00927 to LEN. The type of watchpoint is given in RW. */ 00928 static void 00929 arm_linux_hw_watchpoint_initialize (CORE_ADDR addr, int len, int rw, 00930 struct arm_linux_hw_breakpoint *p) 00931 { 00932 const struct arm_linux_hwbp_cap *cap = arm_linux_get_hwbp_cap (); 00933 unsigned mask; 00934 00935 gdb_assert (cap != NULL); 00936 gdb_assert (cap->max_wp_length != 0); 00937 00938 mask = (1 << len) - 1; 00939 00940 p->address = (unsigned int) addr; 00941 p->control = arm_hwbp_control_initialize (mask, 00942 arm_linux_get_hwbp_type (rw), 1); 00943 } 00944 00945 /* Are two break-/watch-points equal? */ 00946 static int 00947 arm_linux_hw_breakpoint_equal (const struct arm_linux_hw_breakpoint *p1, 00948 const struct arm_linux_hw_breakpoint *p2) 00949 { 00950 return p1->address == p2->address && p1->control == p2->control; 00951 } 00952 00953 /* Insert the hardware breakpoint (WATCHPOINT = 0) or watchpoint (WATCHPOINT 00954 =1) BPT for thread TID. */ 00955 static void 00956 arm_linux_insert_hw_breakpoint1 (const struct arm_linux_hw_breakpoint* bpt, 00957 int tid, int watchpoint) 00958 { 00959 struct arm_linux_thread_points *t = arm_linux_find_breakpoints_by_tid (tid, 1); 00960 gdb_byte count, i; 00961 struct arm_linux_hw_breakpoint* bpts; 00962 int dir; 00963 00964 gdb_assert (t != NULL); 00965 00966 if (watchpoint) 00967 { 00968 count = arm_linux_get_hw_watchpoint_count (); 00969 bpts = t->wpts; 00970 dir = -1; 00971 } 00972 else 00973 { 00974 count = arm_linux_get_hw_breakpoint_count (); 00975 bpts = t->bpts; 00976 dir = 1; 00977 } 00978 00979 for (i = 0; i < count; ++i) 00980 if (!arm_hwbp_control_is_enabled (bpts[i].control)) 00981 { 00982 errno = 0; 00983 if (ptrace (PTRACE_SETHBPREGS, tid, dir * ((i << 1) + 1), 00984 &bpt->address) < 0) 00985 perror_with_name (_("Unexpected error setting breakpoint address")); 00986 if (ptrace (PTRACE_SETHBPREGS, tid, dir * ((i << 1) + 2), 00987 &bpt->control) < 0) 00988 perror_with_name (_("Unexpected error setting breakpoint")); 00989 00990 memcpy (bpts + i, bpt, sizeof (struct arm_linux_hw_breakpoint)); 00991 break; 00992 } 00993 00994 gdb_assert (i != count); 00995 } 00996 00997 /* Remove the hardware breakpoint (WATCHPOINT = 0) or watchpoint 00998 (WATCHPOINT = 1) BPT for thread TID. */ 00999 static void 01000 arm_linux_remove_hw_breakpoint1 (const struct arm_linux_hw_breakpoint *bpt, 01001 int tid, int watchpoint) 01002 { 01003 struct arm_linux_thread_points *t = arm_linux_find_breakpoints_by_tid (tid, 0); 01004 gdb_byte count, i; 01005 struct arm_linux_hw_breakpoint *bpts; 01006 int dir; 01007 01008 gdb_assert (t != NULL); 01009 01010 if (watchpoint) 01011 { 01012 count = arm_linux_get_hw_watchpoint_count (); 01013 bpts = t->wpts; 01014 dir = -1; 01015 } 01016 else 01017 { 01018 count = arm_linux_get_hw_breakpoint_count (); 01019 bpts = t->bpts; 01020 dir = 1; 01021 } 01022 01023 for (i = 0; i < count; ++i) 01024 if (arm_linux_hw_breakpoint_equal (bpt, bpts + i)) 01025 { 01026 errno = 0; 01027 bpts[i].control = arm_hwbp_control_disable (bpts[i].control); 01028 if (ptrace (PTRACE_SETHBPREGS, tid, dir * ((i << 1) + 2), 01029 &bpts[i].control) < 0) 01030 perror_with_name (_("Unexpected error clearing breakpoint")); 01031 break; 01032 } 01033 01034 gdb_assert (i != count); 01035 } 01036 01037 /* Insert a Hardware breakpoint. */ 01038 static int 01039 arm_linux_insert_hw_breakpoint (struct gdbarch *gdbarch, 01040 struct bp_target_info *bp_tgt) 01041 { 01042 struct lwp_info *lp; 01043 struct arm_linux_hw_breakpoint p; 01044 01045 if (arm_linux_get_hw_breakpoint_count () == 0) 01046 return -1; 01047 01048 arm_linux_hw_breakpoint_initialize (gdbarch, bp_tgt, &p); 01049 ALL_LWPS (lp) 01050 arm_linux_insert_hw_breakpoint1 (&p, ptid_get_lwp (lp->ptid), 0); 01051 01052 return 0; 01053 } 01054 01055 /* Remove a hardware breakpoint. */ 01056 static int 01057 arm_linux_remove_hw_breakpoint (struct gdbarch *gdbarch, 01058 struct bp_target_info *bp_tgt) 01059 { 01060 struct lwp_info *lp; 01061 struct arm_linux_hw_breakpoint p; 01062 01063 if (arm_linux_get_hw_breakpoint_count () == 0) 01064 return -1; 01065 01066 arm_linux_hw_breakpoint_initialize (gdbarch, bp_tgt, &p); 01067 ALL_LWPS (lp) 01068 arm_linux_remove_hw_breakpoint1 (&p, ptid_get_lwp (lp->ptid), 0); 01069 01070 return 0; 01071 } 01072 01073 /* Are we able to use a hardware watchpoint for the LEN bytes starting at 01074 ADDR? */ 01075 static int 01076 arm_linux_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) 01077 { 01078 const struct arm_linux_hwbp_cap *cap = arm_linux_get_hwbp_cap (); 01079 CORE_ADDR max_wp_length, aligned_addr; 01080 01081 /* Can not set watchpoints for zero or negative lengths. */ 01082 if (len <= 0) 01083 return 0; 01084 01085 /* Need to be able to use the ptrace interface. */ 01086 if (cap == NULL || cap->wp_count == 0) 01087 return 0; 01088 01089 /* Test that the range [ADDR, ADDR + LEN) fits into the largest address 01090 range covered by a watchpoint. */ 01091 max_wp_length = (CORE_ADDR)cap->max_wp_length; 01092 aligned_addr = addr & ~(max_wp_length - 1); 01093 01094 if (aligned_addr + max_wp_length < addr + len) 01095 return 0; 01096 01097 /* The current ptrace interface can only handle watchpoints that are a 01098 power of 2. */ 01099 if ((len & (len - 1)) != 0) 01100 return 0; 01101 01102 /* All tests passed so we must be able to set a watchpoint. */ 01103 return 1; 01104 } 01105 01106 /* Insert a Hardware breakpoint. */ 01107 static int 01108 arm_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw, 01109 struct expression *cond) 01110 { 01111 struct lwp_info *lp; 01112 struct arm_linux_hw_breakpoint p; 01113 01114 if (arm_linux_get_hw_watchpoint_count () == 0) 01115 return -1; 01116 01117 arm_linux_hw_watchpoint_initialize (addr, len, rw, &p); 01118 ALL_LWPS (lp) 01119 arm_linux_insert_hw_breakpoint1 (&p, ptid_get_lwp (lp->ptid), 1); 01120 01121 return 0; 01122 } 01123 01124 /* Remove a hardware breakpoint. */ 01125 static int 01126 arm_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw, 01127 struct expression *cond) 01128 { 01129 struct lwp_info *lp; 01130 struct arm_linux_hw_breakpoint p; 01131 01132 if (arm_linux_get_hw_watchpoint_count () == 0) 01133 return -1; 01134 01135 arm_linux_hw_watchpoint_initialize (addr, len, rw, &p); 01136 ALL_LWPS (lp) 01137 arm_linux_remove_hw_breakpoint1 (&p, ptid_get_lwp (lp->ptid), 1); 01138 01139 return 0; 01140 } 01141 01142 /* What was the data address the target was stopped on accessing. */ 01143 static int 01144 arm_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p) 01145 { 01146 siginfo_t siginfo; 01147 int slot; 01148 01149 if (!linux_nat_get_siginfo (inferior_ptid, &siginfo)) 01150 return 0; 01151 01152 /* This must be a hardware breakpoint. */ 01153 if (siginfo.si_signo != SIGTRAP 01154 || (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */) 01155 return 0; 01156 01157 /* We must be able to set hardware watchpoints. */ 01158 if (arm_linux_get_hw_watchpoint_count () == 0) 01159 return 0; 01160 01161 slot = siginfo.si_errno; 01162 01163 /* If we are in a positive slot then we're looking at a breakpoint and not 01164 a watchpoint. */ 01165 if (slot >= 0) 01166 return 0; 01167 01168 *addr_p = (CORE_ADDR) (uintptr_t) siginfo.si_addr; 01169 return 1; 01170 } 01171 01172 /* Has the target been stopped by hitting a watchpoint? */ 01173 static int 01174 arm_linux_stopped_by_watchpoint (void) 01175 { 01176 CORE_ADDR addr; 01177 return arm_linux_stopped_data_address (¤t_target, &addr); 01178 } 01179 01180 static int 01181 arm_linux_watchpoint_addr_within_range (struct target_ops *target, 01182 CORE_ADDR addr, 01183 CORE_ADDR start, int length) 01184 { 01185 return start <= addr && start + length - 1 >= addr; 01186 } 01187 01188 /* Handle thread creation. We need to copy the breakpoints and watchpoints 01189 in the parent thread to the child thread. */ 01190 static void 01191 arm_linux_new_thread (struct lwp_info *lp) 01192 { 01193 int tid = ptid_get_lwp (lp->ptid); 01194 const struct arm_linux_hwbp_cap *info = arm_linux_get_hwbp_cap (); 01195 01196 if (info != NULL) 01197 { 01198 int i; 01199 struct arm_linux_thread_points *p; 01200 struct arm_linux_hw_breakpoint *bpts; 01201 01202 if (VEC_empty (arm_linux_thread_points_p, arm_threads)) 01203 return; 01204 01205 /* Get a list of breakpoints from any thread. */ 01206 p = VEC_last (arm_linux_thread_points_p, arm_threads); 01207 01208 /* Copy that thread's breakpoints and watchpoints to the new thread. */ 01209 for (i = 0; i < info->bp_count; i++) 01210 if (arm_hwbp_control_is_enabled (p->bpts[i].control)) 01211 arm_linux_insert_hw_breakpoint1 (p->bpts + i, tid, 0); 01212 for (i = 0; i < info->wp_count; i++) 01213 if (arm_hwbp_control_is_enabled (p->wpts[i].control)) 01214 arm_linux_insert_hw_breakpoint1 (p->wpts + i, tid, 1); 01215 } 01216 } 01217 01218 /* Handle thread exit. Tidy up the memory that has been allocated for the 01219 thread. */ 01220 static void 01221 arm_linux_thread_exit (struct thread_info *tp, int silent) 01222 { 01223 const struct arm_linux_hwbp_cap *info = arm_linux_get_hwbp_cap (); 01224 01225 if (info != NULL) 01226 { 01227 int i; 01228 int tid = ptid_get_lwp (tp->ptid); 01229 struct arm_linux_thread_points *t = NULL, *p; 01230 01231 for (i = 0; 01232 VEC_iterate (arm_linux_thread_points_p, arm_threads, i, p); i++) 01233 { 01234 if (p->tid == tid) 01235 { 01236 t = p; 01237 break; 01238 } 01239 } 01240 01241 if (t == NULL) 01242 return; 01243 01244 VEC_unordered_remove (arm_linux_thread_points_p, arm_threads, i); 01245 01246 xfree (t->bpts); 01247 xfree (t->wpts); 01248 xfree (t); 01249 } 01250 } 01251 01252 void _initialize_arm_linux_nat (void); 01253 01254 void 01255 _initialize_arm_linux_nat (void) 01256 { 01257 struct target_ops *t; 01258 01259 /* Fill in the generic GNU/Linux methods. */ 01260 t = linux_target (); 01261 01262 /* Add our register access methods. */ 01263 t->to_fetch_registers = arm_linux_fetch_inferior_registers; 01264 t->to_store_registers = arm_linux_store_inferior_registers; 01265 01266 /* Add our hardware breakpoint and watchpoint implementation. */ 01267 t->to_can_use_hw_breakpoint = arm_linux_can_use_hw_breakpoint; 01268 t->to_insert_hw_breakpoint = arm_linux_insert_hw_breakpoint; 01269 t->to_remove_hw_breakpoint = arm_linux_remove_hw_breakpoint; 01270 t->to_region_ok_for_hw_watchpoint = arm_linux_region_ok_for_hw_watchpoint; 01271 t->to_insert_watchpoint = arm_linux_insert_watchpoint; 01272 t->to_remove_watchpoint = arm_linux_remove_watchpoint; 01273 t->to_stopped_by_watchpoint = arm_linux_stopped_by_watchpoint; 01274 t->to_stopped_data_address = arm_linux_stopped_data_address; 01275 t->to_watchpoint_addr_within_range = arm_linux_watchpoint_addr_within_range; 01276 01277 t->to_read_description = arm_linux_read_description; 01278 01279 /* Register the target. */ 01280 linux_nat_add_target (t); 01281 01282 /* Handle thread creation and exit */ 01283 observer_attach_thread_exit (arm_linux_thread_exit); 01284 linux_nat_set_new_thread (t, arm_linux_new_thread); 01285 }