GDB (xrefs)
Loading...
Searching...
No Matches
arm-none-tdep.c
Go to the documentation of this file.
1/* none on ARM target support.
2
3 Copyright (C) 2020-2023 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 "arm-tdep.h"
22#include "arch-utils.h"
23#include "regcache.h"
24#include "elf-bfd.h"
25#include "regset.h"
26#include "user-regs.h"
27
28#ifdef HAVE_ELF
29#include "elf-none-tdep.h"
30#endif
31
32/* Core file and register set support. */
33#define ARM_NONE_SIZEOF_GREGSET (18 * ARM_INT_REGISTER_SIZE)
34
35/* Support VFP register format. */
36#define ARM_NONE_SIZEOF_VFP (32 * 8 + 4)
37
38/* The index to access CPSR in user_regs as defined in GLIBC. */
39#define ARM_NONE_CPSR_GREGNUM 16
40
41/* Supply register REGNUM from buffer GREGS_BUF (length LEN bytes) into
42 REGCACHE. If REGNUM is -1 then supply all registers. The set of
43 registers that this function will supply is limited to the general
44 purpose registers.
45
46 The layout of the registers here is based on the ARM GNU/Linux
47 layout. */
48
49static void
51 struct regcache *regcache,
52 int regnum, const void *gregs_buf, size_t len)
53{
54 struct gdbarch *gdbarch = regcache->arch ();
55 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
56 const gdb_byte *gregs = (const gdb_byte *) gregs_buf;
57
58 for (int regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
59 if (regnum == -1 || regnum == regno)
60 regcache->raw_supply (regno, gregs + ARM_INT_REGISTER_SIZE * regno);
61
62 if (regnum == ARM_PS_REGNUM || regnum == -1)
63 {
64 if (arm_apcs_32)
68 else
71 }
72
73 if (regnum == ARM_PC_REGNUM || regnum == -1)
74 {
75 gdb_byte pc_buf[ARM_INT_REGISTER_SIZE];
76
77 CORE_ADDR reg_pc
80 ARM_INT_REGISTER_SIZE, byte_order);
81 reg_pc = gdbarch_addr_bits_remove (gdbarch, reg_pc);
83 reg_pc);
85 }
86}
87
88/* Collect register REGNUM from REGCACHE and place it into buffer GREGS_BUF
89 (length LEN bytes). If REGNUM is -1 then collect all registers. The
90 set of registers that this function will collect is limited to the
91 general purpose registers.
92
93 The layout of the registers here is based on the ARM GNU/Linux
94 layout. */
95
96static void
98 const struct regcache *regcache,
99 int regnum, void *gregs_buf, size_t len)
100{
101 gdb_byte *gregs = (gdb_byte *) gregs_buf;
102
103 for (int regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
104 if (regnum == -1 || regnum == regno)
105 regcache->raw_collect (regno,
106 gregs + ARM_INT_REGISTER_SIZE * regno);
107
108 if (regnum == ARM_PS_REGNUM || regnum == -1)
109 {
110 if (arm_apcs_32)
114 else
117 }
118
119 if (regnum == ARM_PC_REGNUM || regnum == -1)
122}
123
124/* Supply VFP registers from REGS_BUF into REGCACHE. */
125
126static void
128 struct regcache *regcache,
129 int regnum, const void *regs_buf, size_t len)
130{
131 const gdb_byte *regs = (const gdb_byte *) regs_buf;
132
133 if (regnum == ARM_FPSCR_REGNUM || regnum == -1)
134 regcache->raw_supply (ARM_FPSCR_REGNUM, regs + 32 * 8);
135
136 for (int regno = ARM_D0_REGNUM; regno <= ARM_D31_REGNUM; regno++)
137 if (regnum == -1 || regnum == regno)
138 regcache->raw_supply (regno, regs + (regno - ARM_D0_REGNUM) * 8);
139}
140
141/* Collect VFP registers from REGCACHE into REGS_BUF. */
142
143static void
145 const struct regcache *regcache,
146 int regnum, void *regs_buf, size_t len)
147{
148 gdb_byte *regs = (gdb_byte *) regs_buf;
149
150 if (regnum == ARM_FPSCR_REGNUM || regnum == -1)
151 regcache->raw_collect (ARM_FPSCR_REGNUM, regs + 32 * 8);
152
153 for (int regno = ARM_D0_REGNUM; regno <= ARM_D31_REGNUM; regno++)
154 if (regnum == -1 || regnum == regno)
155 regcache->raw_collect (regno, regs + (regno - ARM_D0_REGNUM) * 8);
156}
157
158/* The general purpose register set. */
159
160static const struct regset arm_none_gregset =
161 {
163 };
164
165/* The VFP register set. */
166
167static const struct regset arm_none_vfpregset =
168 {
170 };
171
172/* Iterate over core file register note sections. */
173
174static void
177 void *cb_data,
178 const struct regcache *regcache)
179{
180 arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch);
181
183 &arm_none_gregset, nullptr, cb_data);
184
185 if (tdep->vfp_register_count > 0)
186 cb (".reg-arm-vfp", ARM_NONE_SIZEOF_VFP, ARM_NONE_SIZEOF_VFP,
187 &arm_none_vfpregset, "VFP floating-point", cb_data);
188}
189
190/* Initialize ARM bare-metal ABI info. */
191
192static void
194{
195#ifdef HAVE_ELF
197#endif
198
199 /* Iterate over registers for reading and writing bare metal ARM core
200 files. */
203}
204
205/* Initialize ARM bare-metal target support. */
206
208void
int regnum
#define ARM_NONE_SIZEOF_VFP
static void arm_none_iterate_over_regset_sections(struct gdbarch *gdbarch, iterate_over_regset_sections_cb *cb, void *cb_data, const struct regcache *regcache)
#define ARM_NONE_SIZEOF_GREGSET
static void arm_none_collect_gregset(const struct regset *regset, const struct regcache *regcache, int regnum, void *gregs_buf, size_t len)
void _initialize_arm_none_tdep()
static const struct regset arm_none_gregset
#define ARM_NONE_CPSR_GREGNUM
static const struct regset arm_none_vfpregset
static void arm_none_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
static void arm_none_collect_vfp(const struct regset *regset, const struct regcache *regcache, int regnum, void *regs_buf, size_t len)
static void arm_none_supply_gregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs_buf, size_t len)
static void arm_none_supply_vfp(const struct regset *regset, struct regcache *regcache, int regnum, const void *regs_buf, size_t len)
bool arm_apcs_32
Definition arm-tdep.c:598
#define ARM_INT_REGISTER_SIZE
Definition arm.h:155
@ ARM_D31_REGNUM
Definition arm.h:63
@ ARM_PC_REGNUM
Definition arm.h:46
@ ARM_FPSCR_REGNUM
Definition arm.h:64
@ ARM_PS_REGNUM
Definition arm.h:52
@ ARM_D0_REGNUM
Definition arm.h:62
@ ARM_A1_REGNUM
Definition arm.h:40
gdbarch * arch() const
Definition regcache.c:231
void raw_collect(int regnum, void *buf) const override
Definition regcache.c:1127
void raw_supply(int regnum, const void *buf) override
Definition regcache.c:1062
static void store_unsigned_integer(gdb_byte *addr, int len, enum bfd_endian byte_order, ULONGEST val)
Definition defs.h:515
static ULONGEST extract_unsigned_integer(gdb::array_view< const gdb_byte > buf, enum bfd_endian byte_order)
Definition defs.h:480
void elf_none_init_abi(struct gdbarch *gdbarch)
enum bfd_endian gdbarch_byte_order(struct gdbarch *gdbarch)
Definition gdbarch.c:1396
CORE_ADDR gdbarch_addr_bits_remove(struct gdbarch *gdbarch, CORE_ADDR addr)
Definition gdbarch.c:3152
void set_gdbarch_iterate_over_regset_sections(struct gdbarch *gdbarch, gdbarch_iterate_over_regset_sections_ftype *iterate_over_regset_sections)
void iterate_over_regset_sections_cb(const char *sect_name, int supply_size, int collect_size, const struct regset *regset, const char *human_name, void *cb_data)
Definition gdbarch.h:104
void gdbarch_register_osabi(enum bfd_architecture arch, unsigned long machine, enum gdb_osabi osabi, void(*init_osabi)(struct gdbarch_info, struct gdbarch *))
Definition osabi.c:146
@ GDB_OSABI_NONE
Definition osabi.h:27