Sort includes for files gdb/[a-f]*.[chyl].
[external/binutils.git] / gdb / alpha-linux-tdep.c
1 /* Target-dependent code for GNU/Linux on Alpha.
2    Copyright (C) 2002-2019 Free Software Foundation, Inc.
3
4    This file is part of GDB.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18
19 #include "defs.h"
20
21 /* Local non-gdb includes.  */
22 #include "alpha-tdep.h"
23 #include "frame.h"
24 #include "linux-tdep.h"
25 #include "osabi.h"
26 #include "regcache.h"
27 #include "regset.h"
28 #include "solib-svr4.h"
29 #include "symtab.h"
30
31 /* This enum represents the signals' numbers on the Alpha
32    architecture.  It just contains the signal definitions which are
33    different from the generic implementation.
34
35    It is derived from the file <arch/alpha/include/uapi/asm/signal.h>,
36    from the Linux kernel tree.  */
37
38 enum
39   {
40     /* SIGABRT is the same as in the generic implementation, but is
41        defined here because SIGIOT depends on it.  */
42     ALPHA_LINUX_SIGABRT = 6,
43     ALPHA_LINUX_SIGEMT = 7,
44     ALPHA_LINUX_SIGBUS = 10,
45     ALPHA_LINUX_SIGSYS = 12,
46     ALPHA_LINUX_SIGURG = 16,
47     ALPHA_LINUX_SIGSTOP = 17,
48     ALPHA_LINUX_SIGTSTP = 18,
49     ALPHA_LINUX_SIGCONT = 19,
50     ALPHA_LINUX_SIGCHLD = 20,
51     ALPHA_LINUX_SIGIO = 23,
52     ALPHA_LINUX_SIGINFO = 29,
53     ALPHA_LINUX_SIGUSR1 = 30,
54     ALPHA_LINUX_SIGUSR2 = 31,
55     ALPHA_LINUX_SIGPOLL = ALPHA_LINUX_SIGIO,
56     ALPHA_LINUX_SIGPWR = ALPHA_LINUX_SIGINFO,
57     ALPHA_LINUX_SIGIOT = ALPHA_LINUX_SIGABRT,
58   };
59
60 /* Under GNU/Linux, signal handler invocations can be identified by
61    the designated code sequence that is used to return from a signal
62    handler.  In particular, the return address of a signal handler
63    points to a sequence that copies $sp to $16, loads $0 with the
64    appropriate syscall number, and finally enters the kernel.
65
66    This is somewhat complicated in that:
67      (1) the expansion of the "mov" assembler macro has changed over
68          time, from "bis src,src,dst" to "bis zero,src,dst",
69      (2) the kernel has changed from using "addq" to "lda" to load the
70          syscall number,
71      (3) there is a "normal" sigreturn and an "rt" sigreturn which
72          has a different stack layout.  */
73
74 static long
75 alpha_linux_sigtramp_offset_1 (struct gdbarch *gdbarch, CORE_ADDR pc)
76 {
77   switch (alpha_read_insn (gdbarch, pc))
78     {
79     case 0x47de0410:            /* bis $30,$30,$16 */
80     case 0x47fe0410:            /* bis $31,$30,$16 */
81       return 0;
82
83     case 0x43ecf400:            /* addq $31,103,$0 */
84     case 0x201f0067:            /* lda $0,103($31) */
85     case 0x201f015f:            /* lda $0,351($31) */
86       return 4;
87
88     case 0x00000083:            /* call_pal callsys */
89       return 8;
90
91     default:
92       return -1;
93     }
94 }
95
96 static LONGEST
97 alpha_linux_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc)
98 {
99   long i, off;
100
101   if (pc & 3)
102     return -1;
103
104   /* Guess where we might be in the sequence.  */
105   off = alpha_linux_sigtramp_offset_1 (gdbarch, pc);
106   if (off < 0)
107     return -1;
108
109   /* Verify that the other two insns of the sequence are as we expect.  */
110   pc -= off;
111   for (i = 0; i < 12; i += 4)
112     {
113       if (i == off)
114         continue;
115       if (alpha_linux_sigtramp_offset_1 (gdbarch, pc + i) != i)
116         return -1;
117     }
118
119   return off;
120 }
121
122 static int
123 alpha_linux_pc_in_sigtramp (struct gdbarch *gdbarch,
124                             CORE_ADDR pc, const char *func_name)
125 {
126   return alpha_linux_sigtramp_offset (gdbarch, pc) >= 0;
127 }
128
129 static CORE_ADDR
130 alpha_linux_sigcontext_addr (struct frame_info *this_frame)
131 {
132   struct gdbarch *gdbarch = get_frame_arch (this_frame);
133   CORE_ADDR pc;
134   ULONGEST sp;
135   long off;
136
137   pc = get_frame_pc (this_frame);
138   sp = get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM);
139
140   off = alpha_linux_sigtramp_offset (gdbarch, pc);
141   gdb_assert (off >= 0);
142
143   /* __NR_rt_sigreturn has a couple of structures on the stack.  This is:
144
145         struct rt_sigframe {
146           struct siginfo info;
147           struct ucontext uc;
148         };
149
150         offsetof (struct rt_sigframe, uc.uc_mcontext);  */
151
152   if (alpha_read_insn (gdbarch, pc - off + 4) == 0x201f015f)
153     return sp + 176;
154
155   /* __NR_sigreturn has the sigcontext structure at the top of the stack.  */
156   return sp;
157 }
158
159 /* Supply register REGNUM from the buffer specified by GREGS and LEN
160    in the general-purpose register set REGSET to register cache
161    REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
162
163 static void
164 alpha_linux_supply_gregset (const struct regset *regset,
165                             struct regcache *regcache,
166                             int regnum, const void *gregs, size_t len)
167 {
168   const gdb_byte *regs = (const gdb_byte *) gregs;
169
170   gdb_assert (len >= 32 * 8);
171   alpha_supply_int_regs (regcache, regnum, regs, regs + 31 * 8,
172                          len >= 33 * 8 ? regs + 32 * 8 : NULL);
173 }
174
175 /* Collect register REGNUM from the register cache REGCACHE and store
176    it in the buffer specified by GREGS and LEN as described by the
177    general-purpose register set REGSET.  If REGNUM is -1, do this for
178    all registers in REGSET.  */
179
180 static void
181 alpha_linux_collect_gregset (const struct regset *regset,
182                              const struct regcache *regcache,
183                              int regnum, void *gregs, size_t len)
184 {
185   gdb_byte *regs = (gdb_byte *) gregs;
186
187   gdb_assert (len >= 32 * 8);
188   alpha_fill_int_regs (regcache, regnum, regs, regs + 31 * 8,
189                        len >= 33 * 8 ? regs + 32 * 8 : NULL);
190 }
191
192 /* Supply register REGNUM from the buffer specified by FPREGS and LEN
193    in the floating-point register set REGSET to register cache
194    REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
195
196 static void
197 alpha_linux_supply_fpregset (const struct regset *regset,
198                              struct regcache *regcache,
199                              int regnum, const void *fpregs, size_t len)
200 {
201   const gdb_byte *regs = (const gdb_byte *) fpregs;
202
203   gdb_assert (len >= 32 * 8);
204   alpha_supply_fp_regs (regcache, regnum, regs, regs + 31 * 8);
205 }
206
207 /* Collect register REGNUM from the register cache REGCACHE and store
208    it in the buffer specified by FPREGS and LEN as described by the
209    general-purpose register set REGSET.  If REGNUM is -1, do this for
210    all registers in REGSET.  */
211
212 static void
213 alpha_linux_collect_fpregset (const struct regset *regset,
214                               const struct regcache *regcache,
215                               int regnum, void *fpregs, size_t len)
216 {
217   gdb_byte *regs = (gdb_byte *) fpregs;
218
219   gdb_assert (len >= 32 * 8);
220   alpha_fill_fp_regs (regcache, regnum, regs, regs + 31 * 8);
221 }
222
223 static const struct regset alpha_linux_gregset =
224 {
225   NULL,
226   alpha_linux_supply_gregset, alpha_linux_collect_gregset
227 };
228
229 static const struct regset alpha_linux_fpregset =
230 {
231   NULL,
232   alpha_linux_supply_fpregset, alpha_linux_collect_fpregset
233 };
234
235 /* Iterate over core file register note sections.  */
236
237 static void
238 alpha_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
239                                           iterate_over_regset_sections_cb *cb,
240                                           void *cb_data,
241                                           const struct regcache *regcache)
242 {
243   cb (".reg", 32 * 8, 32 * 8, &alpha_linux_gregset, NULL, cb_data);
244   cb (".reg2", 32 * 8, 32 * 8, &alpha_linux_fpregset, NULL, cb_data);
245 }
246
247 /* Implementation of `gdbarch_gdb_signal_from_target', as defined in
248    gdbarch.h.  */
249
250 static enum gdb_signal
251 alpha_linux_gdb_signal_from_target (struct gdbarch *gdbarch,
252                                     int signal)
253 {
254   switch (signal)
255     {
256     case ALPHA_LINUX_SIGEMT:
257       return GDB_SIGNAL_EMT;
258
259     case ALPHA_LINUX_SIGBUS:
260       return GDB_SIGNAL_BUS;
261
262     case ALPHA_LINUX_SIGSYS:
263       return GDB_SIGNAL_SYS;
264
265     case ALPHA_LINUX_SIGURG:
266       return GDB_SIGNAL_URG;
267
268     case ALPHA_LINUX_SIGSTOP:
269       return GDB_SIGNAL_STOP;
270
271     case ALPHA_LINUX_SIGTSTP:
272       return GDB_SIGNAL_TSTP;
273
274     case ALPHA_LINUX_SIGCONT:
275       return GDB_SIGNAL_CONT;
276
277     case ALPHA_LINUX_SIGCHLD:
278       return GDB_SIGNAL_CHLD;
279
280     /* No way to differentiate between SIGIO and SIGPOLL.
281        Therefore, we just handle the first one.  */
282     case ALPHA_LINUX_SIGIO:
283       return GDB_SIGNAL_IO;
284
285     /* No way to differentiate between SIGINFO and SIGPWR.
286        Therefore, we just handle the first one.  */
287     case ALPHA_LINUX_SIGINFO:
288       return GDB_SIGNAL_INFO;
289
290     case ALPHA_LINUX_SIGUSR1:
291       return GDB_SIGNAL_USR1;
292
293     case ALPHA_LINUX_SIGUSR2:
294       return GDB_SIGNAL_USR2;
295     }
296
297   return linux_gdb_signal_from_target (gdbarch, signal);
298 }
299
300 /* Implementation of `gdbarch_gdb_signal_to_target', as defined in
301    gdbarch.h.  */
302
303 static int
304 alpha_linux_gdb_signal_to_target (struct gdbarch *gdbarch,
305                                   enum gdb_signal signal)
306 {
307   switch (signal)
308     {
309     case GDB_SIGNAL_EMT:
310       return ALPHA_LINUX_SIGEMT;
311
312     case GDB_SIGNAL_BUS:
313       return ALPHA_LINUX_SIGBUS;
314
315     case GDB_SIGNAL_SYS:
316       return ALPHA_LINUX_SIGSYS;
317
318     case GDB_SIGNAL_URG:
319       return ALPHA_LINUX_SIGURG;
320
321     case GDB_SIGNAL_STOP:
322       return ALPHA_LINUX_SIGSTOP;
323
324     case GDB_SIGNAL_TSTP:
325       return ALPHA_LINUX_SIGTSTP;
326
327     case GDB_SIGNAL_CONT:
328       return ALPHA_LINUX_SIGCONT;
329
330     case GDB_SIGNAL_CHLD:
331       return ALPHA_LINUX_SIGCHLD;
332
333     case GDB_SIGNAL_IO:
334       return ALPHA_LINUX_SIGIO;
335
336     case GDB_SIGNAL_INFO:
337       return ALPHA_LINUX_SIGINFO;
338
339     case GDB_SIGNAL_USR1:
340       return ALPHA_LINUX_SIGUSR1;
341
342     case GDB_SIGNAL_USR2:
343       return ALPHA_LINUX_SIGUSR2;
344
345     case GDB_SIGNAL_POLL:
346       return ALPHA_LINUX_SIGPOLL;
347
348     case GDB_SIGNAL_PWR:
349       return ALPHA_LINUX_SIGPWR;
350     }
351
352   return linux_gdb_signal_to_target (gdbarch, signal);
353 }
354
355 static void
356 alpha_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
357 {
358   struct gdbarch_tdep *tdep;
359
360   linux_init_abi (info, gdbarch);
361
362   /* Hook into the DWARF CFI frame unwinder.  */
363   alpha_dwarf2_init_abi (info, gdbarch);
364
365   /* Hook into the MDEBUG frame unwinder.  */
366   alpha_mdebug_init_abi (info, gdbarch);
367
368   tdep = gdbarch_tdep (gdbarch);
369   tdep->dynamic_sigtramp_offset = alpha_linux_sigtramp_offset;
370   tdep->sigcontext_addr = alpha_linux_sigcontext_addr;
371   tdep->pc_in_sigtramp = alpha_linux_pc_in_sigtramp;
372   tdep->jb_pc = 2;
373   tdep->jb_elt_size = 8;
374
375   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
376
377   set_solib_svr4_fetch_link_map_offsets
378     (gdbarch, svr4_lp64_fetch_link_map_offsets);
379
380   /* Enable TLS support.  */
381   set_gdbarch_fetch_tls_load_module_address (gdbarch,
382                                              svr4_fetch_objfile_link_map);
383
384   set_gdbarch_iterate_over_regset_sections
385     (gdbarch, alpha_linux_iterate_over_regset_sections);
386
387   set_gdbarch_gdb_signal_from_target (gdbarch,
388                                       alpha_linux_gdb_signal_from_target);
389   set_gdbarch_gdb_signal_to_target (gdbarch,
390                                     alpha_linux_gdb_signal_to_target);
391 }
392
393 void
394 _initialize_alpha_linux_tdep (void)
395 {
396   gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_LINUX,
397                           alpha_linux_init_abi);
398 }