xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/arm-none-tdep.c (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
1*6881a400Schristos /* none on ARM target support.
2*6881a400Schristos 
3*6881a400Schristos    Copyright (C) 2020-2023 Free Software Foundation, Inc.
4*6881a400Schristos 
5*6881a400Schristos    This file is part of GDB.
6*6881a400Schristos 
7*6881a400Schristos    This program is free software; you can redistribute it and/or modify
8*6881a400Schristos    it under the terms of the GNU General Public License as published by
9*6881a400Schristos    the Free Software Foundation; either version 3 of the License, or
10*6881a400Schristos    (at your option) any later version.
11*6881a400Schristos 
12*6881a400Schristos    This program is distributed in the hope that it will be useful,
13*6881a400Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
14*6881a400Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*6881a400Schristos    GNU General Public License for more details.
16*6881a400Schristos 
17*6881a400Schristos    You should have received a copy of the GNU General Public License
18*6881a400Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19*6881a400Schristos 
20*6881a400Schristos #include "defs.h"
21*6881a400Schristos #include "arm-tdep.h"
22*6881a400Schristos #include "arch-utils.h"
23*6881a400Schristos #include "regcache.h"
24*6881a400Schristos #include "elf-bfd.h"
25*6881a400Schristos #include "regset.h"
26*6881a400Schristos #include "user-regs.h"
27*6881a400Schristos 
28*6881a400Schristos #ifdef HAVE_ELF
29*6881a400Schristos #include "elf-none-tdep.h"
30*6881a400Schristos #endif
31*6881a400Schristos 
32*6881a400Schristos /* Core file and register set support.  */
33*6881a400Schristos #define ARM_NONE_SIZEOF_GREGSET (18 * ARM_INT_REGISTER_SIZE)
34*6881a400Schristos 
35*6881a400Schristos /* Support VFP register format.  */
36*6881a400Schristos #define ARM_NONE_SIZEOF_VFP (32 * 8 + 4)
37*6881a400Schristos 
38*6881a400Schristos /* The index to access CPSR in user_regs as defined in GLIBC.  */
39*6881a400Schristos #define ARM_NONE_CPSR_GREGNUM 16
40*6881a400Schristos 
41*6881a400Schristos /* Supply register REGNUM from buffer GREGS_BUF (length LEN bytes) into
42*6881a400Schristos    REGCACHE.  If REGNUM is -1 then supply all registers.  The set of
43*6881a400Schristos    registers that this function will supply is limited to the general
44*6881a400Schristos    purpose registers.
45*6881a400Schristos 
46*6881a400Schristos    The layout of the registers here is based on the ARM GNU/Linux
47*6881a400Schristos    layout.  */
48*6881a400Schristos 
49*6881a400Schristos static void
50*6881a400Schristos arm_none_supply_gregset (const struct regset *regset,
51*6881a400Schristos 			 struct regcache *regcache,
52*6881a400Schristos 			 int regnum, const void *gregs_buf, size_t len)
53*6881a400Schristos {
54*6881a400Schristos   struct gdbarch *gdbarch = regcache->arch ();
55*6881a400Schristos   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
56*6881a400Schristos   const gdb_byte *gregs = (const gdb_byte *) gregs_buf;
57*6881a400Schristos 
58*6881a400Schristos   for (int regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
59*6881a400Schristos     if (regnum == -1 || regnum == regno)
60*6881a400Schristos       regcache->raw_supply (regno, gregs + ARM_INT_REGISTER_SIZE * regno);
61*6881a400Schristos 
62*6881a400Schristos   if (regnum == ARM_PS_REGNUM || regnum == -1)
63*6881a400Schristos     {
64*6881a400Schristos       if (arm_apcs_32)
65*6881a400Schristos 	regcache->raw_supply (ARM_PS_REGNUM,
66*6881a400Schristos 			      gregs + ARM_INT_REGISTER_SIZE
67*6881a400Schristos 			      * ARM_NONE_CPSR_GREGNUM);
68*6881a400Schristos       else
69*6881a400Schristos 	regcache->raw_supply (ARM_PS_REGNUM,
70*6881a400Schristos 			     gregs + ARM_INT_REGISTER_SIZE * ARM_PC_REGNUM);
71*6881a400Schristos     }
72*6881a400Schristos 
73*6881a400Schristos   if (regnum == ARM_PC_REGNUM || regnum == -1)
74*6881a400Schristos     {
75*6881a400Schristos       gdb_byte pc_buf[ARM_INT_REGISTER_SIZE];
76*6881a400Schristos 
77*6881a400Schristos       CORE_ADDR reg_pc
78*6881a400Schristos 	= extract_unsigned_integer (gregs + ARM_INT_REGISTER_SIZE
79*6881a400Schristos 				    * ARM_PC_REGNUM,
80*6881a400Schristos 				    ARM_INT_REGISTER_SIZE, byte_order);
81*6881a400Schristos       reg_pc = gdbarch_addr_bits_remove (gdbarch, reg_pc);
82*6881a400Schristos       store_unsigned_integer (pc_buf, ARM_INT_REGISTER_SIZE, byte_order,
83*6881a400Schristos 			      reg_pc);
84*6881a400Schristos       regcache->raw_supply (ARM_PC_REGNUM, pc_buf);
85*6881a400Schristos     }
86*6881a400Schristos }
87*6881a400Schristos 
88*6881a400Schristos /* Collect register REGNUM from REGCACHE and place it into buffer GREGS_BUF
89*6881a400Schristos    (length LEN bytes).  If REGNUM is -1 then collect all registers.  The
90*6881a400Schristos    set of registers that this function will collect is limited to the
91*6881a400Schristos    general purpose registers.
92*6881a400Schristos 
93*6881a400Schristos    The layout of the registers here is based on the ARM GNU/Linux
94*6881a400Schristos    layout.  */
95*6881a400Schristos 
96*6881a400Schristos static void
97*6881a400Schristos arm_none_collect_gregset (const struct regset *regset,
98*6881a400Schristos 			  const struct regcache *regcache,
99*6881a400Schristos 			  int regnum, void *gregs_buf, size_t len)
100*6881a400Schristos {
101*6881a400Schristos   gdb_byte *gregs = (gdb_byte *) gregs_buf;
102*6881a400Schristos 
103*6881a400Schristos   for (int regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
104*6881a400Schristos     if (regnum == -1 || regnum == regno)
105*6881a400Schristos       regcache->raw_collect (regno,
106*6881a400Schristos 			     gregs + ARM_INT_REGISTER_SIZE * regno);
107*6881a400Schristos 
108*6881a400Schristos   if (regnum == ARM_PS_REGNUM || regnum == -1)
109*6881a400Schristos     {
110*6881a400Schristos       if (arm_apcs_32)
111*6881a400Schristos 	regcache->raw_collect (ARM_PS_REGNUM,
112*6881a400Schristos 			       gregs + ARM_INT_REGISTER_SIZE
113*6881a400Schristos 			       * ARM_NONE_CPSR_GREGNUM);
114*6881a400Schristos       else
115*6881a400Schristos 	regcache->raw_collect (ARM_PS_REGNUM,
116*6881a400Schristos 			       gregs + ARM_INT_REGISTER_SIZE * ARM_PC_REGNUM);
117*6881a400Schristos     }
118*6881a400Schristos 
119*6881a400Schristos   if (regnum == ARM_PC_REGNUM || regnum == -1)
120*6881a400Schristos     regcache->raw_collect (ARM_PC_REGNUM,
121*6881a400Schristos 			   gregs + ARM_INT_REGISTER_SIZE * ARM_PC_REGNUM);
122*6881a400Schristos }
123*6881a400Schristos 
124*6881a400Schristos /* Supply VFP registers from REGS_BUF into REGCACHE.  */
125*6881a400Schristos 
126*6881a400Schristos static void
127*6881a400Schristos arm_none_supply_vfp (const struct regset *regset,
128*6881a400Schristos 		     struct regcache *regcache,
129*6881a400Schristos 		     int regnum, const void *regs_buf, size_t len)
130*6881a400Schristos {
131*6881a400Schristos   const gdb_byte *regs = (const gdb_byte *) regs_buf;
132*6881a400Schristos 
133*6881a400Schristos   if (regnum == ARM_FPSCR_REGNUM || regnum == -1)
134*6881a400Schristos     regcache->raw_supply (ARM_FPSCR_REGNUM, regs + 32 * 8);
135*6881a400Schristos 
136*6881a400Schristos   for (int regno = ARM_D0_REGNUM; regno <= ARM_D31_REGNUM; regno++)
137*6881a400Schristos     if (regnum == -1 || regnum == regno)
138*6881a400Schristos       regcache->raw_supply (regno, regs + (regno - ARM_D0_REGNUM) * 8);
139*6881a400Schristos }
140*6881a400Schristos 
141*6881a400Schristos /* Collect VFP registers from REGCACHE into REGS_BUF.  */
142*6881a400Schristos 
143*6881a400Schristos static void
144*6881a400Schristos arm_none_collect_vfp (const struct regset *regset,
145*6881a400Schristos 		      const struct regcache *regcache,
146*6881a400Schristos 		      int regnum, void *regs_buf, size_t len)
147*6881a400Schristos {
148*6881a400Schristos   gdb_byte *regs = (gdb_byte *) regs_buf;
149*6881a400Schristos 
150*6881a400Schristos   if (regnum == ARM_FPSCR_REGNUM || regnum == -1)
151*6881a400Schristos     regcache->raw_collect (ARM_FPSCR_REGNUM, regs + 32 * 8);
152*6881a400Schristos 
153*6881a400Schristos   for (int regno = ARM_D0_REGNUM; regno <= ARM_D31_REGNUM; regno++)
154*6881a400Schristos     if (regnum == -1 || regnum == regno)
155*6881a400Schristos       regcache->raw_collect (regno, regs + (regno - ARM_D0_REGNUM) * 8);
156*6881a400Schristos }
157*6881a400Schristos 
158*6881a400Schristos /* The general purpose register set.  */
159*6881a400Schristos 
160*6881a400Schristos static const struct regset arm_none_gregset =
161*6881a400Schristos   {
162*6881a400Schristos     nullptr, arm_none_supply_gregset, arm_none_collect_gregset
163*6881a400Schristos   };
164*6881a400Schristos 
165*6881a400Schristos /* The VFP register set.  */
166*6881a400Schristos 
167*6881a400Schristos static const struct regset arm_none_vfpregset =
168*6881a400Schristos   {
169*6881a400Schristos     nullptr, arm_none_supply_vfp, arm_none_collect_vfp
170*6881a400Schristos   };
171*6881a400Schristos 
172*6881a400Schristos /* Iterate over core file register note sections.  */
173*6881a400Schristos 
174*6881a400Schristos static void
175*6881a400Schristos arm_none_iterate_over_regset_sections (struct gdbarch *gdbarch,
176*6881a400Schristos 				       iterate_over_regset_sections_cb *cb,
177*6881a400Schristos 				       void *cb_data,
178*6881a400Schristos 				       const struct regcache *regcache)
179*6881a400Schristos {
180*6881a400Schristos   arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch);
181*6881a400Schristos 
182*6881a400Schristos   cb (".reg", ARM_NONE_SIZEOF_GREGSET, ARM_NONE_SIZEOF_GREGSET,
183*6881a400Schristos       &arm_none_gregset, nullptr, cb_data);
184*6881a400Schristos 
185*6881a400Schristos   if (tdep->vfp_register_count > 0)
186*6881a400Schristos     cb (".reg-arm-vfp", ARM_NONE_SIZEOF_VFP, ARM_NONE_SIZEOF_VFP,
187*6881a400Schristos 	&arm_none_vfpregset, "VFP floating-point", cb_data);
188*6881a400Schristos }
189*6881a400Schristos 
190*6881a400Schristos /* Initialize ARM bare-metal ABI info.  */
191*6881a400Schristos 
192*6881a400Schristos static void
193*6881a400Schristos arm_none_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
194*6881a400Schristos {
195*6881a400Schristos #ifdef HAVE_ELF
196*6881a400Schristos   elf_none_init_abi (gdbarch);
197*6881a400Schristos #endif
198*6881a400Schristos 
199*6881a400Schristos   /* Iterate over registers for reading and writing bare metal ARM core
200*6881a400Schristos      files.  */
201*6881a400Schristos   set_gdbarch_iterate_over_regset_sections
202*6881a400Schristos     (gdbarch, arm_none_iterate_over_regset_sections);
203*6881a400Schristos }
204*6881a400Schristos 
205*6881a400Schristos /* Initialize ARM bare-metal target support.  */
206*6881a400Schristos 
207*6881a400Schristos void _initialize_arm_none_tdep ();
208*6881a400Schristos void
209*6881a400Schristos _initialize_arm_none_tdep ()
210*6881a400Schristos {
211*6881a400Schristos   gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_NONE,
212*6881a400Schristos 			  arm_none_init_abi);
213*6881a400Schristos }
214