1*6881a400Schristos /* Native-dependent code for NetBSD/amd64. 2*6881a400Schristos 3*6881a400Schristos Copyright (C) 2003-2023 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 "netbsd-nat.h" 24*6881a400Schristos #include "amd64-tdep.h" 25*6881a400Schristos #include "amd64-bsd-nat.h" 26*6881a400Schristos #include "amd64-nat.h" 27*6881a400Schristos #include "regcache.h" 28*6881a400Schristos #include "gdbcore.h" 29*6881a400Schristos #include "bsd-kvm.h" 30*6881a400Schristos 31*6881a400Schristos #include <machine/frame.h> 32*6881a400Schristos #include <machine/pcb.h> 33*6881a400Schristos #include <machine/reg.h> 34*6881a400Schristos 35*6881a400Schristos /* Mapping between the general-purpose registers in NetBSD/amd64 36*6881a400Schristos `struct reg' format and GDB's register cache layout for 37*6881a400Schristos NetBSD/i386. 38*6881a400Schristos 39*6881a400Schristos Note that most (if not all) NetBSD/amd64 registers are 64-bit, 40*6881a400Schristos while the NetBSD/i386 registers are all 32-bit, but since we're 41*6881a400Schristos little-endian we get away with that. */ 42*6881a400Schristos 43*6881a400Schristos /* From <machine/reg.h>. */ 44*6881a400Schristos static int amd64nbsd32_r_reg_offset[] = 45*6881a400Schristos { 46*6881a400Schristos 14 * 8, /* %eax */ 47*6881a400Schristos 3 * 8, /* %ecx */ 48*6881a400Schristos 2 * 8, /* %edx */ 49*6881a400Schristos 13 * 8, /* %ebx */ 50*6881a400Schristos 24 * 8, /* %esp */ 51*6881a400Schristos 12 * 8, /* %ebp */ 52*6881a400Schristos 1 * 8, /* %esi */ 53*6881a400Schristos 0 * 8, /* %edi */ 54*6881a400Schristos 21 * 8, /* %eip */ 55*6881a400Schristos 23 * 8, /* %eflags */ 56*6881a400Schristos 22 * 8, /* %cs */ 57*6881a400Schristos 25 * 8, /* %ss */ 58*6881a400Schristos 18 * 8, /* %ds */ 59*6881a400Schristos 17 * 8, /* %es */ 60*6881a400Schristos 16 * 8, /* %fs */ 61*6881a400Schristos 15 * 8 /* %gs */ 62*6881a400Schristos }; 63*6881a400Schristos 64*6881a400Schristos static int 65*6881a400Schristos amd64nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) 66*6881a400Schristos { 67*6881a400Schristos struct switchframe sf; 68*6881a400Schristos 69*6881a400Schristos /* The following is true for NetBSD/amd64: 70*6881a400Schristos 71*6881a400Schristos The pcb contains the stack pointer at the point of the context 72*6881a400Schristos switch in cpu_switchto(). At that point we have a stack frame as 73*6881a400Schristos described by `struct switchframe', which for NetBSD/amd64 has the 74*6881a400Schristos following layout: 75*6881a400Schristos 76*6881a400Schristos interrupt level 77*6881a400Schristos %r15 78*6881a400Schristos %r14 79*6881a400Schristos %r13 80*6881a400Schristos %r12 81*6881a400Schristos %rbx 82*6881a400Schristos return address 83*6881a400Schristos 84*6881a400Schristos Together with %rsp in the pcb, this accounts for all callee-saved 85*6881a400Schristos registers specified by the psABI. From this information we 86*6881a400Schristos reconstruct the register state as it would look when we just 87*6881a400Schristos returned from cpu_switchto(). 88*6881a400Schristos 89*6881a400Schristos For kernel core dumps, dumpsys() builds a fake switchframe for us. */ 90*6881a400Schristos 91*6881a400Schristos /* The stack pointer shouldn't be zero. */ 92*6881a400Schristos if (pcb->pcb_rsp == 0) 93*6881a400Schristos return 0; 94*6881a400Schristos 95*6881a400Schristos /* Read the stack frame, and check its validity. */ 96*6881a400Schristos read_memory (pcb->pcb_rsp, (gdb_byte *) &sf, sizeof sf); 97*6881a400Schristos pcb->pcb_rsp += sizeof (struct switchframe); 98*6881a400Schristos regcache->raw_supply (12, &sf.sf_r12); 99*6881a400Schristos regcache->raw_supply (13, &sf.sf_r13); 100*6881a400Schristos regcache->raw_supply (14, &sf.sf_r14); 101*6881a400Schristos regcache->raw_supply (15, &sf.sf_r15); 102*6881a400Schristos regcache->raw_supply (AMD64_RBX_REGNUM, &sf.sf_rbx); 103*6881a400Schristos regcache->raw_supply (AMD64_RIP_REGNUM, &sf.sf_rip); 104*6881a400Schristos 105*6881a400Schristos regcache->raw_supply (AMD64_RSP_REGNUM, &pcb->pcb_rsp); 106*6881a400Schristos regcache->raw_supply (AMD64_RBP_REGNUM, &pcb->pcb_rbp); 107*6881a400Schristos regcache->raw_supply (AMD64_FS_REGNUM, &pcb->pcb_fs); 108*6881a400Schristos regcache->raw_supply (AMD64_GS_REGNUM, &pcb->pcb_gs); 109*6881a400Schristos 110*6881a400Schristos return 1; 111*6881a400Schristos } 112*6881a400Schristos 113*6881a400Schristos static amd64_bsd_nat_target<nbsd_nat_target> the_amd64_nbsd_nat_target; 114*6881a400Schristos 115*6881a400Schristos void _initialize_amd64nbsd_nat (); 116*6881a400Schristos void 117*6881a400Schristos _initialize_amd64nbsd_nat () 118*6881a400Schristos { 119*6881a400Schristos amd64_native_gregset32_reg_offset = amd64nbsd32_r_reg_offset; 120*6881a400Schristos amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64nbsd32_r_reg_offset); 121*6881a400Schristos amd64_native_gregset64_reg_offset = amd64nbsd_r_reg_offset; 122*6881a400Schristos 123*6881a400Schristos add_inf_child_target (&the_amd64_nbsd_nat_target); 124*6881a400Schristos 125*6881a400Schristos bsd_kvm_add_target (amd64nbsd_supply_pcb); 126*6881a400Schristos } 127