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