1699b0f92Schristos /* Native-dependent code for OpenBSD/hppa. 2699b0f92Schristos 3*6881a400Schristos Copyright (C) 2004-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 <sys/types.h> 26699b0f92Schristos #include <sys/ptrace.h> 27699b0f92Schristos #include <machine/reg.h> 28699b0f92Schristos 29699b0f92Schristos #include "hppa-tdep.h" 30699b0f92Schristos #include "inf-ptrace.h" 31699b0f92Schristos 32699b0f92Schristos #include "obsd-nat.h" 33699b0f92Schristos 347f2ac410Schristos struct hppa_obsd_nat_target final : public obsd_nat_target 357f2ac410Schristos { 367f2ac410Schristos void fetch_registers (struct regcache *, int) override; 377f2ac410Schristos void store_registers (struct regcache *, int) override; 387f2ac410Schristos }; 397f2ac410Schristos 407f2ac410Schristos static hppa_obsd_nat_target the_hppa_obsd_nat_target; 417f2ac410Schristos 42699b0f92Schristos static int 43699b0f92Schristos hppaobsd_gregset_supplies_p (int regnum) 44699b0f92Schristos { 45699b0f92Schristos return (regnum >= HPPA_R0_REGNUM && regnum <= HPPA_CR27_REGNUM); 46699b0f92Schristos } 47699b0f92Schristos 48699b0f92Schristos static int 49699b0f92Schristos hppaobsd_fpregset_supplies_p (int regnum) 50699b0f92Schristos { 51699b0f92Schristos return (regnum >= HPPA_FP0_REGNUM && regnum <= HPPA_FP31R_REGNUM); 52699b0f92Schristos } 53699b0f92Schristos 54699b0f92Schristos /* Supply the general-purpose registers stored in GREGS to REGCACHE. */ 55699b0f92Schristos 56699b0f92Schristos static void 57699b0f92Schristos hppaobsd_supply_gregset (struct regcache *regcache, const void *gregs) 58699b0f92Schristos { 59699b0f92Schristos gdb_byte zero[4] = { 0 }; 60699b0f92Schristos const char *regs = gregs; 61699b0f92Schristos int regnum; 62699b0f92Schristos 637f2ac410Schristos regcache->raw_supply (HPPA_R0_REGNUM, &zero); 64699b0f92Schristos for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++) 657f2ac410Schristos regcache->raw_supply (regnum, regs + regnum * 4); 66699b0f92Schristos 67699b0f92Schristos if (sizeof(struct reg) >= 46 * 4) 68699b0f92Schristos { 697f2ac410Schristos regcache->raw_supply (HPPA_IPSW_REGNUM, regs); 707f2ac410Schristos regcache->raw_supply (HPPA_SAR_REGNUM, regs + 32 * 4); 717f2ac410Schristos regcache->raw_supply (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4); 727f2ac410Schristos regcache->raw_supply (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4); 737f2ac410Schristos regcache->raw_supply (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4); 747f2ac410Schristos regcache->raw_supply (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4); 757f2ac410Schristos regcache->raw_supply (HPPA_SR0_REGNUM, regs + 37 * 4); 767f2ac410Schristos regcache->raw_supply (HPPA_SR1_REGNUM, regs + 38 * 4); 777f2ac410Schristos regcache->raw_supply (HPPA_SR2_REGNUM, regs + 39 * 4); 787f2ac410Schristos regcache->raw_supply (HPPA_SR3_REGNUM, regs + 40 * 4); 797f2ac410Schristos regcache->raw_supply (HPPA_SR4_REGNUM, regs + 41 * 4); 807f2ac410Schristos regcache->raw_supply (HPPA_SR5_REGNUM, regs + 42 * 4); 817f2ac410Schristos regcache->raw_supply (HPPA_SR6_REGNUM, regs + 43 * 4); 827f2ac410Schristos regcache->raw_supply (HPPA_SR7_REGNUM, regs + 44 * 4); 837f2ac410Schristos regcache->raw_supply (HPPA_CR26_REGNUM, regs + 45 * 4); 847f2ac410Schristos regcache->raw_supply (HPPA_CR27_REGNUM, regs + 46 * 4); 85699b0f92Schristos } 86699b0f92Schristos else 87699b0f92Schristos { 887f2ac410Schristos regcache->raw_supply (HPPA_SAR_REGNUM, regs); 897f2ac410Schristos regcache->raw_supply (HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4); 907f2ac410Schristos regcache->raw_supply (HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4); 91699b0f92Schristos } 92699b0f92Schristos } 93699b0f92Schristos 94699b0f92Schristos /* Supply the floating-point registers stored in FPREGS to REGCACHE. */ 95699b0f92Schristos 96699b0f92Schristos static void 97699b0f92Schristos hppaobsd_supply_fpregset (struct regcache *regcache, const void *fpregs) 98699b0f92Schristos { 99699b0f92Schristos const char *regs = fpregs; 100699b0f92Schristos int regnum; 101699b0f92Schristos 102699b0f92Schristos for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM; 103699b0f92Schristos regnum += 2, regs += 8) 104699b0f92Schristos { 1057f2ac410Schristos regcache->raw_supply (regnum, regs); 1067f2ac410Schristos regcache->raw_supply (regnum + 1, regs + 4); 107699b0f92Schristos } 108699b0f92Schristos } 109699b0f92Schristos 110699b0f92Schristos /* Collect the general-purpose registers from REGCACHE and store them 111699b0f92Schristos in GREGS. */ 112699b0f92Schristos 113699b0f92Schristos static void 114699b0f92Schristos hppaobsd_collect_gregset (const struct regcache *regcache, 115699b0f92Schristos void *gregs, int regnum) 116699b0f92Schristos { 117699b0f92Schristos char *regs = gregs; 118699b0f92Schristos int i; 119699b0f92Schristos 120699b0f92Schristos for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++) 121699b0f92Schristos { 122699b0f92Schristos if (regnum == -1 || regnum == i) 1237f2ac410Schristos regcache->raw_collect (i, regs + i * 4); 124699b0f92Schristos } 125699b0f92Schristos 126699b0f92Schristos if (sizeof(struct reg) >= 46 * 4) 127699b0f92Schristos { 128699b0f92Schristos if (regnum == -1 || regnum == HPPA_IPSW_REGNUM) 1297f2ac410Schristos regcache->raw_collect (HPPA_IPSW_REGNUM, regs); 130699b0f92Schristos if (regnum == -1 || regnum == HPPA_SAR_REGNUM) 1317f2ac410Schristos regcache->raw_collect (HPPA_SAR_REGNUM, regs + 32 * 4); 132699b0f92Schristos if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM) 1337f2ac410Schristos regcache->raw_collect (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4); 134699b0f92Schristos if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM) 1357f2ac410Schristos regcache->raw_collect (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4); 136699b0f92Schristos if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM) 1377f2ac410Schristos regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4); 138699b0f92Schristos if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM) 1397f2ac410Schristos regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4); 140699b0f92Schristos if (regnum == -1 || regnum == HPPA_SR0_REGNUM) 1417f2ac410Schristos regcache->raw_collect (HPPA_SR0_REGNUM, regs + 37 * 4); 142699b0f92Schristos if (regnum == -1 || regnum == HPPA_SR1_REGNUM) 1437f2ac410Schristos regcache->raw_collect (HPPA_SR1_REGNUM, regs + 38 * 4); 144699b0f92Schristos if (regnum == -1 || regnum == HPPA_SR2_REGNUM) 1457f2ac410Schristos regcache->raw_collect (HPPA_SR2_REGNUM, regs + 39 * 4); 146699b0f92Schristos if (regnum == -1 || regnum == HPPA_SR3_REGNUM) 1477f2ac410Schristos regcache->raw_collect (HPPA_SR3_REGNUM, regs + 40 * 4); 148699b0f92Schristos if (regnum == -1 || regnum == HPPA_SR4_REGNUM) 1497f2ac410Schristos regcache->raw_collect (HPPA_SR4_REGNUM, regs + 41 * 4); 150699b0f92Schristos if (regnum == -1 || regnum == HPPA_SR5_REGNUM) 1517f2ac410Schristos regcache->raw_collect (HPPA_SR5_REGNUM, regs + 42 * 4); 152699b0f92Schristos if (regnum == -1 || regnum == HPPA_SR6_REGNUM) 1537f2ac410Schristos regcache->raw_collect (HPPA_SR6_REGNUM, regs + 43 * 4); 154699b0f92Schristos if (regnum == -1 || regnum == HPPA_SR7_REGNUM) 1557f2ac410Schristos regcache->raw_collect (HPPA_SR7_REGNUM, regs + 44 * 4); 156699b0f92Schristos if (regnum == -1 || regnum == HPPA_CR26_REGNUM) 1577f2ac410Schristos regcache->raw_collect (HPPA_CR26_REGNUM, regs + 45 * 4); 158699b0f92Schristos if (regnum == -1 || regnum == HPPA_CR27_REGNUM) 1597f2ac410Schristos regcache->raw_collect (HPPA_CR27_REGNUM, regs + 46 * 4); 160699b0f92Schristos } 161699b0f92Schristos else 162699b0f92Schristos { 163699b0f92Schristos if (regnum == -1 || regnum == HPPA_SAR_REGNUM) 1647f2ac410Schristos regcache->raw_collect (HPPA_SAR_REGNUM, regs); 165699b0f92Schristos if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM) 1667f2ac410Schristos regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4); 167699b0f92Schristos if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM) 1687f2ac410Schristos regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4); 169699b0f92Schristos } 170699b0f92Schristos } 171699b0f92Schristos 172699b0f92Schristos /* Collect the floating-point registers from REGCACHE and store them 173699b0f92Schristos in FPREGS. */ 174699b0f92Schristos 175699b0f92Schristos static void 176699b0f92Schristos hppaobsd_collect_fpregset (struct regcache *regcache, 177699b0f92Schristos void *fpregs, int regnum) 178699b0f92Schristos { 179699b0f92Schristos char *regs = fpregs; 180699b0f92Schristos int i; 181699b0f92Schristos 182699b0f92Schristos for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8) 183699b0f92Schristos { 184699b0f92Schristos if (regnum == -1 || regnum == i || regnum == i + 1) 185699b0f92Schristos { 1867f2ac410Schristos regcache->raw_collect (i, regs); 1877f2ac410Schristos regcache->raw_collect (i + 1, regs + 4); 188699b0f92Schristos } 189699b0f92Schristos } 190699b0f92Schristos } 191699b0f92Schristos 192699b0f92Schristos 193699b0f92Schristos /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this 194699b0f92Schristos for all registers (including the floating-point registers). */ 195699b0f92Schristos 1967f2ac410Schristos void 1977f2ac410Schristos hppa_obsd_nat_target::fetch_registers (struct regcache *regcache, int regnum) 198699b0f92Schristos { 1997f2ac410Schristos pid_t pid = regcache->ptid ().pid (); 200699b0f92Schristos 201699b0f92Schristos if (regnum == -1 || hppaobsd_gregset_supplies_p (regnum)) 202699b0f92Schristos { 203699b0f92Schristos struct reg regs; 204699b0f92Schristos 205699b0f92Schristos if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1) 206699b0f92Schristos perror_with_name (_("Couldn't get registers")); 207699b0f92Schristos 208699b0f92Schristos hppaobsd_supply_gregset (regcache, ®s); 209699b0f92Schristos } 210699b0f92Schristos 211699b0f92Schristos if (regnum == -1 || hppaobsd_fpregset_supplies_p (regnum)) 212699b0f92Schristos { 213699b0f92Schristos struct fpreg fpregs; 214699b0f92Schristos 215699b0f92Schristos if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) 216699b0f92Schristos perror_with_name (_("Couldn't get floating point status")); 217699b0f92Schristos 218699b0f92Schristos hppaobsd_supply_fpregset (regcache, &fpregs); 219699b0f92Schristos } 220699b0f92Schristos } 221699b0f92Schristos 222699b0f92Schristos /* Store register REGNUM back into the inferior. If REGNUM is -1, do 223699b0f92Schristos this for all registers (including the floating-point registers). */ 224699b0f92Schristos 2257f2ac410Schristos void 2267f2ac410Schristos hppa_obsd_nat_target::store_registers (struct regcache *regcache, int regnum) 227699b0f92Schristos { 228699b0f92Schristos if (regnum == -1 || hppaobsd_gregset_supplies_p (regnum)) 229699b0f92Schristos { 230699b0f92Schristos struct reg regs; 231699b0f92Schristos 232699b0f92Schristos if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1) 233699b0f92Schristos perror_with_name (_("Couldn't get registers")); 234699b0f92Schristos 235699b0f92Schristos hppaobsd_collect_gregset (regcache, ®s, regnum); 236699b0f92Schristos 237699b0f92Schristos if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1) 238699b0f92Schristos perror_with_name (_("Couldn't write registers")); 239699b0f92Schristos } 240699b0f92Schristos 241699b0f92Schristos if (regnum == -1 || hppaobsd_fpregset_supplies_p (regnum)) 242699b0f92Schristos { 243699b0f92Schristos struct fpreg fpregs; 244699b0f92Schristos 245699b0f92Schristos if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) 246699b0f92Schristos perror_with_name (_("Couldn't get floating point status")); 247699b0f92Schristos 248699b0f92Schristos hppaobsd_collect_fpregset (regcache, &fpregs, regnum); 249699b0f92Schristos 250699b0f92Schristos if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) 251699b0f92Schristos perror_with_name (_("Couldn't write floating point status")); 252699b0f92Schristos } 253699b0f92Schristos } 254699b0f92Schristos 2557d62b00eSchristos void _initialize_hppaobsd_nat (); 256699b0f92Schristos void 2577d62b00eSchristos _initialize_hppaobsd_nat () 258699b0f92Schristos { 2597f2ac410Schristos add_inf_child_target (&the_hppa_obsd_nat_target); 260699b0f92Schristos } 261