Home | History | Annotate | Line # | Download | only in gdb
mips-fbsd-nat.c revision 1.1.1.1.2.2
      1 /* Native-dependent code for FreeBSD/mips.
      2 
      3    Copyright (C) 2017 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 /* Determine if PT_GETREGS fetches this register.  */
     35 
     36 static bool
     37 getregs_supplies (struct gdbarch *gdbarch, int regnum)
     38 {
     39   return (regnum >= MIPS_ZERO_REGNUM
     40 	  && regnum <= gdbarch_pc_regnum (gdbarch));
     41 }
     42 
     43 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
     44    for all registers.  */
     45 
     46 static void
     47 mips_fbsd_fetch_inferior_registers (struct target_ops *ops,
     48 				    struct regcache *regcache, int regnum)
     49 {
     50   pid_t pid = get_ptrace_pid (regcache_get_ptid (regcache));
     51 
     52   struct gdbarch *gdbarch = get_regcache_arch (regcache);
     53   if (regnum == -1 || getregs_supplies (gdbarch, regnum))
     54     {
     55       struct reg regs;
     56 
     57       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
     58 	perror_with_name (_("Couldn't get registers"));
     59 
     60       mips_fbsd_supply_gregs (regcache, regnum, &regs, sizeof (register_t));
     61       if (regnum != -1)
     62 	return;
     63     }
     64 
     65   if (regnum == -1
     66       || regnum >= gdbarch_fp0_regnum (get_regcache_arch (regcache)))
     67     {
     68       struct fpreg fpregs;
     69 
     70       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
     71 	perror_with_name (_("Couldn't get floating point status"));
     72 
     73       mips_fbsd_supply_fpregs (regcache, regnum, &fpregs,
     74 			       sizeof (f_register_t));
     75     }
     76 }
     77 
     78 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
     79    this for all registers.  */
     80 
     81 static void
     82 mips_fbsd_store_inferior_registers (struct target_ops *ops,
     83 				    struct regcache *regcache, int regnum)
     84 {
     85   pid_t pid = get_ptrace_pid (regcache_get_ptid (regcache));
     86 
     87   struct gdbarch *gdbarch = get_regcache_arch (regcache);
     88   if (regnum == -1 || getregs_supplies (gdbarch, regnum))
     89     {
     90       struct reg regs;
     91 
     92       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
     93 	perror_with_name (_("Couldn't get registers"));
     94 
     95       mips_fbsd_collect_gregs (regcache, regnum, (char *) &regs,
     96 			       sizeof (register_t));
     97 
     98       if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
     99 	perror_with_name (_("Couldn't write registers"));
    100 
    101       if (regnum != -1)
    102 	return;
    103     }
    104 
    105   if (regnum == -1
    106       || regnum >= gdbarch_fp0_regnum (get_regcache_arch (regcache)))
    107     {
    108       struct fpreg fpregs;
    109 
    110       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
    111 	perror_with_name (_("Couldn't get floating point status"));
    112 
    113       mips_fbsd_collect_fpregs (regcache, regnum, (char *) &fpregs,
    114 				sizeof (f_register_t));
    115 
    116       if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
    117 	perror_with_name (_("Couldn't write floating point status"));
    118     }
    119 }
    120 
    121 
    123 /* Provide a prototype to silence -Wmissing-prototypes.  */
    124 void _initialize_mips_fbsd_nat (void);
    125 
    126 void
    127 _initialize_mips_fbsd_nat (void)
    128 {
    129   struct target_ops *t;
    130 
    131   t = inf_ptrace_target ();
    132   t->to_fetch_registers = mips_fbsd_fetch_inferior_registers;
    133   t->to_store_registers = mips_fbsd_store_inferior_registers;
    134   fbsd_nat_add_target (t);
    135 }
    136