xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/arm-bsd-tdep.c (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
1699b0f92Schristos /* Target-dependent code for ARM BSD's.
2699b0f92Schristos 
3*6881a400Schristos    Copyright (C) 2006-2023 Free Software Foundation, Inc.
4699b0f92Schristos 
5699b0f92Schristos    This file is part of GDB.
6699b0f92Schristos 
7699b0f92Schristos    This program is free software; you can redistribute it and/or modify
8699b0f92Schristos    it under the terms of the GNU General Public License as published by
9699b0f92Schristos    the Free Software Foundation; either version 3 of the License, or
10699b0f92Schristos    (at your option) any later version.
11699b0f92Schristos 
12699b0f92Schristos    This program is distributed in the hope that it will be useful,
13699b0f92Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
14699b0f92Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15699b0f92Schristos    GNU General Public License for more details.
16699b0f92Schristos 
17699b0f92Schristos    You should have received a copy of the GNU General Public License
18699b0f92Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19699b0f92Schristos 
20699b0f92Schristos #include "defs.h"
21699b0f92Schristos #include "osabi.h"
22699b0f92Schristos #include "regcache.h"
23699b0f92Schristos #include "regset.h"
24699b0f92Schristos 
25699b0f92Schristos #include "arm-tdep.h"
26699b0f92Schristos 
27699b0f92Schristos /* Core file support.  */
28699b0f92Schristos 
29699b0f92Schristos /* Sizeof `struct reg' in <machine/reg.h>.  */
30699b0f92Schristos #define ARMBSD_SIZEOF_GREGS	(17 * 4)
31699b0f92Schristos 
32699b0f92Schristos /* Sizeof `struct fpreg' in <machine/reg.h.  */
33699b0f92Schristos #define ARMBSD_SIZEOF_FPREGS	((1 + (8 * 3)) * 4)
34699b0f92Schristos 
35699b0f92Schristos static int
36699b0f92Schristos armbsd_fpreg_offset (int regnum)
37699b0f92Schristos {
38699b0f92Schristos   if (regnum == ARM_FPS_REGNUM)
39699b0f92Schristos     return 0;
40699b0f92Schristos 
41699b0f92Schristos   return 4 + (regnum - ARM_F0_REGNUM) * 12;
42699b0f92Schristos }
43699b0f92Schristos 
44699b0f92Schristos /* Supply register REGNUM from the buffer specified by FPREGS and LEN
45699b0f92Schristos    in the floating-point register set REGSET to register cache
46699b0f92Schristos    REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
47699b0f92Schristos 
48699b0f92Schristos static void
49699b0f92Schristos armbsd_supply_fpregset (const struct regset *regset,
50699b0f92Schristos 			struct regcache *regcache,
51699b0f92Schristos 			int regnum, const void *fpregs, size_t len)
52699b0f92Schristos {
53699b0f92Schristos   const gdb_byte *regs = (const gdb_byte *) fpregs;
54699b0f92Schristos   int i;
55699b0f92Schristos 
56699b0f92Schristos   gdb_assert (len >= ARMBSD_SIZEOF_FPREGS);
57699b0f92Schristos 
58699b0f92Schristos   for (i = ARM_F0_REGNUM; i <= ARM_FPS_REGNUM; i++)
59699b0f92Schristos     {
60699b0f92Schristos       if (regnum == i || regnum == -1)
617f2ac410Schristos 	regcache->raw_supply (i, regs + armbsd_fpreg_offset (i));
62699b0f92Schristos     }
63699b0f92Schristos }
64699b0f92Schristos 
65699b0f92Schristos /* Supply register REGNUM from the buffer specified by GREGS and LEN
66699b0f92Schristos    in the general-purpose register set REGSET to register cache
67699b0f92Schristos    REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
68699b0f92Schristos 
69699b0f92Schristos static void
70699b0f92Schristos armbsd_supply_gregset (const struct regset *regset,
71699b0f92Schristos 		       struct regcache *regcache,
72699b0f92Schristos 		       int regnum, const void *gregs, size_t len)
73699b0f92Schristos {
74699b0f92Schristos   const gdb_byte *regs = (const gdb_byte *) gregs;
75699b0f92Schristos   int i;
76699b0f92Schristos 
77699b0f92Schristos   gdb_assert (len >= ARMBSD_SIZEOF_GREGS);
78699b0f92Schristos 
79699b0f92Schristos   for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++)
80699b0f92Schristos     {
81699b0f92Schristos       if (regnum == i || regnum == -1)
827f2ac410Schristos 	regcache->raw_supply (i, regs + i * 4);
83699b0f92Schristos     }
84699b0f92Schristos 
85699b0f92Schristos   if (regnum == ARM_PS_REGNUM || regnum == -1)
867f2ac410Schristos     regcache->raw_supply (i, regs + 16 * 4);
87699b0f92Schristos 
88699b0f92Schristos   if (len >= ARMBSD_SIZEOF_GREGS + ARMBSD_SIZEOF_FPREGS)
89699b0f92Schristos     {
90699b0f92Schristos       regs += ARMBSD_SIZEOF_GREGS;
91699b0f92Schristos       len -= ARMBSD_SIZEOF_GREGS;
92699b0f92Schristos       armbsd_supply_fpregset (regset, regcache, regnum, regs, len);
93699b0f92Schristos     }
94699b0f92Schristos }
95699b0f92Schristos 
96699b0f92Schristos /* ARM register sets.  */
97699b0f92Schristos 
98699b0f92Schristos static const struct regset armbsd_gregset =
99699b0f92Schristos {
100699b0f92Schristos   NULL,
101699b0f92Schristos   armbsd_supply_gregset,
102699b0f92Schristos   NULL,
103699b0f92Schristos   REGSET_VARIABLE_SIZE
104699b0f92Schristos };
105699b0f92Schristos 
106699b0f92Schristos static const struct regset armbsd_fpregset =
107699b0f92Schristos {
108699b0f92Schristos   NULL,
109699b0f92Schristos   armbsd_supply_fpregset
110699b0f92Schristos };
111699b0f92Schristos 
112699b0f92Schristos /* Iterate over supported core file register note sections. */
113699b0f92Schristos 
114699b0f92Schristos void
115699b0f92Schristos armbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
116699b0f92Schristos 				     iterate_over_regset_sections_cb *cb,
117699b0f92Schristos 				     void *cb_data,
118699b0f92Schristos 				     const struct regcache *regcache)
119699b0f92Schristos {
1207f2ac410Schristos   cb (".reg", ARMBSD_SIZEOF_GREGS, ARMBSD_SIZEOF_GREGS, &armbsd_gregset, NULL,
1217f2ac410Schristos       cb_data);
1227f2ac410Schristos   cb (".reg2", ARMBSD_SIZEOF_FPREGS, ARMBSD_SIZEOF_FPREGS, &armbsd_fpregset,
1237f2ac410Schristos       NULL, cb_data);
124699b0f92Schristos }
125