GDB (API)
|
00001 /* Native-dependent code for BSD Unix running on ARM's, for GDB. 00002 00003 Copyright (C) 1988-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include "gdbcore.h" 00022 #include "inferior.h" 00023 #include "regcache.h" 00024 #include "target.h" 00025 00026 #include "gdb_string.h" 00027 #include <sys/types.h> 00028 #include <sys/ptrace.h> 00029 #include <machine/reg.h> 00030 #include <machine/frame.h> 00031 00032 #include "arm-tdep.h" 00033 #include "inf-ptrace.h" 00034 00035 extern int arm_apcs_32; 00036 00037 static void 00038 arm_supply_gregset (struct regcache *regcache, struct reg *gregset) 00039 { 00040 int regno; 00041 CORE_ADDR r_pc; 00042 00043 /* Integer registers. */ 00044 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++) 00045 regcache_raw_supply (regcache, regno, (char *) &gregset->r[regno]); 00046 00047 regcache_raw_supply (regcache, ARM_SP_REGNUM, 00048 (char *) &gregset->r_sp); 00049 regcache_raw_supply (regcache, ARM_LR_REGNUM, 00050 (char *) &gregset->r_lr); 00051 /* This is ok: we're running native... */ 00052 r_pc = gdbarch_addr_bits_remove (get_regcache_arch (regcache), gregset->r_pc); 00053 regcache_raw_supply (regcache, ARM_PC_REGNUM, (char *) &r_pc); 00054 00055 if (arm_apcs_32) 00056 regcache_raw_supply (regcache, ARM_PS_REGNUM, 00057 (char *) &gregset->r_cpsr); 00058 else 00059 regcache_raw_supply (regcache, ARM_PS_REGNUM, 00060 (char *) &gregset->r_pc); 00061 } 00062 00063 static void 00064 arm_supply_fparegset (struct regcache *regcache, struct fpreg *fparegset) 00065 { 00066 int regno; 00067 00068 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++) 00069 regcache_raw_supply (regcache, regno, 00070 (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]); 00071 00072 regcache_raw_supply (regcache, ARM_FPS_REGNUM, 00073 (char *) &fparegset->fpr_fpsr); 00074 } 00075 00076 static void 00077 fetch_register (struct regcache *regcache, int regno) 00078 { 00079 struct reg inferior_registers; 00080 int ret; 00081 00082 ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), 00083 (PTRACE_TYPE_ARG3) &inferior_registers, 0); 00084 00085 if (ret < 0) 00086 { 00087 warning (_("unable to fetch general register")); 00088 return; 00089 } 00090 00091 switch (regno) 00092 { 00093 case ARM_SP_REGNUM: 00094 regcache_raw_supply (regcache, ARM_SP_REGNUM, 00095 (char *) &inferior_registers.r_sp); 00096 break; 00097 00098 case ARM_LR_REGNUM: 00099 regcache_raw_supply (regcache, ARM_LR_REGNUM, 00100 (char *) &inferior_registers.r_lr); 00101 break; 00102 00103 case ARM_PC_REGNUM: 00104 /* This is ok: we're running native... */ 00105 inferior_registers.r_pc = gdbarch_addr_bits_remove 00106 (get_regcache_arch (regcache), 00107 inferior_registers.r_pc); 00108 regcache_raw_supply (regcache, ARM_PC_REGNUM, 00109 (char *) &inferior_registers.r_pc); 00110 break; 00111 00112 case ARM_PS_REGNUM: 00113 if (arm_apcs_32) 00114 regcache_raw_supply (regcache, ARM_PS_REGNUM, 00115 (char *) &inferior_registers.r_cpsr); 00116 else 00117 regcache_raw_supply (regcache, ARM_PS_REGNUM, 00118 (char *) &inferior_registers.r_pc); 00119 break; 00120 00121 default: 00122 regcache_raw_supply (regcache, regno, 00123 (char *) &inferior_registers.r[regno]); 00124 break; 00125 } 00126 } 00127 00128 static void 00129 fetch_regs (struct regcache *regcache) 00130 { 00131 struct reg inferior_registers; 00132 int ret; 00133 int regno; 00134 00135 ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), 00136 (PTRACE_TYPE_ARG3) &inferior_registers, 0); 00137 00138 if (ret < 0) 00139 { 00140 warning (_("unable to fetch general registers")); 00141 return; 00142 } 00143 00144 arm_supply_gregset (regcache, &inferior_registers); 00145 } 00146 00147 static void 00148 fetch_fp_register (struct regcache *regcache, int regno) 00149 { 00150 struct fpreg inferior_fp_registers; 00151 int ret; 00152 00153 ret = ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), 00154 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0); 00155 00156 if (ret < 0) 00157 { 00158 warning (_("unable to fetch floating-point register")); 00159 return; 00160 } 00161 00162 switch (regno) 00163 { 00164 case ARM_FPS_REGNUM: 00165 regcache_raw_supply (regcache, ARM_FPS_REGNUM, 00166 (char *) &inferior_fp_registers.fpr_fpsr); 00167 break; 00168 00169 default: 00170 regcache_raw_supply (regcache, regno, 00171 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]); 00172 break; 00173 } 00174 } 00175 00176 static void 00177 fetch_fp_regs (struct regcache *regcache) 00178 { 00179 struct fpreg inferior_fp_registers; 00180 int ret; 00181 int regno; 00182 00183 ret = ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), 00184 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0); 00185 00186 if (ret < 0) 00187 { 00188 warning (_("unable to fetch general registers")); 00189 return; 00190 } 00191 00192 arm_supply_fparegset (regcache, &inferior_fp_registers); 00193 } 00194 00195 static void 00196 armnbsd_fetch_registers (struct target_ops *ops, 00197 struct regcache *regcache, int regno) 00198 { 00199 if (regno >= 0) 00200 { 00201 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM) 00202 fetch_register (regcache, regno); 00203 else 00204 fetch_fp_register (regcache, regno); 00205 } 00206 else 00207 { 00208 fetch_regs (regcache); 00209 fetch_fp_regs (regcache); 00210 } 00211 } 00212 00213 00214 static void 00215 store_register (const struct regcache *regcache, int regno) 00216 { 00217 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00218 struct reg inferior_registers; 00219 int ret; 00220 00221 ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), 00222 (PTRACE_TYPE_ARG3) &inferior_registers, 0); 00223 00224 if (ret < 0) 00225 { 00226 warning (_("unable to fetch general registers")); 00227 return; 00228 } 00229 00230 switch (regno) 00231 { 00232 case ARM_SP_REGNUM: 00233 regcache_raw_collect (regcache, ARM_SP_REGNUM, 00234 (char *) &inferior_registers.r_sp); 00235 break; 00236 00237 case ARM_LR_REGNUM: 00238 regcache_raw_collect (regcache, ARM_LR_REGNUM, 00239 (char *) &inferior_registers.r_lr); 00240 break; 00241 00242 case ARM_PC_REGNUM: 00243 if (arm_apcs_32) 00244 regcache_raw_collect (regcache, ARM_PC_REGNUM, 00245 (char *) &inferior_registers.r_pc); 00246 else 00247 { 00248 unsigned pc_val; 00249 00250 regcache_raw_collect (regcache, ARM_PC_REGNUM, 00251 (char *) &pc_val); 00252 00253 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val); 00254 inferior_registers.r_pc ^= gdbarch_addr_bits_remove 00255 (gdbarch, inferior_registers.r_pc); 00256 inferior_registers.r_pc |= pc_val; 00257 } 00258 break; 00259 00260 case ARM_PS_REGNUM: 00261 if (arm_apcs_32) 00262 regcache_raw_collect (regcache, ARM_PS_REGNUM, 00263 (char *) &inferior_registers.r_cpsr); 00264 else 00265 { 00266 unsigned psr_val; 00267 00268 regcache_raw_collect (regcache, ARM_PS_REGNUM, 00269 (char *) &psr_val); 00270 00271 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val); 00272 inferior_registers.r_pc = gdbarch_addr_bits_remove 00273 (gdbarch, inferior_registers.r_pc); 00274 inferior_registers.r_pc |= psr_val; 00275 } 00276 break; 00277 00278 default: 00279 regcache_raw_collect (regcache, regno, 00280 (char *) &inferior_registers.r[regno]); 00281 break; 00282 } 00283 00284 ret = ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid), 00285 (PTRACE_TYPE_ARG3) &inferior_registers, 0); 00286 00287 if (ret < 0) 00288 warning (_("unable to write register %d to inferior"), regno); 00289 } 00290 00291 static void 00292 store_regs (const struct regcache *regcache) 00293 { 00294 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00295 struct reg inferior_registers; 00296 int ret; 00297 int regno; 00298 00299 00300 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++) 00301 regcache_raw_collect (regcache, regno, 00302 (char *) &inferior_registers.r[regno]); 00303 00304 regcache_raw_collect (regcache, ARM_SP_REGNUM, 00305 (char *) &inferior_registers.r_sp); 00306 regcache_raw_collect (regcache, ARM_LR_REGNUM, 00307 (char *) &inferior_registers.r_lr); 00308 00309 if (arm_apcs_32) 00310 { 00311 regcache_raw_collect (regcache, ARM_PC_REGNUM, 00312 (char *) &inferior_registers.r_pc); 00313 regcache_raw_collect (regcache, ARM_PS_REGNUM, 00314 (char *) &inferior_registers.r_cpsr); 00315 } 00316 else 00317 { 00318 unsigned pc_val; 00319 unsigned psr_val; 00320 00321 regcache_raw_collect (regcache, ARM_PC_REGNUM, 00322 (char *) &pc_val); 00323 regcache_raw_collect (regcache, ARM_PS_REGNUM, 00324 (char *) &psr_val); 00325 00326 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val); 00327 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val); 00328 00329 inferior_registers.r_pc = pc_val | psr_val; 00330 } 00331 00332 ret = ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid), 00333 (PTRACE_TYPE_ARG3) &inferior_registers, 0); 00334 00335 if (ret < 0) 00336 warning (_("unable to store general registers")); 00337 } 00338 00339 static void 00340 store_fp_register (const struct regcache *regcache, int regno) 00341 { 00342 struct fpreg inferior_fp_registers; 00343 int ret; 00344 00345 ret = ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), 00346 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0); 00347 00348 if (ret < 0) 00349 { 00350 warning (_("unable to fetch floating-point registers")); 00351 return; 00352 } 00353 00354 switch (regno) 00355 { 00356 case ARM_FPS_REGNUM: 00357 regcache_raw_collect (regcache, ARM_FPS_REGNUM, 00358 (char *) &inferior_fp_registers.fpr_fpsr); 00359 break; 00360 00361 default: 00362 regcache_raw_collect (regcache, regno, 00363 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]); 00364 break; 00365 } 00366 00367 ret = ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid), 00368 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0); 00369 00370 if (ret < 0) 00371 warning (_("unable to write register %d to inferior"), regno); 00372 } 00373 00374 static void 00375 store_fp_regs (const struct regcache *regcache) 00376 { 00377 struct fpreg inferior_fp_registers; 00378 int ret; 00379 int regno; 00380 00381 00382 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++) 00383 regcache_raw_collect (regcache, regno, 00384 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]); 00385 00386 regcache_raw_collect (regcache, ARM_FPS_REGNUM, 00387 (char *) &inferior_fp_registers.fpr_fpsr); 00388 00389 ret = ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid), 00390 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0); 00391 00392 if (ret < 0) 00393 warning (_("unable to store floating-point registers")); 00394 } 00395 00396 static void 00397 armnbsd_store_registers (struct target_ops *ops, 00398 struct regcache *regcache, int regno) 00399 { 00400 if (regno >= 0) 00401 { 00402 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM) 00403 store_register (regcache, regno); 00404 else 00405 store_fp_register (regcache, regno); 00406 } 00407 else 00408 { 00409 store_regs (regcache); 00410 store_fp_regs (regcache); 00411 } 00412 } 00413 00414 struct md_core 00415 { 00416 struct reg intreg; 00417 struct fpreg freg; 00418 }; 00419 00420 static void 00421 fetch_core_registers (struct regcache *regcache, 00422 char *core_reg_sect, unsigned core_reg_size, 00423 int which, CORE_ADDR ignore) 00424 { 00425 struct md_core *core_reg = (struct md_core *) core_reg_sect; 00426 int regno; 00427 CORE_ADDR r_pc; 00428 00429 arm_supply_gregset (regcache, &core_reg->intreg); 00430 arm_supply_fparegset (regcache, &core_reg->freg); 00431 } 00432 00433 static void 00434 fetch_elfcore_registers (struct regcache *regcache, 00435 char *core_reg_sect, unsigned core_reg_size, 00436 int which, CORE_ADDR ignore) 00437 { 00438 struct reg gregset; 00439 struct fpreg fparegset; 00440 00441 switch (which) 00442 { 00443 case 0: /* Integer registers. */ 00444 if (core_reg_size != sizeof (struct reg)) 00445 warning (_("wrong size of register set in core file")); 00446 else 00447 { 00448 /* The memcpy may be unnecessary, but we can't really be sure 00449 of the alignment of the data in the core file. */ 00450 memcpy (&gregset, core_reg_sect, sizeof (gregset)); 00451 arm_supply_gregset (regcache, &gregset); 00452 } 00453 break; 00454 00455 case 2: 00456 if (core_reg_size != sizeof (struct fpreg)) 00457 warning (_("wrong size of FPA register set in core file")); 00458 else 00459 { 00460 /* The memcpy may be unnecessary, but we can't really be sure 00461 of the alignment of the data in the core file. */ 00462 memcpy (&fparegset, core_reg_sect, sizeof (fparegset)); 00463 arm_supply_fparegset (regcache, &fparegset); 00464 } 00465 break; 00466 00467 default: 00468 /* Don't know what kind of register request this is; just ignore it. */ 00469 break; 00470 } 00471 } 00472 00473 static struct core_fns arm_netbsd_core_fns = 00474 { 00475 bfd_target_unknown_flavour, /* core_flovour. */ 00476 default_check_format, /* check_format. */ 00477 default_core_sniffer, /* core_sniffer. */ 00478 fetch_core_registers, /* core_read_registers. */ 00479 NULL 00480 }; 00481 00482 static struct core_fns arm_netbsd_elfcore_fns = 00483 { 00484 bfd_target_elf_flavour, /* core_flovour. */ 00485 default_check_format, /* check_format. */ 00486 default_core_sniffer, /* core_sniffer. */ 00487 fetch_elfcore_registers, /* core_read_registers. */ 00488 NULL 00489 }; 00490 00491 void 00492 _initialize_arm_netbsd_nat (void) 00493 { 00494 struct target_ops *t; 00495 00496 t = inf_ptrace_target (); 00497 t->to_fetch_registers = armnbsd_fetch_registers; 00498 t->to_store_registers = armnbsd_store_registers; 00499 add_target (t); 00500 00501 deprecated_add_core_fns (&arm_netbsd_core_fns); 00502 deprecated_add_core_fns (&arm_netbsd_elfcore_fns); 00503 }