bfd/arc: Add R_ prefix to all relocation names
[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
16d5f642
JB
30/* Some older versions of GNU/Linux and Android do not define
31 the following macros. */
32#ifndef NT_ARM_VFP
33#define NT_ARM_VFP 0x400
34#endif
35
bd9e6534
YQ
36/* Collect GP registers from REGCACHE to buffer BUF. */
37
38void
39arm_fill_gregset (struct regcache *regcache, void *buf)
40{
41 int i;
04248ead 42 uint32_t *regs = (uint32_t *) buf;
bd9e6534
YQ
43
44 for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++)
45 collect_register (regcache, i, &regs[i]);
46
47 collect_register (regcache, ARM_PS_REGNUM, &regs[16]);
48}
49
50/* Supply GP registers contents, stored in BUF, to REGCACHE. */
51
52void
53arm_store_gregset (struct regcache *regcache, const void *buf)
54{
55 int i;
56 char zerobuf[8];
04248ead 57 const uint32_t *regs = (const uint32_t *) buf;
bd9e6534
YQ
58
59 memset (zerobuf, 0, 8);
60 for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++)
61 supply_register (regcache, i, &regs[i]);
62
63 for (; i < ARM_PS_REGNUM; i++)
64 supply_register (regcache, i, zerobuf);
65
66 supply_register (regcache, ARM_PS_REGNUM, &regs[16]);
67}
68
69/* Collect NUM number of VFP registers from REGCACHE to buffer BUF. */
70
71void
72arm_fill_vfpregset_num (struct regcache *regcache, void *buf, int num)
73{
74 int i, base;
75
76 gdb_assert (num == 16 || num == 32);
77
78 base = find_regno (regcache->tdesc, "d0");
79 for (i = 0; i < num; i++)
80 collect_register (regcache, base + i, (char *) buf + i * 8);
81
82 collect_register_by_name (regcache, "fpscr", (char *) buf + 32 * 8);
83}
84
85/* Supply NUM number of VFP registers contents, stored in BUF, to
86 REGCACHE. */
87
88void
89arm_store_vfpregset_num (struct regcache *regcache, const void *buf, int num)
90{
91 int i, base;
92
93 gdb_assert (num == 16 || num == 32);
94
95 base = find_regno (regcache->tdesc, "d0");
96 for (i = 0; i < num; i++)
97 supply_register (regcache, base + i, (char *) buf + i * 8);
98
99 supply_register_by_name (regcache, "fpscr", (char *) buf + 32 * 8);
100}
101
102static void
103arm_fill_vfpregset (struct regcache *regcache, void *buf)
104{
105 arm_fill_vfpregset_num (regcache, buf, 32);
106}
107
108static void
109arm_store_vfpregset (struct regcache *regcache, const void *buf)
110{
111 arm_store_vfpregset_num (regcache, buf, 32);
112}
113
114/* Register sets with using PTRACE_GETREGSET. */
115
116static struct regset_info aarch32_regsets[] = {
117 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS, 18 * 4,
118 GENERAL_REGS,
119 arm_fill_gregset, arm_store_gregset },
120 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_VFP, 32 * 8 + 4,
121 EXTENDED_REGS,
122 arm_fill_vfpregset, arm_store_vfpregset },
04b3479c 123 NULL_REGSET
bd9e6534
YQ
124};
125
126static struct regsets_info aarch32_regsets_info =
127 {
128 aarch32_regsets, /* regsets */
129 0, /* num_regsets */
130 NULL, /* disabled_regsets */
131 };
132
133struct regs_info regs_info_aarch32 =
134 {
135 NULL, /* regset_bitmap */
136 NULL, /* usrregs */
137 &aarch32_regsets_info
138 };
139
17b1509a
YQ
140/* Returns 1 if the current instruction set is thumb, 0 otherwise. */
141
d9311bfa 142int
17b1509a
YQ
143arm_is_thumb_mode (void)
144{
145 struct regcache *regcache = get_thread_regcache (current_thread, 1);
146 unsigned long cpsr;
147
148 collect_register_by_name (regcache, "cpsr", &cpsr);
149
150 if (cpsr & 0x20)
151 return 1;
152 else
153 return 0;
154}
155
156/* Returns 1 if there is a software breakpoint at location. */
157
158int
159arm_breakpoint_at (CORE_ADDR where)
160{
161 if (arm_is_thumb_mode ())
162 {
163 /* Thumb mode. */
164 unsigned short insn;
165
166 (*the_target->read_memory) (where, (unsigned char *) &insn, 2);
167 if (insn == thumb_breakpoint)
168 return 1;
169
170 if (insn == thumb2_breakpoint[0])
171 {
172 (*the_target->read_memory) (where + 2, (unsigned char *) &insn, 2);
173 if (insn == thumb2_breakpoint[1])
174 return 1;
175 }
176 }
177 else
178 {
179 /* ARM mode. */
180 unsigned long insn;
181
182 (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
183 if (insn == arm_abi_breakpoint)
184 return 1;
185
186 if (insn == arm_eabi_breakpoint)
187 return 1;
188 }
189
190 return 0;
191}
192
193/* Enum describing the different kinds of breakpoints. */
194enum arm_breakpoint_kinds
195{
196 ARM_BP_KIND_THUMB = 2,
197 ARM_BP_KIND_THUMB2 = 3,
198 ARM_BP_KIND_ARM = 4,
199};
200
201/* Implementation of linux_target_ops method "breakpoint_kind_from_pc".
202
203 Determine the type and size of breakpoint to insert at PCPTR. Uses the
204 program counter value to determine whether a 16-bit or 32-bit breakpoint
205 should be used. It returns the breakpoint's kind, and adjusts the program
206 counter (if necessary) to point to the actual memory location where the
207 breakpoint should be inserted. */
208
209int
210arm_breakpoint_kind_from_pc (CORE_ADDR *pcptr)
211{
212 if (IS_THUMB_ADDR (*pcptr))
213 {
214 gdb_byte buf[2];
215
216 *pcptr = UNMAKE_THUMB_ADDR (*pcptr);
217
218 /* Check whether we are replacing a thumb2 32-bit instruction. */
219 if ((*the_target->read_memory) (*pcptr, buf, 2) == 0)
220 {
221 unsigned short inst1 = 0;
222
223 (*the_target->read_memory) (*pcptr, (gdb_byte *) &inst1, 2);
224 if (thumb_insn_size (inst1) == 4)
225 return ARM_BP_KIND_THUMB2;
226 }
227 return ARM_BP_KIND_THUMB;
228 }
229 else
230 return ARM_BP_KIND_ARM;
231}
232
233/* Implementation of the linux_target_ops method "sw_breakpoint_from_kind". */
234
235const gdb_byte *
236arm_sw_breakpoint_from_kind (int kind , int *size)
237{
238 *size = arm_breakpoint_len;
239 /* Define an ARM-mode breakpoint; we only set breakpoints in the C
240 library, which is most likely to be ARM. If the kernel supports
241 clone events, we will never insert a breakpoint, so even a Thumb
242 C library will work; so will mixing EABI/non-EABI gdbserver and
243 application. */
244 switch (kind)
245 {
246 case ARM_BP_KIND_THUMB:
247 *size = thumb_breakpoint_len;
248 return (gdb_byte *) &thumb_breakpoint;
249 case ARM_BP_KIND_THUMB2:
250 *size = thumb2_breakpoint_len;
251 return (gdb_byte *) &thumb2_breakpoint;
252 case ARM_BP_KIND_ARM:
253 *size = arm_breakpoint_len;
254 return (const gdb_byte *) &arm_breakpoint;
255 default:
256 return NULL;
257 }
258 return NULL;
259}
260
261/* Implementation of the linux_target_ops method
262 "breakpoint_kind_from_current_state". */
263
264int
265arm_breakpoint_kind_from_current_state (CORE_ADDR *pcptr)
266{
267 if (arm_is_thumb_mode ())
268 {
269 *pcptr = MAKE_THUMB_ADDR (*pcptr);
270 return arm_breakpoint_kind_from_pc (pcptr);
271 }
272 else
273 {
274 return arm_breakpoint_kind_from_pc (pcptr);
275 }
276}
277
bd9e6534
YQ
278void
279initialize_low_arch_aarch32 (void)
280{
281 init_registers_arm_with_neon ();
282
283 initialize_regsets_info (&aarch32_regsets_info);
284}
This page took 0.07116 seconds and 4 git commands to generate.