gdb: Fix out of bounds array access in buildsym_compunit::record_line
[deliverable/binutils-gdb.git] / gdb / arm-nbsd-nat.c
CommitLineData
e7a42bc8 1/* Native-dependent code for BSD Unix running on ARM's, for GDB.
9f8e0089 2
b811d2c2 3 Copyright (C) 1988-2020 Free Software Foundation, Inc.
e7a42bc8
FN
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
e7a42bc8
FN
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
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
e7a42bc8 19
73685c7e
CB
20/* We define this to get types like register_t. */
21#define _KERNTYPES
e7a42bc8 22#include "defs.h"
d55e5aa6 23#include "gdbcore.h"
d55e5aa6
TT
24#include "inferior.h"
25#include "regcache.h"
26#include "target.h"
4de283e4
TT
27#include <sys/types.h>
28#include <sys/ptrace.h>
81b86b97 29#include <sys/sysctl.h>
4de283e4
TT
30#include <machine/reg.h>
31#include <machine/frame.h>
32
33#include "arm-tdep.h"
81b86b97 34#include "aarch32-tdep.h"
4de283e4 35#include "inf-ptrace.h"
e7a42bc8 36
f6ac5f3d
PA
37class arm_netbsd_nat_target final : public inf_ptrace_target
38{
39public:
40 /* Add our register access methods. */
41 void fetch_registers (struct regcache *, int) override;
42 void store_registers (struct regcache *, int) override;
81b86b97 43 const struct target_desc *read_description () override;
f6ac5f3d
PA
44};
45
46static arm_netbsd_nat_target the_arm_netbsd_nat_target;
47
b34db576 48static void
d683e2b7 49arm_supply_gregset (struct regcache *regcache, struct reg *gregset)
b34db576
RE
50{
51 int regno;
52 CORE_ADDR r_pc;
53
54 /* Integer registers. */
55 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
73e1c03f 56 regcache->raw_supply (regno, (char *) &gregset->r[regno]);
b34db576 57
73e1c03f
SM
58 regcache->raw_supply (ARM_SP_REGNUM, (char *) &gregset->r_sp);
59 regcache->raw_supply (ARM_LR_REGNUM, (char *) &gregset->r_lr);
b34db576 60 /* This is ok: we're running native... */
ac7936df 61 r_pc = gdbarch_addr_bits_remove (regcache->arch (), gregset->r_pc);
73e1c03f 62 regcache->raw_supply (ARM_PC_REGNUM, (char *) &r_pc);
b34db576
RE
63
64 if (arm_apcs_32)
73e1c03f 65 regcache->raw_supply (ARM_PS_REGNUM, (char *) &gregset->r_cpsr);
b34db576 66 else
73e1c03f 67 regcache->raw_supply (ARM_PS_REGNUM, (char *) &gregset->r_pc);
b34db576
RE
68}
69
70static void
81b86b97 71arm_supply_vfpregset (struct regcache *regcache, struct fpreg *fpregset)
b34db576 72{
81b86b97
CB
73 struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
74 if (tdep->vfp_register_count == 0)
75 return;
b34db576 76
81b86b97
CB
77 struct vfpreg &vfp = fpregset->fpr_vfp;
78 for (int regno = 0; regno <= tdep->vfp_register_count; regno++)
79 regcache->raw_supply (regno + ARM_D0_REGNUM, (char *) &vfp.vfp_regs[regno]);
b34db576 80
81b86b97 81 regcache->raw_supply (ARM_FPSCR_REGNUM, (char *) &vfp.vfp_fpscr);
b34db576
RE
82}
83
47221191 84static void
56be3814 85fetch_register (struct regcache *regcache, int regno)
47221191
RE
86{
87 struct reg inferior_registers;
88 int ret;
89
e99b03dc 90 ret = ptrace (PT_GETREGS, regcache->ptid ().pid (),
9f8e0089 91 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
47221191
RE
92
93 if (ret < 0)
94 {
edefbb7c 95 warning (_("unable to fetch general register"));
47221191
RE
96 return;
97 }
98
99 switch (regno)
100 {
101 case ARM_SP_REGNUM:
73e1c03f 102 regcache->raw_supply (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
47221191
RE
103 break;
104
105 case ARM_LR_REGNUM:
73e1c03f 106 regcache->raw_supply (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
47221191
RE
107 break;
108
109 case ARM_PC_REGNUM:
0963b4bd 110 /* This is ok: we're running native... */
bf6ae464 111 inferior_registers.r_pc = gdbarch_addr_bits_remove
ac7936df 112 (regcache->arch (),
b2cb219a 113 inferior_registers.r_pc);
73e1c03f 114 regcache->raw_supply (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
47221191
RE
115 break;
116
117 case ARM_PS_REGNUM:
118 if (arm_apcs_32)
73e1c03f
SM
119 regcache->raw_supply (ARM_PS_REGNUM,
120 (char *) &inferior_registers.r_cpsr);
47221191 121 else
73e1c03f
SM
122 regcache->raw_supply (ARM_PS_REGNUM,
123 (char *) &inferior_registers.r_pc);
47221191
RE
124 break;
125
126 default:
73e1c03f 127 regcache->raw_supply (regno, (char *) &inferior_registers.r[regno]);
47221191
RE
128 break;
129 }
130}
131
132static void
56be3814 133fetch_regs (struct regcache *regcache)
e7a42bc8
FN
134{
135 struct reg inferior_registers;
47221191
RE
136 int ret;
137 int regno;
138
e99b03dc 139 ret = ptrace (PT_GETREGS, regcache->ptid ().pid (),
9f8e0089 140 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
47221191
RE
141
142 if (ret < 0)
143 {
edefbb7c 144 warning (_("unable to fetch general registers"));
47221191
RE
145 return;
146 }
147
56be3814 148 arm_supply_gregset (regcache, &inferior_registers);
47221191
RE
149}
150
151static void
56be3814 152fetch_fp_register (struct regcache *regcache, int regno)
47221191
RE
153{
154 struct fpreg inferior_fp_registers;
81b86b97
CB
155 int ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
156 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
47221191 157
81b86b97 158 struct vfpreg &vfp = inferior_fp_registers.fpr_vfp;
47221191
RE
159
160 if (ret < 0)
161 {
edefbb7c 162 warning (_("unable to fetch floating-point register"));
47221191
RE
163 return;
164 }
165
81b86b97
CB
166 struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
167 if (regno == ARM_FPSCR_REGNUM && tdep->vfp_register_count != 0)
168 regcache->raw_supply (ARM_FPSCR_REGNUM, (char *) &vfp.vfp_fpscr);
169 else if (regno >= ARM_D0_REGNUM
170 && regno <= ARM_D0_REGNUM + tdep->vfp_register_count)
47221191 171 {
81b86b97
CB
172 regcache->raw_supply (regno,
173 (char *) &vfp.vfp_regs[regno - ARM_D0_REGNUM]);
47221191 174 }
81b86b97
CB
175 else
176 warning (_("Invalid register number."));
47221191
RE
177}
178
179static void
56be3814 180fetch_fp_regs (struct regcache *regcache)
47221191
RE
181{
182 struct fpreg inferior_fp_registers;
183 int ret;
184 int regno;
185
e99b03dc 186 ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
9f8e0089 187 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
47221191
RE
188
189 if (ret < 0)
190 {
edefbb7c 191 warning (_("unable to fetch general registers"));
47221191
RE
192 return;
193 }
194
81b86b97 195 arm_supply_vfpregset (regcache, &inferior_fp_registers);
e7a42bc8
FN
196}
197
f6ac5f3d 198void
3050c6f4 199arm_netbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
47221191
RE
200{
201 if (regno >= 0)
202 {
203 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
56be3814 204 fetch_register (regcache, regno);
47221191 205 else
56be3814 206 fetch_fp_register (regcache, regno);
47221191
RE
207 }
208 else
209 {
56be3814
UW
210 fetch_regs (regcache);
211 fetch_fp_regs (regcache);
47221191
RE
212 }
213}
214
215
216static void
56be3814 217store_register (const struct regcache *regcache, int regno)
e7a42bc8 218{
ac7936df 219 struct gdbarch *gdbarch = regcache->arch ();
e7a42bc8 220 struct reg inferior_registers;
47221191
RE
221 int ret;
222
e99b03dc 223 ret = ptrace (PT_GETREGS, regcache->ptid ().pid (),
9f8e0089 224 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
47221191
RE
225
226 if (ret < 0)
227 {
edefbb7c 228 warning (_("unable to fetch general registers"));
47221191
RE
229 return;
230 }
231
232 switch (regno)
233 {
234 case ARM_SP_REGNUM:
34a79281 235 regcache->raw_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
47221191
RE
236 break;
237
238 case ARM_LR_REGNUM:
34a79281 239 regcache->raw_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
47221191 240 break;
e7a42bc8 241
47221191
RE
242 case ARM_PC_REGNUM:
243 if (arm_apcs_32)
34a79281
SM
244 regcache->raw_collect (ARM_PC_REGNUM,
245 (char *) &inferior_registers.r_pc);
47221191
RE
246 else
247 {
248 unsigned pc_val;
e7a42bc8 249
34a79281 250 regcache->raw_collect (ARM_PC_REGNUM, (char *) &pc_val);
47221191 251
b2cb219a 252 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
bf6ae464 253 inferior_registers.r_pc ^= gdbarch_addr_bits_remove
b2cb219a 254 (gdbarch, inferior_registers.r_pc);
47221191
RE
255 inferior_registers.r_pc |= pc_val;
256 }
257 break;
258
259 case ARM_PS_REGNUM:
260 if (arm_apcs_32)
34a79281
SM
261 regcache->raw_collect (ARM_PS_REGNUM,
262 (char *) &inferior_registers.r_cpsr);
47221191
RE
263 else
264 {
265 unsigned psr_val;
266
34a79281 267 regcache->raw_collect (ARM_PS_REGNUM, (char *) &psr_val);
47221191 268
b2cb219a 269 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
bf6ae464 270 inferior_registers.r_pc = gdbarch_addr_bits_remove
b2cb219a 271 (gdbarch, inferior_registers.r_pc);
47221191
RE
272 inferior_registers.r_pc |= psr_val;
273 }
274 break;
275
276 default:
34a79281 277 regcache->raw_collect (regno, (char *) &inferior_registers.r[regno]);
47221191
RE
278 break;
279 }
280
e99b03dc 281 ret = ptrace (PT_SETREGS, regcache->ptid ().pid (),
9f8e0089 282 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
47221191
RE
283
284 if (ret < 0)
edefbb7c 285 warning (_("unable to write register %d to inferior"), regno);
47221191
RE
286}
287
288static void
56be3814 289store_regs (const struct regcache *regcache)
47221191 290{
ac7936df 291 struct gdbarch *gdbarch = regcache->arch ();
47221191
RE
292 struct reg inferior_registers;
293 int ret;
294 int regno;
295
296
297 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
34a79281 298 regcache->raw_collect (regno, (char *) &inferior_registers.r[regno]);
47221191 299
34a79281
SM
300 regcache->raw_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
301 regcache->raw_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
47221191
RE
302
303 if (arm_apcs_32)
304 {
34a79281
SM
305 regcache->raw_collect (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
306 regcache->raw_collect (ARM_PS_REGNUM,
307 (char *) &inferior_registers.r_cpsr);
47221191
RE
308 }
309 else
310 {
311 unsigned pc_val;
312 unsigned psr_val;
313
34a79281
SM
314 regcache->raw_collect (ARM_PC_REGNUM, (char *) &pc_val);
315 regcache->raw_collect (ARM_PS_REGNUM, (char *) &psr_val);
47221191 316
b2cb219a
UW
317 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
318 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
47221191
RE
319
320 inferior_registers.r_pc = pc_val | psr_val;
321 }
322
e99b03dc 323 ret = ptrace (PT_SETREGS, regcache->ptid ().pid (),
9f8e0089 324 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
47221191
RE
325
326 if (ret < 0)
edefbb7c 327 warning (_("unable to store general registers"));
47221191
RE
328}
329
330static void
56be3814 331store_fp_register (const struct regcache *regcache, int regno)
47221191
RE
332{
333 struct fpreg inferior_fp_registers;
81b86b97
CB
334 int ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
335 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
336 struct vfpreg &vfp = inferior_fp_registers.fpr_vfp;
47221191
RE
337
338 if (ret < 0)
339 {
edefbb7c 340 warning (_("unable to fetch floating-point registers"));
47221191
RE
341 return;
342 }
343
81b86b97
CB
344 struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
345 if (regno == ARM_FPSCR_REGNUM && tdep->vfp_register_count != 0)
346 regcache->raw_collect (ARM_FPSCR_REGNUM, (char *) &vfp.vfp_fpscr);
347 else if (regno >= ARM_D0_REGNUM
348 && regno <= ARM_D0_REGNUM + tdep->vfp_register_count)
47221191 349 {
81b86b97
CB
350 regcache->raw_collect (regno,
351 (char *) &vfp.vfp_regs[regno - ARM_D0_REGNUM]);
47221191 352 }
81b86b97
CB
353 else
354 warning (_("Invalid register number."));
47221191 355
e99b03dc 356 ret = ptrace (PT_SETFPREGS, regcache->ptid ().pid (),
9f8e0089 357 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
47221191
RE
358
359 if (ret < 0)
edefbb7c 360 warning (_("unable to write register %d to inferior"), regno);
47221191
RE
361}
362
363static void
56be3814 364store_fp_regs (const struct regcache *regcache)
47221191 365{
81b86b97
CB
366 struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
367 if (tdep->vfp_register_count == 0)
368 return;
47221191 369
81b86b97
CB
370 struct fpreg fpregs;
371 for (int regno = 0; regno <= tdep->vfp_register_count; regno++)
34a79281 372 regcache->raw_collect
81b86b97 373 (regno + ARM_D0_REGNUM, (char *) &fpregs.fpr_vfp.vfp_regs[regno]);
47221191 374
81b86b97
CB
375 regcache->raw_collect (ARM_FPSCR_REGNUM,
376 (char *) &fpregs.fpr_vfp.vfp_fpscr);
47221191 377
81b86b97
CB
378 int ret = ptrace (PT_SETFPREGS, regcache->ptid ().pid (),
379 (PTRACE_TYPE_ARG3) &fpregs, 0);
47221191
RE
380
381 if (ret < 0)
edefbb7c 382 warning (_("unable to store floating-point registers"));
47221191
RE
383}
384
f6ac5f3d 385void
3050c6f4 386arm_netbsd_nat_target::store_registers (struct regcache *regcache, int regno)
47221191
RE
387{
388 if (regno >= 0)
389 {
390 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
56be3814 391 store_register (regcache, regno);
47221191 392 else
56be3814 393 store_fp_register (regcache, regno);
47221191
RE
394 }
395 else
396 {
56be3814
UW
397 store_regs (regcache);
398 store_fp_regs (regcache);
47221191 399 }
e7a42bc8
FN
400}
401
81b86b97
CB
402const struct target_desc *
403arm_netbsd_nat_target::read_description ()
404{
405 int flag;
406 size_t len = sizeof (flag);
407
408 if (sysctlbyname("machdep.fpu_present", &flag, &len, NULL, 0) != 0
409 || !flag)
410 return arm_read_description (ARM_FP_TYPE_NONE);
411
412 len = sizeof(flag);
413 if (sysctlbyname("machdep.neon_present", &flag, &len, NULL, 0) == 0 && flag)
414 return aarch32_read_description ();
415
416 return arm_read_description (ARM_FP_TYPE_VFPV3);
417}
418
b34db576 419static void
9eefc95f 420fetch_elfcore_registers (struct regcache *regcache,
0cac9354 421 gdb_byte *core_reg_sect, unsigned core_reg_size,
b34db576
RE
422 int which, CORE_ADDR ignore)
423{
424 struct reg gregset;
425 struct fpreg fparegset;
e7a42bc8 426
b34db576
RE
427 switch (which)
428 {
429 case 0: /* Integer registers. */
430 if (core_reg_size != sizeof (struct reg))
edefbb7c 431 warning (_("wrong size of register set in core file"));
b34db576
RE
432 else
433 {
434 /* The memcpy may be unnecessary, but we can't really be sure
435 of the alignment of the data in the core file. */
436 memcpy (&gregset, core_reg_sect, sizeof (gregset));
9eefc95f 437 arm_supply_gregset (regcache, &gregset);
b34db576
RE
438 }
439 break;
440
441 case 2:
81b86b97
CB
442 /* cbiesinger/2020-02-12 -- as far as I can tell, ARM/NetBSD does
443 not write any floating point registers into the core file (tested
444 with NetBSD 9.1_RC1). When it does, this block will need to read them,
445 and the arm-netbsd gdbarch will need a core_read_description function
446 to return the right description for them. */
b34db576 447 break;
3e56fc4b 448
b34db576
RE
449 default:
450 /* Don't know what kind of register request this is; just ignore it. */
451 break;
452 }
e7a42bc8
FN
453}
454
b34db576
RE
455static struct core_fns arm_netbsd_elfcore_fns =
456{
405feb71 457 bfd_target_elf_flavour, /* core_flavour. */
b34db576
RE
458 default_check_format, /* check_format. */
459 default_core_sniffer, /* core_sniffer. */
460 fetch_elfcore_registers, /* core_read_registers. */
461 NULL
462};
463
6c265988 464void _initialize_arm_netbsd_nat ();
3e56fc4b 465void
6c265988 466_initialize_arm_netbsd_nat ()
3e56fc4b 467{
d9f719f1 468 add_inf_child_target (&the_arm_netbsd_nat_target);
2b73aeb1 469
00e32a35 470 deprecated_add_core_fns (&arm_netbsd_elfcore_fns);
3e56fc4b 471}
This page took 1.368502 seconds and 4 git commands to generate.