Home | History | Annotate | Line # | Download | only in gdb
mips-fbsd-nat.c revision 1.1.1.3.2.1
      1 /* Native-dependent code for FreeBSD/mips.
      2 
      3    Copyright (C) 2017-2023 Free Software Foundation, Inc.
      4 
      5    This file is part of GDB.
      6 
      7    This program is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3 of the License, or
     10    (at your option) any later version.
     11 
     12    This program is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19 
     20 #include "defs.h"
     21 #include "inferior.h"
     22 #include "regcache.h"
     23 #include "target.h"
     24 
     25 #include <sys/types.h>
     26 #include <sys/ptrace.h>
     27 #include <machine/reg.h>
     28 
     29 #include "fbsd-nat.h"
     30 #include "mips-tdep.h"
     31 #include "mips-fbsd-tdep.h"
     32 #include "inf-ptrace.h"
     33 
     34 struct mips_fbsd_nat_target final : public fbsd_nat_target
     35 {
     36   void fetch_registers (struct regcache *, int) override;
     37   void store_registers (struct regcache *, int) override;
     38 };
     39 
     40 static mips_fbsd_nat_target the_mips_fbsd_nat_target;
     41 
     42 /* Determine if PT_GETREGS fetches REGNUM.  */
     43 
     44 static bool
     45 getregs_supplies (struct gdbarch *gdbarch, int regnum)
     46 {
     47   return (regnum >= MIPS_ZERO_REGNUM
     48 	  && regnum <= mips_regnum (gdbarch)->pc);
     49 }
     50 
     51 /* Determine if PT_GETFPREGS fetches REGNUM.  */
     52 
     53 static bool
     54 getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
     55 {
     56   return (regnum >= mips_regnum (gdbarch)->fp0
     57 	  && regnum <= mips_regnum (gdbarch)->fp_implementation_revision);
     58 }
     59 
     60 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
     61    for all registers.  */
     62 
     63 void
     64 mips_fbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
     65 {
     66   pid_t pid = get_ptrace_pid (regcache->ptid ());
     67 
     68   struct gdbarch *gdbarch = regcache->arch ();
     69   if (regnum == -1 || getregs_supplies (gdbarch, regnum))
     70     {
     71       struct reg regs;
     72 
     73       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
     74 	perror_with_name (_("Couldn't get registers"));
     75 
     76       mips_fbsd_supply_gregs (regcache, regnum, &regs, sizeof (register_t));
     77     }
     78 
     79   if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
     80     {
     81       struct fpreg fpregs;
     82 
     83       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
     84 	perror_with_name (_("Couldn't get floating point status"));
     85 
     86       mips_fbsd_supply_fpregs (regcache, regnum, &fpregs,
     87 			       sizeof (f_register_t));
     88     }
     89 }
     90 
     91 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
     92    this for all registers.  */
     93 
     94 void
     95 mips_fbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
     96 {
     97   pid_t pid = get_ptrace_pid (regcache->ptid ());
     98 
     99   struct gdbarch *gdbarch = regcache->arch ();
    100   if (regnum == -1 || getregs_supplies (gdbarch, regnum))
    101     {
    102       struct reg regs;
    103 
    104       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
    105 	perror_with_name (_("Couldn't get registers"));
    106 
    107       mips_fbsd_collect_gregs (regcache, regnum, (char *) &regs,
    108 			       sizeof (register_t));
    109 
    110       if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
    111 	perror_with_name (_("Couldn't write registers"));
    112     }
    113 
    114   if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
    115     {
    116       struct fpreg fpregs;
    117 
    118       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
    119 	perror_with_name (_("Couldn't get floating point status"));
    120 
    121       mips_fbsd_collect_fpregs (regcache, regnum, (char *) &fpregs,
    122 				sizeof (f_register_t));
    123 
    124       if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
    125 	perror_with_name (_("Couldn't write floating point status"));
    126     }
    127 }
    128 
    129 void _initialize_mips_fbsd_nat ();
    130 void
    131 _initialize_mips_fbsd_nat ()
    132 {
    133   add_inf_child_target (&the_mips_fbsd_nat_target);
    134 }
    135