Home | History | Annotate | Line # | Download | only in gdb
      1      1.1  christos /* Native-dependent code for NetBSD/hppa.
      2      1.1  christos 
      3  1.1.1.2  christos    Copyright (C) 2008-2024 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 "inferior.h"
     21      1.1  christos #include "regcache.h"
     22      1.1  christos 
     23      1.1  christos #include <sys/types.h>
     24      1.1  christos #include <sys/ptrace.h>
     25      1.1  christos #include <machine/reg.h>
     26      1.1  christos 
     27      1.1  christos #include "hppa-tdep.h"
     28      1.1  christos #include "inf-ptrace.h"
     29      1.1  christos 
     30      1.1  christos #include "netbsd-nat.h"
     31      1.1  christos 
     32      1.1  christos class hppa_nbsd_nat_target final : public nbsd_nat_target
     33      1.1  christos {
     34      1.1  christos   void fetch_registers (struct regcache *, int) override;
     35      1.1  christos   void store_registers (struct regcache *, int) override;
     36      1.1  christos };
     37      1.1  christos 
     38      1.1  christos static hppa_nbsd_nat_target the_hppa_nbsd_nat_target;
     39      1.1  christos 
     40      1.1  christos static int
     41      1.1  christos hppanbsd_gregset_supplies_p (int regnum)
     42      1.1  christos {
     43      1.1  christos   return ((regnum >= HPPA_R0_REGNUM && regnum <= HPPA_R31_REGNUM) ||
     44      1.1  christos 	  (regnum >= HPPA_SAR_REGNUM && regnum <= HPPA_PCSQ_TAIL_REGNUM) ||
     45      1.1  christos 	  regnum == HPPA_IPSW_REGNUM ||
     46      1.1  christos 	  (regnum >= HPPA_SR4_REGNUM && regnum <= HPPA_SR4_REGNUM + 5));
     47      1.1  christos }
     48      1.1  christos 
     49      1.1  christos static int
     50      1.1  christos hppanbsd_fpregset_supplies_p (int regnum)
     51      1.1  christos {
     52      1.1  christos   return (regnum >= HPPA_FP0_REGNUM && regnum <= HPPA_FP31R_REGNUM);
     53      1.1  christos }
     54      1.1  christos 
     55      1.1  christos /* Supply the general-purpose registers stored in GREGS to REGCACHE.  */
     56      1.1  christos 
     57      1.1  christos static void
     58      1.1  christos hppanbsd_supply_gregset (struct regcache *regcache, const void *gregs)
     59      1.1  christos {
     60      1.1  christos   const char *regs = (const char *)gregs;
     61      1.1  christos   int regnum;
     62      1.1  christos 
     63      1.1  christos   for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
     64      1.1  christos     regcache->raw_supply (regnum, regs + regnum * 4);
     65      1.1  christos 
     66      1.1  christos   regcache->raw_supply (HPPA_SAR_REGNUM, regs + 32 * 4);
     67      1.1  christos   regcache->raw_supply (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
     68      1.1  christos   regcache->raw_supply (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
     69      1.1  christos   regcache->raw_supply (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
     70      1.1  christos   regcache->raw_supply (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
     71      1.1  christos   regcache->raw_supply (HPPA_IPSW_REGNUM, regs);
     72      1.1  christos   regcache->raw_supply (HPPA_SR4_REGNUM, regs + 41 * 4);
     73      1.1  christos   regcache->raw_supply (HPPA_SR4_REGNUM + 1, regs + 37 * 4);
     74      1.1  christos   regcache->raw_supply (HPPA_SR4_REGNUM + 2, regs + 38 * 4);
     75      1.1  christos   regcache->raw_supply (HPPA_SR4_REGNUM + 3, regs + 39 * 4);
     76      1.1  christos   regcache->raw_supply (HPPA_SR4_REGNUM + 4, regs + 40 * 4);
     77      1.1  christos }
     78      1.1  christos 
     79      1.1  christos /* Supply the floating-point registers stored in FPREGS to REGCACHE.  */
     80      1.1  christos 
     81      1.1  christos static void
     82      1.1  christos hppanbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
     83      1.1  christos {
     84      1.1  christos   const char *regs = (const char *)fpregs;
     85      1.1  christos   int regnum;
     86      1.1  christos 
     87      1.1  christos   for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM;
     88      1.1  christos        regnum += 2, regs += 8)
     89      1.1  christos     {
     90      1.1  christos       regcache->raw_supply (regnum, regs);
     91      1.1  christos       regcache->raw_supply (regnum + 1, regs + 4);
     92      1.1  christos     }
     93      1.1  christos }
     94      1.1  christos 
     95      1.1  christos /* Collect the general-purpose registers from REGCACHE and store them
     96      1.1  christos    in GREGS.  */
     97      1.1  christos 
     98      1.1  christos static void
     99      1.1  christos hppanbsd_collect_gregset (const struct regcache *regcache,
    100      1.1  christos 			  void *gregs, int regnum)
    101      1.1  christos {
    102      1.1  christos   char *regs = (char *)gregs;
    103      1.1  christos   int i;
    104      1.1  christos 
    105      1.1  christos   for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
    106      1.1  christos     {
    107      1.1  christos       if (regnum == -1 || regnum == i)
    108      1.1  christos 	regcache->raw_collect (i, regs + i * 4);
    109      1.1  christos     }
    110      1.1  christos 
    111      1.1  christos   if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
    112      1.1  christos     regcache->raw_collect (HPPA_IPSW_REGNUM, regs);
    113      1.1  christos   if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
    114      1.1  christos     regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
    115      1.1  christos   if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
    116      1.1  christos     regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
    117      1.1  christos 
    118      1.1  christos   if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
    119      1.1  christos     regcache->raw_collect (HPPA_SAR_REGNUM, regs + 32 * 4);
    120      1.1  christos   if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM)
    121      1.1  christos     regcache->raw_collect (HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4);
    122      1.1  christos   if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM)
    123      1.1  christos     regcache->raw_collect (HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4);
    124      1.1  christos   if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
    125      1.1  christos     regcache->raw_collect (HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4);
    126      1.1  christos   if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
    127      1.1  christos     regcache->raw_collect (HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4);
    128      1.1  christos   if (regnum == -1 || regnum == HPPA_IPSW_REGNUM)
    129      1.1  christos     regcache->raw_collect (HPPA_IPSW_REGNUM, regs);
    130      1.1  christos   if (regnum == -1 || regnum == HPPA_SR4_REGNUM)
    131      1.1  christos     regcache->raw_collect (HPPA_SR4_REGNUM, regs + 41 * 4);
    132      1.1  christos   if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 1)
    133      1.1  christos     regcache->raw_collect (HPPA_SR4_REGNUM + 1, regs + 37 * 4);
    134      1.1  christos   if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 2)
    135      1.1  christos     regcache->raw_collect (HPPA_SR4_REGNUM + 2, regs + 38 * 4);
    136      1.1  christos   if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 3)
    137      1.1  christos     regcache->raw_collect (HPPA_SR4_REGNUM + 3, regs + 39 * 4);
    138      1.1  christos   if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 4)
    139      1.1  christos     regcache->raw_collect (HPPA_SR4_REGNUM + 4, regs + 40 * 4);
    140      1.1  christos }
    141      1.1  christos 
    142      1.1  christos /* Collect the floating-point registers from REGCACHE and store them
    143      1.1  christos    in FPREGS.  */
    144      1.1  christos 
    145      1.1  christos static void
    146      1.1  christos hppanbsd_collect_fpregset (const struct regcache *regcache,
    147      1.1  christos 			  void *fpregs, int regnum)
    148      1.1  christos {
    149      1.1  christos   char *regs = (char *)fpregs;
    150      1.1  christos   int i;
    151      1.1  christos 
    152      1.1  christos   for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8)
    153      1.1  christos     {
    154      1.1  christos       if (regnum == -1 || regnum == i || regnum == i + 1)
    155      1.1  christos 	{
    156      1.1  christos 	  regcache->raw_collect (i, regs);
    157      1.1  christos 	  regcache->raw_collect (i + 1, regs + 4);
    158      1.1  christos 	}
    159      1.1  christos     }
    160      1.1  christos }
    161      1.1  christos 
    162      1.1  christos 
    164      1.1  christos /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    165      1.1  christos    for all registers (including the floating-point registers).  */
    166      1.1  christos 
    167      1.1  christos void
    168      1.1  christos hppa_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
    169      1.1  christos 
    170      1.1  christos {
    171      1.1  christos   pid_t pid = regcache->ptid ().pid ();
    172      1.1  christos   int lwp = regcache->ptid ().lwp ();
    173      1.1  christos 
    174      1.1  christos   if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
    175      1.1  christos     {
    176      1.1  christos       struct reg regs;
    177      1.1  christos 
    178      1.1  christos       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
    179      1.1  christos 	perror_with_name (_("Couldn't get registers"));
    180      1.1  christos 
    181      1.1  christos       hppanbsd_supply_gregset (regcache, &regs);
    182      1.1  christos     }
    183      1.1  christos 
    184      1.1  christos   if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
    185      1.1  christos     {
    186      1.1  christos       struct fpreg fpregs;
    187      1.1  christos 
    188      1.1  christos       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
    189      1.1  christos 	perror_with_name (_("Couldn't get floating point status"));
    190      1.1  christos 
    191      1.1  christos       hppanbsd_supply_fpregset (regcache, &fpregs);
    192      1.1  christos     }
    193      1.1  christos }
    194      1.1  christos 
    195      1.1  christos /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    196      1.1  christos    this for all registers (including the floating-point registers).  */
    197      1.1  christos 
    198      1.1  christos void
    199      1.1  christos hppa_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
    200      1.1  christos {
    201      1.1  christos   pid_t pid = regcache->ptid ().pid ();
    202      1.1  christos   int lwp = regcache->ptid ().lwp ();
    203      1.1  christos 
    204      1.1  christos   if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
    205      1.1  christos     {
    206      1.1  christos       struct reg regs;
    207      1.1  christos 
    208      1.1  christos       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
    209      1.1  christos 	perror_with_name (_("Couldn't get registers"));
    210      1.1  christos 
    211      1.1  christos       hppanbsd_collect_gregset (regcache, &regs, regnum);
    212      1.1  christos 
    213      1.1  christos       if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, lwp) == -1)
    214      1.1  christos 	perror_with_name (_("Couldn't write registers"));
    215      1.1  christos     }
    216      1.1  christos 
    217      1.1  christos   if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum))
    218      1.1  christos     {
    219      1.1  christos       struct fpreg fpregs;
    220      1.1  christos 
    221      1.1  christos       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
    222      1.1  christos 	perror_with_name (_("Couldn't get floating point status"));
    223      1.1  christos 
    224      1.1  christos       hppanbsd_collect_fpregset (regcache, &fpregs, regnum);
    225      1.1  christos 
    226      1.1  christos       if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1)
    227      1.1  christos 	perror_with_name (_("Couldn't write floating point status"));
    228      1.1  christos     }
    229      1.1  christos }
    230      1.1  christos 
    231      1.1  christos void _initialize_hppanbsd_nat ();
    232      1.1  christos void
    233      1.1  christos _initialize_hppanbsd_nat ()
    234      1.1  christos {
    235      1.1  christos   add_inf_child_target (&the_hppa_nbsd_nat_target);
    236                    }
    237