GDB (xrefs)
/tmp/gdb-7.10/gdb/alpha-linux-tdep.c
Go to the documentation of this file.
1 /* Target-dependent code for GNU/Linux on Alpha.
2  Copyright (C) 2002-2015 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 #include "frame.h"
21 #include "osabi.h"
22 #include "solib-svr4.h"
23 #include "symtab.h"
24 #include "regset.h"
25 #include "regcache.h"
26 #include "linux-tdep.h"
27 #include "alpha-tdep.h"
28 
29 /* This enum represents the signals' numbers on the Alpha
30  architecture. It just contains the signal definitions which are
31  different from the generic implementation.
32 
33  It is derived from the file <arch/alpha/include/uapi/asm/signal.h>,
34  from the Linux kernel tree. */
35 
36 enum
37  {
38  /* SIGABRT is the same as in the generic implementation, but is
39  defined here because SIGIOT depends on it. */
56  };
57 
58 /* Under GNU/Linux, signal handler invocations can be identified by
59  the designated code sequence that is used to return from a signal
60  handler. In particular, the return address of a signal handler
61  points to a sequence that copies $sp to $16, loads $0 with the
62  appropriate syscall number, and finally enters the kernel.
63 
64  This is somewhat complicated in that:
65  (1) the expansion of the "mov" assembler macro has changed over
66  time, from "bis src,src,dst" to "bis zero,src,dst",
67  (2) the kernel has changed from using "addq" to "lda" to load the
68  syscall number,
69  (3) there is a "normal" sigreturn and an "rt" sigreturn which
70  has a different stack layout. */
71 
72 static long
74 {
75  switch (alpha_read_insn (gdbarch, pc))
76  {
77  case 0x47de0410: /* bis $30,$30,$16 */
78  case 0x47fe0410: /* bis $31,$30,$16 */
79  return 0;
80 
81  case 0x43ecf400: /* addq $31,103,$0 */
82  case 0x201f0067: /* lda $0,103($31) */
83  case 0x201f015f: /* lda $0,351($31) */
84  return 4;
85 
86  case 0x00000083: /* call_pal callsys */
87  return 8;
88 
89  default:
90  return -1;
91  }
92 }
93 
94 static LONGEST
96 {
97  long i, off;
98 
99  if (pc & 3)
100  return -1;
101 
102  /* Guess where we might be in the sequence. */
103  off = alpha_linux_sigtramp_offset_1 (gdbarch, pc);
104  if (off < 0)
105  return -1;
106 
107  /* Verify that the other two insns of the sequence are as we expect. */
108  pc -= off;
109  for (i = 0; i < 12; i += 4)
110  {
111  if (i == off)
112  continue;
113  if (alpha_linux_sigtramp_offset_1 (gdbarch, pc + i) != i)
114  return -1;
115  }
116 
117  return off;
118 }
119 
120 static int
122  CORE_ADDR pc, const char *func_name)
123 {
124  return alpha_linux_sigtramp_offset (gdbarch, pc) >= 0;
125 }
126 
127 static CORE_ADDR
129 {
130  struct gdbarch *gdbarch = get_frame_arch (this_frame);
131  CORE_ADDR pc;
132  ULONGEST sp;
133  long off;
134 
135  pc = get_frame_pc (this_frame);
136  sp = get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM);
137 
138  off = alpha_linux_sigtramp_offset (gdbarch, pc);
139  gdb_assert (off >= 0);
140 
141  /* __NR_rt_sigreturn has a couple of structures on the stack. This is:
142 
143  struct rt_sigframe {
144  struct siginfo info;
145  struct ucontext uc;
146  };
147 
148  offsetof (struct rt_sigframe, uc.uc_mcontext); */
149 
150  if (alpha_read_insn (gdbarch, pc - off + 4) == 0x201f015f)
151  return sp + 176;
152 
153  /* __NR_sigreturn has the sigcontext structure at the top of the stack. */
154  return sp;
155 }
156 
157 /* Supply register REGNUM from the buffer specified by GREGS and LEN
158  in the general-purpose register set REGSET to register cache
159  REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
160 
161 static void
163  struct regcache *regcache,
164  int regnum, const void *gregs, size_t len)
165 {
166  const gdb_byte *regs = gregs;
167 
168  gdb_assert (len >= 32 * 8);
169  alpha_supply_int_regs (regcache, regnum, regs, regs + 31 * 8,
170  len >= 33 * 8 ? regs + 32 * 8 : NULL);
171 }
172 
173 /* Collect register REGNUM from the register cache REGCACHE and store
174  it in the buffer specified by GREGS and LEN as described by the
175  general-purpose register set REGSET. If REGNUM is -1, do this for
176  all registers in REGSET. */
177 
178 static void
180  const struct regcache *regcache,
181  int regnum, void *gregs, size_t len)
182 {
183  gdb_byte *regs = gregs;
184 
185  gdb_assert (len >= 32 * 8);
186  alpha_fill_int_regs (regcache, regnum, regs, regs + 31 * 8,
187  len >= 33 * 8 ? regs + 32 * 8 : NULL);
188 }
189 
190 /* Supply register REGNUM from the buffer specified by FPREGS and LEN
191  in the floating-point register set REGSET to register cache
192  REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
193 
194 static void
196  struct regcache *regcache,
197  int regnum, const void *fpregs, size_t len)
198 {
199  const gdb_byte *regs = fpregs;
200 
201  gdb_assert (len >= 32 * 8);
202  alpha_supply_fp_regs (regcache, regnum, regs, regs + 31 * 8);
203 }
204 
205 /* Collect register REGNUM from the register cache REGCACHE and store
206  it in the buffer specified by FPREGS and LEN as described by the
207  general-purpose register set REGSET. If REGNUM is -1, do this for
208  all registers in REGSET. */
209 
210 static void
212  const struct regcache *regcache,
213  int regnum, void *fpregs, size_t len)
214 {
215  gdb_byte *regs = fpregs;
216 
217  gdb_assert (len >= 32 * 8);
218  alpha_fill_fp_regs (regcache, regnum, regs, regs + 31 * 8);
219 }
220 
221 static const struct regset alpha_linux_gregset =
222 {
223  NULL,
225 };
226 
227 static const struct regset alpha_linux_fpregset =
228 {
229  NULL,
231 };
232 
233 /* Iterate over core file register note sections. */
234 
235 static void
238  void *cb_data,
239  const struct regcache *regcache)
240 {
241  cb (".reg", 32 * 8, &alpha_linux_gregset, NULL, cb_data);
242  cb (".reg2", 32 * 8, &alpha_linux_fpregset, NULL, cb_data);
243 }
244 
245 /* Implementation of `gdbarch_gdb_signal_from_target', as defined in
246  gdbarch.h. */
247 
248 static enum gdb_signal
250  int signal)
251 {
252  switch (signal)
253  {
254  case ALPHA_LINUX_SIGEMT:
255  return GDB_SIGNAL_EMT;
256 
257  case ALPHA_LINUX_SIGBUS:
258  return GDB_SIGNAL_BUS;
259 
260  case ALPHA_LINUX_SIGSYS:
261  return GDB_SIGNAL_SYS;
262 
263  case ALPHA_LINUX_SIGURG:
264  return GDB_SIGNAL_URG;
265 
266  case ALPHA_LINUX_SIGSTOP:
267  return GDB_SIGNAL_STOP;
268 
269  case ALPHA_LINUX_SIGTSTP:
270  return GDB_SIGNAL_TSTP;
271 
272  case ALPHA_LINUX_SIGCONT:
273  return GDB_SIGNAL_CONT;
274 
275  case ALPHA_LINUX_SIGCHLD:
276  return GDB_SIGNAL_CHLD;
277 
278  /* No way to differentiate between SIGIO and SIGPOLL.
279  Therefore, we just handle the first one. */
280  case ALPHA_LINUX_SIGIO:
281  return GDB_SIGNAL_IO;
282 
283  /* No way to differentiate between SIGINFO and SIGPWR.
284  Therefore, we just handle the first one. */
285  case ALPHA_LINUX_SIGINFO:
286  return GDB_SIGNAL_INFO;
287 
288  case ALPHA_LINUX_SIGUSR1:
289  return GDB_SIGNAL_USR1;
290 
291  case ALPHA_LINUX_SIGUSR2:
292  return GDB_SIGNAL_USR2;
293  }
294 
295  return linux_gdb_signal_from_target (gdbarch, signal);
296 }
297 
298 /* Implementation of `gdbarch_gdb_signal_to_target', as defined in
299  gdbarch.h. */
300 
301 static int
303  enum gdb_signal signal)
304 {
305  switch (signal)
306  {
307  case GDB_SIGNAL_EMT:
308  return ALPHA_LINUX_SIGEMT;
309 
310  case GDB_SIGNAL_BUS:
311  return ALPHA_LINUX_SIGBUS;
312 
313  case GDB_SIGNAL_SYS:
314  return ALPHA_LINUX_SIGSYS;
315 
316  case GDB_SIGNAL_URG:
317  return ALPHA_LINUX_SIGURG;
318 
319  case GDB_SIGNAL_STOP:
320  return ALPHA_LINUX_SIGSTOP;
321 
322  case GDB_SIGNAL_TSTP:
323  return ALPHA_LINUX_SIGTSTP;
324 
325  case GDB_SIGNAL_CONT:
326  return ALPHA_LINUX_SIGCONT;
327 
328  case GDB_SIGNAL_CHLD:
329  return ALPHA_LINUX_SIGCHLD;
330 
331  case GDB_SIGNAL_IO:
332  return ALPHA_LINUX_SIGIO;
333 
334  case GDB_SIGNAL_INFO:
335  return ALPHA_LINUX_SIGINFO;
336 
337  case GDB_SIGNAL_USR1:
338  return ALPHA_LINUX_SIGUSR1;
339 
340  case GDB_SIGNAL_USR2:
341  return ALPHA_LINUX_SIGUSR2;
342 
343  case GDB_SIGNAL_POLL:
344  return ALPHA_LINUX_SIGPOLL;
345 
346  case GDB_SIGNAL_PWR:
347  return ALPHA_LINUX_SIGPWR;
348  }
349 
350  return linux_gdb_signal_to_target (gdbarch, signal);
351 }
352 
353 static void
355 {
356  struct gdbarch_tdep *tdep;
357 
358  linux_init_abi (info, gdbarch);
359 
360  /* Hook into the DWARF CFI frame unwinder. */
361  alpha_dwarf2_init_abi (info, gdbarch);
362 
363  /* Hook into the MDEBUG frame unwinder. */
364  alpha_mdebug_init_abi (info, gdbarch);
365 
366  tdep = gdbarch_tdep (gdbarch);
370  tdep->jb_pc = 2;
371  tdep->jb_elt_size = 8;
372 
374 
377 
378  /* Enable TLS support. */
381 
384 
389 }
390 
391 /* Provide a prototype to silence -Wmissing-prototypes. */
393 
394 void
396 {
397  gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_LINUX,
399 }
void alpha_mdebug_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
static void alpha_linux_iterate_over_regset_sections(struct gdbarch *gdbarch, iterate_over_regset_sections_cb *cb, void *cb_data, const struct regcache *regcache)
CORE_ADDR get_frame_pc(struct frame_info *frame)
Definition: frame.c:2217
void set_gdbarch_gdb_signal_to_target(struct gdbarch *gdbarch, gdbarch_gdb_signal_to_target_ftype gdb_signal_to_target)
Definition: gdbarch.c:3953
void alpha_supply_int_regs(struct regcache *regcache, int regno, const void *r0_r30, const void *pc, const void *unique)
Definition: alpha-tdep.c:1499
bfd_vma CORE_ADDR
Definition: common-types.h:41
void set_gdbarch_fetch_tls_load_module_address(struct gdbarch *gdbarch, gdbarch_fetch_tls_load_module_address_ftype fetch_tls_load_module_address)
Definition: gdbarch.c:2822
void alpha_fill_int_regs(const struct regcache *regcache, int regno, void *r0_r30, void *pc, void *unique)
Definition: alpha-tdep.c:1524
struct link_map_offsets * svr4_lp64_fetch_link_map_offsets(void)
Definition: solib-svr4.c:3180
LONGEST(* dynamic_sigtramp_offset)(struct gdbarch *, CORE_ADDR)
Definition: alpha-tdep.h:78
void set_gdbarch_skip_trampoline_code(struct gdbarch *gdbarch, gdbarch_skip_trampoline_code_ftype skip_trampoline_code)
Definition: gdbarch.c:3084
void alpha_dwarf2_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
Definition: alpha-tdep.c:1849
#define ALPHA_SP_REGNUM
Definition: alpha-tdep.h:45
struct m32c_reg * pc
Definition: m32c-tdep.c:111
unsigned int alpha_read_insn(struct gdbarch *gdbarch, CORE_ADDR pc)
Definition: alpha-tdep.c:681
void set_gdbarch_gdb_signal_from_target(struct gdbarch *gdbarch, gdbarch_gdb_signal_from_target_ftype gdb_signal_from_target)
Definition: gdbarch.c:3929
void linux_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
Definition: linux-tdep.c:2427
initialize_file_ftype _initialize_alpha_linux_tdep
static int alpha_linux_gdb_signal_to_target(struct gdbarch *gdbarch, enum gdb_signal signal)
CORE_ADDR(* sigcontext_addr)(struct frame_info *)
Definition: alpha-tdep.h:82
static long alpha_linux_sigtramp_offset_1(struct gdbarch *gdbarch, CORE_ADDR pc)
struct gdbarch_tdep * gdbarch_tdep(struct gdbarch *gdbarch)
Definition: gdbarch.c:1402
static CORE_ADDR alpha_linux_sigcontext_addr(struct frame_info *this_frame)
CORE_ADDR svr4_fetch_objfile_link_map(struct objfile *objfile)
Definition: solib-svr4.c:1573
Definition: regset.h:34
static enum gdb_signal alpha_linux_gdb_signal_from_target(struct gdbarch *gdbarch, int signal)
static int alpha_linux_pc_in_sigtramp(struct gdbarch *gdbarch, CORE_ADDR pc, const char *func_name)
static LONGEST alpha_linux_sigtramp_offset(struct gdbarch *gdbarch, CORE_ADDR pc)
enum gdb_signal linux_gdb_signal_from_target(struct gdbarch *gdbarch, int signal)
Definition: linux-tdep.c:2002
void initialize_file_ftype(void)
Definition: defs.h:281
void alpha_fill_fp_regs(const struct regcache *regcache, int regno, void *f0_f30, void *fpcr)
Definition: alpha-tdep.c:1558
CORE_ADDR find_solib_trampoline_target(struct frame_info *frame, CORE_ADDR pc)
Definition: minsyms.c:1394
static void alpha_linux_collect_fpregset(const struct regset *regset, const struct regcache *regcache, int regnum, void *fpregs, size_t len)
void set_solib_svr4_fetch_link_map_offsets(struct gdbarch *gdbarch, struct link_map_offsets *(*flmo)(void))
Definition: solib-svr4.c:3108
#define gdb_assert(expr)
Definition: gdb_assert.h:33
int regnum
Definition: aarch64-tdep.c:69
void( iterate_over_regset_sections_cb)(const char *sect_name, int size, const struct regset *regset, const char *human_name, void *cb_data)
Definition: gdbarch.h:98
ULONGEST get_frame_register_unsigned(struct frame_info *frame, int regnum)
Definition: frame.c:1194
static void alpha_linux_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
size_t jb_elt_size
Definition: aarch64-tdep.h:83
static void alpha_linux_collect_gregset(const struct regset *regset, const struct regcache *regcache, int regnum, void *gregs, size_t len)
bfd_byte gdb_byte
Definition: common-types.h:38
int(* pc_in_sigtramp)(struct gdbarch *gdbarch, CORE_ADDR pc, const char *name)
Definition: alpha-tdep.h:88
static void alpha_linux_supply_fpregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *fpregs, size_t len)
int linux_gdb_signal_to_target(struct gdbarch *gdbarch, enum gdb_signal signal)
Definition: linux-tdep.c:2125
unsigned long long ULONGEST
Definition: common-types.h:53
void alpha_supply_fp_regs(struct regcache *regcache, int regno, const void *f0_f30, const void *fpcr)
Definition: alpha-tdep.c:1542
void set_gdbarch_iterate_over_regset_sections(struct gdbarch *gdbarch, gdbarch_iterate_over_regset_sections_ftype iterate_over_regset_sections)
Definition: gdbarch.c:3398
static void alpha_linux_supply_gregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs, size_t len)
void gdbarch_register_osabi(enum bfd_architecture arch, unsigned long machine, enum gdb_osabi osabi, void(*init_osabi)(struct gdbarch_info, struct gdbarch *))
Definition: osabi.c:148
struct gdbarch * get_frame_arch(struct frame_info *this_frame)
Definition: frame.c:2535
long long LONGEST
Definition: common-types.h:52
const ULONGEST const LONGEST len
Definition: target.h:309