Home | History | Annotate | Line # | Download | only in gdb
      1 /* Native-dependent code for OpenBSD/mips64.
      2 
      3    Copyright (C) 2004-2024 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 "inferior.h"
     21 #include "regcache.h"
     22 #include "target.h"
     23 
     24 #include <sys/types.h>
     25 #include <sys/ptrace.h>
     26 #include <machine/reg.h>
     27 
     28 #include "mips-tdep.h"
     29 #include "inf-ptrace.h"
     30 #include "obsd-nat.h"
     31 
     32 /* Shorthand for some register numbers used below.  */
     33 #define MIPS_PC_REGNUM	MIPS_EMBED_PC_REGNUM
     34 #define MIPS_FP0_REGNUM	MIPS_EMBED_FP0_REGNUM
     35 #define MIPS_FSR_REGNUM MIPS_EMBED_FP0_REGNUM + 32
     36 
     37 struct mips64_obsd_nat_target final : public obsd_nat_target
     38 {
     39   void fetch_registers (struct regcache *, int) override;
     40   void store_registers (struct regcache *, int) override;
     41 };
     42 
     43 static mips64_obsd_nat_target the_mips64_obsd_nat_target;
     44 
     45 /* Supply the general-purpose registers stored in GREGS to REGCACHE.  */
     46 
     47 static void
     48 mips64obsd_supply_gregset (struct regcache *regcache, const void *gregs)
     49 {
     50   const char *regs = gregs;
     51   int regnum;
     52 
     53   for (regnum = MIPS_ZERO_REGNUM; regnum <= MIPS_PC_REGNUM; regnum++)
     54     regcache->raw_supply (regnum, regs + regnum * 8);
     55 
     56   for (regnum = MIPS_FP0_REGNUM; regnum <= MIPS_FSR_REGNUM; regnum++)
     57     regcache->raw_supply (regnum, regs + (regnum + 2) * 8);
     58 }
     59 
     60 /* Collect the general-purpose registers from REGCACHE and store them
     61    in GREGS.  */
     62 
     63 static void
     64 mips64obsd_collect_gregset (const struct regcache *regcache,
     65 			    void *gregs, int regnum)
     66 {
     67   char *regs = gregs;
     68   int i;
     69 
     70   for (i = MIPS_ZERO_REGNUM; i <= MIPS_PC_REGNUM; i++)
     71     {
     72       if (regnum == -1 || regnum == i)
     73 	regcache->raw_collect (i, regs + i * 8);
     74     }
     75 
     76   for (i = MIPS_FP0_REGNUM; i <= MIPS_FSR_REGNUM; i++)
     77     {
     78       if (regnum == -1 || regnum == i)
     79 	regcache->raw_collect (i, regs + (i + 2) * 8);
     80     }
     81 }
     82 
     83 
     85 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
     86    for all registers.  */
     87 
     88 void
     89 mips64_obsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
     90 {
     91   struct reg regs;
     92   pid_t pid = regcache->ptid ().pid ();
     93 
     94   if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
     95     perror_with_name (_("Couldn't get registers"));
     96 
     97   mips64obsd_supply_gregset (regcache, &regs);
     98 }
     99 
    100 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    101    this for all registers.  */
    102 
    103 static void
    104 mips64_obsd_nat_target::store_registers (struct regcache *regcache, int regnum)
    105 {
    106   struct reg regs;
    107   pid_t pid = regcache->ptid ().pid ();
    108 
    109   if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
    110     perror_with_name (_("Couldn't get registers"));
    111 
    112   mips64obsd_collect_gregset (regcache, &regs, regnum);
    113 
    114   if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
    115     perror_with_name (_("Couldn't write registers"));
    116 }
    117 
    118 void _initialize_mips64obsd_nat ();
    119 void
    120 _initialize_mips64obsd_nat ()
    121 {
    122   add_inf_child_target (&the_mips64_obsd_nat_target);
    123 }
    124