1699b0f92Schristos /* Native-dependent code for FreeBSD/amd64. 2699b0f92Schristos 3*6881a400Schristos Copyright (C) 2003-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 20699b0f92Schristos #include "defs.h" 21699b0f92Schristos #include "inferior.h" 22699b0f92Schristos #include "regcache.h" 23699b0f92Schristos #include "target.h" 24699b0f92Schristos 25699b0f92Schristos #include <signal.h> 26699b0f92Schristos #include <sys/types.h> 27699b0f92Schristos #include <sys/ptrace.h> 28699b0f92Schristos #include <sys/sysctl.h> 29699b0f92Schristos #include <sys/user.h> 30699b0f92Schristos #include <machine/reg.h> 31699b0f92Schristos 32699b0f92Schristos #include "amd64-tdep.h" 33*6881a400Schristos #include "amd64-fbsd-tdep.h" 34699b0f92Schristos #include "amd64-nat.h" 35699b0f92Schristos #include "x86-nat.h" 367d62b00eSchristos #include "gdbsupport/x86-xstate.h" 37*6881a400Schristos #include "x86-fbsd-nat.h" 38699b0f92Schristos 39*6881a400Schristos class amd64_fbsd_nat_target final : public x86_fbsd_nat_target 407f2ac410Schristos { 417f2ac410Schristos public: 42*6881a400Schristos void fetch_registers (struct regcache *, int) override; 43*6881a400Schristos void store_registers (struct regcache *, int) override; 447f2ac410Schristos 45*6881a400Schristos const struct target_desc *read_description () override; 467f2ac410Schristos }; 477f2ac410Schristos 487f2ac410Schristos static amd64_fbsd_nat_target the_amd64_fbsd_nat_target; 497f2ac410Schristos 50*6881a400Schristos #ifdef PT_GETXSTATE_INFO 51*6881a400Schristos static size_t xsave_len; 52*6881a400Schristos #endif 53699b0f92Schristos 54*6881a400Schristos /* This is a layout of the amd64 'struct reg' but with i386 55*6881a400Schristos registers. */ 56*6881a400Schristos 57*6881a400Schristos static const struct regcache_map_entry amd64_fbsd32_gregmap[] = 58699b0f92Schristos { 59*6881a400Schristos { 8, REGCACHE_MAP_SKIP, 8 }, 60*6881a400Schristos { 1, I386_EDI_REGNUM, 8 }, 61*6881a400Schristos { 1, I386_ESI_REGNUM, 8 }, 62*6881a400Schristos { 1, I386_EBP_REGNUM, 8 }, 63*6881a400Schristos { 1, I386_EBX_REGNUM, 8 }, 64*6881a400Schristos { 1, I386_EDX_REGNUM, 8 }, 65*6881a400Schristos { 1, I386_ECX_REGNUM, 8 }, 66*6881a400Schristos { 1, I386_EAX_REGNUM, 8 }, 67*6881a400Schristos { 1, REGCACHE_MAP_SKIP, 4 }, /* trapno */ 68*6881a400Schristos { 1, I386_FS_REGNUM, 2 }, 69*6881a400Schristos { 1, I386_GS_REGNUM, 2 }, 70*6881a400Schristos { 1, REGCACHE_MAP_SKIP, 4 }, /* err */ 71*6881a400Schristos { 1, I386_ES_REGNUM, 2 }, 72*6881a400Schristos { 1, I386_DS_REGNUM, 2 }, 73*6881a400Schristos { 1, I386_EIP_REGNUM, 8 }, 74*6881a400Schristos { 1, I386_CS_REGNUM, 8 }, 75*6881a400Schristos { 1, I386_EFLAGS_REGNUM, 8 }, 76*6881a400Schristos { 1, I386_ESP_REGNUM, 0 }, 77*6881a400Schristos { 1, I386_SS_REGNUM, 8 }, 78*6881a400Schristos { 0 } 79699b0f92Schristos }; 80699b0f92Schristos 81*6881a400Schristos static const struct regset amd64_fbsd32_gregset = 82699b0f92Schristos { 83*6881a400Schristos amd64_fbsd32_gregmap, regcache_supply_regset, regcache_collect_regset 84699b0f92Schristos }; 85*6881a400Schristos 86*6881a400Schristos /* Return the regset to use for 'struct reg' for the GDBARCH. */ 87*6881a400Schristos 88*6881a400Schristos static const struct regset * 89*6881a400Schristos find_gregset (struct gdbarch *gdbarch) 90*6881a400Schristos { 91*6881a400Schristos if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32) 92*6881a400Schristos return &amd64_fbsd32_gregset; 93*6881a400Schristos else 94*6881a400Schristos return &amd64_fbsd_gregset; 95*6881a400Schristos } 96*6881a400Schristos 97*6881a400Schristos /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this 98*6881a400Schristos for all registers. */ 99*6881a400Schristos 100*6881a400Schristos void 101*6881a400Schristos amd64_fbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum) 102*6881a400Schristos { 103*6881a400Schristos struct gdbarch *gdbarch = regcache->arch (); 104*6881a400Schristos #if defined(PT_GETFSBASE) || defined(PT_GETGSBASE) 105*6881a400Schristos const i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch); 106*6881a400Schristos #endif 107*6881a400Schristos pid_t pid = get_ptrace_pid (regcache->ptid ()); 108*6881a400Schristos const struct regset *gregset = find_gregset (gdbarch); 109*6881a400Schristos 110*6881a400Schristos if (fetch_register_set<struct reg> (regcache, regnum, PT_GETREGS, gregset)) 111*6881a400Schristos { 112*6881a400Schristos if (regnum != -1) 113*6881a400Schristos return; 114*6881a400Schristos } 115*6881a400Schristos 116*6881a400Schristos #ifdef PT_GETFSBASE 117*6881a400Schristos if (regnum == -1 || regnum == tdep->fsbase_regnum) 118*6881a400Schristos { 119*6881a400Schristos register_t base; 120*6881a400Schristos 121*6881a400Schristos if (ptrace (PT_GETFSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) 122*6881a400Schristos perror_with_name (_("Couldn't get segment register fs_base")); 123*6881a400Schristos 124*6881a400Schristos regcache->raw_supply (tdep->fsbase_regnum, &base); 125*6881a400Schristos if (regnum != -1) 126*6881a400Schristos return; 127*6881a400Schristos } 128*6881a400Schristos #endif 129*6881a400Schristos #ifdef PT_GETGSBASE 130*6881a400Schristos if (regnum == -1 || regnum == tdep->fsbase_regnum + 1) 131*6881a400Schristos { 132*6881a400Schristos register_t base; 133*6881a400Schristos 134*6881a400Schristos if (ptrace (PT_GETGSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) 135*6881a400Schristos perror_with_name (_("Couldn't get segment register gs_base")); 136*6881a400Schristos 137*6881a400Schristos regcache->raw_supply (tdep->fsbase_regnum + 1, &base); 138*6881a400Schristos if (regnum != -1) 139*6881a400Schristos return; 140*6881a400Schristos } 141*6881a400Schristos #endif 142*6881a400Schristos 143*6881a400Schristos /* There is no amd64_fxsave_supplies or amd64_xsave_supplies. 144*6881a400Schristos Instead, the earlier register sets return early if the request 145*6881a400Schristos was for a specific register that was already satisified to avoid 146*6881a400Schristos fetching the FPU/XSAVE state unnecessarily. */ 147*6881a400Schristos 148*6881a400Schristos #ifdef PT_GETXSTATE_INFO 149*6881a400Schristos if (xsave_len != 0) 150*6881a400Schristos { 151*6881a400Schristos void *xstateregs = alloca (xsave_len); 152*6881a400Schristos 153*6881a400Schristos if (ptrace (PT_GETXSTATE, pid, (PTRACE_TYPE_ARG3) xstateregs, 0) == -1) 154*6881a400Schristos perror_with_name (_("Couldn't get extended state status")); 155*6881a400Schristos 156*6881a400Schristos amd64_supply_xsave (regcache, regnum, xstateregs); 157*6881a400Schristos return; 158*6881a400Schristos } 159*6881a400Schristos #endif 160*6881a400Schristos 161*6881a400Schristos struct fpreg fpregs; 162*6881a400Schristos 163*6881a400Schristos if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) 164*6881a400Schristos perror_with_name (_("Couldn't get floating point status")); 165*6881a400Schristos 166*6881a400Schristos amd64_supply_fxsave (regcache, regnum, &fpregs); 167*6881a400Schristos } 168*6881a400Schristos 169*6881a400Schristos /* Store register REGNUM back into the inferior. If REGNUM is -1, do 170*6881a400Schristos this for all registers. */ 171*6881a400Schristos 172*6881a400Schristos void 173*6881a400Schristos amd64_fbsd_nat_target::store_registers (struct regcache *regcache, int regnum) 174*6881a400Schristos { 175*6881a400Schristos struct gdbarch *gdbarch = regcache->arch (); 176*6881a400Schristos #if defined(PT_GETFSBASE) || defined(PT_GETGSBASE) 177*6881a400Schristos const i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch); 178*6881a400Schristos #endif 179*6881a400Schristos pid_t pid = get_ptrace_pid (regcache->ptid ()); 180*6881a400Schristos const struct regset *gregset = find_gregset (gdbarch); 181*6881a400Schristos 182*6881a400Schristos if (store_register_set<struct reg> (regcache, regnum, PT_GETREGS, PT_SETREGS, 183*6881a400Schristos gregset)) 184*6881a400Schristos { 185*6881a400Schristos if (regnum != -1) 186*6881a400Schristos return; 187*6881a400Schristos } 188*6881a400Schristos 189*6881a400Schristos #ifdef PT_SETFSBASE 190*6881a400Schristos if (regnum == -1 || regnum == tdep->fsbase_regnum) 191*6881a400Schristos { 192*6881a400Schristos register_t base; 193*6881a400Schristos 194*6881a400Schristos /* Clear the full base value to support 32-bit targets. */ 195*6881a400Schristos base = 0; 196*6881a400Schristos regcache->raw_collect (tdep->fsbase_regnum, &base); 197*6881a400Schristos 198*6881a400Schristos if (ptrace (PT_SETFSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) 199*6881a400Schristos perror_with_name (_("Couldn't write segment register fs_base")); 200*6881a400Schristos if (regnum != -1) 201*6881a400Schristos return; 202*6881a400Schristos } 203*6881a400Schristos #endif 204*6881a400Schristos #ifdef PT_SETGSBASE 205*6881a400Schristos if (regnum == -1 || regnum == tdep->fsbase_regnum + 1) 206*6881a400Schristos { 207*6881a400Schristos register_t base; 208*6881a400Schristos 209*6881a400Schristos /* Clear the full base value to support 32-bit targets. */ 210*6881a400Schristos base = 0; 211*6881a400Schristos regcache->raw_collect (tdep->fsbase_regnum + 1, &base); 212*6881a400Schristos 213*6881a400Schristos if (ptrace (PT_SETGSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) 214*6881a400Schristos perror_with_name (_("Couldn't write segment register gs_base")); 215*6881a400Schristos if (regnum != -1) 216*6881a400Schristos return; 217*6881a400Schristos } 218*6881a400Schristos #endif 219*6881a400Schristos 220*6881a400Schristos /* There is no amd64_fxsave_supplies or amd64_xsave_supplies. 221*6881a400Schristos Instead, the earlier register sets return early if the request 222*6881a400Schristos was for a specific register that was already satisified to avoid 223*6881a400Schristos fetching the FPU/XSAVE state unnecessarily. */ 224*6881a400Schristos 225*6881a400Schristos #ifdef PT_GETXSTATE_INFO 226*6881a400Schristos if (xsave_len != 0) 227*6881a400Schristos { 228*6881a400Schristos void *xstateregs = alloca (xsave_len); 229*6881a400Schristos 230*6881a400Schristos if (ptrace (PT_GETXSTATE, pid, (PTRACE_TYPE_ARG3) xstateregs, 0) == -1) 231*6881a400Schristos perror_with_name (_("Couldn't get extended state status")); 232*6881a400Schristos 233*6881a400Schristos amd64_collect_xsave (regcache, regnum, xstateregs, 0); 234*6881a400Schristos 235*6881a400Schristos if (ptrace (PT_SETXSTATE, pid, (PTRACE_TYPE_ARG3) xstateregs, 236*6881a400Schristos xsave_len) == -1) 237*6881a400Schristos perror_with_name (_("Couldn't write extended state status")); 238*6881a400Schristos return; 239*6881a400Schristos } 240*6881a400Schristos #endif 241*6881a400Schristos 242*6881a400Schristos struct fpreg fpregs; 243*6881a400Schristos 244*6881a400Schristos if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) 245*6881a400Schristos perror_with_name (_("Couldn't get floating point status")); 246*6881a400Schristos 247*6881a400Schristos amd64_collect_fxsave (regcache, regnum, &fpregs); 248*6881a400Schristos 249*6881a400Schristos if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) 250*6881a400Schristos perror_with_name (_("Couldn't write floating point status")); 251*6881a400Schristos } 252699b0f92Schristos 253699b0f92Schristos /* Support for debugging kernel virtual memory images. */ 254699b0f92Schristos 255699b0f92Schristos #include <machine/pcb.h> 256699b0f92Schristos #include <osreldate.h> 257699b0f92Schristos 258699b0f92Schristos #include "bsd-kvm.h" 259699b0f92Schristos 260699b0f92Schristos static int 261699b0f92Schristos amd64fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) 262699b0f92Schristos { 263699b0f92Schristos /* The following is true for FreeBSD 5.2: 264699b0f92Schristos 265699b0f92Schristos The pcb contains %rip, %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15, 266699b0f92Schristos %ds, %es, %fs and %gs. This accounts for all callee-saved 267699b0f92Schristos registers specified by the psABI and then some. Here %esp 268699b0f92Schristos contains the stack pointer at the point just after the call to 269699b0f92Schristos cpu_switch(). From this information we reconstruct the register 270699b0f92Schristos state as it would like when we just returned from cpu_switch(). */ 271699b0f92Schristos 272699b0f92Schristos /* The stack pointer shouldn't be zero. */ 273699b0f92Schristos if (pcb->pcb_rsp == 0) 274699b0f92Schristos return 0; 275699b0f92Schristos 276699b0f92Schristos pcb->pcb_rsp += 8; 2777f2ac410Schristos regcache->raw_supply (AMD64_RIP_REGNUM, &pcb->pcb_rip); 2787f2ac410Schristos regcache->raw_supply (AMD64_RBX_REGNUM, &pcb->pcb_rbx); 2797f2ac410Schristos regcache->raw_supply (AMD64_RSP_REGNUM, &pcb->pcb_rsp); 2807f2ac410Schristos regcache->raw_supply (AMD64_RBP_REGNUM, &pcb->pcb_rbp); 2817f2ac410Schristos regcache->raw_supply (12, &pcb->pcb_r12); 2827f2ac410Schristos regcache->raw_supply (13, &pcb->pcb_r13); 2837f2ac410Schristos regcache->raw_supply (14, &pcb->pcb_r14); 2847f2ac410Schristos regcache->raw_supply (15, &pcb->pcb_r15); 285699b0f92Schristos #if (__FreeBSD_version < 800075) && (__FreeBSD_kernel_version < 800075) 286699b0f92Schristos /* struct pcb provides the pcb_ds/pcb_es/pcb_fs/pcb_gs fields only 287699b0f92Schristos up until __FreeBSD_version 800074: The removal of these fields 288699b0f92Schristos occurred on 2009-04-01 while the __FreeBSD_version number was 289699b0f92Schristos bumped to 800075 on 2009-04-06. So 800075 is the closest version 290699b0f92Schristos number where we should not try to access these fields. */ 2917f2ac410Schristos regcache->raw_supply (AMD64_DS_REGNUM, &pcb->pcb_ds); 2927f2ac410Schristos regcache->raw_supply (AMD64_ES_REGNUM, &pcb->pcb_es); 2937f2ac410Schristos regcache->raw_supply (AMD64_FS_REGNUM, &pcb->pcb_fs); 2947f2ac410Schristos regcache->raw_supply (AMD64_GS_REGNUM, &pcb->pcb_gs); 295699b0f92Schristos #endif 296699b0f92Schristos 297699b0f92Schristos return 1; 298699b0f92Schristos } 299699b0f92Schristos 300699b0f92Schristos 3017f2ac410Schristos /* Implement the read_description method. */ 302699b0f92Schristos 3037f2ac410Schristos const struct target_desc * 3047f2ac410Schristos amd64_fbsd_nat_target::read_description () 305699b0f92Schristos { 306699b0f92Schristos #ifdef PT_GETXSTATE_INFO 307699b0f92Schristos static int xsave_probed; 308699b0f92Schristos static uint64_t xcr0; 309699b0f92Schristos #endif 310699b0f92Schristos struct reg regs; 311699b0f92Schristos int is64; 312699b0f92Schristos 3137f2ac410Schristos if (ptrace (PT_GETREGS, inferior_ptid.pid (), 314699b0f92Schristos (PTRACE_TYPE_ARG3) ®s, 0) == -1) 315699b0f92Schristos perror_with_name (_("Couldn't get registers")); 316699b0f92Schristos is64 = (regs.r_cs == GSEL (GUCODE_SEL, SEL_UPL)); 317699b0f92Schristos #ifdef PT_GETXSTATE_INFO 318699b0f92Schristos if (!xsave_probed) 319699b0f92Schristos { 320699b0f92Schristos struct ptrace_xstate_info info; 321699b0f92Schristos 3227f2ac410Schristos if (ptrace (PT_GETXSTATE_INFO, inferior_ptid.pid (), 323699b0f92Schristos (PTRACE_TYPE_ARG3) &info, sizeof (info)) == 0) 324699b0f92Schristos { 325*6881a400Schristos xsave_len = info.xsave_len; 326699b0f92Schristos xcr0 = info.xsave_mask; 327699b0f92Schristos } 328699b0f92Schristos xsave_probed = 1; 329699b0f92Schristos } 330699b0f92Schristos 331*6881a400Schristos if (xsave_len != 0) 332699b0f92Schristos { 333699b0f92Schristos if (is64) 3347f2ac410Schristos return amd64_target_description (xcr0, true); 335699b0f92Schristos else 3367d62b00eSchristos return i386_target_description (xcr0, true); 337699b0f92Schristos } 338699b0f92Schristos #endif 339699b0f92Schristos if (is64) 3407f2ac410Schristos return amd64_target_description (X86_XSTATE_SSE_MASK, true); 341699b0f92Schristos else 3427d62b00eSchristos return i386_target_description (X86_XSTATE_SSE_MASK, true); 343699b0f92Schristos } 344699b0f92Schristos 3457d62b00eSchristos void _initialize_amd64fbsd_nat (); 346699b0f92Schristos void 3477d62b00eSchristos _initialize_amd64fbsd_nat () 348699b0f92Schristos { 3497f2ac410Schristos add_inf_child_target (&the_amd64_fbsd_nat_target); 350699b0f92Schristos 351699b0f92Schristos /* Support debugging kernel virtual memory images. */ 352699b0f92Schristos bsd_kvm_add_target (amd64fbsd_supply_pcb); 353699b0f92Schristos } 354