1 /* Copyright (C) 1995-2015 Free Software Foundation, Inc.
3 This file is part of GDB.
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.
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.
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/>. */
20 #include "linux-low.h"
21 #include "linux-aarch32-low.h"
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. */
30 /* Some older versions of GNU/Linux and Android do not define
31 the following macros. */
33 #define NT_ARM_VFP 0x400
36 /* Collect GP registers from REGCACHE to buffer BUF. */
39 arm_fill_gregset (struct regcache
*regcache
, void *buf
)
42 uint32_t *regs
= (uint32_t *) buf
;
44 for (i
= ARM_A1_REGNUM
; i
<= ARM_PC_REGNUM
; i
++)
45 collect_register (regcache
, i
, ®s
[i
]);
47 collect_register (regcache
, ARM_PS_REGNUM
, ®s
[16]);
50 /* Supply GP registers contents, stored in BUF, to REGCACHE. */
53 arm_store_gregset (struct regcache
*regcache
, const void *buf
)
57 const uint32_t *regs
= (const uint32_t *) buf
;
59 memset (zerobuf
, 0, 8);
60 for (i
= ARM_A1_REGNUM
; i
<= ARM_PC_REGNUM
; i
++)
61 supply_register (regcache
, i
, ®s
[i
]);
63 for (; i
< ARM_PS_REGNUM
; i
++)
64 supply_register (regcache
, i
, zerobuf
);
66 supply_register (regcache
, ARM_PS_REGNUM
, ®s
[16]);
69 /* Collect NUM number of VFP registers from REGCACHE to buffer BUF. */
72 arm_fill_vfpregset_num (struct regcache
*regcache
, void *buf
, int num
)
76 gdb_assert (num
== 16 || num
== 32);
78 base
= find_regno (regcache
->tdesc
, "d0");
79 for (i
= 0; i
< num
; i
++)
80 collect_register (regcache
, base
+ i
, (char *) buf
+ i
* 8);
82 collect_register_by_name (regcache
, "fpscr", (char *) buf
+ 32 * 8);
85 /* Supply NUM number of VFP registers contents, stored in BUF, to
89 arm_store_vfpregset_num (struct regcache
*regcache
, const void *buf
, int num
)
93 gdb_assert (num
== 16 || num
== 32);
95 base
= find_regno (regcache
->tdesc
, "d0");
96 for (i
= 0; i
< num
; i
++)
97 supply_register (regcache
, base
+ i
, (char *) buf
+ i
* 8);
99 supply_register_by_name (regcache
, "fpscr", (char *) buf
+ 32 * 8);
103 arm_fill_vfpregset (struct regcache
*regcache
, void *buf
)
105 arm_fill_vfpregset_num (regcache
, buf
, 32);
109 arm_store_vfpregset (struct regcache
*regcache
, const void *buf
)
111 arm_store_vfpregset_num (regcache
, buf
, 32);
114 /* Register sets with using PTRACE_GETREGSET. */
116 static struct regset_info aarch32_regsets
[] = {
117 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_PRSTATUS
, 18 * 4,
119 arm_fill_gregset
, arm_store_gregset
},
120 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_ARM_VFP
, 32 * 8 + 4,
122 arm_fill_vfpregset
, arm_store_vfpregset
},
126 static struct regsets_info aarch32_regsets_info
=
128 aarch32_regsets
, /* regsets */
130 NULL
, /* disabled_regsets */
133 struct regs_info regs_info_aarch32
=
135 NULL
, /* regset_bitmap */
137 &aarch32_regsets_info
140 /* Returns 1 if the current instruction set is thumb, 0 otherwise. */
143 arm_is_thumb_mode (void)
145 struct regcache
*regcache
= get_thread_regcache (current_thread
, 1);
148 collect_register_by_name (regcache
, "cpsr", &cpsr
);
156 /* Returns 1 if there is a software breakpoint at location. */
159 arm_breakpoint_at (CORE_ADDR where
)
161 if (arm_is_thumb_mode ())
166 (*the_target
->read_memory
) (where
, (unsigned char *) &insn
, 2);
167 if (insn
== thumb_breakpoint
)
170 if (insn
== thumb2_breakpoint
[0])
172 (*the_target
->read_memory
) (where
+ 2, (unsigned char *) &insn
, 2);
173 if (insn
== thumb2_breakpoint
[1])
182 (*the_target
->read_memory
) (where
, (unsigned char *) &insn
, 4);
183 if (insn
== arm_abi_breakpoint
)
186 if (insn
== arm_eabi_breakpoint
)
193 /* Enum describing the different kinds of breakpoints. */
194 enum arm_breakpoint_kinds
196 ARM_BP_KIND_THUMB
= 2,
197 ARM_BP_KIND_THUMB2
= 3,
201 /* Implementation of linux_target_ops method "breakpoint_kind_from_pc".
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. */
210 arm_breakpoint_kind_from_pc (CORE_ADDR
*pcptr
)
212 if (IS_THUMB_ADDR (*pcptr
))
216 *pcptr
= UNMAKE_THUMB_ADDR (*pcptr
);
218 /* Check whether we are replacing a thumb2 32-bit instruction. */
219 if ((*the_target
->read_memory
) (*pcptr
, buf
, 2) == 0)
221 unsigned short inst1
= 0;
223 (*the_target
->read_memory
) (*pcptr
, (gdb_byte
*) &inst1
, 2);
224 if (thumb_insn_size (inst1
) == 4)
225 return ARM_BP_KIND_THUMB2
;
227 return ARM_BP_KIND_THUMB
;
230 return ARM_BP_KIND_ARM
;
233 /* Implementation of the linux_target_ops method "sw_breakpoint_from_kind". */
236 arm_sw_breakpoint_from_kind (int kind
, int *size
)
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
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
;
261 /* Implementation of the linux_target_ops method
262 "breakpoint_kind_from_current_state". */
265 arm_breakpoint_kind_from_current_state (CORE_ADDR
*pcptr
)
267 if (arm_is_thumb_mode ())
269 *pcptr
= MAKE_THUMB_ADDR (*pcptr
);
270 return arm_breakpoint_kind_from_pc (pcptr
);
274 return arm_breakpoint_kind_from_pc (pcptr
);
279 initialize_low_arch_aarch32 (void)
281 init_registers_arm_with_neon ();
283 initialize_regsets_info (&aarch32_regsets_info
);