1*6881a400Schristos /* Native-dependent code for NetBSD/aarch64. 2*6881a400Schristos 3*6881a400Schristos Copyright (C) 2017-2018 Free Software Foundation, Inc. 4*6881a400Schristos 5*6881a400Schristos This file is part of GDB. 6*6881a400Schristos 7*6881a400Schristos This program is free software; you can redistribute it and/or modify 8*6881a400Schristos it under the terms of the GNU General Public License as published by 9*6881a400Schristos the Free Software Foundation; either version 3 of the License, or 10*6881a400Schristos (at your option) any later version. 11*6881a400Schristos 12*6881a400Schristos This program is distributed in the hope that it will be useful, 13*6881a400Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 14*6881a400Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*6881a400Schristos GNU General Public License for more details. 16*6881a400Schristos 17*6881a400Schristos You should have received a copy of the GNU General Public License 18*6881a400Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19*6881a400Schristos 20*6881a400Schristos #include "defs.h" 21*6881a400Schristos #include "target.h" 22*6881a400Schristos 23*6881a400Schristos #include <sys/types.h> 24*6881a400Schristos #include <sys/ptrace.h> 25*6881a400Schristos 26*6881a400Schristos #include <machine/frame.h> 27*6881a400Schristos #include <machine/pcb.h> 28*6881a400Schristos 29*6881a400Schristos #include "netbsd-nat.h" 30*6881a400Schristos #include "aarch64-tdep.h" 31*6881a400Schristos #include "aarch64-netbsd-tdep.h" 32*6881a400Schristos #include "regcache.h" 33*6881a400Schristos #include "gdbcore.h" 34*6881a400Schristos #include "bsd-kvm.h" 35*6881a400Schristos #include "inf-ptrace.h" 36*6881a400Schristos 37*6881a400Schristos struct aarch64_nbsd_nat_target final : public nbsd_nat_target 38*6881a400Schristos { 39*6881a400Schristos void fetch_registers (struct regcache *, int) override; 40*6881a400Schristos void store_registers (struct regcache *, int) override; 41*6881a400Schristos }; 42*6881a400Schristos 43*6881a400Schristos static aarch64_nbsd_nat_target the_aarch64_nbsd_nat_target; 44*6881a400Schristos 45*6881a400Schristos /* Determine if PT_GETREGS fetches REGNUM. */ 46*6881a400Schristos 47*6881a400Schristos static bool 48*6881a400Schristos getregs_supplies (struct gdbarch *gdbarch, int regnum) 49*6881a400Schristos { 50*6881a400Schristos return (regnum >= AARCH64_X0_REGNUM && regnum <= AARCH64_CPSR_REGNUM); 51*6881a400Schristos } 52*6881a400Schristos 53*6881a400Schristos /* Determine if PT_GETFPREGS fetches REGNUM. */ 54*6881a400Schristos 55*6881a400Schristos static bool 56*6881a400Schristos getfpregs_supplies (struct gdbarch *gdbarch, int regnum) 57*6881a400Schristos { 58*6881a400Schristos return (regnum >= AARCH64_V0_REGNUM && regnum <= AARCH64_FPCR_REGNUM); 59*6881a400Schristos } 60*6881a400Schristos 61*6881a400Schristos void 62*6881a400Schristos aarch64_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum) 63*6881a400Schristos { 64*6881a400Schristos ptid_t ptid = regcache->ptid (); 65*6881a400Schristos pid_t pid = ptid.pid (); 66*6881a400Schristos int lwp = ptid.lwp (); 67*6881a400Schristos 68*6881a400Schristos struct gdbarch *gdbarch = regcache->arch (); 69*6881a400Schristos if (regnum == -1 || getregs_supplies (gdbarch, regnum)) 70*6881a400Schristos { 71*6881a400Schristos struct reg regs; 72*6881a400Schristos 73*6881a400Schristos if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1) 74*6881a400Schristos perror_with_name (_("Couldn't get registers")); 75*6881a400Schristos 76*6881a400Schristos regcache_supply_regset (&aarch64_nbsd_gregset, regcache, regnum, ®s, 77*6881a400Schristos sizeof (regs)); 78*6881a400Schristos } 79*6881a400Schristos 80*6881a400Schristos if (regnum == -1 || getfpregs_supplies (gdbarch, regnum)) 81*6881a400Schristos { 82*6881a400Schristos struct fpreg fpregs; 83*6881a400Schristos 84*6881a400Schristos if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1) 85*6881a400Schristos perror_with_name (_("Couldn't get floating point status")); 86*6881a400Schristos 87*6881a400Schristos regcache_supply_regset (&aarch64_nbsd_fpregset, regcache, regnum, &fpregs, 88*6881a400Schristos sizeof (fpregs)); 89*6881a400Schristos } 90*6881a400Schristos } 91*6881a400Schristos 92*6881a400Schristos /* Store register REGNUM back into the inferior. If REGNUM is -1, do 93*6881a400Schristos this for all registers. */ 94*6881a400Schristos 95*6881a400Schristos void 96*6881a400Schristos aarch64_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum) 97*6881a400Schristos { 98*6881a400Schristos ptid_t ptid = regcache->ptid (); 99*6881a400Schristos pid_t pid = ptid.pid (); 100*6881a400Schristos int lwp = ptid.lwp (); 101*6881a400Schristos 102*6881a400Schristos struct gdbarch *gdbarch = regcache->arch (); 103*6881a400Schristos if (regnum == -1 || getregs_supplies (gdbarch, regnum)) 104*6881a400Schristos { 105*6881a400Schristos struct reg regs; 106*6881a400Schristos 107*6881a400Schristos if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1) 108*6881a400Schristos perror_with_name (_("Couldn't get registers")); 109*6881a400Schristos 110*6881a400Schristos regcache_collect_regset (&aarch64_nbsd_gregset, regcache,regnum, ®s, 111*6881a400Schristos sizeof (regs)); 112*6881a400Schristos 113*6881a400Schristos if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1) 114*6881a400Schristos perror_with_name (_("Couldn't write registers")); 115*6881a400Schristos } 116*6881a400Schristos 117*6881a400Schristos if (regnum == -1 || getfpregs_supplies (gdbarch, regnum)) 118*6881a400Schristos { 119*6881a400Schristos struct fpreg fpregs; 120*6881a400Schristos 121*6881a400Schristos if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1) 122*6881a400Schristos perror_with_name (_("Couldn't get floating point status")); 123*6881a400Schristos 124*6881a400Schristos regcache_collect_regset (&aarch64_nbsd_fpregset, regcache,regnum, &fpregs, 125*6881a400Schristos sizeof (fpregs)); 126*6881a400Schristos 127*6881a400Schristos if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1) 128*6881a400Schristos perror_with_name (_("Couldn't write floating point status")); 129*6881a400Schristos } 130*6881a400Schristos } 131*6881a400Schristos 132*6881a400Schristos static int 133*6881a400Schristos aarch64_nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) 134*6881a400Schristos { 135*6881a400Schristos struct trapframe tf; 136*6881a400Schristos int i; 137*6881a400Schristos 138*6881a400Schristos /* The following is true for NetBSD/arm64: 139*6881a400Schristos 140*6881a400Schristos The pcb contains the frame pointer at the point of the context 141*6881a400Schristos switch in cpu_switchto(). At that point we have a stack frame as 142*6881a400Schristos described by `struct trapframe', which has the following layout: 143*6881a400Schristos 144*6881a400Schristos x0..x30 145*6881a400Schristos sp 146*6881a400Schristos pc 147*6881a400Schristos spsr 148*6881a400Schristos tpidr 149*6881a400Schristos 150*6881a400Schristos This accounts for all callee-saved registers specified by the psABI. 151*6881a400Schristos From this information we reconstruct the register state as it would 152*6881a400Schristos look when we just returned from cpu_switchto(). 153*6881a400Schristos 154*6881a400Schristos For kernel core dumps, dumpsys() builds a fake trapframe for us. */ 155*6881a400Schristos 156*6881a400Schristos /* The trapframe pointer shouldn't be zero. */ 157*6881a400Schristos if (pcb->pcb_tf == 0) 158*6881a400Schristos return 0; 159*6881a400Schristos 160*6881a400Schristos /* Read the stack frame, and check its validity. */ 161*6881a400Schristos read_memory ((uintptr_t)pcb->pcb_tf, (gdb_byte *) &tf, sizeof tf); 162*6881a400Schristos 163*6881a400Schristos for (i = 0; i <= 30; i++) 164*6881a400Schristos { 165*6881a400Schristos regcache->raw_supply (AARCH64_X0_REGNUM + i, &tf.tf_reg[i]); 166*6881a400Schristos } 167*6881a400Schristos regcache->raw_supply (AARCH64_SP_REGNUM, &tf.tf_sp); 168*6881a400Schristos regcache->raw_supply (AARCH64_PC_REGNUM, &tf.tf_pc); 169*6881a400Schristos 170*6881a400Schristos regcache->raw_supply (AARCH64_FPCR_REGNUM, &pcb->pcb_fpregs.fpcr); 171*6881a400Schristos regcache->raw_supply (AARCH64_FPSR_REGNUM, &pcb->pcb_fpregs.fpsr); 172*6881a400Schristos 173*6881a400Schristos return 1; 174*6881a400Schristos } 175*6881a400Schristos 176*6881a400Schristos void 177*6881a400Schristos _initialize_aarch64_nbsd_nat () 178*6881a400Schristos { 179*6881a400Schristos add_inf_child_target (&the_aarch64_nbsd_nat_target); 180*6881a400Schristos 181*6881a400Schristos /* Support debugging kernel virtual memory images. */ 182*6881a400Schristos bsd_kvm_add_target (aarch64_nbsd_supply_pcb); 183*6881a400Schristos } 184