GDB (xrefs)
/tmp/gdb-7.10/gdb/sparcobsd-tdep.c
Go to the documentation of this file.
1 /* Target-dependent code for OpenBSD/sparc.
2 
3  Copyright (C) 2004-2015 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 "floatformat.h"
22 #include "frame.h"
23 #include "frame-unwind.h"
24 #include "gdbcore.h"
25 #include "osabi.h"
26 #include "regcache.h"
27 #include "symtab.h"
28 #include "trad-frame.h"
29 
30 #include "obsd-tdep.h"
31 #include "sparc-tdep.h"
32 #include "solib-svr4.h"
33 #include "bsd-uthread.h"
34 
35 /* Signal trampolines. */
36 
37 /* The OpenBSD kernel maps the signal trampoline at some random
38  location in user space, which means that the traditional BSD way of
39  detecting it won't work.
40 
41  The signal trampoline will be mapped at an address that is page
42  aligned. We recognize the signal trampoline by looking for the
43  sigreturn system call. */
44 
45 static const int sparc32obsd_page_size = 4096;
46 
47 static int
49 {
50  CORE_ADDR start_pc = (pc & ~(sparc32obsd_page_size - 1));
51  unsigned long insn;
52 
53  if (name)
54  return 0;
55 
56  /* Check for "restore %g0, SYS_sigreturn, %g1". */
57  insn = sparc_fetch_instruction (start_pc + 0xec);
58  if (insn != 0x83e82067)
59  return 0;
60 
61  /* Check for "t ST_SYSCALL". */
62  insn = sparc_fetch_instruction (start_pc + 0xf4);
63  if (insn != 0x91d02000)
64  return 0;
65 
66  return 1;
67 }
68 
69 static struct sparc_frame_cache *
71  void **this_cache)
72 {
73  struct sparc_frame_cache *cache;
74  CORE_ADDR addr;
75 
76  if (*this_cache)
77  return *this_cache;
78 
79  cache = sparc_frame_cache (this_frame, this_cache);
80  gdb_assert (cache == *this_cache);
81 
82  /* If we couldn't find the frame's function, we're probably dealing
83  with an on-stack signal trampoline. */
84  if (cache->pc == 0)
85  {
86  cache->pc = get_frame_pc (this_frame);
87  cache->pc &= ~(sparc32obsd_page_size - 1);
88 
89  /* Since we couldn't find the frame's function, the cache was
90  initialized under the assumption that we're frameless. */
91  sparc_record_save_insn (cache);
92  addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
93  cache->base = addr;
94  }
95 
96  cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (this_frame);
97 
98  return cache;
99 }
100 
101 static void
103  void **this_cache,
104  struct frame_id *this_id)
105 {
106  struct sparc_frame_cache *cache =
107  sparc32obsd_sigtramp_frame_cache (this_frame, this_cache);
108 
109  (*this_id) = frame_id_build (cache->base, cache->pc);
110 }
111 
112 static struct value *
114  void **this_cache, int regnum)
115 {
116  struct sparc_frame_cache *cache =
117  sparc32obsd_sigtramp_frame_cache (this_frame, this_cache);
118 
119  return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
120 }
121 
122 static int
124  struct frame_info *this_frame,
125  void **this_cache)
126 {
127  CORE_ADDR pc = get_frame_pc (this_frame);
128  const char *name;
129 
130  find_pc_partial_function (pc, &name, NULL, NULL);
131  if (sparc32obsd_pc_in_sigtramp (pc, name))
132  return 1;
133 
134  return 0;
135 }
136 static const struct frame_unwind sparc32obsd_sigtramp_frame_unwind =
137 {
142  NULL,
144 };
145 
146 
147 
148 /* Offset wthin the thread structure where we can find %fp and %i7. */
149 #define SPARC32OBSD_UTHREAD_FP_OFFSET 128
150 #define SPARC32OBSD_UTHREAD_PC_OFFSET 132
151 
152 static void
154  int regnum, CORE_ADDR addr)
155 {
156  struct gdbarch *gdbarch = get_regcache_arch (regcache);
157  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
158  CORE_ADDR fp, fp_addr = addr + SPARC32OBSD_UTHREAD_FP_OFFSET;
159  gdb_byte buf[4];
160 
161  gdb_assert (regnum >= -1);
162 
163  fp = read_memory_unsigned_integer (fp_addr, 4, byte_order);
164  if (regnum == SPARC_SP_REGNUM || regnum == -1)
165  {
166  store_unsigned_integer (buf, 4, byte_order, fp);
167  regcache_raw_supply (regcache, SPARC_SP_REGNUM, buf);
168 
169  if (regnum == SPARC_SP_REGNUM)
170  return;
171  }
172 
173  if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM
174  || regnum == -1)
175  {
176  CORE_ADDR i7, i7_addr = addr + SPARC32OBSD_UTHREAD_PC_OFFSET;
177 
178  i7 = read_memory_unsigned_integer (i7_addr, 4, byte_order);
179  if (regnum == SPARC32_PC_REGNUM || regnum == -1)
180  {
181  store_unsigned_integer (buf, 4, byte_order, i7 + 8);
182  regcache_raw_supply (regcache, SPARC32_PC_REGNUM, buf);
183  }
184  if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
185  {
186  store_unsigned_integer (buf, 4, byte_order, i7 + 12);
187  regcache_raw_supply (regcache, SPARC32_NPC_REGNUM, buf);
188  }
189 
190  if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM)
191  return;
192  }
193 
194  sparc_supply_rwindow (regcache, fp, regnum);
195 }
196 
197 static void
199  int regnum, CORE_ADDR addr)
200 {
201  struct gdbarch *gdbarch = get_regcache_arch (regcache);
202  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
203  CORE_ADDR sp;
204  gdb_byte buf[4];
205 
206  gdb_assert (regnum >= -1);
207 
208  if (regnum == SPARC_SP_REGNUM || regnum == -1)
209  {
210  CORE_ADDR fp_addr = addr + SPARC32OBSD_UTHREAD_FP_OFFSET;
211 
212  regcache_raw_collect (regcache, SPARC_SP_REGNUM, buf);
213  write_memory (fp_addr,buf, 4);
214  }
215 
216  if (regnum == SPARC32_PC_REGNUM || regnum == -1)
217  {
218  CORE_ADDR i7, i7_addr = addr + SPARC32OBSD_UTHREAD_PC_OFFSET;
219 
220  regcache_raw_collect (regcache, SPARC32_PC_REGNUM, buf);
221  i7 = extract_unsigned_integer (buf, 4, byte_order) - 8;
222  write_memory_unsigned_integer (i7_addr, 4, byte_order, i7);
223 
224  if (regnum == SPARC32_PC_REGNUM)
225  return;
226  }
227 
228  regcache_raw_collect (regcache, SPARC_SP_REGNUM, buf);
229  sp = extract_unsigned_integer (buf, 4, byte_order);
230  sparc_collect_rwindow (regcache, sp, regnum);
231 }
232 
233 
234 static void
236 {
237  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
238 
239  /* OpenBSD/sparc is very similar to NetBSD/sparc ELF. */
240  sparc32nbsd_elf_init_abi (info, gdbarch);
241 
243 
244  frame_unwind_append_unwinder (gdbarch, &sparc32obsd_sigtramp_frame_unwind);
245 
246  /* OpenBSD provides a user-level threads implementation. */
249 }
250 
251 
252 /* Provide a prototype to silence -Wmissing-prototypes. */
253 void _initialize_sparc32obsd_tdep (void);
254 
255 void
257 {
258  gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_OPENBSD_ELF,
260 }
ULONGEST extract_unsigned_integer(const gdb_byte *, int, enum bfd_endian)
Definition: findvar.c:84
static void sparc32obsd_sigtramp_frame_this_id(struct frame_info *this_frame, void **this_cache, struct frame_id *this_id)
struct frame_id frame_id_build(CORE_ADDR stack_addr, CORE_ADDR code_addr)
Definition: frame.c:554
CORE_ADDR get_frame_pc(struct frame_info *frame)
Definition: frame.c:2217
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:135
struct gdbarch * get_regcache_arch(const struct regcache *regcache)
Definition: regcache.c:297
void sparc_record_save_insn(struct sparc_frame_cache *cache)
Definition: sparc-tdep.c:866
void write_memory_unsigned_integer(CORE_ADDR addr, int len, enum bfd_endian byte_order, ULONGEST value)
Definition: corefile.c:412
struct sparc_frame_cache * sparc_frame_cache(struct frame_info *this_frame, void **this_cache)
Definition: sparc-tdep.c:1098
static struct value * sparc32obsd_sigtramp_frame_prev_register(struct frame_info *this_frame, void **this_cache, int regnum)
struct m32c_reg * pc
Definition: m32c-tdep.c:111
static int sparc32obsd_sigtramp_frame_sniffer(const struct frame_unwind *self, struct frame_info *this_frame, void **this_cache)
void bsd_uthread_set_collect_uthread(struct gdbarch *gdbarch, void(*collect_uthread)(const struct regcache *, int, CORE_ADDR))
Definition: bsd-uthread.c:79
struct gdbarch_tdep * gdbarch_tdep(struct gdbarch *gdbarch)
Definition: gdbarch.c:1402
void sparc_supply_rwindow(struct regcache *regcache, CORE_ADDR sp, int regnum)
Definition: sparc-tdep.c:1750
void frame_unwind_append_unwinder(struct gdbarch *gdbarch, const struct frame_unwind *unwinder)
Definition: frame-unwind.c:78
#define SPARC32OBSD_UTHREAD_FP_OFFSET
void store_unsigned_integer(gdb_byte *, int, enum bfd_endian, ULONGEST)
Definition: findvar.c:212
struct trad_frame_saved_reg * saved_regs
Definition: sparc-tdep.h:173
const char *const name
Definition: aarch64-tdep.c:68
static const int sparc32obsd_page_size
unsigned long sparc_fetch_instruction(CORE_ADDR pc)
Definition: sparc-tdep.c:96
void sparc_collect_rwindow(const struct regcache *regcache, CORE_ADDR sp, int regnum)
Definition: sparc-tdep.c:1823
CORE_ADDR base
Definition: sparc-tdep.h:154
enum bfd_endian gdbarch_byte_order(struct gdbarch *gdbarch)
Definition: gdbarch.c:1420
int find_pc_partial_function(CORE_ADDR pc, const char **name, CORE_ADDR *address, CORE_ADDR *endaddr)
Definition: blockframe.c:321
struct trad_frame_saved_reg * sparc32nbsd_sigcontext_saved_regs(struct frame_info *next_frame)
void sparc32nbsd_elf_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
#define gdb_assert(expr)
Definition: gdb_assert.h:33
static void sparc32obsd_supply_uthread(struct regcache *regcache, int regnum, CORE_ADDR addr)
int regnum
Definition: aarch64-tdep.c:69
ULONGEST get_frame_register_unsigned(struct frame_info *frame, int regnum)
Definition: frame.c:1194
Definition: value.c:172
static int sparc32obsd_pc_in_sigtramp(CORE_ADDR pc, const char *name)
bfd_byte gdb_byte
Definition: common-types.h:38
void _initialize_sparc32obsd_tdep(void)
#define SPARC32OBSD_UTHREAD_PC_OFFSET
void regcache_raw_supply(struct regcache *regcache, int regnum, const void *buf)
Definition: regcache.c:1041
enum unwind_stop_reason default_frame_unwind_stop_reason(struct frame_info *this_frame, void **this_cache)
Definition: frame-unwind.c:180
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:1071
static void sparc32obsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
ULONGEST read_memory_unsigned_integer(CORE_ADDR memaddr, int len, enum bfd_endian byte_order)
Definition: corefile.c:321
void write_memory(CORE_ADDR memaddr, const bfd_byte *myaddr, ssize_t len)
Definition: corefile.c:389
void set_gdbarch_skip_solib_resolver(struct gdbarch *gdbarch, gdbarch_skip_solib_resolver_ftype skip_solib_resolver)
Definition: gdbarch.c:3101
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:128
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 struct sparc_frame_cache * sparc32obsd_sigtramp_frame_cache(struct frame_info *this_frame, void **this_cache)
static void sparc32obsd_collect_uthread(const struct regcache *regcache, int regnum, CORE_ADDR addr)