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