RISC-V: Don't report warnings when linking different privileged spec objects.
[binutils-gdb.git] / gdb / arm-netbsd-nat.c
blob37f6530a0fe877483a5f8e18aa6b0347958074ff
1 /* Native-dependent code for BSD Unix running on ARM's, for GDB.
3 Copyright (C) 1988-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
20 /* We define this to get types like register_t. */
21 #define _KERNTYPES
22 #include "gdbcore.h"
23 #include "inferior.h"
24 #include "regcache.h"
25 #include "target.h"
26 #include <sys/types.h>
27 #include <sys/ptrace.h>
28 #include <sys/sysctl.h>
29 #include <machine/reg.h>
30 #include <machine/frame.h>
32 #include "arm-tdep.h"
33 #include "arm-netbsd-tdep.h"
34 #include "aarch32-tdep.h"
35 #include "inf-ptrace.h"
36 #include "netbsd-nat.h"
38 class arm_netbsd_nat_target final : public nbsd_nat_target
40 public:
41 /* Add our register access methods. */
42 void fetch_registers (struct regcache *, int) override;
43 void store_registers (struct regcache *, int) override;
44 const struct target_desc *read_description () override;
47 static arm_netbsd_nat_target the_arm_netbsd_nat_target;
49 static void
50 arm_supply_vfpregset (struct regcache *regcache, struct fpreg *fpregset)
52 arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (regcache->arch ());
53 if (tdep->vfp_register_count == 0)
54 return;
56 struct vfpreg &vfp = fpregset->fpr_vfp;
57 for (int regno = 0; regno <= tdep->vfp_register_count; regno++)
58 regcache->raw_supply (regno + ARM_D0_REGNUM, (char *) &vfp.vfp_regs[regno]);
60 regcache->raw_supply (ARM_FPSCR_REGNUM, (char *) &vfp.vfp_fpscr);
63 static void
64 fetch_register (struct regcache *regcache, int regno)
66 struct reg inferior_registers;
67 int ret;
68 int lwp = regcache->ptid ().lwp ();
70 ret = ptrace (PT_GETREGS, regcache->ptid ().pid (),
71 (PTRACE_TYPE_ARG3) &inferior_registers, lwp);
73 if (ret < 0)
75 warning (_("unable to fetch general register"));
76 return;
78 arm_nbsd_supply_gregset (nullptr, regcache, regno, &inferior_registers,
79 sizeof (inferior_registers));
82 static void
83 fetch_fp_register (struct regcache *regcache, int regno)
85 struct fpreg inferior_fp_registers;
86 int lwp = regcache->ptid ().lwp ();
88 int ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
89 (PTRACE_TYPE_ARG3) &inferior_fp_registers, lwp);
91 struct vfpreg &vfp = inferior_fp_registers.fpr_vfp;
93 if (ret < 0)
95 warning (_("unable to fetch floating-point register"));
96 return;
99 arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (regcache->arch ());
100 if (regno == ARM_FPSCR_REGNUM && tdep->vfp_register_count != 0)
101 regcache->raw_supply (ARM_FPSCR_REGNUM, (char *) &vfp.vfp_fpscr);
102 else if (regno >= ARM_D0_REGNUM
103 && regno <= ARM_D0_REGNUM + tdep->vfp_register_count)
105 regcache->raw_supply (regno,
106 (char *) &vfp.vfp_regs[regno - ARM_D0_REGNUM]);
108 else
109 warning (_("Invalid register number."));
112 static void
113 fetch_fp_regs (struct regcache *regcache)
115 struct fpreg inferior_fp_registers;
116 int lwp = regcache->ptid ().lwp ();
117 int ret;
118 int regno;
120 ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
121 (PTRACE_TYPE_ARG3) &inferior_fp_registers, lwp);
123 if (ret < 0)
125 warning (_("unable to fetch general registers"));
126 return;
129 arm_supply_vfpregset (regcache, &inferior_fp_registers);
132 void
133 arm_netbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
135 if (regno >= 0)
137 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
138 fetch_register (regcache, regno);
139 else
140 fetch_fp_register (regcache, regno);
142 else
144 fetch_register (regcache, -1);
145 fetch_fp_regs (regcache);
150 static void
151 store_register (const struct regcache *regcache, int regno)
153 struct gdbarch *gdbarch = regcache->arch ();
154 struct reg inferior_registers;
155 int lwp = regcache->ptid ().lwp ();
156 int ret;
158 ret = ptrace (PT_GETREGS, regcache->ptid ().pid (),
159 (PTRACE_TYPE_ARG3) &inferior_registers, lwp);
161 if (ret < 0)
163 warning (_("unable to fetch general registers"));
164 return;
167 switch (regno)
169 case ARM_SP_REGNUM:
170 regcache->raw_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
171 break;
173 case ARM_LR_REGNUM:
174 regcache->raw_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
175 break;
177 case ARM_PC_REGNUM:
178 if (arm_apcs_32)
179 regcache->raw_collect (ARM_PC_REGNUM,
180 (char *) &inferior_registers.r_pc);
181 else
183 unsigned pc_val;
185 regcache->raw_collect (ARM_PC_REGNUM, (char *) &pc_val);
187 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
188 inferior_registers.r_pc ^= gdbarch_addr_bits_remove
189 (gdbarch, inferior_registers.r_pc);
190 inferior_registers.r_pc |= pc_val;
192 break;
194 case ARM_PS_REGNUM:
195 if (arm_apcs_32)
196 regcache->raw_collect (ARM_PS_REGNUM,
197 (char *) &inferior_registers.r_cpsr);
198 else
200 unsigned psr_val;
202 regcache->raw_collect (ARM_PS_REGNUM, (char *) &psr_val);
204 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
205 inferior_registers.r_pc = gdbarch_addr_bits_remove
206 (gdbarch, inferior_registers.r_pc);
207 inferior_registers.r_pc |= psr_val;
209 break;
211 default:
212 regcache->raw_collect (regno, (char *) &inferior_registers.r[regno]);
213 break;
216 ret = ptrace (PT_SETREGS, regcache->ptid ().pid (),
217 (PTRACE_TYPE_ARG3) &inferior_registers, lwp);
219 if (ret < 0)
220 warning (_("unable to write register %d to inferior"), regno);
223 static void
224 store_regs (const struct regcache *regcache)
226 struct gdbarch *gdbarch = regcache->arch ();
227 struct reg inferior_registers;
228 int lwp = regcache->ptid ().lwp ();
229 int ret;
230 int regno;
233 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
234 regcache->raw_collect (regno, (char *) &inferior_registers.r[regno]);
236 regcache->raw_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
237 regcache->raw_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
239 if (arm_apcs_32)
241 regcache->raw_collect (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
242 regcache->raw_collect (ARM_PS_REGNUM,
243 (char *) &inferior_registers.r_cpsr);
245 else
247 unsigned pc_val;
248 unsigned psr_val;
250 regcache->raw_collect (ARM_PC_REGNUM, (char *) &pc_val);
251 regcache->raw_collect (ARM_PS_REGNUM, (char *) &psr_val);
253 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
254 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
256 inferior_registers.r_pc = pc_val | psr_val;
259 ret = ptrace (PT_SETREGS, regcache->ptid ().pid (),
260 (PTRACE_TYPE_ARG3) &inferior_registers, lwp);
262 if (ret < 0)
263 warning (_("unable to store general registers"));
266 static void
267 store_fp_register (const struct regcache *regcache, int regno)
269 struct fpreg inferior_fp_registers;
270 int lwp = regcache->ptid ().lwp ();
271 int ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
272 (PTRACE_TYPE_ARG3) &inferior_fp_registers, lwp);
273 struct vfpreg &vfp = inferior_fp_registers.fpr_vfp;
275 if (ret < 0)
277 warning (_("unable to fetch floating-point registers"));
278 return;
281 arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (regcache->arch ());
282 if (regno == ARM_FPSCR_REGNUM && tdep->vfp_register_count != 0)
283 regcache->raw_collect (ARM_FPSCR_REGNUM, (char *) &vfp.vfp_fpscr);
284 else if (regno >= ARM_D0_REGNUM
285 && regno <= ARM_D0_REGNUM + tdep->vfp_register_count)
287 regcache->raw_collect (regno,
288 (char *) &vfp.vfp_regs[regno - ARM_D0_REGNUM]);
290 else
291 warning (_("Invalid register number."));
293 ret = ptrace (PT_SETFPREGS, regcache->ptid ().pid (),
294 (PTRACE_TYPE_ARG3) &inferior_fp_registers, lwp);
296 if (ret < 0)
297 warning (_("unable to write register %d to inferior"), regno);
300 static void
301 store_fp_regs (const struct regcache *regcache)
303 arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (regcache->arch ());
304 int lwp = regcache->ptid ().lwp ();
305 if (tdep->vfp_register_count == 0)
306 return;
308 struct fpreg fpregs;
309 for (int regno = 0; regno <= tdep->vfp_register_count; regno++)
310 regcache->raw_collect
311 (regno + ARM_D0_REGNUM, (char *) &fpregs.fpr_vfp.vfp_regs[regno]);
313 regcache->raw_collect (ARM_FPSCR_REGNUM,
314 (char *) &fpregs.fpr_vfp.vfp_fpscr);
316 int ret = ptrace (PT_SETFPREGS, regcache->ptid ().pid (),
317 (PTRACE_TYPE_ARG3) &fpregs, lwp);
319 if (ret < 0)
320 warning (_("unable to store floating-point registers"));
323 void
324 arm_netbsd_nat_target::store_registers (struct regcache *regcache, int regno)
326 if (regno >= 0)
328 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
329 store_register (regcache, regno);
330 else
331 store_fp_register (regcache, regno);
333 else
335 store_regs (regcache);
336 store_fp_regs (regcache);
340 const struct target_desc *
341 arm_netbsd_nat_target::read_description ()
343 int flag;
344 size_t len = sizeof (flag);
346 if (sysctlbyname("machdep.fpu_present", &flag, &len, NULL, 0) != 0
347 || !flag)
348 return arm_read_description (ARM_FP_TYPE_NONE, false);
350 len = sizeof(flag);
351 if (sysctlbyname("machdep.neon_present", &flag, &len, NULL, 0) == 0 && flag)
352 return aarch32_read_description (false);
354 return arm_read_description (ARM_FP_TYPE_VFPV3, false);
357 void _initialize_arm_netbsd_nat ();
358 void
359 _initialize_arm_netbsd_nat ()
361 add_inf_child_target (&the_arm_netbsd_nat_target);