Merge {i386,amd64}_linux_read_description
[deliverable/binutils-gdb.git] / gdb / aarch64-linux-tdep.c
1 /* Target-dependent code for GNU/Linux AArch64.
2
3 Copyright (C) 2009-2014 Free Software Foundation, Inc.
4 Contributed by ARM Ltd.
5
6 This file is part of GDB.
7
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.
12
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.
17
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/>. */
20
21 #include "defs.h"
22
23 #include "gdbarch.h"
24 #include "glibc-tdep.h"
25 #include "linux-tdep.h"
26 #include "aarch64-tdep.h"
27 #include "aarch64-linux-tdep.h"
28 #include "osabi.h"
29 #include "solib-svr4.h"
30 #include "symtab.h"
31 #include "tramp-frame.h"
32 #include "trad-frame.h"
33
34 #include "inferior.h"
35 #include "regcache.h"
36 #include "regset.h"
37
38 #include "cli/cli-utils.h"
39 #include "stap-probe.h"
40 #include "parser-defs.h"
41 #include "user-regs.h"
42 #include <ctype.h>
43
44 /* The general-purpose regset consists of 31 X registers, plus SP, PC,
45 and PSTATE registers, as defined in the AArch64 port of the Linux
46 kernel. */
47 #define AARCH64_LINUX_SIZEOF_GREGSET (34 * X_REGISTER_SIZE)
48
49 /* The fp regset consists of 32 V registers, plus FPCR and FPSR which
50 are 4 bytes wide each, and the whole structure is padded to 128 bit
51 alignment. */
52 #define AARCH64_LINUX_SIZEOF_FPREGSET (33 * V_REGISTER_SIZE)
53
54 /* Signal frame handling.
55
56 +------------+ ^
57 | saved lr | |
58 +->| saved fp |--+
59 | | |
60 | | |
61 | +------------+
62 | | saved lr |
63 +--| saved fp |
64 ^ | |
65 | | |
66 | +------------+
67 ^ | |
68 | | signal |
69 | | | SIGTRAMP_FRAME (struct rt_sigframe)
70 | | saved regs |
71 +--| saved sp |--> interrupted_sp
72 | | saved pc |--> interrupted_pc
73 | | |
74 | +------------+
75 | | saved lr |--> default_restorer (movz x8, NR_sys_rt_sigreturn; svc 0)
76 +--| saved fp |<- FP
77 | | NORMAL_FRAME
78 | |<- SP
79 +------------+
80
81 On signal delivery, the kernel will create a signal handler stack
82 frame and setup the return address in LR to point at restorer stub.
83 The signal stack frame is defined by:
84
85 struct rt_sigframe
86 {
87 siginfo_t info;
88 struct ucontext uc;
89 };
90
91 typedef struct
92 {
93 ... 128 bytes
94 } siginfo_t;
95
96 The ucontext has the following form:
97 struct ucontext
98 {
99 unsigned long uc_flags;
100 struct ucontext *uc_link;
101 stack_t uc_stack;
102 sigset_t uc_sigmask;
103 struct sigcontext uc_mcontext;
104 };
105
106 typedef struct sigaltstack
107 {
108 void *ss_sp;
109 int ss_flags;
110 size_t ss_size;
111 } stack_t;
112
113 struct sigcontext
114 {
115 unsigned long fault_address;
116 unsigned long regs[31];
117 unsigned long sp; / * 31 * /
118 unsigned long pc; / * 32 * /
119 unsigned long pstate; / * 33 * /
120 __u8 __reserved[4096]
121 };
122
123 The restorer stub will always have the form:
124
125 d28015a8 movz x8, #0xad
126 d4000001 svc #0x0
127
128 This is a system call sys_rt_sigreturn.
129
130 We detect signal frames by snooping the return code for the restorer
131 instruction sequence.
132
133 The handler then needs to recover the saved register set from
134 ucontext.uc_mcontext. */
135
136 /* These magic numbers need to reflect the layout of the kernel
137 defined struct rt_sigframe and ucontext. */
138 #define AARCH64_SIGCONTEXT_REG_SIZE 8
139 #define AARCH64_RT_SIGFRAME_UCONTEXT_OFFSET 128
140 #define AARCH64_UCONTEXT_SIGCONTEXT_OFFSET 176
141 #define AARCH64_SIGCONTEXT_XO_OFFSET 8
142
143 /* Implement the "init" method of struct tramp_frame. */
144
145 static void
146 aarch64_linux_sigframe_init (const struct tramp_frame *self,
147 struct frame_info *this_frame,
148 struct trad_frame_cache *this_cache,
149 CORE_ADDR func)
150 {
151 struct gdbarch *gdbarch = get_frame_arch (this_frame);
152 CORE_ADDR sp = get_frame_register_unsigned (this_frame, AARCH64_SP_REGNUM);
153 CORE_ADDR sigcontext_addr =
154 sp
155 + AARCH64_RT_SIGFRAME_UCONTEXT_OFFSET
156 + AARCH64_UCONTEXT_SIGCONTEXT_OFFSET;
157 int i;
158
159 for (i = 0; i < 31; i++)
160 {
161 trad_frame_set_reg_addr (this_cache,
162 AARCH64_X0_REGNUM + i,
163 sigcontext_addr + AARCH64_SIGCONTEXT_XO_OFFSET
164 + i * AARCH64_SIGCONTEXT_REG_SIZE);
165 }
166 trad_frame_set_reg_addr (this_cache, AARCH64_SP_REGNUM,
167 sigcontext_addr + AARCH64_SIGCONTEXT_XO_OFFSET
168 + 31 * AARCH64_SIGCONTEXT_REG_SIZE);
169 trad_frame_set_reg_addr (this_cache, AARCH64_PC_REGNUM,
170 sigcontext_addr + AARCH64_SIGCONTEXT_XO_OFFSET
171 + 32 * AARCH64_SIGCONTEXT_REG_SIZE);
172
173 trad_frame_set_id (this_cache, frame_id_build (sp, func));
174 }
175
176 static const struct tramp_frame aarch64_linux_rt_sigframe =
177 {
178 SIGTRAMP_FRAME,
179 4,
180 {
181 /* movz x8, 0x8b (S=1,o=10,h=0,i=0x8b,r=8)
182 Soo1 0010 1hhi iiii iiii iiii iiir rrrr */
183 {0xd2801168, -1},
184
185 /* svc 0x0 (o=0, l=1)
186 1101 0100 oooi iiii iiii iiii iii0 00ll */
187 {0xd4000001, -1},
188 {TRAMP_SENTINEL_INSN, -1}
189 },
190 aarch64_linux_sigframe_init
191 };
192
193 /* Fill GDB's register array with the general-purpose register values
194 in the buffer pointed by GREGS_BUF. */
195
196 void
197 aarch64_linux_supply_gregset (struct regcache *regcache,
198 const gdb_byte *gregs_buf)
199 {
200 int regno;
201
202 for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_CPSR_REGNUM; regno++)
203 regcache_raw_supply (regcache, regno,
204 gregs_buf + X_REGISTER_SIZE
205 * (regno - AARCH64_X0_REGNUM));
206 }
207
208 /* The "supply_regset" function for the general-purpose register set. */
209
210 static void
211 supply_gregset_from_core (const struct regset *regset,
212 struct regcache *regcache,
213 int regnum, const void *regbuf, size_t len)
214 {
215 aarch64_linux_supply_gregset (regcache, (const gdb_byte *) regbuf);
216 }
217
218 /* Fill GDB's register array with the floating-point register values
219 in the buffer pointed by FPREGS_BUF. */
220
221 void
222 aarch64_linux_supply_fpregset (struct regcache *regcache,
223 const gdb_byte *fpregs_buf)
224 {
225 int regno;
226
227 for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++)
228 regcache_raw_supply (regcache, regno,
229 fpregs_buf + V_REGISTER_SIZE
230 * (regno - AARCH64_V0_REGNUM));
231
232 regcache_raw_supply (regcache, AARCH64_FPSR_REGNUM,
233 fpregs_buf + V_REGISTER_SIZE * 32);
234 regcache_raw_supply (regcache, AARCH64_FPCR_REGNUM,
235 fpregs_buf + V_REGISTER_SIZE * 32 + 4);
236 }
237
238 /* The "supply_regset" function for the floating-point register set. */
239
240 static void
241 supply_fpregset_from_core (const struct regset *regset,
242 struct regcache *regcache,
243 int regnum, const void *regbuf, size_t len)
244 {
245 aarch64_linux_supply_fpregset (regcache, (const gdb_byte *) regbuf);
246 }
247
248 /* Register set definitions. */
249
250 static const struct regset aarch64_linux_gregset =
251 {
252 NULL, supply_gregset_from_core, NULL
253 };
254
255 static const struct regset aarch64_linux_fpregset =
256 {
257 NULL, supply_fpregset_from_core, NULL
258 };
259
260 /* Implement the "regset_from_core_section" gdbarch method. */
261
262 static const struct regset *
263 aarch64_linux_regset_from_core_section (struct gdbarch *gdbarch,
264 const char *sect_name,
265 size_t sect_size)
266 {
267 if (strcmp (sect_name, ".reg") == 0
268 && sect_size == AARCH64_LINUX_SIZEOF_GREGSET)
269 return &aarch64_linux_gregset;
270
271 if (strcmp (sect_name, ".reg2") == 0
272 && sect_size == AARCH64_LINUX_SIZEOF_FPREGSET)
273 return &aarch64_linux_fpregset;
274
275 return NULL;
276 }
277
278 /* Implementation of `gdbarch_stap_is_single_operand', as defined in
279 gdbarch.h. */
280
281 static int
282 aarch64_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
283 {
284 return (*s == '#' || isdigit (*s) /* Literal number. */
285 || *s == '[' /* Register indirection. */
286 || isalpha (*s)); /* Register value. */
287 }
288
289 /* This routine is used to parse a special token in AArch64's assembly.
290
291 The special tokens parsed by it are:
292
293 - Register displacement (e.g, [fp, #-8])
294
295 It returns one if the special token has been parsed successfully,
296 or zero if the current token is not considered special. */
297
298 static int
299 aarch64_stap_parse_special_token (struct gdbarch *gdbarch,
300 struct stap_parse_info *p)
301 {
302 if (*p->arg == '[')
303 {
304 /* Temporary holder for lookahead. */
305 const char *tmp = p->arg;
306 char *endp;
307 /* Used to save the register name. */
308 const char *start;
309 char *regname;
310 int len;
311 int got_minus = 0;
312 long displacement;
313 struct stoken str;
314
315 ++tmp;
316 start = tmp;
317
318 /* Register name. */
319 while (isalnum (*tmp))
320 ++tmp;
321
322 if (*tmp != ',')
323 return 0;
324
325 len = tmp - start;
326 regname = alloca (len + 2);
327
328 strncpy (regname, start, len);
329 regname[len] = '\0';
330
331 if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1)
332 error (_("Invalid register name `%s' on expression `%s'."),
333 regname, p->saved_arg);
334
335 ++tmp;
336 tmp = skip_spaces_const (tmp);
337 /* Now we expect a number. It can begin with '#' or simply
338 a digit. */
339 if (*tmp == '#')
340 ++tmp;
341
342 if (*tmp == '-')
343 {
344 ++tmp;
345 got_minus = 1;
346 }
347 else if (*tmp == '+')
348 ++tmp;
349
350 if (!isdigit (*tmp))
351 return 0;
352
353 displacement = strtol (tmp, &endp, 10);
354 tmp = endp;
355
356 /* Skipping last `]'. */
357 if (*tmp++ != ']')
358 return 0;
359
360 /* The displacement. */
361 write_exp_elt_opcode (&p->pstate, OP_LONG);
362 write_exp_elt_type (&p->pstate, builtin_type (gdbarch)->builtin_long);
363 write_exp_elt_longcst (&p->pstate, displacement);
364 write_exp_elt_opcode (&p->pstate, OP_LONG);
365 if (got_minus)
366 write_exp_elt_opcode (&p->pstate, UNOP_NEG);
367
368 /* The register name. */
369 write_exp_elt_opcode (&p->pstate, OP_REGISTER);
370 str.ptr = regname;
371 str.length = len;
372 write_exp_string (&p->pstate, str);
373 write_exp_elt_opcode (&p->pstate, OP_REGISTER);
374
375 write_exp_elt_opcode (&p->pstate, BINOP_ADD);
376
377 /* Casting to the expected type. */
378 write_exp_elt_opcode (&p->pstate, UNOP_CAST);
379 write_exp_elt_type (&p->pstate, lookup_pointer_type (p->arg_type));
380 write_exp_elt_opcode (&p->pstate, UNOP_CAST);
381
382 write_exp_elt_opcode (&p->pstate, UNOP_IND);
383
384 p->arg = tmp;
385 }
386 else
387 return 0;
388
389 return 1;
390 }
391
392 static void
393 aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
394 {
395 static const char *const stap_integer_prefixes[] = { "#", "", NULL };
396 static const char *const stap_register_prefixes[] = { "", NULL };
397 static const char *const stap_register_indirection_prefixes[] = { "[",
398 NULL };
399 static const char *const stap_register_indirection_suffixes[] = { "]",
400 NULL };
401 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
402
403 tdep->lowest_pc = 0x8000;
404
405 linux_init_abi (info, gdbarch);
406
407 set_solib_svr4_fetch_link_map_offsets (gdbarch,
408 svr4_lp64_fetch_link_map_offsets);
409
410 /* Enable TLS support. */
411 set_gdbarch_fetch_tls_load_module_address (gdbarch,
412 svr4_fetch_objfile_link_map);
413
414 /* Shared library handling. */
415 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
416
417 set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type);
418 tramp_frame_prepend_unwinder (gdbarch, &aarch64_linux_rt_sigframe);
419
420 /* Enable longjmp. */
421 tdep->jb_pc = 11;
422
423 set_gdbarch_regset_from_core_section (gdbarch,
424 aarch64_linux_regset_from_core_section);
425
426 /* SystemTap related. */
427 set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes);
428 set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes);
429 set_gdbarch_stap_register_indirection_prefixes (gdbarch,
430 stap_register_indirection_prefixes);
431 set_gdbarch_stap_register_indirection_suffixes (gdbarch,
432 stap_register_indirection_suffixes);
433 set_gdbarch_stap_is_single_operand (gdbarch, aarch64_stap_is_single_operand);
434 set_gdbarch_stap_parse_special_token (gdbarch,
435 aarch64_stap_parse_special_token);
436 }
437
438 /* Provide a prototype to silence -Wmissing-prototypes. */
439 extern initialize_file_ftype _initialize_aarch64_linux_tdep;
440
441 void
442 _initialize_aarch64_linux_tdep (void)
443 {
444 gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_LINUX,
445 aarch64_linux_init_abi);
446 }
This page took 0.045319 seconds and 4 git commands to generate.