1 /* Target-dependent code for GNU/Linux AArch64.
3 Copyright (C) 2009-2015 Free Software Foundation, Inc.
4 Contributed by ARM Ltd.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 #include "glibc-tdep.h"
25 #include "linux-tdep.h"
26 #include "aarch64-tdep.h"
27 #include "aarch64-linux-tdep.h"
29 #include "solib-svr4.h"
31 #include "tramp-frame.h"
32 #include "trad-frame.h"
38 #include "cli/cli-utils.h"
39 #include "stap-probe.h"
40 #include "parser-defs.h"
41 #include "user-regs.h"
42 #include "xml-syscall.h"
45 /* Signal frame handling.
60 | | | SIGTRAMP_FRAME (struct rt_sigframe)
62 +--| saved sp |--> interrupted_sp
63 | | saved pc |--> interrupted_pc
66 | | saved lr |--> default_restorer (movz x8, NR_sys_rt_sigreturn; svc 0)
72 On signal delivery, the kernel will create a signal handler stack
73 frame and setup the return address in LR to point at restorer stub.
74 The signal stack frame is defined by:
87 The ucontext has the following form:
90 unsigned long uc_flags;
91 struct ucontext *uc_link;
94 struct sigcontext uc_mcontext;
97 typedef struct sigaltstack
106 unsigned long fault_address;
107 unsigned long regs[31];
108 unsigned long sp; / * 31 * /
109 unsigned long pc; / * 32 * /
110 unsigned long pstate; / * 33 * /
111 __u8 __reserved[4096]
114 The restorer stub will always have the form:
116 d28015a8 movz x8, #0xad
119 This is a system call sys_rt_sigreturn.
121 We detect signal frames by snooping the return code for the restorer
122 instruction sequence.
124 The handler then needs to recover the saved register set from
125 ucontext.uc_mcontext. */
127 /* These magic numbers need to reflect the layout of the kernel
128 defined struct rt_sigframe and ucontext. */
129 #define AARCH64_SIGCONTEXT_REG_SIZE 8
130 #define AARCH64_RT_SIGFRAME_UCONTEXT_OFFSET 128
131 #define AARCH64_UCONTEXT_SIGCONTEXT_OFFSET 176
132 #define AARCH64_SIGCONTEXT_XO_OFFSET 8
134 /* Implement the "init" method of struct tramp_frame. */
137 aarch64_linux_sigframe_init (const struct tramp_frame
*self
,
138 struct frame_info
*this_frame
,
139 struct trad_frame_cache
*this_cache
,
142 struct gdbarch
*gdbarch
= get_frame_arch (this_frame
);
143 CORE_ADDR sp
= get_frame_register_unsigned (this_frame
, AARCH64_SP_REGNUM
);
144 CORE_ADDR sigcontext_addr
=
146 + AARCH64_RT_SIGFRAME_UCONTEXT_OFFSET
147 + AARCH64_UCONTEXT_SIGCONTEXT_OFFSET
;
150 for (i
= 0; i
< 31; i
++)
152 trad_frame_set_reg_addr (this_cache
,
153 AARCH64_X0_REGNUM
+ i
,
154 sigcontext_addr
+ AARCH64_SIGCONTEXT_XO_OFFSET
155 + i
* AARCH64_SIGCONTEXT_REG_SIZE
);
157 trad_frame_set_reg_addr (this_cache
, AARCH64_SP_REGNUM
,
158 sigcontext_addr
+ AARCH64_SIGCONTEXT_XO_OFFSET
159 + 31 * AARCH64_SIGCONTEXT_REG_SIZE
);
160 trad_frame_set_reg_addr (this_cache
, AARCH64_PC_REGNUM
,
161 sigcontext_addr
+ AARCH64_SIGCONTEXT_XO_OFFSET
162 + 32 * AARCH64_SIGCONTEXT_REG_SIZE
);
164 trad_frame_set_id (this_cache
, frame_id_build (sp
, func
));
167 static const struct tramp_frame aarch64_linux_rt_sigframe
=
172 /* movz x8, 0x8b (S=1,o=10,h=0,i=0x8b,r=8)
173 Soo1 0010 1hhi iiii iiii iiii iiir rrrr */
176 /* svc 0x0 (o=0, l=1)
177 1101 0100 oooi iiii iiii iiii iii0 00ll */
179 {TRAMP_SENTINEL_INSN
, -1}
181 aarch64_linux_sigframe_init
186 static const struct regcache_map_entry aarch64_linux_gregmap
[] =
188 { 31, AARCH64_X0_REGNUM
, 8 }, /* x0 ... x30 */
189 { 1, AARCH64_SP_REGNUM
, 8 },
190 { 1, AARCH64_PC_REGNUM
, 8 },
191 { 1, AARCH64_CPSR_REGNUM
, 8 },
195 static const struct regcache_map_entry aarch64_linux_fpregmap
[] =
197 { 32, AARCH64_V0_REGNUM
, 16 }, /* v0 ... v31 */
198 { 1, AARCH64_FPSR_REGNUM
, 4 },
199 { 1, AARCH64_FPCR_REGNUM
, 4 },
203 /* Register set definitions. */
205 const struct regset aarch64_linux_gregset
=
207 aarch64_linux_gregmap
,
208 regcache_supply_regset
, regcache_collect_regset
211 const struct regset aarch64_linux_fpregset
=
213 aarch64_linux_fpregmap
,
214 regcache_supply_regset
, regcache_collect_regset
217 /* Implement the "regset_from_core_section" gdbarch method. */
220 aarch64_linux_iterate_over_regset_sections (struct gdbarch
*gdbarch
,
221 iterate_over_regset_sections_cb
*cb
,
223 const struct regcache
*regcache
)
225 cb (".reg", AARCH64_LINUX_SIZEOF_GREGSET
, &aarch64_linux_gregset
,
227 cb (".reg2", AARCH64_LINUX_SIZEOF_FPREGSET
, &aarch64_linux_fpregset
,
231 /* Implementation of `gdbarch_stap_is_single_operand', as defined in
235 aarch64_stap_is_single_operand (struct gdbarch
*gdbarch
, const char *s
)
237 return (*s
== '#' || isdigit (*s
) /* Literal number. */
238 || *s
== '[' /* Register indirection. */
239 || isalpha (*s
)); /* Register value. */
242 /* This routine is used to parse a special token in AArch64's assembly.
244 The special tokens parsed by it are:
246 - Register displacement (e.g, [fp, #-8])
248 It returns one if the special token has been parsed successfully,
249 or zero if the current token is not considered special. */
252 aarch64_stap_parse_special_token (struct gdbarch
*gdbarch
,
253 struct stap_parse_info
*p
)
257 /* Temporary holder for lookahead. */
258 const char *tmp
= p
->arg
;
260 /* Used to save the register name. */
272 while (isalnum (*tmp
))
279 regname
= alloca (len
+ 2);
281 strncpy (regname
, start
, len
);
284 if (user_reg_map_name_to_regnum (gdbarch
, regname
, len
) == -1)
285 error (_("Invalid register name `%s' on expression `%s'."),
286 regname
, p
->saved_arg
);
289 tmp
= skip_spaces_const (tmp
);
290 /* Now we expect a number. It can begin with '#' or simply
300 else if (*tmp
== '+')
306 displacement
= strtol (tmp
, &endp
, 10);
309 /* Skipping last `]'. */
313 /* The displacement. */
314 write_exp_elt_opcode (&p
->pstate
, OP_LONG
);
315 write_exp_elt_type (&p
->pstate
, builtin_type (gdbarch
)->builtin_long
);
316 write_exp_elt_longcst (&p
->pstate
, displacement
);
317 write_exp_elt_opcode (&p
->pstate
, OP_LONG
);
319 write_exp_elt_opcode (&p
->pstate
, UNOP_NEG
);
321 /* The register name. */
322 write_exp_elt_opcode (&p
->pstate
, OP_REGISTER
);
325 write_exp_string (&p
->pstate
, str
);
326 write_exp_elt_opcode (&p
->pstate
, OP_REGISTER
);
328 write_exp_elt_opcode (&p
->pstate
, BINOP_ADD
);
330 /* Casting to the expected type. */
331 write_exp_elt_opcode (&p
->pstate
, UNOP_CAST
);
332 write_exp_elt_type (&p
->pstate
, lookup_pointer_type (p
->arg_type
));
333 write_exp_elt_opcode (&p
->pstate
, UNOP_CAST
);
335 write_exp_elt_opcode (&p
->pstate
, UNOP_IND
);
345 /* Implement the "get_syscall_number" gdbarch method. */
348 aarch64_linux_get_syscall_number (struct gdbarch
*gdbarch
,
351 struct regcache
*regs
= get_thread_regcache (ptid
);
352 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
354 /* The content of register x8. */
355 gdb_byte buf
[X_REGISTER_SIZE
];
359 /* Getting the system call number from the register x8. */
360 regcache_cooked_read (regs
, AARCH64_DWARF_X0
+ 8, buf
);
362 ret
= extract_signed_integer (buf
, X_REGISTER_SIZE
, byte_order
);
368 aarch64_linux_init_abi (struct gdbarch_info info
, struct gdbarch
*gdbarch
)
370 static const char *const stap_integer_prefixes
[] = { "#", "", NULL
};
371 static const char *const stap_register_prefixes
[] = { "", NULL
};
372 static const char *const stap_register_indirection_prefixes
[] = { "[",
374 static const char *const stap_register_indirection_suffixes
[] = { "]",
376 struct gdbarch_tdep
*tdep
= gdbarch_tdep (gdbarch
);
378 tdep
->lowest_pc
= 0x8000;
380 linux_init_abi (info
, gdbarch
);
382 set_solib_svr4_fetch_link_map_offsets (gdbarch
,
383 svr4_lp64_fetch_link_map_offsets
);
385 /* Enable TLS support. */
386 set_gdbarch_fetch_tls_load_module_address (gdbarch
,
387 svr4_fetch_objfile_link_map
);
389 /* Shared library handling. */
390 set_gdbarch_skip_trampoline_code (gdbarch
, find_solib_trampoline_target
);
392 set_gdbarch_get_siginfo_type (gdbarch
, linux_get_siginfo_type
);
393 tramp_frame_prepend_unwinder (gdbarch
, &aarch64_linux_rt_sigframe
);
395 /* Enable longjmp. */
398 set_gdbarch_iterate_over_regset_sections
399 (gdbarch
, aarch64_linux_iterate_over_regset_sections
);
401 /* SystemTap related. */
402 set_gdbarch_stap_integer_prefixes (gdbarch
, stap_integer_prefixes
);
403 set_gdbarch_stap_register_prefixes (gdbarch
, stap_register_prefixes
);
404 set_gdbarch_stap_register_indirection_prefixes (gdbarch
,
405 stap_register_indirection_prefixes
);
406 set_gdbarch_stap_register_indirection_suffixes (gdbarch
,
407 stap_register_indirection_suffixes
);
408 set_gdbarch_stap_is_single_operand (gdbarch
, aarch64_stap_is_single_operand
);
409 set_gdbarch_stap_parse_special_token (gdbarch
,
410 aarch64_stap_parse_special_token
);
412 /* `catch syscall' */
413 set_xml_syscall_file_name (gdbarch
, "syscalls/aarch64-linux.xml");
414 set_gdbarch_get_syscall_number (gdbarch
, aarch64_linux_get_syscall_number
);
417 /* Provide a prototype to silence -Wmissing-prototypes. */
418 extern initialize_file_ftype _initialize_aarch64_linux_tdep
;
421 _initialize_aarch64_linux_tdep (void)
423 gdbarch_register_osabi (bfd_arch_aarch64
, 0, GDB_OSABI_LINUX
,
424 aarch64_linux_init_abi
);