Add linux_get_hwcap
[external/binutils.git] / gdb / mips-nbsd-nat.c
1 /* Native-dependent code for MIPS systems running NetBSD.
2
3    Copyright (C) 2000-2019 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 "mips-tdep.h"
30 #include "mips-nbsd-tdep.h"
31 #include "inf-ptrace.h"
32
33 class mips_nbsd_nat_target final : public inf_ptrace_target
34 {
35   void fetch_registers (struct regcache *, int) override;
36   void store_registers (struct regcache *, int) override;
37 };
38
39 static mips_nbsd_nat_target the_mips_nbsd_nat_target;
40
41 /* Determine if PT_GETREGS fetches this register.  */
42 static int
43 getregs_supplies (struct gdbarch *gdbarch, int regno)
44 {
45   return ((regno) >= MIPS_ZERO_REGNUM
46           && (regno) <= gdbarch_pc_regnum (gdbarch));
47 }
48
49 void
50 mips_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
51 {
52   pid_t pid = regcache->ptid ().pid ();
53
54   struct gdbarch *gdbarch = regcache->arch ();
55   if (regno == -1 || getregs_supplies (gdbarch, regno))
56     {
57       struct reg regs;
58
59       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
60         perror_with_name (_("Couldn't get registers"));
61       
62       mipsnbsd_supply_reg (regcache, (char *) &regs, regno);
63       if (regno != -1)
64         return;
65     }
66
67   if (regno == -1
68       || regno >= gdbarch_fp0_regnum (regcache->arch ()))
69     {
70       struct fpreg fpregs;
71
72       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
73         perror_with_name (_("Couldn't get floating point status"));
74
75       mipsnbsd_supply_fpreg (regcache, (char *) &fpregs, regno);
76     }
77 }
78
79 void
80 mips_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
81 {
82   pid_t pid = regcache->ptid ().pid ();
83
84   struct gdbarch *gdbarch = regcache->arch ();
85   if (regno == -1 || getregs_supplies (gdbarch, regno))
86     {
87       struct reg regs;
88
89       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
90         perror_with_name (_("Couldn't get registers"));
91
92       mipsnbsd_fill_reg (regcache, (char *) &regs, regno);
93
94       if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
95         perror_with_name (_("Couldn't write registers"));
96
97       if (regno != -1)
98         return;
99     }
100
101   if (regno == -1
102       || regno >= gdbarch_fp0_regnum (regcache->arch ()))
103     {
104       struct fpreg fpregs; 
105
106       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
107         perror_with_name (_("Couldn't get floating point status"));
108
109       mipsnbsd_fill_fpreg (regcache, (char *) &fpregs, regno);
110
111       if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
112         perror_with_name (_("Couldn't write floating point status"));
113     }
114 }
115
116 void
117 _initialize_mipsnbsd_nat (void)
118 {
119   add_inf_child_target (&the_mips_nbsd_nat_target);
120 }