GDBserver

linux-aarch32-low.c
Go to the documentation of this file.
1 /* Copyright (C) 1995-2018 Free Software Foundation, Inc.
2
3 This file is part of GDB.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18 #include "server.h"
19 #include "arch/arm.h"
20 #include "arch/arm-linux.h"
21 #include "linux-low.h"
22 #include "linux-aarch32-low.h"
23
24 #include <sys/ptrace.h>
25 /* Don't include elf.h if linux/elf.h got included by gdb_proc_service.h.
26 On Bionic elf.h and linux/elf.h have conflicting definitions. */
27 #ifndef ELFMAG0
28 #include <elf.h>
29 #endif
30
31 /* Correct in either endianness. */
32 #define arm_abi_breakpoint 0xef9f0001UL
33
34 /* For new EABI binaries. We recognize it regardless of which ABI
35 is used for gdbserver, so single threaded debugging should work
36 OK, but for multi-threaded debugging we only insert the current
37 ABI's breakpoint instruction. For now at least. */
38 #define arm_eabi_breakpoint 0xe7f001f0UL
39
40 #if (defined __ARM_EABI__ || defined __aarch64__)
41 static const unsigned long arm_breakpoint = arm_eabi_breakpoint;
42 #else
43 static const unsigned long arm_breakpoint = arm_abi_breakpoint;
44 #endif
45
46 #define arm_breakpoint_len 4
47 static const unsigned short thumb_breakpoint = 0xde01;
48 #define thumb_breakpoint_len 2
49 static const unsigned short thumb2_breakpoint[] = { 0xf7f0, 0xa000 };
50 #define thumb2_breakpoint_len 4
51
52 /* Some older versions of GNU/Linux and Android do not define
53 the following macros. */
54 #ifndef NT_ARM_VFP
55 #define NT_ARM_VFP 0x400
56 #endif
57
58 /* Collect GP registers from REGCACHE to buffer BUF. */
59
60 void
61 arm_fill_gregset (struct regcache *regcache, void *buf)
62 {
63 int i;
64 uint32_t *regs = (uint32_t *) buf;
65 uint32_t cpsr = regs[ARM_CPSR_GREGNUM];
66
67 for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++)
68 collect_register (regcache, i, &regs[i]);
69
70 collect_register (regcache, ARM_PS_REGNUM, &regs[ARM_CPSR_GREGNUM]);
71 /* Keep reserved bits bit 20 to bit 23. */
72 regs[ARM_CPSR_GREGNUM] = ((regs[ARM_CPSR_GREGNUM] & 0xff0fffff)
73 | (cpsr & 0x00f00000));
74 }
75
76 /* Supply GP registers contents, stored in BUF, to REGCACHE. */
77
78 void
79 arm_store_gregset (struct regcache *regcache, const void *buf)
80 {
81 int i;
82 char zerobuf[8];
83 const uint32_t *regs = (const uint32_t *) buf;
84 uint32_t cpsr = regs[ARM_CPSR_GREGNUM];
85
86 memset (zerobuf, 0, 8);
87 for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++)
88 supply_register (regcache, i, &regs[i]);
89
90 for (; i < ARM_PS_REGNUM; i++)
91 supply_register (regcache, i, zerobuf);
92
93 /* Clear reserved bits bit 20 to bit 23. */
94 cpsr &= 0xff0fffff;
95 supply_register (regcache, ARM_PS_REGNUM, &cpsr);
96 }
97
98 /* Collect NUM number of VFP registers from REGCACHE to buffer BUF. */
99
100 void
101 arm_fill_vfpregset_num (struct regcache *regcache, void *buf, int num)
102 {
103 int i, base;
104
105 gdb_assert (num == 16 || num == 32);
106
107 base = find_regno (regcache->tdesc, "d0");
108 for (i = 0; i < num; i++)
109 collect_register (regcache, base + i, (char *) buf + i * 8);
110
111 collect_register_by_name (regcache, "fpscr", (char *) buf + 32 * 8);
112 }
113
114 /* Supply NUM number of VFP registers contents, stored in BUF, to
115 REGCACHE. */
116
117 void
118 arm_store_vfpregset_num (struct regcache *regcache, const void *buf, int num)
119 {
120 int i, base;
121
122 gdb_assert (num == 16 || num == 32);
123
124 base = find_regno (regcache->tdesc, "d0");
125 for (i = 0; i < num; i++)
126 supply_register (regcache, base + i, (char *) buf + i * 8);
127
128 supply_register_by_name (regcache, "fpscr", (char *) buf + 32 * 8);
129 }
130
131 static void
132 arm_fill_vfpregset (struct regcache *regcache, void *buf)
133 {
134 arm_fill_vfpregset_num (regcache, buf, 32);
135 }
136
137 static void
138 arm_store_vfpregset (struct regcache *regcache, const void *buf)
139 {
140 arm_store_vfpregset_num (regcache, buf, 32);
141 }
142
143 /* Register sets with using PTRACE_GETREGSET. */
144
145 static struct regset_info aarch32_regsets[] = {
146 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS, 18 * 4,
147 GENERAL_REGS,
148 arm_fill_gregset, arm_store_gregset },
149 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_VFP, 32 * 8 + 4,
150 EXTENDED_REGS,
151 arm_fill_vfpregset, arm_store_vfpregset },
152 NULL_REGSET
153 };
154
155 static struct regsets_info aarch32_regsets_info =
156 {
157 aarch32_regsets, /* regsets */
158 0, /* num_regsets */
159 NULL, /* disabled_regsets */
160 };
161
162 struct regs_info regs_info_aarch32 =
163 {
164 NULL, /* regset_bitmap */
165 NULL, /* usrregs */
166 &aarch32_regsets_info
167 };
168
169 /* Returns 1 if the current instruction set is thumb, 0 otherwise. */
170
171 int
172 arm_is_thumb_mode (void)
173 {
174 struct regcache *regcache = get_thread_regcache (current_thread, 1);
175 unsigned long cpsr;
176
177 collect_register_by_name (regcache, "cpsr", &cpsr);
178
179 if (cpsr & 0x20)
180 return 1;
181 else
182 return 0;
183 }
184
185 /* Returns 1 if there is a software breakpoint at location. */
186
187 int
188 arm_breakpoint_at (CORE_ADDR where)
189 {
190 if (arm_is_thumb_mode ())
191 {
192 /* Thumb mode. */
193 unsigned short insn;
194
195 (*the_target->read_memory) (where, (unsigned char *) &insn, 2);
196 if (insn == thumb_breakpoint)
197 return 1;
198
199 if (insn == thumb2_breakpoint[0])
200 {
201 (*the_target->read_memory) (where + 2, (unsigned char *) &insn, 2);
202 if (insn == thumb2_breakpoint[1])
203 return 1;
204 }
205 }
206 else
207 {
208 /* ARM mode. */
209 unsigned long insn;
210
211 (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
212 if (insn == arm_abi_breakpoint)
213 return 1;
214
215 if (insn == arm_eabi_breakpoint)
216 return 1;
217 }
218
219 return 0;
220 }
221
222 /* Implementation of linux_target_ops method "breakpoint_kind_from_pc".
223
224 Determine the type and size of breakpoint to insert at PCPTR. Uses the
225 program counter value to determine whether a 16-bit or 32-bit breakpoint
226 should be used. It returns the breakpoint's kind, and adjusts the program
227 counter (if necessary) to point to the actual memory location where the
228 breakpoint should be inserted. */
229
230 int
231 arm_breakpoint_kind_from_pc (CORE_ADDR *pcptr)
232 {
233 if (IS_THUMB_ADDR (*pcptr))
234 {
235 gdb_byte buf[2];
236
237 *pcptr = UNMAKE_THUMB_ADDR (*pcptr);
238
239 /* Check whether we are replacing a thumb2 32-bit instruction. */
240 if (target_read_memory (*pcptr, buf, 2) == 0)
241 {
242 unsigned short inst1 = 0;
243
244 target_read_memory (*pcptr, (gdb_byte *) &inst1, 2);
245 if (thumb_insn_size (inst1) == 4)
246 return ARM_BP_KIND_THUMB2;
247 }
248 return ARM_BP_KIND_THUMB;
249 }
250 else
251 return ARM_BP_KIND_ARM;
252 }
253
254 /* Implementation of the linux_target_ops method "sw_breakpoint_from_kind". */
255
256 const gdb_byte *
257 arm_sw_breakpoint_from_kind (int kind , int *size)
258 {
259 *size = arm_breakpoint_len;
260 /* Define an ARM-mode breakpoint; we only set breakpoints in the C
261 library, which is most likely to be ARM. If the kernel supports
262 clone events, we will never insert a breakpoint, so even a Thumb
263 C library will work; so will mixing EABI/non-EABI gdbserver and
264 application. */
265 switch (kind)
266 {
267 case ARM_BP_KIND_THUMB:
268 *size = thumb_breakpoint_len;
269 return (gdb_byte *) &thumb_breakpoint;
270 case ARM_BP_KIND_THUMB2:
271 *size = thumb2_breakpoint_len;
272 return (gdb_byte *) &thumb2_breakpoint;
273 case ARM_BP_KIND_ARM:
274 *size = arm_breakpoint_len;
275 return (const gdb_byte *) &arm_breakpoint;
276 default:
277 return NULL;
278 }
279 return NULL;
280 }
281
282 /* Implementation of the linux_target_ops method
283 "breakpoint_kind_from_current_state". */
284
285 int
286 arm_breakpoint_kind_from_current_state (CORE_ADDR *pcptr)
287 {
288 if (arm_is_thumb_mode ())
289 {
290 *pcptr = MAKE_THUMB_ADDR (*pcptr);
291 return arm_breakpoint_kind_from_pc (pcptr);
292 }
293 else
294 {
295 return arm_breakpoint_kind_from_pc (pcptr);
296 }
297 }
298
299 void
300 initialize_low_arch_aarch32 (void)
301 {
302 init_registers_arm_with_neon ();
303
304 initialize_regsets_info (&aarch32_regsets_info);
305 }
regcache::tdesc
const struct target_desc * tdesc
Definition: regcache.h:34
arm_breakpoint_at
int arm_breakpoint_at(CORE_ADDR where)
Definition: linux-aarch32-low.c:188
arm_store_gregset
void arm_store_gregset(struct regcache *regcache, const void *buf)
Definition: linux-aarch32-low.c:79
current_thread
struct thread_info * current_thread
Definition: inferiors.c:28
collect_register
void collect_register(struct regcache *regcache, int n, void *buf)
Definition: regcache.c:402
aarch32_regsets_info
static struct regsets_info aarch32_regsets_info
Definition: linux-aarch32-low.c:155
CORE_ADDR
bfd_vma CORE_ADDR
Definition: common-types.h:41
supply_register_by_name
void supply_register_by_name(struct regcache *regcache, const char *name, const void *buf)
Definition: regcache.c:393
initialize_low_arch_aarch32
void initialize_low_arch_aarch32(void)
Definition: linux-aarch32-low.c:300
init_registers_arm_with_neon
void init_registers_arm_with_neon(void)
arm_fill_vfpregset
static void arm_fill_vfpregset(struct regcache *regcache, void *buf)
Definition: linux-aarch32-low.c:132
memset
void * memset(T *s, int c, size_t n)=delete
thumb_breakpoint
static const unsigned short thumb_breakpoint
Definition: linux-aarch32-low.c:47
target_read_memory
int target_read_memory(CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
Definition: target.c:131
regs_info_aarch32
struct regs_info regs_info_aarch32
Definition: linux-aarch32-low.c:162
the_target
struct target_ops * the_target
Definition: target.c:24
NT_ARM_VFP
#define NT_ARM_VFP
Definition: linux-aarch32-low.c:55
regcache
Definition: regcache.h:31
arm_sw_breakpoint_from_kind
const gdb_byte * arm_sw_breakpoint_from_kind(int kind, int *size)
Definition: linux-aarch32-low.c:257
linux-low.h
collect_register_by_name
void collect_register_by_name(struct regcache *regcache, const char *name, void *buf)
Definition: regcache.c:441
thumb_breakpoint_len
#define thumb_breakpoint_len
Definition: linux-aarch32-low.c:48
arm_breakpoint_kind_from_pc
int arm_breakpoint_kind_from_pc(CORE_ADDR *pcptr)
Definition: linux-aarch32-low.c:231
arm_breakpoint
static const unsigned long arm_breakpoint
Definition: linux-aarch32-low.c:43
arm_breakpoint_kind_from_current_state
int arm_breakpoint_kind_from_current_state(CORE_ADDR *pcptr)
Definition: linux-aarch32-low.c:286
regs_info
Definition: linux-low.h:94
arm_is_thumb_mode
int arm_is_thumb_mode(void)
Definition: linux-aarch32-low.c:172
thumb2_breakpoint_len
#define thumb2_breakpoint_len
Definition: linux-aarch32-low.c:50
server.h
thumb2_breakpoint
static const unsigned short thumb2_breakpoint[]
Definition: linux-aarch32-low.c:49
arm_abi_breakpoint
#define arm_abi_breakpoint
Definition: linux-aarch32-low.c:32
PTRACE_SETREGSET
#define PTRACE_SETREGSET
Definition: linux-ptrace.h:51
arm_fill_gregset
void arm_fill_gregset(struct regcache *regcache, void *buf)
Definition: linux-aarch32-low.c:61
PTRACE_GETREGSET
#define PTRACE_GETREGSET
Definition: linux-ptrace.h:47
gdb_assert
#define gdb_assert(expr)
Definition: gdb_assert.h:32
arm_fill_vfpregset_num
void arm_fill_vfpregset_num(struct regcache *regcache, void *buf, int num)
Definition: linux-aarch32-low.c:101
gdb_byte
bfd_byte gdb_byte
Definition: common-types.h:38
find_regno
int find_regno(const struct target_desc *tdesc, const char *name)
Definition: regcache.c:243
arm_eabi_breakpoint
#define arm_eabi_breakpoint
Definition: linux-aarch32-low.c:38
arm_breakpoint_len
#define arm_breakpoint_len
Definition: linux-aarch32-low.c:46
target_ops::read_memory
int(* read_memory)(CORE_ADDR memaddr, unsigned char *myaddr, int len)
Definition: target.h:166
get_thread_regcache
struct regcache * get_thread_regcache(struct thread_info *thread, int fetch)
Definition: regcache.c:27
arm_store_vfpregset
static void arm_store_vfpregset(struct regcache *regcache, const void *buf)
Definition: linux-aarch32-low.c:138
aarch32_regsets
static struct regset_info aarch32_regsets[]
Definition: linux-aarch32-low.c:145
linux-aarch32-low.h
supply_register
void supply_register(struct regcache *regcache, int n, const void *buf)
Definition: regcache.c:318
arm_store_vfpregset_num
void arm_store_vfpregset_num(struct regcache *regcache, const void *buf, int num)
Definition: linux-aarch32-low.c:118