GDB (xrefs)
/tmp/gdb-8.1/gdb/sparc64-obsd-tdep.c
Go to the documentation of this file.
1 /* Target-dependent code for OpenBSD/sparc64.
2 
3  Copyright (C) 2004-2018 Free Software Foundation, Inc.
4 
5  This file is part of GDB.
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 
20 #include "defs.h"
21 #include "frame.h"
22 #include "frame-unwind.h"
23 #include "gdbcore.h"
24 #include "osabi.h"
25 #include "regcache.h"
26 #include "regset.h"
27 #include "symtab.h"
28 #include "objfiles.h"
29 #include "trad-frame.h"
30 
31 #include "obsd-tdep.h"
32 #include "sparc64-tdep.h"
33 #include "solib-svr4.h"
34 #include "bsd-uthread.h"
35 
36 /* Older OpenBSD versions used the traditional NetBSD core file
37  format, even for ports that use ELF. These core files don't use
38  multiple register sets. Instead, the general-purpose and
39  floating-point registers are lumped together in a single section.
40  Unlike on NetBSD, OpenBSD uses a different layout for its
41  general-purpose registers than the layout used for ptrace(2).
42 
43  Newer OpenBSD versions use ELF core files. Here the register sets
44  match the ptrace(2) layout. */
45 
46 /* From <machine/reg.h>. */
48 {
49  0 * 8, /* "tstate" */
50  1 * 8, /* %pc */
51  2 * 8, /* %npc */
52  3 * 8, /* %y */
53  -1, /* %fprs */
54  -1,
55  5 * 8, /* %g1 */
56  20 * 8, /* %l0 */
57  4 /* sizeof (%y) */
58 };
59 
61 {
62  0 * 8, /* "tstate" */
63  1 * 8, /* %pc */
64  2 * 8, /* %npc */
65  3 * 8, /* %y */
66  -1, /* %fprs */
67  -1,
68  7 * 8, /* %g1 */
69  22 * 8, /* %l0 */
70  4 /* sizeof (%y) */
71 };
72 
73 static void
75  struct regcache *regcache,
76  int regnum, const void *gregs, size_t len)
77 {
78  const void *fpregs = (char *)gregs + 288;
79 
80  if (len < 832)
81  {
83  return;
84  }
85 
88 }
89 
90 static void
92  struct regcache *regcache,
93  int regnum, const void *fpregs, size_t len)
94 {
96 }
97 
98 
99 /* Signal trampolines. */
100 
101 /* Since OpenBSD 3.2, the sigtramp routine is mapped at a random page
102  in virtual memory. The randomness makes it somewhat tricky to
103  detect it, but fortunately we can rely on the fact that the start
104  of the sigtramp routine is page-aligned. We recognize the
105  trampoline by looking for the code that invokes the sigreturn
106  system call. The offset where we can find that code varies from
107  release to release.
108 
109  By the way, the mapping mentioned above is read-only, so you cannot
110  place a breakpoint in the signal trampoline. */
111 
112 /* Default page size. */
113 static const int sparc64obsd_page_size = 8192;
114 
115 /* Offset for sigreturn(2). */
116 static const int sparc64obsd_sigreturn_offset[] = {
117  0xf0, /* OpenBSD 3.8 */
118  0xec, /* OpenBSD 3.6 */
119  0xe8, /* OpenBSD 3.2 */
120  -1
121 };
122 
123 static int
125 {
126  CORE_ADDR start_pc = (pc & ~(sparc64obsd_page_size - 1));
127  unsigned long insn;
128  const int *offset;
129 
130  if (name)
131  return 0;
132 
134  {
135  /* Check for "restore %g0, SYS_sigreturn, %g1". */
136  insn = sparc_fetch_instruction (start_pc + *offset);
137  if (insn != 0x83e82067)
138  continue;
139 
140  /* Check for "t ST_SYSCALL". */
141  insn = sparc_fetch_instruction (start_pc + *offset + 8);
142  if (insn != 0x91d02000)
143  continue;
144 
145  return 1;
146  }
147 
148  return 0;
149 }
150 
151 static struct sparc_frame_cache *
152 sparc64obsd_frame_cache (struct frame_info *this_frame, void **this_cache)
153 {
154  struct sparc_frame_cache *cache;
155  CORE_ADDR addr;
156 
157  if (*this_cache)
158  return (struct sparc_frame_cache *) *this_cache;
159 
160  cache = sparc_frame_cache (this_frame, this_cache);
161  gdb_assert (cache == *this_cache);
162 
163  /* If we couldn't find the frame's function, we're probably dealing
164  with an on-stack signal trampoline. */
165  if (cache->pc == 0)
166  {
167  cache->pc = get_frame_pc (this_frame);
168  cache->pc &= ~(sparc64obsd_page_size - 1);
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 + 16;
182  cache->saved_regs = sparc64nbsd_sigcontext_saved_regs (addr, this_frame);
183 
184  return cache;
185 }
186 
187 static void
188 sparc64obsd_frame_this_id (struct frame_info *this_frame, void **this_cache,
189  struct frame_id *this_id)
190 {
191  struct sparc_frame_cache *cache =
192  sparc64obsd_frame_cache (this_frame, this_cache);
193 
194  (*this_id) = frame_id_build (cache->base, cache->pc);
195 }
196 
197 static struct value *
199  void **this_cache, int regnum)
200 {
201  struct sparc_frame_cache *cache =
202  sparc64obsd_frame_cache (this_frame, this_cache);
203 
204  return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
205 }
206 
207 static int
209  struct frame_info *this_frame,
210  void **this_cache)
211 {
212  CORE_ADDR pc = get_frame_pc (this_frame);
213  const char *name;
214 
215  find_pc_partial_function (pc, &name, NULL, NULL);
217  return 1;
218 
219  return 0;
220 }
221 
223 {
228  NULL,
230 };
231 
232 /* Kernel debugging support. */
233 
234 static struct sparc_frame_cache *
235 sparc64obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
236 {
237  struct sparc_frame_cache *cache;
238  CORE_ADDR sp, trapframe_addr;
239  int regnum;
240 
241  if (*this_cache)
242  return (struct sparc_frame_cache *) *this_cache;
243 
244  cache = sparc_frame_cache (this_frame, this_cache);
245  gdb_assert (cache == *this_cache);
246 
247  sp = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
248  trapframe_addr = sp + BIAS + 176;
249 
250  cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
251 
252  cache->saved_regs[SPARC64_STATE_REGNUM].addr = trapframe_addr;
253  cache->saved_regs[SPARC64_PC_REGNUM].addr = trapframe_addr + 8;
254  cache->saved_regs[SPARC64_NPC_REGNUM].addr = trapframe_addr + 16;
255 
257  cache->saved_regs[regnum].addr =
258  trapframe_addr + 48 + (regnum - SPARC_G0_REGNUM) * 8;
259 
260  return cache;
261 }
262 
263 static void
265  void **this_cache, struct frame_id *this_id)
266 {
267  struct sparc_frame_cache *cache =
268  sparc64obsd_trapframe_cache (this_frame, this_cache);
269 
270  (*this_id) = frame_id_build (cache->base, cache->pc);
271 }
272 
273 static struct value *
275  void **this_cache, int regnum)
276 {
277  struct sparc_frame_cache *cache =
278  sparc64obsd_trapframe_cache (this_frame, this_cache);
279 
280  return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
281 }
282 
283 static int
285  struct frame_info *this_frame,
286  void **this_cache)
287 {
288  CORE_ADDR pc;
290  const char *name;
291 
292  /* Check whether we are in privileged mode, and bail out if we're not. */
294  if ((pstate & SPARC64_PSTATE_PRIV) == 0)
295  return 0;
296 
297  pc = get_frame_address_in_block (this_frame);
298  find_pc_partial_function (pc, &name, NULL, NULL);
299  if (name && strcmp (name, "Lslowtrap_reenter") == 0)
300  return 1;
301 
302  return 0;
303 }
304 
306 {
307  NORMAL_FRAME,
311  NULL,
313 };
314 
315 
316 /* Threads support. */
317 
318 /* Offset wthin the thread structure where we can find %fp and %i7. */
319 #define SPARC64OBSD_UTHREAD_FP_OFFSET 232
320 #define SPARC64OBSD_UTHREAD_PC_OFFSET 240
321 
322 static void
324  int regnum, CORE_ADDR addr)
325 {
326  struct gdbarch *gdbarch = regcache->arch ();
327  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
328  CORE_ADDR fp, fp_addr = addr + SPARC64OBSD_UTHREAD_FP_OFFSET;
329  gdb_byte buf[8];
330 
331  gdb_assert (regnum >= -1);
332 
333  fp = read_memory_unsigned_integer (fp_addr, 8, byte_order);
334  if (regnum == SPARC_SP_REGNUM || regnum == -1)
335  {
336  store_unsigned_integer (buf, 8, byte_order, fp);
338 
339  if (regnum == SPARC_SP_REGNUM)
340  return;
341  }
342 
344  || regnum == -1)
345  {
346  CORE_ADDR i7, i7_addr = addr + SPARC64OBSD_UTHREAD_PC_OFFSET;
347 
348  i7 = read_memory_unsigned_integer (i7_addr, 8, byte_order);
349  if (regnum == SPARC64_PC_REGNUM || regnum == -1)
350  {
351  store_unsigned_integer (buf, 8, byte_order, i7 + 8);
353  }
354  if (regnum == SPARC64_NPC_REGNUM || regnum == -1)
355  {
356  store_unsigned_integer (buf, 8, byte_order, i7 + 12);
358  }
359 
361  return;
362  }
363 
365 }
366 
367 static void
369  int regnum, CORE_ADDR addr)
370 {
371  struct gdbarch *gdbarch = regcache->arch ();
372  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
373  CORE_ADDR sp;
374  gdb_byte buf[8];
375 
376  gdb_assert (regnum >= -1);
377 
378  if (regnum == SPARC_SP_REGNUM || regnum == -1)
379  {
380  CORE_ADDR fp_addr = addr + SPARC64OBSD_UTHREAD_FP_OFFSET;
381 
383  write_memory (fp_addr,buf, 8);
384  }
385 
386  if (regnum == SPARC64_PC_REGNUM || regnum == -1)
387  {
388  CORE_ADDR i7, i7_addr = addr + SPARC64OBSD_UTHREAD_PC_OFFSET;
389 
391  i7 = extract_unsigned_integer (buf, 8, byte_order) - 8;
392  write_memory_unsigned_integer (i7_addr, 8, byte_order, i7);
393 
394  if (regnum == SPARC64_PC_REGNUM)
395  return;
396  }
397 
399  sp = extract_unsigned_integer (buf, 8, byte_order);
401 }
402 
403 
404 static const struct regset sparc64obsd_gregset =
405  {
406  NULL, sparc64obsd_supply_gregset, NULL
407  };
408 
409 static const struct regset sparc64obsd_fpregset =
410  {
411  NULL, sparc64obsd_supply_fpregset, NULL
412  };
413 
414 static void
416 {
417  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
418 
419  tdep->gregset = &sparc64obsd_gregset;
420  tdep->sizeof_gregset = 288;
422  tdep->sizeof_fpregset = 272;
423 
424  /* Make sure we can single-step "new" syscalls. */
426 
429 
430  sparc64_init_abi (info, gdbarch);
431  obsd_init_abi (info, gdbarch);
432 
433  /* OpenBSD/sparc64 has SVR4-style shared libraries. */
437 
438  /* OpenBSD provides a user-level threads implementation. */
441 }
442 
443 void
445 {
446  gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
448 }
static const struct frame_unwind sparc64obsd_frame_unwind
void sparc64_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
static const struct regset sparc64obsd_gregset
struct frame_id frame_id_build(CORE_ADDR stack_addr, CORE_ADDR code_addr)
Definition: frame.c:624
CORE_ADDR get_frame_address_in_block(struct frame_info *this_frame)
Definition: frame.c:2407
static const struct regset sparc64obsd_fpregset
static void sparc64obsd_frame_this_id(struct frame_info *this_frame, void **this_cache, struct frame_id *this_id)
CORE_ADDR get_frame_pc(struct frame_info *frame)
Definition: frame.c:2376
bfd_vma CORE_ADDR
Definition: common-types.h:41
struct link_map_offsets * svr4_lp64_fetch_link_map_offsets(void)
Definition: solib-svr4.c:3214
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
void sparc_record_save_insn(struct sparc_frame_cache *cache)
Definition: sparc-tdep.c:942
void write_memory_unsigned_integer(CORE_ADDR addr, int len, enum bfd_endian byte_order, ULONGEST value)
Definition: corefile.c:417
static int sparc64obsd_sigtramp_frame_sniffer(const struct frame_unwind *self, struct frame_info *this_frame, void **this_cache)
const struct regset * gregset
Definition: sparc-tdep.h:73
struct sparc_frame_cache * sparc_frame_cache(struct frame_info *this_frame, void **this_cache)
Definition: sparc-tdep.c:1174
#define BIAS
Definition: sparc-tdep.c:72
static struct sparc_frame_cache * sparc64obsd_frame_cache(struct frame_info *this_frame, void **this_cache)
CORE_ADDR(* step_trap)(struct frame_info *frame, unsigned long insn)
Definition: sparc-tdep.h:86
static void sparc64obsd_supply_fpregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *fpregs, size_t len)
void bsd_uthread_set_collect_uthread(struct gdbarch *gdbarch, void(*collect_uthread)(const struct regcache *, int, CORE_ADDR))
Definition: bsd-uthread.c:81
size_t sizeof_fpregset
Definition: i386-tdep.h:66
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:1491
void sparc_supply_rwindow(struct regcache *regcache, CORE_ADDR sp, int regnum)
Definition: sparc-tdep.c:1925
void obsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
Definition: obsd-tdep.c:319
void frame_unwind_append_unwinder(struct gdbarch *gdbarch, const struct frame_unwind *unwinder)
Definition: frame-unwind.c:79
#define SPARC64_PSTATE_PRIV
Definition: sparc64-tdep.h:91
static void sparc64obsd_trapframe_this_id(struct frame_info *this_frame, void **this_cache, struct frame_id *this_id)
struct trad_frame_saved_reg * sparc64nbsd_sigcontext_saved_regs(CORE_ADDR sigcontext_addr, struct frame_info *this_frame)
struct trad_frame_saved_reg * saved_regs
Definition: sparc-tdep.h:189
const struct sparc_gregmap sparc64obsd_gregmap
static const int sparc64obsd_sigreturn_offset[]
Definition: regset.h:34
const struct sparc_fpregmap sparc64_bsd_fpregmap
const char *const name
Definition: aarch64-tdep.c:76
static const struct frame_unwind sparc64obsd_trapframe_unwind
static const int sparc64obsd_page_size
static struct parser_state * pstate
Definition: ada-exp.c:98
unsigned long sparc_fetch_instruction(CORE_ADDR pc)
Definition: sparc-tdep.c:98
void sparc_collect_rwindow(const struct regcache *regcache, CORE_ADDR sp, int regnum)
Definition: sparc-tdep.c:1998
static ULONGEST extract_unsigned_integer(const gdb_byte *addr, int len, enum bfd_endian byte_order)
Definition: defs.h:577
static struct sparc_frame_cache * sparc64obsd_trapframe_cache(struct frame_info *this_frame, void **this_cache)
CORE_ADDR base
Definition: sparc-tdep.h:170
void sparc64_supply_fpregset(const struct sparc_fpregmap *fpregmap, struct regcache *regcache, int regnum, const void *fpregs)
enum bfd_endian gdbarch_byte_order(struct gdbarch *gdbarch)
Definition: gdbarch.c:1509
void set_solib_svr4_fetch_link_map_offsets(struct gdbarch *gdbarch, struct link_map_offsets *(*flmo)(void))
Definition: solib-svr4.c:3137
#define SPARC64OBSD_UTHREAD_PC_OFFSET
int find_pc_partial_function(CORE_ADDR pc, const char **name, CORE_ADDR *address, CORE_ADDR *endaddr)
Definition: blockframe.c:320
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
static void sparc64obsd_collect_uthread(const struct regcache *regcache, int regnum, CORE_ADDR addr)
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
bfd_byte gdb_byte
Definition: common-types.h:38
const struct sparc_gregmap sparc64obsd_core_gregmap
static void sparc64obsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
void _initialize_sparc64obsd_tdep(void)
int offset
Definition: agent.c:65
static struct value * sparc64obsd_frame_prev_register(struct frame_info *this_frame, void **this_cache, int regnum)
gdbarch * arch() const
Definition: regcache.c:221
size_t sizeof_gregset
Definition: i386-tdep.h:63
const struct regset * fpregset
Definition: i386-tdep.h:253
void regcache_raw_supply(struct regcache *regcache, int regnum, const void *buf)
Definition: regcache.c:1004
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
static void sparc64obsd_supply_uthread(struct regcache *regcache, int regnum, CORE_ADDR addr)
CORE_ADDR obsd_skip_solib_resolver(struct gdbarch *gdbarch, CORE_ADDR pc)
Definition: obsd-tdep.c:28
void regcache_raw_collect(const struct regcache *regcache, int regnum, void *buf)
Definition: regcache.c:1085
#define SPARC64OBSD_UTHREAD_FP_OFFSET
static int sparc64obsd_pc_in_sigtramp(CORE_ADDR pc, const char *name)
ULONGEST read_memory_unsigned_integer(CORE_ADDR memaddr, int len, enum bfd_endian byte_order)
Definition: corefile.c:326
static void sparc64obsd_supply_gregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs, size_t len)
void write_memory(CORE_ADDR memaddr, const bfd_byte *myaddr, ssize_t len)
Definition: corefile.c:394
static int sparc64obsd_trapframe_sniffer(const struct frame_unwind *self, struct frame_info *this_frame, void **this_cache)
void set_gdbarch_skip_solib_resolver(struct gdbarch *gdbarch, gdbarch_skip_solib_resolver_ftype skip_solib_resolver)
Definition: gdbarch.c:3333
void bsd_uthread_set_supply_uthread(struct gdbarch *gdbarch, void(*supply_uthread)(struct regcache *, int, CORE_ADDR))
Definition: bsd-uthread.c:67
enum bfd_endian byte_order
Definition: gdbarch.c:137
static struct value * sparc64obsd_trapframe_prev_register(struct frame_info *this_frame, void **this_cache, int regnum)
static void store_unsigned_integer(gdb_byte *addr, int len, enum bfd_endian byte_order, ULONGEST val)
Definition: defs.h:604