1699b0f92Schristos /* Native-dependent code for Alpha BSD's. 2699b0f92Schristos 3*6881a400Schristos Copyright (C) 2000-2023 Free Software Foundation, Inc. 4699b0f92Schristos 5699b0f92Schristos This file is part of GDB. 6699b0f92Schristos 7699b0f92Schristos This program is free software; you can redistribute it and/or modify 8699b0f92Schristos it under the terms of the GNU General Public License as published by 9699b0f92Schristos the Free Software Foundation; either version 3 of the License, or 10699b0f92Schristos (at your option) any later version. 11699b0f92Schristos 12699b0f92Schristos This program is distributed in the hope that it will be useful, 13699b0f92Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 14699b0f92Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15699b0f92Schristos GNU General Public License for more details. 16699b0f92Schristos 17699b0f92Schristos You should have received a copy of the GNU General Public License 18699b0f92Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19699b0f92Schristos 207d62b00eSchristos /* We define this to get types like register_t. */ 21699b0f92Schristos #include "defs.h" 22699b0f92Schristos #include "inferior.h" 23699b0f92Schristos #include "regcache.h" 24699b0f92Schristos 25699b0f92Schristos #include "alpha-tdep.h" 26699b0f92Schristos #include "alpha-bsd-tdep.h" 27699b0f92Schristos #include "inf-ptrace.h" 28*6881a400Schristos #include "netbsd-nat.h" 29699b0f92Schristos 30699b0f92Schristos #include <sys/types.h> 31699b0f92Schristos #include <sys/ptrace.h> 32699b0f92Schristos #include <machine/reg.h> 33699b0f92Schristos 347f2ac410Schristos struct alpha_bsd_nat_target final : public nbsd_nat_target 35699b0f92Schristos { 367f2ac410Schristos void fetch_registers (struct regcache *, int) override; 377f2ac410Schristos void store_registers (struct regcache *, int) override; 387f2ac410Schristos }; 39699b0f92Schristos 407f2ac410Schristos static alpha_bsd_nat_target the_alpha_bsd_nat_target; 41699b0f92Schristos 42699b0f92Schristos /* Determine if PT_GETREGS fetches this register. */ 43699b0f92Schristos 44699b0f92Schristos static int 45699b0f92Schristos getregs_supplies (int regno) 46699b0f92Schristos { 47699b0f92Schristos return ((regno >= ALPHA_V0_REGNUM && regno <= ALPHA_ZERO_REGNUM) 48699b0f92Schristos || regno >= ALPHA_PC_REGNUM); 49699b0f92Schristos } 50699b0f92Schristos 51699b0f92Schristos /* Fetch register REGNO from the inferior. If REGNO is -1, do this 52699b0f92Schristos for all registers (including the floating point registers). */ 53699b0f92Schristos 547f2ac410Schristos void 557f2ac410Schristos alpha_bsd_nat_target::fetch_registers (struct regcache *regcache, int regno) 56699b0f92Schristos { 577d62b00eSchristos int lwp = regcache->ptid ().lwp (); 587f2ac410Schristos 59699b0f92Schristos if (regno == -1 || getregs_supplies (regno)) 60699b0f92Schristos { 61699b0f92Schristos struct reg gregs; 62699b0f92Schristos 637d62b00eSchristos if (ptrace (PT_GETREGS, regcache->ptid ().pid (), 647d62b00eSchristos (PTRACE_TYPE_ARG3) &gregs, lwp) == -1) 65699b0f92Schristos perror_with_name (_("Couldn't get registers")); 66699b0f92Schristos 67699b0f92Schristos alphabsd_supply_reg (regcache, (char *) &gregs, regno); 68699b0f92Schristos if (regno != -1) 69699b0f92Schristos return; 70699b0f92Schristos } 71699b0f92Schristos 72699b0f92Schristos if (regno == -1 737f2ac410Schristos || regno >= gdbarch_fp0_regnum (regcache->arch ())) 74699b0f92Schristos { 75699b0f92Schristos struct fpreg fpregs; 76699b0f92Schristos 777d62b00eSchristos if (ptrace (PT_GETFPREGS, regcache->ptid ().pid (), 787d62b00eSchristos (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1) 79699b0f92Schristos perror_with_name (_("Couldn't get floating point status")); 80699b0f92Schristos 81699b0f92Schristos alphabsd_supply_fpreg (regcache, (char *) &fpregs, regno); 82699b0f92Schristos } 83699b0f92Schristos } 84699b0f92Schristos 85699b0f92Schristos /* Store register REGNO back into the inferior. If REGNO is -1, do 86699b0f92Schristos this for all registers (including the floating point registers). */ 87699b0f92Schristos 887f2ac410Schristos void 897f2ac410Schristos alpha_bsd_nat_target::store_registers (struct regcache *regcache, int regno) 90699b0f92Schristos { 917d62b00eSchristos int lwp = regcache->ptid ().lwp (); 927f2ac410Schristos 93699b0f92Schristos if (regno == -1 || getregs_supplies (regno)) 94699b0f92Schristos { 95699b0f92Schristos struct reg gregs; 967d62b00eSchristos if (ptrace (PT_GETREGS, regcache->ptid ().pid (), 977f2ac410Schristos (PTRACE_TYPE_ARG3) &gregs, lwp) == -1) 98699b0f92Schristos perror_with_name (_("Couldn't get registers")); 99699b0f92Schristos 100699b0f92Schristos alphabsd_fill_reg (regcache, (char *) &gregs, regno); 101699b0f92Schristos 1027d62b00eSchristos if (ptrace (PT_SETREGS, regcache->ptid ().pid (), 1037d62b00eSchristos (PTRACE_TYPE_ARG3) &gregs, lwp) == -1) 104699b0f92Schristos perror_with_name (_("Couldn't write registers")); 105699b0f92Schristos 106699b0f92Schristos if (regno != -1) 107699b0f92Schristos return; 108699b0f92Schristos } 109699b0f92Schristos 110699b0f92Schristos if (regno == -1 1117f2ac410Schristos || regno >= gdbarch_fp0_regnum (regcache->arch ())) 112699b0f92Schristos { 113699b0f92Schristos struct fpreg fpregs; 114699b0f92Schristos 1157d62b00eSchristos if (ptrace (PT_GETFPREGS, regcache->ptid ().pid (), 1167d62b00eSchristos (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1) 117699b0f92Schristos perror_with_name (_("Couldn't get floating point status")); 118699b0f92Schristos 119699b0f92Schristos alphabsd_fill_fpreg (regcache, (char *) &fpregs, regno); 120699b0f92Schristos 1217d62b00eSchristos if (ptrace (PT_SETFPREGS, regcache->ptid ().pid (), 1227f2ac410Schristos (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1) 123699b0f92Schristos perror_with_name (_("Couldn't write floating point status")); 124699b0f92Schristos } 125699b0f92Schristos } 126699b0f92Schristos 127699b0f92Schristos 128699b0f92Schristos /* Support for debugging kernel virtual memory images. */ 129699b0f92Schristos 130699b0f92Schristos #include <sys/signal.h> 131699b0f92Schristos #include <machine/pcb.h> 132699b0f92Schristos 133699b0f92Schristos #include "bsd-kvm.h" 134699b0f92Schristos 135699b0f92Schristos static int 136699b0f92Schristos alphabsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) 137699b0f92Schristos { 138699b0f92Schristos int regnum; 139699b0f92Schristos 140699b0f92Schristos /* The following is true for OpenBSD 3.9: 141699b0f92Schristos 142699b0f92Schristos The pcb contains the register state at the context switch inside 143699b0f92Schristos cpu_switch(). */ 144699b0f92Schristos 145699b0f92Schristos /* The stack pointer shouldn't be zero. */ 146699b0f92Schristos if (pcb->pcb_hw.apcb_ksp == 0) 147699b0f92Schristos return 0; 148699b0f92Schristos 1497f2ac410Schristos regcache->raw_supply (ALPHA_SP_REGNUM, &pcb->pcb_hw.apcb_ksp); 150699b0f92Schristos 151699b0f92Schristos for (regnum = ALPHA_S0_REGNUM; regnum < ALPHA_A0_REGNUM; regnum++) 1527f2ac410Schristos regcache->raw_supply (regnum, &pcb->pcb_context[regnum - ALPHA_S0_REGNUM]); 1537f2ac410Schristos regcache->raw_supply (ALPHA_RA_REGNUM, &pcb->pcb_context[7]); 154699b0f92Schristos 155699b0f92Schristos return 1; 156699b0f92Schristos } 157699b0f92Schristos 158699b0f92Schristos 1597d62b00eSchristos void _initialize_alphabsd_nat (); 160699b0f92Schristos void 1617d62b00eSchristos _initialize_alphabsd_nat () 162699b0f92Schristos { 1637f2ac410Schristos add_inf_child_target (&the_alpha_bsd_nat_target); 164699b0f92Schristos 165699b0f92Schristos /* Support debugging kernel virtual memory images. */ 166699b0f92Schristos bsd_kvm_add_target (alphabsd_supply_pcb); 167699b0f92Schristos } 168