Commit | Line | Data |
---|---|---|
4f9d9906 JB |
1 | /* Native-dependent code for FreeBSD/arm. |
2 | ||
42a4f53d | 3 | Copyright (C) 2017-2019 Free Software Foundation, Inc. |
4f9d9906 JB |
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" | |
4de283e4 | 21 | #include "target.h" |
4f9d9906 | 22 | |
d55e5aa6 | 23 | #include <sys/types.h> |
4de283e4 TT |
24 | #include <sys/ptrace.h> |
25 | #include <machine/reg.h> | |
4f9d9906 | 26 | |
d55e5aa6 | 27 | #include "fbsd-nat.h" |
4de283e4 TT |
28 | #include "arm-tdep.h" |
29 | #include "arm-fbsd-tdep.h" | |
4f9d9906 JB |
30 | #include "inf-ptrace.h" |
31 | ||
f6ac5f3d PA |
32 | struct arm_fbsd_nat_target : public fbsd_nat_target |
33 | { | |
34 | void fetch_registers (struct regcache *, int) override; | |
35 | void store_registers (struct regcache *, int) override; | |
36 | const struct target_desc *read_description () override; | |
37 | }; | |
38 | ||
39 | static arm_fbsd_nat_target the_arm_fbsd_nat_target; | |
40 | ||
4f9d9906 JB |
41 | /* Determine if PT_GETREGS fetches REGNUM. */ |
42 | ||
43 | static bool | |
206e6c58 | 44 | getregs_supplies (int regnum) |
4f9d9906 JB |
45 | { |
46 | return ((regnum >= ARM_A1_REGNUM && regnum <= ARM_PC_REGNUM) | |
47 | || regnum == ARM_PS_REGNUM); | |
48 | } | |
49 | ||
50 | #ifdef PT_GETVFPREGS | |
51 | /* Determine if PT_GETVFPREGS fetches REGNUM. */ | |
52 | ||
53 | static bool | |
206e6c58 | 54 | getvfpregs_supplies (int regnum) |
4f9d9906 JB |
55 | { |
56 | return ((regnum >= ARM_D0_REGNUM && regnum <= ARM_D31_REGNUM) | |
57 | || regnum == ARM_FPSCR_REGNUM); | |
58 | } | |
59 | #endif | |
60 | ||
61 | /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this | |
62 | for all registers. */ | |
63 | ||
f6ac5f3d PA |
64 | void |
65 | arm_fbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum) | |
4f9d9906 | 66 | { |
222312d3 | 67 | pid_t pid = get_ptrace_pid (regcache->ptid ()); |
4f9d9906 | 68 | |
206e6c58 | 69 | if (regnum == -1 || getregs_supplies (regnum)) |
4f9d9906 JB |
70 | { |
71 | struct reg regs; | |
72 | ||
73 | if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1) | |
74 | perror_with_name (_("Couldn't get registers")); | |
75 | ||
76 | regcache->supply_regset (&arm_fbsd_gregset, regnum, ®s, | |
77 | sizeof (regs)); | |
78 | } | |
79 | ||
80 | #ifdef PT_GETVFPREGS | |
206e6c58 | 81 | if (regnum == -1 || getvfpregs_supplies (regnum)) |
4f9d9906 JB |
82 | { |
83 | struct vfpreg vfpregs; | |
84 | ||
85 | if (ptrace (PT_GETVFPREGS, pid, (PTRACE_TYPE_ARG3) &vfpregs, 0) == -1) | |
86 | perror_with_name (_("Couldn't get floating point status")); | |
87 | ||
88 | regcache->supply_regset (&arm_fbsd_vfpregset, regnum, &vfpregs, | |
89 | sizeof (vfpregs)); | |
90 | } | |
91 | #endif | |
92 | } | |
93 | ||
94 | /* Store register REGNUM back into the inferior. If REGNUM is -1, do | |
95 | this for all registers. */ | |
96 | ||
f6ac5f3d PA |
97 | void |
98 | arm_fbsd_nat_target::store_registers (struct regcache *regcache, int regnum) | |
4f9d9906 | 99 | { |
222312d3 | 100 | pid_t pid = get_ptrace_pid (regcache->ptid ()); |
4f9d9906 | 101 | |
206e6c58 | 102 | if (regnum == -1 || getregs_supplies (regnum)) |
4f9d9906 JB |
103 | { |
104 | struct reg regs; | |
105 | ||
106 | if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1) | |
107 | perror_with_name (_("Couldn't get registers")); | |
108 | ||
109 | regcache->collect_regset (&arm_fbsd_gregset, regnum, ®s, | |
110 | sizeof (regs)); | |
111 | ||
112 | if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1) | |
113 | perror_with_name (_("Couldn't write registers")); | |
114 | } | |
115 | ||
116 | #ifdef PT_GETVFPREGS | |
206e6c58 | 117 | if (regnum == -1 || getvfpregs_supplies (regnum)) |
4f9d9906 JB |
118 | { |
119 | struct vfpreg vfpregs; | |
120 | ||
121 | if (ptrace (PT_GETVFPREGS, pid, (PTRACE_TYPE_ARG3) &vfpregs, 0) == -1) | |
122 | perror_with_name (_("Couldn't get floating point status")); | |
123 | ||
124 | regcache->collect_regset (&arm_fbsd_vfpregset, regnum, &vfpregs, | |
125 | sizeof (vfpregs)); | |
126 | ||
127 | if (ptrace (PT_SETVFPREGS, pid, (PTRACE_TYPE_ARG3) &vfpregs, 0) == -1) | |
128 | perror_with_name (_("Couldn't write floating point status")); | |
129 | } | |
130 | #endif | |
131 | } | |
132 | ||
133 | /* Implement the to_read_description method. */ | |
134 | ||
f6ac5f3d PA |
135 | const struct target_desc * |
136 | arm_fbsd_nat_target::read_description () | |
4f9d9906 JB |
137 | { |
138 | const struct target_desc *desc; | |
139 | ||
f6ac5f3d | 140 | desc = arm_fbsd_read_description_auxv (this); |
4f9d9906 | 141 | if (desc == NULL) |
4360561f | 142 | desc = this->beneath ()->read_description (); |
4f9d9906 JB |
143 | return desc; |
144 | } | |
145 | ||
146 | void | |
147 | _initialize_arm_fbsd_nat (void) | |
148 | { | |
d9f719f1 | 149 | add_inf_child_target (&the_arm_fbsd_nat_target); |
4f9d9906 | 150 | } |