1/* Native-dependent code for BSD Unix running on ARM's, for GDB. 2 3 Copyright (C) 1988, 1989, 1991, 1992, 1994, 1996, 1999, 2002, 2004, 2007, 4 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 5 6 This file is part of GDB. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 21#include "defs.h" 22#include "gdbcore.h" 23#include "inferior.h" 24#include "regcache.h" 25#include "target.h" 26 27#include "nbsd-nat.h" 28#include "gdb_string.h" 29#include <sys/types.h> 30#include <sys/ptrace.h> 31#include <machine/reg.h> 32#include <machine/frame.h> 33 34/* Support for debugging kernel virtual memory images. */ 35#include <machine/pcb.h> 36 37#include "arm-tdep.h" 38#include "inf-ptrace.h" 39#include "bsd-kvm.h" 40 41#ifndef HAVE_GREGSET_T 42typedef struct reg gregset_t; 43#endif 44 45#ifndef HAVE_FPREGSET_T 46typedef struct fpreg fpregset_t; 47#endif 48 49#include "gregset.h" 50 51extern int arm_apcs_32; 52 53static int 54armnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) 55{ 56 struct switchframe sf; 57 58 /* The following is true for NetBSD/arm32 in 5.0 and after: 59 60 The pcb contains r8-r13 (sp) at the point of context switch in 61 cpu_switchto() or call of dumpsys(). At that point we have a 62 stack frame as described by `struct switchframe', which for 63 NetBSD/arm32 has the following layout: 64 65 r4 ascending. 66 r5 | 67 r6 | 68 r7 \|/ 69 old sp 70 pc 71 72 we reconstruct the register state as it would look when we just 73 returned from cpu_switchto() or dumpsys(). */ 74 75 if (!arm_apcs_32) 76 return 0; 77 78 /* The stack pointer shouldn't be zero. */ 79 if (pcb->pcb_un.un_32.pcb32_sp == 0) 80 return 0; 81 82 read_memory (pcb->pcb_un.un_32.pcb32_sp, (gdb_byte *) &sf, sizeof sf); 83 84 regcache_raw_supply (regcache, ARM_PC_REGNUM, &sf.sf_pc); 85 regcache_raw_supply (regcache, ARM_SP_REGNUM, &pcb->pcb_un.un_32.pcb32_sp); 86 regcache_raw_supply (regcache, 12, &pcb->pcb_un.un_32.pcb32_r12); 87 regcache_raw_supply (regcache, 11, &pcb->pcb_un.un_32.pcb32_r11); 88 regcache_raw_supply (regcache, 10, &pcb->pcb_un.un_32.pcb32_r10); 89 regcache_raw_supply (regcache, 9, &pcb->pcb_un.un_32.pcb32_r9); 90 regcache_raw_supply (regcache, 8, &pcb->pcb_un.un_32.pcb32_r8); 91 regcache_raw_supply (regcache, 7, &sf.sf_r7); 92 regcache_raw_supply (regcache, 6, &sf.sf_r6); 93 regcache_raw_supply (regcache, 5, &sf.sf_r5); 94 regcache_raw_supply (regcache, 4, &sf.sf_r4); 95 96 return 1; 97} 98 99static void 100arm_supply_gregset (struct regcache *regcache, struct reg *gregset) 101{ 102 int regno; 103 CORE_ADDR r_pc; 104 105 /* Integer registers. */ 106 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++) 107 regcache_raw_supply (regcache, regno, (char *) &gregset->r[regno]); 108 109 regcache_raw_supply (regcache, ARM_SP_REGNUM, 110 (char *) &gregset->r_sp); 111 regcache_raw_supply (regcache, ARM_LR_REGNUM, 112 (char *) &gregset->r_lr); 113 /* This is ok: we're running native... */ 114 r_pc = gdbarch_addr_bits_remove (get_regcache_arch (regcache), gregset->r_pc); 115 regcache_raw_supply (regcache, ARM_PC_REGNUM, (char *) &r_pc); 116 117 if (arm_apcs_32) 118 regcache_raw_supply (regcache, ARM_PS_REGNUM, 119 (char *) &gregset->r_cpsr); 120 else 121 regcache_raw_supply (regcache, ARM_PS_REGNUM, 122 (char *) &gregset->r_pc); 123} 124 125static void 126arm_supply_fparegset (struct regcache *regcache, struct fpreg *fparegset) 127{ 128 int regno; 129 130 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++) 131 regcache_raw_supply (regcache, regno, 132 (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]); 133 134 regcache_raw_supply (regcache, ARM_FPS_REGNUM, 135 (char *) &fparegset->fpr_fpsr); 136} 137 138void 139fill_gregset (const struct regcache *regcache, gregset_t *gregsetp, int regno) 140{ 141 if (-1 == regno) 142 { 143 int regnum; 144 for (regnum = ARM_A1_REGNUM; regnum < ARM_SP_REGNUM; regnum++) 145 regcache_raw_collect (regcache, regnum, (char *) &gregsetp->r[regnum]); 146 } 147 else if (regno >= ARM_A1_REGNUM && regno < ARM_SP_REGNUM) 148 regcache_raw_collect (regcache, regno, (char *) &gregsetp->r[regno]); 149 150 if (ARM_SP_REGNUM == regno || -1 == regno) 151 regcache_raw_collect (regcache, ARM_SP_REGNUM, (char *) &gregsetp->r_sp); 152 153 if (ARM_LR_REGNUM == regno || -1 == regno) 154 regcache_raw_collect (regcache, ARM_LR_REGNUM, (char *) &gregsetp->r_lr); 155 156 if (ARM_PC_REGNUM == regno || -1 == regno) 157 regcache_raw_collect (regcache, ARM_PC_REGNUM, (char *) &gregsetp->r_pc); 158 159 if (ARM_PS_REGNUM == regno || -1 == regno) 160 { 161 if (arm_apcs_32) 162 regcache_raw_collect (regcache, ARM_PS_REGNUM, (char *) &gregsetp->r_cpsr); 163 else 164 regcache_raw_collect (regcache, ARM_PS_REGNUM, (char *) &gregsetp->r_pc); 165 } 166 } 167 168void 169fill_fpregset (const struct regcache *regcache, fpregset_t *fpregsetp, int regno) 170{ 171 if (-1 == regno) 172 { 173 int regnum; 174 for (regnum = ARM_F0_REGNUM; regnum <= ARM_F7_REGNUM; regnum++) 175 regcache_raw_collect(regcache, regnum, (char *) &fpregsetp->fpr[regnum - ARM_F0_REGNUM]); 176 } 177 else if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM) 178 regcache_raw_collect(regcache, regno, (char *) &fpregsetp->fpr[regno - ARM_F0_REGNUM]); 179 180 if (ARM_FPS_REGNUM == regno || -1 == regno) 181 regcache_raw_collect (regcache, ARM_FPS_REGNUM, (char *) &fpregsetp->fpr_fpsr); 182} 183 184void 185supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp) 186{ 187 arm_supply_gregset (regcache, (struct reg *)gregsetp); 188} 189 190void 191supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp) 192{ 193 arm_supply_fparegset (regcache, (struct fpreg *)fpregsetp); 194} 195 196static void 197fetch_register (struct regcache *regcache, int regno) 198{ 199 struct reg inferior_registers; 200 int ret; 201 202 ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid), 203 (PTRACE_TYPE_ARG3) &inferior_registers, TIDGET (inferior_ptid)); 204 205 if (ret < 0) 206 { 207 warning (_("unable to fetch general register")); 208 return; 209 } 210 211 switch (regno) 212 { 213 case ARM_SP_REGNUM: 214 regcache_raw_supply (regcache, ARM_SP_REGNUM, 215 (char *) &inferior_registers.r_sp); 216 break; 217 218 case ARM_LR_REGNUM: 219 regcache_raw_supply (regcache, ARM_LR_REGNUM, 220 (char *) &inferior_registers.r_lr); 221 break; 222 223 case ARM_PC_REGNUM: 224 /* This is ok: we're running native... */ 225 inferior_registers.r_pc = gdbarch_addr_bits_remove 226 (get_regcache_arch (regcache), 227 inferior_registers.r_pc); 228 regcache_raw_supply (regcache, ARM_PC_REGNUM, 229 (char *) &inferior_registers.r_pc); 230 break; 231 232 case ARM_PS_REGNUM: 233 if (arm_apcs_32) 234 regcache_raw_supply (regcache, ARM_PS_REGNUM, 235 (char *) &inferior_registers.r_cpsr); 236 else 237 regcache_raw_supply (regcache, ARM_PS_REGNUM, 238 (char *) &inferior_registers.r_pc); 239 break; 240 241 default: 242 regcache_raw_supply (regcache, regno, 243 (char *) &inferior_registers.r[regno]); 244 break; 245 } 246} 247 248static void 249fetch_regs (struct regcache *regcache) 250{ 251 struct reg inferior_registers; 252 int ret; 253 int regno; 254 255 ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid), 256 (PTRACE_TYPE_ARG3) &inferior_registers, TIDGET (inferior_ptid)); 257 258 if (ret < 0) 259 { 260 warning (_("unable to fetch general registers")); 261 return; 262 } 263 264 arm_supply_gregset (regcache, &inferior_registers); 265} 266 267static void 268fetch_fp_register (struct regcache *regcache, int regno) 269{ 270 struct fpreg inferior_fp_registers; 271 int ret; 272 273 ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), 274 (PTRACE_TYPE_ARG3) &inferior_fp_registers, TIDGET (inferior_ptid)); 275 276 if (ret < 0) 277 { 278 warning (_("unable to fetch floating-point register")); 279 return; 280 } 281 282 switch (regno) 283 { 284 case ARM_FPS_REGNUM: 285 regcache_raw_supply (regcache, ARM_FPS_REGNUM, 286 (char *) &inferior_fp_registers.fpr_fpsr); 287 break; 288 289 default: 290 regcache_raw_supply (regcache, regno, 291 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]); 292 break; 293 } 294} 295 296static void 297fetch_fp_regs (struct regcache *regcache) 298{ 299 struct fpreg inferior_fp_registers; 300 int ret; 301 int regno; 302 303 ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), 304 (PTRACE_TYPE_ARG3) &inferior_fp_registers, TIDGET (inferior_ptid)); 305 306 if (ret < 0) 307 { 308 warning (_("unable to fetch general registers")); 309 return; 310 } 311 312 arm_supply_fparegset (regcache, &inferior_fp_registers); 313} 314 315static void 316armnbsd_fetch_registers (struct target_ops *ops, 317 struct regcache *regcache, int regno) 318{ 319 if (regno >= 0) 320 { 321 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM) 322 fetch_register (regcache, regno); 323 else 324 fetch_fp_register (regcache, regno); 325 } 326 else 327 { 328 fetch_regs (regcache); 329 fetch_fp_regs (regcache); 330 } 331} 332 333 334static void 335store_register (const struct regcache *regcache, int regno) 336{ 337 struct gdbarch *gdbarch = get_regcache_arch (regcache); 338 struct reg inferior_registers; 339 int ret; 340 341 ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid), 342 (PTRACE_TYPE_ARG3) &inferior_registers, TIDGET (inferior_ptid)); 343 344 if (ret < 0) 345 { 346 warning (_("unable to fetch general registers")); 347 return; 348 } 349 350 switch (regno) 351 { 352 case ARM_SP_REGNUM: 353 regcache_raw_collect (regcache, ARM_SP_REGNUM, 354 (char *) &inferior_registers.r_sp); 355 break; 356 357 case ARM_LR_REGNUM: 358 regcache_raw_collect (regcache, ARM_LR_REGNUM, 359 (char *) &inferior_registers.r_lr); 360 break; 361 362 case ARM_PC_REGNUM: 363 if (arm_apcs_32) 364 regcache_raw_collect (regcache, ARM_PC_REGNUM, 365 (char *) &inferior_registers.r_pc); 366 else 367 { 368 unsigned pc_val; 369 370 regcache_raw_collect (regcache, ARM_PC_REGNUM, 371 (char *) &pc_val); 372 373 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val); 374 inferior_registers.r_pc ^= gdbarch_addr_bits_remove 375 (gdbarch, inferior_registers.r_pc); 376 inferior_registers.r_pc |= pc_val; 377 } 378 break; 379 380 case ARM_PS_REGNUM: 381 if (arm_apcs_32) 382 regcache_raw_collect (regcache, ARM_PS_REGNUM, 383 (char *) &inferior_registers.r_cpsr); 384 else 385 { 386 unsigned psr_val; 387 388 regcache_raw_collect (regcache, ARM_PS_REGNUM, 389 (char *) &psr_val); 390 391 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val); 392 inferior_registers.r_pc = gdbarch_addr_bits_remove 393 (gdbarch, inferior_registers.r_pc); 394 inferior_registers.r_pc |= psr_val; 395 } 396 break; 397 398 default: 399 regcache_raw_collect (regcache, regno, 400 (char *) &inferior_registers.r[regno]); 401 break; 402 } 403 404 ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid), 405 (PTRACE_TYPE_ARG3) &inferior_registers, TIDGET (inferior_ptid)); 406 407 if (ret < 0) 408 warning (_("unable to write register %d to inferior"), regno); 409} 410 411static void 412store_regs (const struct regcache *regcache) 413{ 414 struct gdbarch *gdbarch = get_regcache_arch (regcache); 415 struct reg inferior_registers; 416 int ret; 417 int regno; 418 419 420 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++) 421 regcache_raw_collect (regcache, regno, 422 (char *) &inferior_registers.r[regno]); 423 424 regcache_raw_collect (regcache, ARM_SP_REGNUM, 425 (char *) &inferior_registers.r_sp); 426 regcache_raw_collect (regcache, ARM_LR_REGNUM, 427 (char *) &inferior_registers.r_lr); 428 429 if (arm_apcs_32) 430 { 431 regcache_raw_collect (regcache, ARM_PC_REGNUM, 432 (char *) &inferior_registers.r_pc); 433 regcache_raw_collect (regcache, ARM_PS_REGNUM, 434 (char *) &inferior_registers.r_cpsr); 435 } 436 else 437 { 438 unsigned pc_val; 439 unsigned psr_val; 440 441 regcache_raw_collect (regcache, ARM_PC_REGNUM, 442 (char *) &pc_val); 443 regcache_raw_collect (regcache, ARM_PS_REGNUM, 444 (char *) &psr_val); 445 446 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val); 447 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val); 448 449 inferior_registers.r_pc = pc_val | psr_val; 450 } 451 452 ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid), 453 (PTRACE_TYPE_ARG3) &inferior_registers, TIDGET (inferior_ptid)); 454 455 if (ret < 0) 456 warning (_("unable to store general registers")); 457} 458 459static void 460store_fp_register (const struct regcache *regcache, int regno) 461{ 462 struct fpreg inferior_fp_registers; 463 int ret; 464 465 ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), 466 (PTRACE_TYPE_ARG3) &inferior_fp_registers, TIDGET (inferior_ptid)); 467 468 if (ret < 0) 469 { 470 warning (_("unable to fetch floating-point registers")); 471 return; 472 } 473 474 switch (regno) 475 { 476 case ARM_FPS_REGNUM: 477 regcache_raw_collect (regcache, ARM_FPS_REGNUM, 478 (char *) &inferior_fp_registers.fpr_fpsr); 479 break; 480 481 default: 482 regcache_raw_collect (regcache, regno, 483 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]); 484 break; 485 } 486 487 ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), 488 (PTRACE_TYPE_ARG3) &inferior_fp_registers, TIDGET (inferior_ptid)); 489 490 if (ret < 0) 491 warning (_("unable to write register %d to inferior"), regno); 492} 493 494static void 495store_fp_regs (const struct regcache *regcache) 496{ 497 struct fpreg inferior_fp_registers; 498 int ret; 499 int regno; 500 501 502 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++) 503 regcache_raw_collect (regcache, regno, 504 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]); 505 506 regcache_raw_collect (regcache, ARM_FPS_REGNUM, 507 (char *) &inferior_fp_registers.fpr_fpsr); 508 509 ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), 510 (PTRACE_TYPE_ARG3) &inferior_fp_registers, TIDGET (inferior_ptid)); 511 512 if (ret < 0) 513 warning (_("unable to store floating-point registers")); 514} 515 516static void 517armnbsd_store_registers (struct target_ops *ops, 518 struct regcache *regcache, int regno) 519{ 520 if (regno >= 0) 521 { 522 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM) 523 store_register (regcache, regno); 524 else 525 store_fp_register (regcache, regno); 526 } 527 else 528 { 529 store_regs (regcache); 530 store_fp_regs (regcache); 531 } 532} 533 534struct md_core 535{ 536 struct reg intreg; 537 struct fpreg freg; 538}; 539 540static void 541fetch_core_registers (struct regcache *regcache, 542 char *core_reg_sect, unsigned core_reg_size, 543 int which, CORE_ADDR ignore) 544{ 545 struct md_core *core_reg = (struct md_core *) core_reg_sect; 546 int regno; 547 CORE_ADDR r_pc; 548 549 arm_supply_gregset (regcache, &core_reg->intreg); 550 arm_supply_fparegset (regcache, &core_reg->freg); 551} 552 553static void 554fetch_elfcore_registers (struct regcache *regcache, 555 char *core_reg_sect, unsigned core_reg_size, 556 int which, CORE_ADDR ignore) 557{ 558 struct reg gregset; 559 struct fpreg fparegset; 560 561 switch (which) 562 { 563 case 0: /* Integer registers. */ 564 if (core_reg_size != sizeof (struct reg)) 565 warning (_("wrong size of register set in core file")); 566 else 567 { 568 /* The memcpy may be unnecessary, but we can't really be sure 569 of the alignment of the data in the core file. */ 570 memcpy (&gregset, core_reg_sect, sizeof (gregset)); 571 arm_supply_gregset (regcache, &gregset); 572 } 573 break; 574 575 case 2: 576 if (core_reg_size != sizeof (struct fpreg)) 577 warning (_("wrong size of FPA register set in core file")); 578 else 579 { 580 /* The memcpy may be unnecessary, but we can't really be sure 581 of the alignment of the data in the core file. */ 582 memcpy (&fparegset, core_reg_sect, sizeof (fparegset)); 583 arm_supply_fparegset (regcache, &fparegset); 584 } 585 break; 586 587 default: 588 /* Don't know what kind of register request this is; just ignore it. */ 589 break; 590 } 591} 592 593static struct core_fns arm_netbsd_core_fns = 594{ 595 bfd_target_unknown_flavour, /* core_flovour. */ 596 default_check_format, /* check_format. */ 597 default_core_sniffer, /* core_sniffer. */ 598 fetch_core_registers, /* core_read_registers. */ 599 NULL 600}; 601 602static struct core_fns arm_netbsd_elfcore_fns = 603{ 604 bfd_target_elf_flavour, /* core_flovour. */ 605 default_check_format, /* check_format. */ 606 default_core_sniffer, /* core_sniffer. */ 607 fetch_elfcore_registers, /* core_read_registers. */ 608 NULL 609}; 610 611void 612_initialize_arm_netbsd_nat (void) 613{ 614 struct target_ops *t; 615 616 t = inf_ptrace_target (); 617 t->to_fetch_registers = armnbsd_fetch_registers; 618 t->to_store_registers = armnbsd_store_registers; 619 t->to_pid_to_exec_file = nbsd_pid_to_exec_file; 620 add_target (t); 621 622 /* Support debugging kernel virtual memory images. */ 623 bsd_kvm_add_target (armnbsd_supply_pcb); 624 625 deprecated_add_core_fns (&arm_netbsd_core_fns); 626 deprecated_add_core_fns (&arm_netbsd_elfcore_fns); 627} 628