GDB (xrefs)
/tmp/gdb-7.10/gdb/sparc64nbsd-tdep.c
Go to the documentation of this file.
1 /* Target-dependent code for NetBSD/sparc64.
2 
3  Copyright (C) 2002-2015 Free Software Foundation, Inc.
4  Based on code contributed by Wasabi Systems, Inc.
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 #include "frame.h"
23 #include "frame-unwind.h"
24 #include "gdbcore.h"
25 #include "osabi.h"
26 #include "regcache.h"
27 #include "regset.h"
28 #include "symtab.h"
29 #include "objfiles.h"
30 #include "solib-svr4.h"
31 #include "trad-frame.h"
32 
33 #include "sparc64-tdep.h"
34 #include "nbsd-tdep.h"
35 
36 /* From <machine/reg.h>. */
37 const struct sparc_gregmap sparc64nbsd_gregmap =
38 {
39  0 * 8, /* "tstate" */
40  1 * 8, /* %pc */
41  2 * 8, /* %npc */
42  3 * 8, /* %y */
43  -1, /* %fprs */
44  -1,
45  5 * 8, /* %g1 */
46  -1, /* %l0 */
47  4 /* sizeof (%y) */
48 };
49 
50 
51 static void
53  struct regcache *regcache,
54  int regnum, const void *gregs, size_t len)
55 {
56  sparc64_supply_gregset (&sparc64nbsd_gregmap, regcache, regnum, gregs);
57 }
58 
59 static void
61  struct regcache *regcache,
62  int regnum, const void *fpregs, size_t len)
63 {
64  sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
65 }
66 
67 
68 /* Signal trampolines. */
69 
70 /* The following variables describe the location of an on-stack signal
71  trampoline. The current values correspond to the memory layout for
72  NetBSD 1.3 and up. These shouldn't be necessary for NetBSD 2.0 and
73  up, since NetBSD uses signal trampolines provided by libc now. */
74 
75 static const CORE_ADDR sparc64nbsd_sigtramp_start = 0xffffffffffffdee4ULL;
76 static const CORE_ADDR sparc64nbsd_sigtramp_end = 0xffffffffffffe000ULL;
77 
78 static int
80 {
82  return 1;
83 
84  return nbsd_pc_in_sigtramp (pc, name);
85 }
86 
87 struct trad_frame_saved_reg *
89  struct frame_info *this_frame)
90 {
91  struct gdbarch *gdbarch = get_frame_arch (this_frame);
92  struct trad_frame_saved_reg *saved_regs;
93  CORE_ADDR addr, sp;
94  int regnum, delta;
95 
96  saved_regs = trad_frame_alloc_saved_regs (this_frame);
97 
98  /* The registers are saved in bits and pieces scattered all over the
99  place. The code below records their location on the assumption
100  that the part of the signal trampoline that saves the state has
101  been executed. */
102 
103  saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8;
104  saved_regs[SPARC64_PC_REGNUM].addr = sigcontext_addr + 16;
105  saved_regs[SPARC64_NPC_REGNUM].addr = sigcontext_addr + 24;
106  saved_regs[SPARC64_STATE_REGNUM].addr = sigcontext_addr + 32;
107  saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 40;
108  saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 48;
109 
110  /* The remaining `global' registers and %y are saved in the `local'
111  registers. */
113  for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
114  saved_regs[regnum].realreg = regnum + delta;
116 
117  /* The remaining `out' registers can be found in the current frame's
118  `in' registers. */
120  for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
121  saved_regs[regnum].realreg = regnum + delta;
123 
124  /* The `local' and `in' registers have been saved in the register
125  save area. */
126  addr = saved_regs[SPARC_SP_REGNUM].addr;
127  sp = get_frame_memory_unsigned (this_frame, addr, 8);
128  for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS;
129  regnum <= SPARC_I7_REGNUM; regnum++, addr += 8)
130  saved_regs[regnum].addr = addr;
131 
132  /* Handle StackGhost. */
133  {
134  ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
135 
136  if (wcookie != 0)
137  {
138  ULONGEST i7;
139 
140  addr = saved_regs[SPARC_I7_REGNUM].addr;
141  i7 = get_frame_memory_unsigned (this_frame, addr, 8);
142  trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie);
143  }
144  }
145 
146  /* TODO: Handle the floating-point registers. */
147 
148  return saved_regs;
149 }
150 
151 static struct sparc_frame_cache *
153  void **this_cache)
154 {
155  struct sparc_frame_cache *cache;
156  CORE_ADDR addr;
157 
158  if (*this_cache)
159  return *this_cache;
160 
161  cache = sparc_frame_cache (this_frame, this_cache);
162  gdb_assert (cache == *this_cache);
163 
164  /* If we couldn't find the frame's function, we're probably dealing
165  with an on-stack signal trampoline. */
166  if (cache->pc == 0)
167  {
169 
170  /* Since we couldn't find the frame's function, the cache was
171  initialized under the assumption that we're frameless. */
172  sparc_record_save_insn (cache);
173  addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
174  if (addr & 1)
175  addr += BIAS;
176  cache->base = addr;
177  }
178 
179  /* We find the appropriate instance of `struct sigcontext' at a
180  fixed offset in the signal frame. */
181  addr = cache->base + 128 + 8;
182  cache->saved_regs = sparc64nbsd_sigcontext_saved_regs (addr, this_frame);
183 
184  return cache;
185 }
186 
187 static void
189  void **this_cache,
190  struct frame_id *this_id)
191 {
192  struct sparc_frame_cache *cache =
193  sparc64nbsd_sigcontext_frame_cache (this_frame, this_cache);
194 
195  (*this_id) = frame_id_build (cache->base, cache->pc);
196 }
197 
198 static struct value *
200  void **this_cache, int regnum)
201 {
202  struct sparc_frame_cache *cache =
203  sparc64nbsd_sigcontext_frame_cache (this_frame, this_cache);
204 
205  return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
206 }
207 
208 static int
210  struct frame_info *this_frame,
211  void **this_cache)
212 {
213  CORE_ADDR pc = get_frame_pc (this_frame);
214  const char *name;
215 
216  find_pc_partial_function (pc, &name, NULL, NULL);
217  if (sparc64nbsd_pc_in_sigtramp (pc, name))
218  {
219  if (name == NULL || !startswith (name, "__sigtramp_sigcontext"))
220  return 1;
221  }
222 
223  return 0;
224 }
225 
226 static const struct frame_unwind sparc64nbsd_sigcontext_frame_unwind =
227 {
232  NULL,
234 };
235 
236 
237 static const struct regset sparc64nbsd_gregset =
238  {
239  NULL, sparc64nbsd_supply_gregset, NULL
240  };
241 
242 static const struct regset sparc64nbsd_fpregset =
243  {
244  NULL, sparc64nbsd_supply_fpregset, NULL
245  };
246 
247 static void
249 {
250  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
251 
252  tdep->gregset = &sparc64nbsd_gregset;
253  tdep->sizeof_gregset = 160;
254 
256  tdep->sizeof_fpregset = 272;
257 
258  /* Make sure we can single-step "new" syscalls. */
260 
261  frame_unwind_append_unwinder (gdbarch, &sparc64nbsd_sigcontext_frame_unwind);
262 
263  sparc64_init_abi (info, gdbarch);
264 
265  /* NetBSD/sparc64 has SVR4-style shared libraries. */
269 }
270 
271 
272 /* Provide a prototype to silence -Wmissing-prototypes. */
273 void _initialize_sparc64nbsd_tdep (void);
274 
275 void
277 {
278  gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
280 }
void sparc64_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
struct frame_id frame_id_build(CORE_ADDR stack_addr, CORE_ADDR code_addr)
Definition: frame.c:554
static const struct regset sparc64nbsd_gregset
CORE_ADDR get_frame_pc(struct frame_info *frame)
Definition: frame.c:2217
bfd_vma CORE_ADDR
Definition: common-types.h:41
struct link_map_offsets * svr4_lp64_fetch_link_map_offsets(void)
Definition: solib-svr4.c:3180
struct value * trad_frame_get_prev_register(struct frame_info *this_frame, struct trad_frame_saved_reg this_saved_regs[], int regnum)
Definition: trad-frame.c:135
void sparc_record_save_insn(struct sparc_frame_cache *cache)
Definition: sparc-tdep.c:866
void set_gdbarch_skip_trampoline_code(struct gdbarch *gdbarch, gdbarch_skip_trampoline_code_ftype skip_trampoline_code)
Definition: gdbarch.c:3084
void trad_frame_set_value(struct trad_frame_saved_reg this_saved_regs[], int regnum, LONGEST val)
Definition: trad-frame.c:92
const struct regset * gregset
Definition: sparc-tdep.h:61
int nbsd_pc_in_sigtramp(CORE_ADDR pc, const char *func_name)
Definition: nbsd-tdep.c:42
struct sparc_frame_cache * sparc_frame_cache(struct frame_info *this_frame, void **this_cache)
Definition: sparc-tdep.c:1098
#define BIAS
Definition: sparc-tdep.c:70
static void sparc64nbsd_supply_gregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs, size_t len)
CORE_ADDR(* step_trap)(struct frame_info *frame, unsigned long insn)
Definition: sparc-tdep.h:74
size_t sizeof_fpregset
Definition: i386-tdep.h:64
ULONGEST get_frame_memory_unsigned(struct frame_info *this_frame, CORE_ADDR addr, int len)
Definition: frame.c:2515
void sparc64_supply_gregset(const struct sparc_gregmap *gregmap, struct regcache *regcache, int regnum, const void *gregs)
struct gdbarch_tdep * gdbarch_tdep(struct gdbarch *gdbarch)
Definition: gdbarch.c:1402
static void sparc64nbsd_sigcontext_frame_this_id(struct frame_info *this_frame, void **this_cache, struct frame_id *this_id)
void frame_unwind_append_unwinder(struct gdbarch *gdbarch, const struct frame_unwind *unwinder)
Definition: frame-unwind.c:78
struct trad_frame_saved_reg * saved_regs
Definition: sparc-tdep.h:173
static void sparc64nbsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
ULONGEST sparc_fetch_wcookie(struct gdbarch *gdbarch)
Definition: sparc-tdep.c:187
Definition: regset.h:34
const struct sparc_fpregmap sparc64_bsd_fpregmap
const char *const name
Definition: aarch64-tdep.c:68
static struct sparc_frame_cache * sparc64nbsd_sigcontext_frame_cache(struct frame_info *this_frame, void **this_cache)
static void sparc64nbsd_supply_fpregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *fpregs, size_t len)
CORE_ADDR find_solib_trampoline_target(struct frame_info *frame, CORE_ADDR pc)
Definition: minsyms.c:1394
CORE_ADDR base
Definition: sparc-tdep.h:154
void sparc64_supply_fpregset(const struct sparc_fpregmap *fpregmap, struct regcache *regcache, int regnum, const void *fpregs)
void set_solib_svr4_fetch_link_map_offsets(struct gdbarch *gdbarch, struct link_map_offsets *(*flmo)(void))
Definition: solib-svr4.c:3108
int find_pc_partial_function(CORE_ADDR pc, const char **name, CORE_ADDR *address, CORE_ADDR *endaddr)
Definition: blockframe.c:321
static int sparc64nbsd_pc_in_sigtramp(CORE_ADDR pc, const char *name)
#define gdb_assert(expr)
Definition: gdb_assert.h:33
static int startswith(const char *string, const char *pattern)
Definition: common-utils.h:75
int regnum
Definition: aarch64-tdep.c:69
ULONGEST get_frame_register_unsigned(struct frame_info *frame, int regnum)
Definition: frame.c:1194
static const CORE_ADDR sparc64nbsd_sigtramp_end
Definition: value.c:172
struct trad_frame_saved_reg * trad_frame_alloc_saved_regs(struct frame_info *this_frame)
Definition: trad-frame.c:52
size_t sizeof_gregset
Definition: i386-tdep.h:61
static struct value * sparc64nbsd_sigcontext_frame_prev_register(struct frame_info *this_frame, void **this_cache, int regnum)
void _initialize_sparc64nbsd_tdep(void)
static const CORE_ADDR sparc64nbsd_sigtramp_start
const struct regset * fpregset
Definition: i386-tdep.h:242
unsigned long long ULONGEST
Definition: common-types.h:53
enum unwind_stop_reason default_frame_unwind_stop_reason(struct frame_info *this_frame, void **this_cache)
Definition: frame-unwind.c:180
static int sparc64nbsd_sigtramp_frame_sniffer(const struct frame_unwind *self, struct frame_info *this_frame, void **this_cache)
struct trad_frame_saved_reg * sparc64nbsd_sigcontext_saved_regs(CORE_ADDR sigcontext_addr, struct frame_info *this_frame)
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
static const struct regset sparc64nbsd_fpregset
struct gdbarch * get_frame_arch(struct frame_info *this_frame)
Definition: frame.c:2535
CORE_ADDR sparcnbsd_step_trap(struct frame_info *frame, unsigned long insn)
const ULONGEST const LONGEST len
Definition: target.h:309