GDB (xrefs)
/tmp/gdb-8.1/gdb/sparc-nbsd-tdep.c
Go to the documentation of this file.
1 /* Target-dependent code for NetBSD/sparc.
2 
3  Copyright (C) 2002-2018 Free Software Foundation, Inc.
4  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 "gdbtypes.h"
26 #include "osabi.h"
27 #include "regcache.h"
28 #include "regset.h"
29 #include "solib-svr4.h"
30 #include "symtab.h"
31 #include "trad-frame.h"
32 
33 #include "sparc-tdep.h"
34 #include "nbsd-tdep.h"
35 
36 /* Macros to extract fields from SPARC instructions. */
37 #define X_RS1(i) (((i) >> 14) & 0x1f)
38 #define X_RS2(i) ((i) & 0x1f)
39 #define X_I(i) (((i) >> 13) & 1)
40 
42 {
43  0 * 4, /* %psr */
44  1 * 4, /* %pc */
45  2 * 4, /* %npc */
46  3 * 4, /* %y */
47  -1, /* %wim */
48  -1, /* %tbr */
49  5 * 4, /* %g1 */
50  -1 /* %l0 */
51 };
52 
53 static void
55  struct regcache *regcache,
56  int regnum, const void *gregs, size_t len)
57 {
59 
60  /* Traditional NetBSD core files don't use multiple register sets.
61  Instead, the general-purpose and floating-point registers are
62  lumped together in a single section. */
63  if (len >= 212)
65  (const char *) gregs + 80);
66 }
67 
68 static void
70  struct regcache *regcache,
71  int regnum, const void *fpregs, size_t len)
72 {
74 }
75 
76 
77 /* Signal trampolines. */
78 
79 /* The following variables describe the location of an on-stack signal
80  trampoline. The current values correspond to the memory layout for
81  NetBSD 1.3 and up. These shouldn't be necessary for NetBSD 2.0 and
82  up, since NetBSD uses signal trampolines provided by libc now. */
83 
84 static const CORE_ADDR sparc32nbsd_sigtramp_start = 0xeffffef0;
85 static const CORE_ADDR sparc32nbsd_sigtramp_end = 0xeffffff0;
86 
87 static int
89 {
91  return 1;
92 
93  return nbsd_pc_in_sigtramp (pc, name);
94 }
95 
96 struct trad_frame_saved_reg *
98 {
99  struct gdbarch *gdbarch = get_frame_arch (this_frame);
100  struct trad_frame_saved_reg *saved_regs;
101  CORE_ADDR addr, sigcontext_addr;
102  int regnum, delta;
103  ULONGEST psr;
104 
105  saved_regs = trad_frame_alloc_saved_regs (this_frame);
106 
107  /* We find the appropriate instance of `struct sigcontext' at a
108  fixed offset in the signal frame. */
110  sigcontext_addr = addr + 64 + 16;
111 
112  /* The registers are saved in bits and pieces scattered all over the
113  place. The code below records their location on the assumption
114  that the part of the signal trampoline that saves the state has
115  been executed. */
116 
117  saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8;
118  saved_regs[SPARC32_PC_REGNUM].addr = sigcontext_addr + 12;
119  saved_regs[SPARC32_NPC_REGNUM].addr = sigcontext_addr + 16;
120  saved_regs[SPARC32_PSR_REGNUM].addr = sigcontext_addr + 20;
121  saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 24;
122  saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 28;
123 
124  /* The remaining `global' registers and %y are saved in the `local'
125  registers. */
128  saved_regs[regnum].realreg = regnum + delta;
130 
131  /* The remaining `out' registers can be found in the current frame's
132  `in' registers. */
135  saved_regs[regnum].realreg = regnum + delta;
137 
138  /* The `local' and `in' registers have been saved in the register
139  save area. */
140  addr = saved_regs[SPARC_SP_REGNUM].addr;
141  addr = get_frame_memory_unsigned (this_frame, addr, 4);
142  for (regnum = SPARC_L0_REGNUM;
143  regnum <= SPARC_I7_REGNUM; regnum++, addr += 4)
144  saved_regs[regnum].addr = addr;
145 
146  /* Handle StackGhost. */
147  {
149 
150  if (wcookie != 0)
151  {
152  ULONGEST i7;
153 
154  addr = saved_regs[SPARC_I7_REGNUM].addr;
155  i7 = get_frame_memory_unsigned (this_frame, addr, 4);
156  trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie);
157  }
158  }
159 
160  /* The floating-point registers are only saved if the EF bit in %prs
161  has been set. */
162 
163 #define PSR_EF 0x00001000
164 
165  addr = saved_regs[SPARC32_PSR_REGNUM].addr;
166  psr = get_frame_memory_unsigned (this_frame, addr, 4);
167  if (psr & PSR_EF)
168  {
169  CORE_ADDR sp;
170 
171  sp = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
172  saved_regs[SPARC32_FSR_REGNUM].addr = sp + 96;
173  for (regnum = SPARC_F0_REGNUM, addr = sp + 96 + 8;
174  regnum <= SPARC_F31_REGNUM; regnum++, addr += 4)
175  saved_regs[regnum].addr = addr;
176  }
177 
178  return saved_regs;
179 }
180 
181 static struct sparc_frame_cache *
183  void **this_cache)
184 {
185  struct sparc_frame_cache *cache;
186  CORE_ADDR addr;
187 
188  if (*this_cache)
189  return (struct sparc_frame_cache *) *this_cache;
190 
191  cache = sparc_frame_cache (this_frame, this_cache);
192  gdb_assert (cache == *this_cache);
193 
194  /* If we couldn't find the frame's function, we're probably dealing
195  with an on-stack signal trampoline. */
196  if (cache->pc == 0)
197  {
199 
200  /* Since we couldn't find the frame's function, the cache was
201  initialized under the assumption that we're frameless. */
202  sparc_record_save_insn (cache);
203  addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
204  cache->base = addr;
205  }
206 
207  cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (this_frame);
208 
209  return cache;
210 }
211 
212 static void
214  void **this_cache,
215  struct frame_id *this_id)
216 {
217  struct sparc_frame_cache *cache =
218  sparc32nbsd_sigcontext_frame_cache (this_frame, this_cache);
219 
220  (*this_id) = frame_id_build (cache->base, cache->pc);
221 }
222 
223 static struct value *
225  void **this_cache, int regnum)
226 {
227  struct sparc_frame_cache *cache =
228  sparc32nbsd_sigcontext_frame_cache (this_frame, this_cache);
229 
230  return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
231 }
232 
233 static int
235  struct frame_info *this_frame,
236  void **this_cache)
237 {
238  CORE_ADDR pc = get_frame_pc (this_frame);
239  const char *name;
240 
241  find_pc_partial_function (pc, &name, NULL, NULL);
243  {
244  if (name == NULL || !startswith (name, "__sigtramp_sigcontext"))
245  return 1;
246  }
247 
248  return 0;
249 }
250 
252 {
257  NULL,
259 };
260 
261 /* Return the address of a system call's alternative return
262  address. */
263 
264 CORE_ADDR
265 sparcnbsd_step_trap (struct frame_info *frame, unsigned long insn)
266 {
267  if ((X_I (insn) == 0 && X_RS1 (insn) == 0 && X_RS2 (insn) == 0)
268  || (X_I (insn) == 1 && X_RS1 (insn) == 0 && (insn & 0x7f) == 0))
269  {
270  /* "New" system call. */
272 
273  if (number & 0x400)
275  if (number & 0x800)
277  }
278 
279  return 0;
280 }
281 
282 
283 static const struct regset sparc32nbsd_gregset =
284  {
285  NULL, sparc32nbsd_supply_gregset, NULL
286  };
287 
288 static const struct regset sparc32nbsd_fpregset =
289  {
290  NULL, sparc32nbsd_supply_fpregset, NULL
291  };
292 
293 void
295 {
296  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
297 
298  /* NetBSD doesn't support the 128-bit `long double' from the psABI. */
301 
302  tdep->gregset = &sparc32nbsd_gregset;
303  tdep->sizeof_gregset = 20 * 4;
304 
306  tdep->sizeof_fpregset = 33 * 4;
307 
308  /* Make sure we can single-step "new" syscalls. */
310 
312 
315 }
316 
317 void
319 {
320  gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_NETBSD,
322 }
struct frame_id frame_id_build(CORE_ADDR stack_addr, CORE_ADDR code_addr)
Definition: frame.c:624
CORE_ADDR get_frame_pc(struct frame_info *frame)
Definition: frame.c:2376
bfd_vma CORE_ADDR
Definition: common-types.h:41
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:142
const struct floatformat * floatformats_ieee_double[BFD_ENDIAN_UNKNOWN]
Definition: gdbtypes.c:76
void sparc32_supply_gregset(const struct sparc_gregmap *gregmap, struct regcache *regcache, int regnum, const void *gregs)
Definition: sparc-tdep.c:2069
void sparc_record_save_insn(struct sparc_frame_cache *cache)
Definition: sparc-tdep.c:942
void trad_frame_set_value(struct trad_frame_saved_reg this_saved_regs[], int regnum, LONGEST val)
Definition: trad-frame.c:99
const struct regset * gregset
Definition: sparc-tdep.h:73
static const struct regset sparc32nbsd_gregset
int nbsd_pc_in_sigtramp(CORE_ADDR pc, const char *func_name)
Definition: nbsd-tdep.c:42
#define PSR_EF
struct sparc_frame_cache * sparc_frame_cache(struct frame_info *this_frame, void **this_cache)
Definition: sparc-tdep.c:1174
static const CORE_ADDR sparc32nbsd_sigtramp_start
struct link_map_offsets * svr4_ilp32_fetch_link_map_offsets(void)
Definition: solib-svr4.c:3183
CORE_ADDR(* step_trap)(struct frame_info *frame, unsigned long insn)
Definition: sparc-tdep.h:86
static void sparc32nbsd_supply_gregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs, size_t len)
size_t sizeof_fpregset
Definition: i386-tdep.h:66
ULONGEST get_frame_memory_unsigned(struct frame_info *this_frame, CORE_ADDR addr, int len)
Definition: frame.c:2671
static int sparc32nbsd_sigcontext_frame_sniffer(const struct frame_unwind *self, struct frame_info *this_frame, void **this_cache)
struct gdbarch_tdep * gdbarch_tdep(struct gdbarch *gdbarch)
Definition: gdbarch.c:1491
void frame_unwind_append_unwinder(struct gdbarch *gdbarch, const struct frame_unwind *unwinder)
Definition: frame-unwind.c:79
static const CORE_ADDR sparc32nbsd_sigtramp_end
void sparc32nbsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
struct trad_frame_saved_reg * saved_regs
Definition: sparc-tdep.h:189
ULONGEST sparc_fetch_wcookie(struct gdbarch *gdbarch)
Definition: sparc-tdep.c:189
Definition: regset.h:34
const struct sparc_gregmap sparc32nbsd_gregmap
#define X_RS1(i)
const char *const name
Definition: aarch64-tdep.c:76
static const struct regset sparc32nbsd_fpregset
#define X_I(i)
void _initialize_sparcnbsd_tdep(void)
CORE_ADDR base
Definition: sparc-tdep.h:170
static struct value * sparc32nbsd_sigcontext_frame_prev_register(struct frame_info *this_frame, void **this_cache, int regnum)
void set_solib_svr4_fetch_link_map_offsets(struct gdbarch *gdbarch, struct link_map_offsets *(*flmo)(void))
Definition: solib-svr4.c:3137
static void sparc32nbsd_supply_fpregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *fpregs, size_t len)
int find_pc_partial_function(CORE_ADDR pc, const char **name, CORE_ADDR *address, CORE_ADDR *endaddr)
Definition: blockframe.c:320
void sparc32_supply_fpregset(const struct sparc_fpregmap *fpregmap, struct regcache *regcache, int regnum, const void *fpregs)
Definition: sparc-tdep.c:2189
static int startswith(const char *string, const char *pattern)
Definition: common-utils.h:107
CORE_ADDR sparcnbsd_step_trap(struct frame_info *frame, unsigned long insn)
int regnum
Definition: aarch64-tdep.c:77
ULONGEST get_frame_register_unsigned(struct frame_info *frame, int regnum)
Definition: frame.c:1308
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:143
struct trad_frame_saved_reg * trad_frame_alloc_saved_regs(struct gdbarch *gdbarch)
Definition: trad-frame.c:47
#define gdb_assert(expr)
Definition: gdb_assert.h:32
Definition: value.c:169
static const struct frame_unwind sparc32nbsd_sigcontext_frame_unwind
const struct sparc_fpregmap sparc32_bsd_fpregmap
Definition: sparc-tdep.c:2250
static int sparc32nbsd_pc_in_sigtramp(CORE_ADDR pc, const char *name)
size_t sizeof_gregset
Definition: i386-tdep.h:63
static void sparc32nbsd_sigcontext_frame_this_id(struct frame_info *this_frame, void **this_cache, struct frame_id *this_id)
static struct sparc_frame_cache * sparc32nbsd_sigcontext_frame_cache(struct frame_info *this_frame, void **this_cache)
const struct regset * fpregset
Definition: i386-tdep.h:253
#define X_RS2(i)
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:184
void set_gdbarch_long_double_bit(struct gdbarch *gdbarch, int long_double_bit)
Definition: gdbarch.c:1756
void set_gdbarch_long_double_format(struct gdbarch *gdbarch, const struct floatformat **long_double_format)
Definition: gdbarch.c:1772
struct gdbarch * get_frame_arch(struct frame_info *this_frame)
Definition: frame.c:2691
struct trad_frame_saved_reg * sparc32nbsd_sigcontext_saved_regs(struct frame_info *this_frame)