Automatic date update in version.in
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-aarch32-low.c
CommitLineData
618f726f 1/* Copyright (C) 1995-2016 Free Software Foundation, Inc.
bd9e6534
YQ
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 "linux-low.h"
21#include "linux-aarch32-low.h"
22
23#include <sys/ptrace.h>
24/* Don't include elf.h if linux/elf.h got included by gdb_proc_service.h.
25 On Bionic elf.h and linux/elf.h have conflicting definitions. */
26#ifndef ELFMAG0
27#include <elf.h>
28#endif
29
b2ca446f
YQ
30/* Correct in either endianness. */
31#define arm_abi_breakpoint 0xef9f0001UL
32
33/* For new EABI binaries. We recognize it regardless of which ABI
34 is used for gdbserver, so single threaded debugging should work
35 OK, but for multi-threaded debugging we only insert the current
36 ABI's breakpoint instruction. For now at least. */
37#define arm_eabi_breakpoint 0xe7f001f0UL
38
39#if (defined __ARM_EABI__ || defined __aarch64__)
40static const unsigned long arm_breakpoint = arm_eabi_breakpoint;
41#else
42static const unsigned long arm_breakpoint = arm_abi_breakpoint;
43#endif
44
45#define arm_breakpoint_len 4
46static const unsigned short thumb_breakpoint = 0xde01;
47#define thumb_breakpoint_len 2
48const unsigned short thumb2_breakpoint[] = { 0xf7f0, 0xa000 };
49#define thumb2_breakpoint_len 4
50
16d5f642
JB
51/* Some older versions of GNU/Linux and Android do not define
52 the following macros. */
53#ifndef NT_ARM_VFP
54#define NT_ARM_VFP 0x400
55#endif
56
bd9e6534
YQ
57/* Collect GP registers from REGCACHE to buffer BUF. */
58
59void
60arm_fill_gregset (struct regcache *regcache, void *buf)
61{
62 int i;
04248ead 63 uint32_t *regs = (uint32_t *) buf;
bd9e6534
YQ
64
65 for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++)
66 collect_register (regcache, i, &regs[i]);
67
68 collect_register (regcache, ARM_PS_REGNUM, &regs[16]);
69}
70
71/* Supply GP registers contents, stored in BUF, to REGCACHE. */
72
73void
74arm_store_gregset (struct regcache *regcache, const void *buf)
75{
76 int i;
77 char zerobuf[8];
04248ead 78 const uint32_t *regs = (const uint32_t *) buf;
bd9e6534
YQ
79
80 memset (zerobuf, 0, 8);
81 for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++)
82 supply_register (regcache, i, &regs[i]);
83
84 for (; i < ARM_PS_REGNUM; i++)
85 supply_register (regcache, i, zerobuf);
86
87 supply_register (regcache, ARM_PS_REGNUM, &regs[16]);
88}
89
90/* Collect NUM number of VFP registers from REGCACHE to buffer BUF. */
91
92void
93arm_fill_vfpregset_num (struct regcache *regcache, void *buf, int num)
94{
95 int i, base;
96
97 gdb_assert (num == 16 || num == 32);
98
99 base = find_regno (regcache->tdesc, "d0");
100 for (i = 0; i < num; i++)
101 collect_register (regcache, base + i, (char *) buf + i * 8);
102
103 collect_register_by_name (regcache, "fpscr", (char *) buf + 32 * 8);
104}
105
106/* Supply NUM number of VFP registers contents, stored in BUF, to
107 REGCACHE. */
108
109void
110arm_store_vfpregset_num (struct regcache *regcache, const void *buf, int num)
111{
112 int i, base;
113
114 gdb_assert (num == 16 || num == 32);
115
116 base = find_regno (regcache->tdesc, "d0");
117 for (i = 0; i < num; i++)
118 supply_register (regcache, base + i, (char *) buf + i * 8);
119
120 supply_register_by_name (regcache, "fpscr", (char *) buf + 32 * 8);
121}
122
123static void
124arm_fill_vfpregset (struct regcache *regcache, void *buf)
125{
126 arm_fill_vfpregset_num (regcache, buf, 32);
127}
128
129static void
130arm_store_vfpregset (struct regcache *regcache, const void *buf)
131{
132 arm_store_vfpregset_num (regcache, buf, 32);
133}
134
135/* Register sets with using PTRACE_GETREGSET. */
136
137static struct regset_info aarch32_regsets[] = {
138 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS, 18 * 4,
139 GENERAL_REGS,
140 arm_fill_gregset, arm_store_gregset },
141 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_VFP, 32 * 8 + 4,
142 EXTENDED_REGS,
143 arm_fill_vfpregset, arm_store_vfpregset },
04b3479c 144 NULL_REGSET
bd9e6534
YQ
145};
146
147static struct regsets_info aarch32_regsets_info =
148 {
149 aarch32_regsets, /* regsets */
150 0, /* num_regsets */
151 NULL, /* disabled_regsets */
152 };
153
154struct regs_info regs_info_aarch32 =
155 {
156 NULL, /* regset_bitmap */
157 NULL, /* usrregs */
158 &aarch32_regsets_info
159 };
160
17b1509a
YQ
161/* Returns 1 if the current instruction set is thumb, 0 otherwise. */
162
d9311bfa 163int
17b1509a
YQ
164arm_is_thumb_mode (void)
165{
166 struct regcache *regcache = get_thread_regcache (current_thread, 1);
167 unsigned long cpsr;
168
169 collect_register_by_name (regcache, "cpsr", &cpsr);
170
171 if (cpsr & 0x20)
172 return 1;
173 else
174 return 0;
175}
176
177/* Returns 1 if there is a software breakpoint at location. */
178
179int
180arm_breakpoint_at (CORE_ADDR where)
181{
182 if (arm_is_thumb_mode ())
183 {
184 /* Thumb mode. */
185 unsigned short insn;
186
187 (*the_target->read_memory) (where, (unsigned char *) &insn, 2);
188 if (insn == thumb_breakpoint)
189 return 1;
190
191 if (insn == thumb2_breakpoint[0])
192 {
193 (*the_target->read_memory) (where + 2, (unsigned char *) &insn, 2);
194 if (insn == thumb2_breakpoint[1])
195 return 1;
196 }
197 }
198 else
199 {
200 /* ARM mode. */
201 unsigned long insn;
202
203 (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
204 if (insn == arm_abi_breakpoint)
205 return 1;
206
207 if (insn == arm_eabi_breakpoint)
208 return 1;
209 }
210
211 return 0;
212}
213
214/* Enum describing the different kinds of breakpoints. */
215enum arm_breakpoint_kinds
216{
217 ARM_BP_KIND_THUMB = 2,
218 ARM_BP_KIND_THUMB2 = 3,
219 ARM_BP_KIND_ARM = 4,
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
230int
231arm_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 ((*the_target->read_memory) (*pcptr, buf, 2) == 0)
241 {
242 unsigned short inst1 = 0;
243
244 (*the_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
256const gdb_byte *
257arm_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
285int
286arm_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
bd9e6534
YQ
299void
300initialize_low_arch_aarch32 (void)
301{
302 init_registers_arm_with_neon ();
303
304 initialize_regsets_info (&aarch32_regsets_info);
305}
This page took 0.080397 seconds and 4 git commands to generate.