Automatic date update in version.in
[external/binutils.git] / gdb / aarch64-fbsd-nat.c
1 /* Native-dependent code for FreeBSD/aarch64.
2
3    Copyright (C) 2017-2018 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 "target.h"
22
23 #include <sys/types.h>
24 #include <sys/ptrace.h>
25 #include <machine/reg.h>
26
27 #include "fbsd-nat.h"
28 #include "aarch64-tdep.h"
29 #include "aarch64-fbsd-tdep.h"
30 #include "inf-ptrace.h"
31
32 struct aarch64_fbsd_nat_target final : public fbsd_nat_target
33 {
34   void fetch_registers (struct regcache *, int) override;
35   void store_registers (struct regcache *, int) override;
36 };
37
38 static aarch64_fbsd_nat_target the_aarch64_fbsd_nat_target;
39
40 /* Determine if PT_GETREGS fetches REGNUM.  */
41
42 static bool
43 getregs_supplies (struct gdbarch *gdbarch, int regnum)
44 {
45   return (regnum >= AARCH64_X0_REGNUM && regnum <= AARCH64_CPSR_REGNUM);
46 }
47
48 /* Determine if PT_GETFPREGS fetches REGNUM.  */
49
50 static bool
51 getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
52 {
53   return (regnum >= AARCH64_V0_REGNUM && regnum <= AARCH64_FPCR_REGNUM);
54 }
55
56 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
57    for all registers.  */
58
59 void
60 aarch64_fbsd_nat_target::fetch_registers (struct regcache *regcache,
61                                           int regnum)
62 {
63   pid_t pid = get_ptrace_pid (regcache->ptid ());
64
65   struct gdbarch *gdbarch = regcache->arch ();
66   if (regnum == -1 || getregs_supplies (gdbarch, regnum))
67     {
68       struct reg regs;
69
70       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
71         perror_with_name (_("Couldn't get registers"));
72
73       regcache->supply_regset (&aarch64_fbsd_gregset, regnum, &regs,
74                                sizeof (regs));
75     }
76
77   if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
78     {
79       struct fpreg fpregs;
80
81       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
82         perror_with_name (_("Couldn't get floating point status"));
83
84       regcache->supply_regset (&aarch64_fbsd_fpregset, regnum, &fpregs,
85                                sizeof (fpregs));
86     }
87 }
88
89 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
90    this for all registers.  */
91
92 void
93 aarch64_fbsd_nat_target::store_registers (struct regcache *regcache,
94                                           int regnum)
95 {
96   pid_t pid = get_ptrace_pid (regcache->ptid ());
97
98   struct gdbarch *gdbarch = regcache->arch ();
99   if (regnum == -1 || getregs_supplies (gdbarch, regnum))
100     {
101       struct reg regs;
102
103       if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
104         perror_with_name (_("Couldn't get registers"));
105
106       regcache->collect_regset (&aarch64_fbsd_gregset, regnum, &regs,
107                                sizeof (regs));
108
109       if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
110         perror_with_name (_("Couldn't write registers"));
111     }
112
113   if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
114     {
115       struct fpreg fpregs;
116
117       if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
118         perror_with_name (_("Couldn't get floating point status"));
119
120       regcache->collect_regset (&aarch64_fbsd_fpregset, regnum, &fpregs,
121                                 sizeof (fpregs));
122
123       if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
124         perror_with_name (_("Couldn't write floating point status"));
125     }
126 }
127
128 void
129 _initialize_aarch64_fbsd_nat (void)
130 {
131   add_inf_child_target (&the_aarch64_fbsd_nat_target);
132 }