ubsan: score: left shift of negative value
[deliverable/binutils-gdb.git] / gdb / arm-nbsd-nat.c
1 /* Native-dependent code for BSD Unix running on ARM's, for GDB.
2
3 Copyright (C) 1988-2020 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 "gdbcore.h"
22 #include "inferior.h"
23 #include "regcache.h"
24 #include "target.h"
25 #include <sys/types.h>
26 #include <sys/ptrace.h>
27 #include <machine/reg.h>
28 #include <machine/frame.h>
29
30 #include "arm-tdep.h"
31 #include "inf-ptrace.h"
32
33 class arm_netbsd_nat_target final : public inf_ptrace_target
34 {
35 public:
36 /* Add our register access methods. */
37 void fetch_registers (struct regcache *, int) override;
38 void store_registers (struct regcache *, int) override;
39 };
40
41 static arm_netbsd_nat_target the_arm_netbsd_nat_target;
42
43 static void
44 arm_supply_gregset (struct regcache *regcache, struct reg *gregset)
45 {
46 int regno;
47 CORE_ADDR r_pc;
48
49 /* Integer registers. */
50 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
51 regcache->raw_supply (regno, (char *) &gregset->r[regno]);
52
53 regcache->raw_supply (ARM_SP_REGNUM, (char *) &gregset->r_sp);
54 regcache->raw_supply (ARM_LR_REGNUM, (char *) &gregset->r_lr);
55 /* This is ok: we're running native... */
56 r_pc = gdbarch_addr_bits_remove (regcache->arch (), gregset->r_pc);
57 regcache->raw_supply (ARM_PC_REGNUM, (char *) &r_pc);
58
59 if (arm_apcs_32)
60 regcache->raw_supply (ARM_PS_REGNUM, (char *) &gregset->r_cpsr);
61 else
62 regcache->raw_supply (ARM_PS_REGNUM, (char *) &gregset->r_pc);
63 }
64
65 static void
66 arm_supply_fparegset (struct regcache *regcache, struct fpreg *fparegset)
67 {
68 int regno;
69
70 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
71 regcache->raw_supply (regno,
72 (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]);
73
74 regcache->raw_supply (ARM_FPS_REGNUM, (char *) &fparegset->fpr_fpsr);
75 }
76
77 static void
78 fetch_register (struct regcache *regcache, int regno)
79 {
80 struct reg inferior_registers;
81 int ret;
82
83 ret = ptrace (PT_GETREGS, regcache->ptid ().pid (),
84 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
85
86 if (ret < 0)
87 {
88 warning (_("unable to fetch general register"));
89 return;
90 }
91
92 switch (regno)
93 {
94 case ARM_SP_REGNUM:
95 regcache->raw_supply (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
96 break;
97
98 case ARM_LR_REGNUM:
99 regcache->raw_supply (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
100 break;
101
102 case ARM_PC_REGNUM:
103 /* This is ok: we're running native... */
104 inferior_registers.r_pc = gdbarch_addr_bits_remove
105 (regcache->arch (),
106 inferior_registers.r_pc);
107 regcache->raw_supply (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
108 break;
109
110 case ARM_PS_REGNUM:
111 if (arm_apcs_32)
112 regcache->raw_supply (ARM_PS_REGNUM,
113 (char *) &inferior_registers.r_cpsr);
114 else
115 regcache->raw_supply (ARM_PS_REGNUM,
116 (char *) &inferior_registers.r_pc);
117 break;
118
119 default:
120 regcache->raw_supply (regno, (char *) &inferior_registers.r[regno]);
121 break;
122 }
123 }
124
125 static void
126 fetch_regs (struct regcache *regcache)
127 {
128 struct reg inferior_registers;
129 int ret;
130 int regno;
131
132 ret = ptrace (PT_GETREGS, regcache->ptid ().pid (),
133 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
134
135 if (ret < 0)
136 {
137 warning (_("unable to fetch general registers"));
138 return;
139 }
140
141 arm_supply_gregset (regcache, &inferior_registers);
142 }
143
144 static void
145 fetch_fp_register (struct regcache *regcache, int regno)
146 {
147 struct fpreg inferior_fp_registers;
148 int ret;
149
150 ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
151 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
152
153 if (ret < 0)
154 {
155 warning (_("unable to fetch floating-point register"));
156 return;
157 }
158
159 switch (regno)
160 {
161 case ARM_FPS_REGNUM:
162 regcache->raw_supply (ARM_FPS_REGNUM,
163 (char *) &inferior_fp_registers.fpr_fpsr);
164 break;
165
166 default:
167 regcache->raw_supply
168 (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
169 break;
170 }
171 }
172
173 static void
174 fetch_fp_regs (struct regcache *regcache)
175 {
176 struct fpreg inferior_fp_registers;
177 int ret;
178 int regno;
179
180 ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
181 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
182
183 if (ret < 0)
184 {
185 warning (_("unable to fetch general registers"));
186 return;
187 }
188
189 arm_supply_fparegset (regcache, &inferior_fp_registers);
190 }
191
192 void
193 arm_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
194 {
195 if (regno >= 0)
196 {
197 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
198 fetch_register (regcache, regno);
199 else
200 fetch_fp_register (regcache, regno);
201 }
202 else
203 {
204 fetch_regs (regcache);
205 fetch_fp_regs (regcache);
206 }
207 }
208
209
210 static void
211 store_register (const struct regcache *regcache, int regno)
212 {
213 struct gdbarch *gdbarch = regcache->arch ();
214 struct reg inferior_registers;
215 int ret;
216
217 ret = ptrace (PT_GETREGS, regcache->ptid ().pid (),
218 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
219
220 if (ret < 0)
221 {
222 warning (_("unable to fetch general registers"));
223 return;
224 }
225
226 switch (regno)
227 {
228 case ARM_SP_REGNUM:
229 regcache->raw_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
230 break;
231
232 case ARM_LR_REGNUM:
233 regcache->raw_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
234 break;
235
236 case ARM_PC_REGNUM:
237 if (arm_apcs_32)
238 regcache->raw_collect (ARM_PC_REGNUM,
239 (char *) &inferior_registers.r_pc);
240 else
241 {
242 unsigned pc_val;
243
244 regcache->raw_collect (ARM_PC_REGNUM, (char *) &pc_val);
245
246 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
247 inferior_registers.r_pc ^= gdbarch_addr_bits_remove
248 (gdbarch, inferior_registers.r_pc);
249 inferior_registers.r_pc |= pc_val;
250 }
251 break;
252
253 case ARM_PS_REGNUM:
254 if (arm_apcs_32)
255 regcache->raw_collect (ARM_PS_REGNUM,
256 (char *) &inferior_registers.r_cpsr);
257 else
258 {
259 unsigned psr_val;
260
261 regcache->raw_collect (ARM_PS_REGNUM, (char *) &psr_val);
262
263 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
264 inferior_registers.r_pc = gdbarch_addr_bits_remove
265 (gdbarch, inferior_registers.r_pc);
266 inferior_registers.r_pc |= psr_val;
267 }
268 break;
269
270 default:
271 regcache->raw_collect (regno, (char *) &inferior_registers.r[regno]);
272 break;
273 }
274
275 ret = ptrace (PT_SETREGS, regcache->ptid ().pid (),
276 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
277
278 if (ret < 0)
279 warning (_("unable to write register %d to inferior"), regno);
280 }
281
282 static void
283 store_regs (const struct regcache *regcache)
284 {
285 struct gdbarch *gdbarch = regcache->arch ();
286 struct reg inferior_registers;
287 int ret;
288 int regno;
289
290
291 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
292 regcache->raw_collect (regno, (char *) &inferior_registers.r[regno]);
293
294 regcache->raw_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
295 regcache->raw_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
296
297 if (arm_apcs_32)
298 {
299 regcache->raw_collect (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
300 regcache->raw_collect (ARM_PS_REGNUM,
301 (char *) &inferior_registers.r_cpsr);
302 }
303 else
304 {
305 unsigned pc_val;
306 unsigned psr_val;
307
308 regcache->raw_collect (ARM_PC_REGNUM, (char *) &pc_val);
309 regcache->raw_collect (ARM_PS_REGNUM, (char *) &psr_val);
310
311 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
312 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
313
314 inferior_registers.r_pc = pc_val | psr_val;
315 }
316
317 ret = ptrace (PT_SETREGS, regcache->ptid ().pid (),
318 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
319
320 if (ret < 0)
321 warning (_("unable to store general registers"));
322 }
323
324 static void
325 store_fp_register (const struct regcache *regcache, int regno)
326 {
327 struct fpreg inferior_fp_registers;
328 int ret;
329
330 ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
331 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
332
333 if (ret < 0)
334 {
335 warning (_("unable to fetch floating-point registers"));
336 return;
337 }
338
339 switch (regno)
340 {
341 case ARM_FPS_REGNUM:
342 regcache->raw_collect (ARM_FPS_REGNUM,
343 (char *) &inferior_fp_registers.fpr_fpsr);
344 break;
345
346 default:
347 regcache->raw_collect
348 (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
349 break;
350 }
351
352 ret = ptrace (PT_SETFPREGS, regcache->ptid ().pid (),
353 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
354
355 if (ret < 0)
356 warning (_("unable to write register %d to inferior"), regno);
357 }
358
359 static void
360 store_fp_regs (const struct regcache *regcache)
361 {
362 struct fpreg inferior_fp_registers;
363 int ret;
364 int regno;
365
366
367 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
368 regcache->raw_collect
369 (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
370
371 regcache->raw_collect (ARM_FPS_REGNUM,
372 (char *) &inferior_fp_registers.fpr_fpsr);
373
374 ret = ptrace (PT_SETFPREGS, regcache->ptid ().pid (),
375 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
376
377 if (ret < 0)
378 warning (_("unable to store floating-point registers"));
379 }
380
381 void
382 arm_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
383 {
384 if (regno >= 0)
385 {
386 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
387 store_register (regcache, regno);
388 else
389 store_fp_register (regcache, regno);
390 }
391 else
392 {
393 store_regs (regcache);
394 store_fp_regs (regcache);
395 }
396 }
397
398 static void
399 fetch_elfcore_registers (struct regcache *regcache,
400 char *core_reg_sect, unsigned core_reg_size,
401 int which, CORE_ADDR ignore)
402 {
403 struct reg gregset;
404 struct fpreg fparegset;
405
406 switch (which)
407 {
408 case 0: /* Integer registers. */
409 if (core_reg_size != sizeof (struct reg))
410 warning (_("wrong size of register set in core file"));
411 else
412 {
413 /* The memcpy may be unnecessary, but we can't really be sure
414 of the alignment of the data in the core file. */
415 memcpy (&gregset, core_reg_sect, sizeof (gregset));
416 arm_supply_gregset (regcache, &gregset);
417 }
418 break;
419
420 case 2:
421 if (core_reg_size != sizeof (struct fpreg))
422 warning (_("wrong size of FPA register set in core file"));
423 else
424 {
425 /* The memcpy may be unnecessary, but we can't really be sure
426 of the alignment of the data in the core file. */
427 memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
428 arm_supply_fparegset (regcache, &fparegset);
429 }
430 break;
431
432 default:
433 /* Don't know what kind of register request this is; just ignore it. */
434 break;
435 }
436 }
437
438 static struct core_fns arm_netbsd_elfcore_fns =
439 {
440 bfd_target_elf_flavour, /* core_flavour. */
441 default_check_format, /* check_format. */
442 default_core_sniffer, /* core_sniffer. */
443 fetch_elfcore_registers, /* core_read_registers. */
444 NULL
445 };
446
447 void
448 _initialize_arm_netbsd_nat (void)
449 {
450 add_inf_child_target (&the_arm_netbsd_nat_target);
451
452 deprecated_add_core_fns (&arm_netbsd_elfcore_fns);
453 }
This page took 0.041767 seconds and 4 git commands to generate.