Home | History | Annotate | Line # | Download | only in gdb
hppa-netbsd-nat.c revision 1.1
      1  1.1  christos /* Native-dependent code for NetBSD/hppa.
      2  1.1  christos 
      3  1.1  christos    Copyright (C) 2008-2023 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    This file is part of GDB.
      6  1.1  christos 
      7  1.1  christos    This program is free software; you can redistribute it and/or modify
      8  1.1  christos    it under the terms of the GNU General Public License as published by
      9  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10  1.1  christos    (at your option) any later version.
     11  1.1  christos 
     12  1.1  christos    This program is distributed in the hope that it will be useful,
     13  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  christos    GNU General Public License for more details.
     16  1.1  christos 
     17  1.1  christos    You should have received a copy of the GNU General Public License
     18  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19  1.1  christos 
     20  1.1  christos #include "defs.h"
     21  1.1  christos #include "inferior.h"
     22  1.1  christos #include "regcache.h"
     23  1.1  christos 
     24  1.1  christos #include <sys/types.h>
     25  1.1  christos #include <sys/ptrace.h>
     26  1.1  christos #include <machine/reg.h>
     27  1.1  christos 
     28  1.1  christos #include "hppa-tdep.h"
     29  1.1  christos #include "inf-ptrace.h"
     30  1.1  christos 
     31  1.1  christos #include "netbsd-nat.h"
     32  1.1  christos 
     33  1.1  christos class hppa_nbsd_nat_target final : public nbsd_nat_target
     34  1.1  christos {
     35  1.1  christos   void fetch_registers (struct regcache *, int) override;
     36  1.1  christos   void store_registers (struct regcache *, int) override;
     37  1.1  christos };
     38  1.1  christos 
     39  1.1  christos static hppa_nbsd_nat_target the_hppa_nbsd_nat_target;
     40  1.1  christos 
     41  1.1  christos static int
     42  1.1  christos hppanbsd_gregset_supplies_p (int regnum)
     43  1.1  christos {
     44  1.1  christos   return ((regnum >= HPPA_R0_REGNUM && regnum <= HPPA_R31_REGNUM) ||
     45  1.1  christos 	  (regnum >= HPPA_SAR_REGNUM && regnum <= HPPA_PCSQ_TAIL_REGNUM) ||
     46  1.1  christos 	  regnum == HPPA_IPSW_REGNUM ||
     47  1.1  christos 	  (regnum >= HPPA_SR4_REGNUM && regnum <= HPPA_SR4_REGNUM + 5));
     48  1.1  christos }
     49  1.1  christos 
     50  1.1  christos static int
     51  1.1  christos hppanbsd_fpregset_supplies_p (int regnum)
     52  1.1  christos {
     53  1.1  christos   return (regnum >= HPPA_FP0_REGNUM && regnum <= HPPA_FP31R_REGNUM);
     54  1.1  christos }
     55  1.1  christos 
     56  1.1  christos /* Supply the general-purpose registers stored in GREGS to REGCACHE.  */
     57  1.1  christos 
     58  1.1  christos static void
     59  1.1  christos hppanbsd_supply_gregset (struct regcache *regcache, const void *gregs)
     60  1.1  christos {
     61  1.1  christos   const char *regs = (const char *)gregs;
     62  1.1  christos   int regnum;
     63  1.1  christos 
     64  1.1  christos   for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
     65  1.1  christos     regcache->raw_supply (regnum, regs + regnum * 4);
     66  1.1  christos 
     67  1.1  christos   regcache->raw_supply (HPPA_SAR_REGNUM, regs + 32 * 4);
     68  1.1  christos   regcache->raw_supply (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
     69  1.1  christos   regcache->raw_supply (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
     70  1.1  christos   regcache->raw_supply (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
     71  1.1  christos   regcache->raw_supply (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
     72  1.1  christos   regcache->raw_supply (HPPA_IPSW_REGNUM, regs);
     73  1.1  christos   regcache->raw_supply (HPPA_SR4_REGNUM, regs + 41 * 4);
     74  1.1  christos   regcache->raw_supply (HPPA_SR4_REGNUM + 1, regs + 37 * 4);
     75  1.1  christos   regcache->raw_supply (HPPA_SR4_REGNUM + 2, regs + 38 * 4);
     76  1.1  christos   regcache->raw_supply (HPPA_SR4_REGNUM + 3, regs + 39 * 4);
     77  1.1  christos   regcache->raw_supply (HPPA_SR4_REGNUM + 4, regs + 40 * 4);
     78  1.1  christos }
     79  1.1  christos 
     80  1.1  christos /* Supply the floating-point registers stored in FPREGS to REGCACHE.  */
     81  1.1  christos 
     82  1.1  christos static void
     83  1.1  christos hppanbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
     84  1.1  christos {
     85  1.1  christos   const char *regs = (const char *)fpregs;
     86  1.1  christos   int regnum;
     87  1.1  christos 
     88  1.1  christos   for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM;
     89  1.1  christos        regnum += 2, regs += 8)
     90  1.1  christos     {
     91  1.1  christos       regcache->raw_supply (regnum, regs);
     92  1.1  christos       regcache->raw_supply (regnum + 1, regs + 4);
     93  1.1  christos     }
     94  1.1  christos }
     95  1.1  christos 
     96  1.1  christos /* Collect the general-purpose registers from REGCACHE and store them
     97  1.1  christos    in GREGS.  */
     98  1.1  christos 
     99  1.1  christos static void
    100  1.1  christos hppanbsd_collect_gregset (const struct regcache *regcache,
    101  1.1  christos 			  void *gregs, int regnum)
    102  1.1  christos {
    103  1.1  christos   char *regs = (char *)gregs;
    104  1.1  christos   int i;
    105  1.1  christos 
    106  1.1  christos   for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
    107  1.1  christos     {
    108  1.1  christos       if (regnum == -1 || regnum == i)
    109  1.1  christos 	regcache->raw_collect (i, regs + i * 4);
    110  1.1  christos     }
    111  1.1  christos 
    112  1.1  christos   if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
    113  1.1  christos     regcache->raw_collect (HPPA_IPSW_REGNUM, regs);
    114  1.1  christos   if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
    115  1.1  christos     regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
    116  1.1  christos   if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
    117  1.1  christos     regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
    118  1.1  christos 
    119  1.1  christos   if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
    120  1.1  christos     regcache->raw_collect (HPPA_SAR_REGNUM, regs + 32 * 4);
    121  1.1  christos   if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM)
    122  1.1  christos     regcache->raw_collect (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
    123  1.1  christos   if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM)
    124  1.1  christos     regcache->raw_collect (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
    125  1.1  christos   if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
    126  1.1  christos     regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
    127  1.1  christos   if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
    128  1.1  christos     regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
    129  1.1  christos   if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
    130  1.1  christos     regcache->raw_collect (HPPA_IPSW_REGNUM, regs);
    131  1.1  christos   if (regnum == -1 || regnum == HPPA_SR4_REGNUM)
    132  1.1  christos     regcache->raw_collect (HPPA_SR4_REGNUM, regs + 41 * 4);
    133  1.1  christos   if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 1)
    134  1.1  christos     regcache->raw_collect (HPPA_SR4_REGNUM + 1, regs + 37 * 4);
    135  1.1  christos   if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 2)
    136  1.1  christos     regcache->raw_collect (HPPA_SR4_REGNUM + 2, regs + 38 * 4);
    137  1.1  christos   if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 3)
    138  1.1  christos     regcache->raw_collect (HPPA_SR4_REGNUM + 3, regs + 39 * 4);
    139  1.1  christos   if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 4)
    140  1.1  christos     regcache->raw_collect (HPPA_SR4_REGNUM + 4, regs + 40 * 4);
    141  1.1  christos }
    142  1.1  christos 
    143  1.1  christos /* Collect the floating-point registers from REGCACHE and store them
    144  1.1  christos    in FPREGS.  */
    145  1.1  christos 
    146  1.1  christos static void
    147  1.1  christos hppanbsd_collect_fpregset (const struct regcache *regcache,
    148  1.1  christos 			  void *fpregs, int regnum)
    149  1.1  christos {
    150  1.1  christos   char *regs = (char *)fpregs;
    151  1.1  christos   int i;
    152  1.1  christos 
    153  1.1  christos   for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8)
    154  1.1  christos     {
    155  1.1  christos       if (regnum == -1 || regnum == i || regnum == i + 1)
    156  1.1  christos 	{
    157  1.1  christos 	  regcache->raw_collect (i, regs);
    158  1.1  christos 	  regcache->raw_collect (i + 1, regs + 4);
    159  1.1  christos 	}
    160  1.1  christos     }
    161  1.1  christos }
    162  1.1  christos 
    163  1.1  christos 
    165  1.1  christos /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    166  1.1  christos    for all registers (including the floating-point registers).  */
    167  1.1  christos 
    168  1.1  christos void
    169  1.1  christos hppa_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
    170  1.1  christos 
    171  1.1  christos {
    172  1.1  christos   pid_t pid = regcache->ptid ().pid ();
    173  1.1  christos   int lwp = regcache->ptid ().lwp ();
    174  1.1  christos 
    175  1.1  christos   if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
    176  1.1  christos     {
    177  1.1  christos       struct reg regs;
    178  1.1  christos 
    179  1.1  christos       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
    180  1.1  christos 	perror_with_name (_("Couldn't get registers"));
    181  1.1  christos 
    182  1.1  christos       hppanbsd_supply_gregset (regcache, &regs);
    183  1.1  christos     }
    184  1.1  christos 
    185  1.1  christos   if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
    186  1.1  christos     {
    187  1.1  christos       struct fpreg fpregs;
    188  1.1  christos 
    189  1.1  christos       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
    190  1.1  christos 	perror_with_name (_("Couldn't get floating point status"));
    191  1.1  christos 
    192  1.1  christos       hppanbsd_supply_fpregset (regcache, &fpregs);
    193  1.1  christos     }
    194  1.1  christos }
    195  1.1  christos 
    196  1.1  christos /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    197  1.1  christos    this for all registers (including the floating-point registers).  */
    198  1.1  christos 
    199  1.1  christos void
    200  1.1  christos hppa_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
    201  1.1  christos {
    202  1.1  christos   pid_t pid = regcache->ptid ().pid ();
    203  1.1  christos   int lwp = regcache->ptid ().lwp ();
    204  1.1  christos 
    205  1.1  christos   if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
    206  1.1  christos     {
    207  1.1  christos       struct reg regs;
    208  1.1  christos 
    209  1.1  christos       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
    210  1.1  christos 	perror_with_name (_("Couldn't get registers"));
    211  1.1  christos 
    212  1.1  christos       hppanbsd_collect_gregset (regcache, &regs, regnum);
    213  1.1  christos 
    214  1.1  christos       if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
    215  1.1  christos 	perror_with_name (_("Couldn't write registers"));
    216  1.1  christos     }
    217  1.1  christos 
    218  1.1  christos   if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
    219  1.1  christos     {
    220  1.1  christos       struct fpreg fpregs;
    221  1.1  christos 
    222  1.1  christos       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
    223  1.1  christos 	perror_with_name (_("Couldn't get floating point status"));
    224  1.1  christos 
    225  1.1  christos       hppanbsd_collect_fpregset (regcache, &fpregs, regnum);
    226  1.1  christos 
    227  1.1  christos       if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
    228  1.1  christos 	perror_with_name (_("Couldn't write floating point status"));
    229  1.1  christos     }
    230  1.1  christos }
    231  1.1  christos 
    232  1.1  christos void _initialize_hppanbsd_nat ();
    233  1.1  christos void
    234  1.1  christos _initialize_hppanbsd_nat ()
    235  1.1  christos {
    236  1.1  christos   add_inf_child_target (&the_hppa_nbsd_nat_target);
    237                }
    238