1 /* Low level Alpha GNU/Linux interface, for GDB when running native. 2 Copyright (C) 2005-2023 Free Software Foundation, Inc. 3 4 This file is part of GDB. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 19 #include "defs.h" 20 #include "target.h" 21 #include "regcache.h" 22 #include "linux-nat-trad.h" 23 24 #include "alpha-tdep.h" 25 #include "gdbarch.h" 26 27 #include "nat/gdb_ptrace.h" 28 #include <alpha/ptrace.h> 29 30 #include <sys/procfs.h> 31 #include "gregset.h" 32 33 /* The address of UNIQUE for ptrace. */ 34 #define ALPHA_UNIQUE_PTRACE_ADDR 65 35 36 class alpha_linux_nat_target final : public linux_nat_trad_target 37 { 38 protected: 39 /* Override linux_nat_trad_target methods. */ 40 CORE_ADDR register_u_offset (struct gdbarch *gdbarch, 41 int regno, int store_p) override; 42 }; 43 44 static alpha_linux_nat_target the_alpha_linux_nat_target; 45 46 /* See the comment in m68k-tdep.c regarding the utility of these 47 functions. */ 48 49 void 50 supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp) 51 { 52 const long *regp = (const long *)gregsetp; 53 54 /* PC is in slot 32, UNIQUE is in slot 33. */ 55 alpha_supply_int_regs (regcache, -1, regp, regp + 31, regp + 32); 56 } 57 58 void 59 fill_gregset (const struct regcache *regcache, 60 gdb_gregset_t *gregsetp, int regno) 61 { 62 long *regp = (long *)gregsetp; 63 64 /* PC is in slot 32, UNIQUE is in slot 33. */ 65 alpha_fill_int_regs (regcache, regno, regp, regp + 31, regp + 32); 66 } 67 68 /* Now we do the same thing for floating-point registers. 69 Again, see the comments in m68k-tdep.c. */ 70 71 void 72 supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp) 73 { 74 const long *regp = (const long *)fpregsetp; 75 76 /* FPCR is in slot 32. */ 77 alpha_supply_fp_regs (regcache, -1, regp, regp + 31); 78 } 79 80 void 81 fill_fpregset (const struct regcache *regcache, 82 gdb_fpregset_t *fpregsetp, int regno) 83 { 84 long *regp = (long *)fpregsetp; 85 86 /* FPCR is in slot 32. */ 87 alpha_fill_fp_regs (regcache, regno, regp, regp + 31); 88 } 89 90 CORE_ADDR 91 alpha_linux_nat_target::register_u_offset (struct gdbarch *gdbarch, 92 int regno, int store_p) 93 { 94 if (regno == gdbarch_pc_regnum (gdbarch)) 95 return PC; 96 if (regno == ALPHA_UNIQUE_REGNUM) 97 return ALPHA_UNIQUE_PTRACE_ADDR; 98 if (regno < gdbarch_fp0_regnum (gdbarch)) 99 return GPR_BASE + regno; 100 else 101 return FPR_BASE + regno - gdbarch_fp0_regnum (gdbarch); 102 } 103 104 void _initialize_alpha_linux_nat (); 105 void 106 _initialize_alpha_linux_nat () 107 { 108 linux_target = &the_alpha_linux_nat_target; 109 add_inf_child_target (&the_alpha_linux_nat_target); 110 } 111