GDB (xrefs)
/tmp/gdb-7.10/gdb/sparc-sol2-tdep.c
Go to the documentation of this file.
1 /* Target-dependent code for Solaris SPARC.
2 
3  Copyright (C) 2003-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 "frame.h"
22 #include "frame-unwind.h"
23 #include "gdbcore.h"
24 #include "symtab.h"
25 #include "objfiles.h"
26 #include "osabi.h"
27 #include "regcache.h"
28 #include "regset.h"
29 #include "target.h"
30 #include "trad-frame.h"
31 
32 #include "sol2-tdep.h"
33 #include "sparc-tdep.h"
34 #include "solib-svr4.h"
35 
36 /* From <sys/regset.h>. */
37 const struct sparc_gregmap sparc32_sol2_gregmap =
38 {
39  32 * 4, /* %psr */
40  33 * 4, /* %pc */
41  34 * 4, /* %npc */
42  35 * 4, /* %y */
43  36 * 4, /* %wim */
44  37 * 4, /* %tbr */
45  1 * 4, /* %g1 */
46  16 * 4, /* %l0 */
47 };
48 
49 const struct sparc_fpregmap sparc32_sol2_fpregmap =
50 {
51  0 * 4, /* %f0 */
52  33 * 4, /* %fsr */
53 };
54 
55 static void
57  struct regcache *regcache,
58  int regnum, const void *gregs, size_t len)
59 {
60  sparc32_supply_gregset (&sparc32_sol2_gregmap, regcache, regnum, gregs);
61 }
62 
63 static void
65  const struct regcache *regcache,
66  int regnum, void *gregs, size_t len)
67 {
68  sparc32_collect_gregset (&sparc32_sol2_gregmap, regcache, regnum, gregs);
69 }
70 
71 static void
73  struct regcache *regcache,
74  int regnum, const void *fpregs, size_t len)
75 {
76  sparc32_supply_fpregset (&sparc32_sol2_fpregmap, regcache, regnum, fpregs);
77 }
78 
79 static void
81  const struct regcache *regcache,
82  int regnum, void *fpregs, size_t len)
83 {
84  sparc32_collect_fpregset (&sparc32_sol2_fpregmap, regcache, regnum, fpregs);
85 }
86 
87 static const struct regset sparc32_sol2_gregset =
88  {
89  NULL,
92  };
93 
94 static const struct regset sparc32_sol2_fpregset =
95  {
96  NULL,
99  };
100 
101 
102 /* The Solaris signal trampolines reside in libc. For normal signals,
103  the function `sigacthandler' is used. This signal trampoline will
104  call the signal handler using the System V calling convention,
105  where the third argument is a pointer to an instance of
106  `ucontext_t', which has a member `uc_mcontext' that contains the
107  saved registers. Incidentally, the kernel passes the `ucontext_t'
108  pointer as the third argument of the signal trampoline too, and
109  `sigacthandler' simply passes it on. However, if you link your
110  program with "-L/usr/ucblib -R/usr/ucblib -lucb", the function
111  `ucbsigvechandler' will be used, which invokes the using the BSD
112  convention, where the third argument is a pointer to an instance of
113  `struct sigcontext'. It is the `ucbsigvechandler' function that
114  converts the `ucontext_t' to a `sigcontext', and back. Unless the
115  signal handler modifies the `struct sigcontext' we can safely
116  ignore this. */
117 
118 int
120 {
121  return (name && (strcmp (name, "sigacthandler") == 0
122  || strcmp (name, "ucbsigvechandler") == 0
123  || strcmp (name, "__sighndlr") == 0));
124 }
125 
126 static struct sparc_frame_cache *
128  void **this_cache)
129 {
130  struct sparc_frame_cache *cache;
131  CORE_ADDR mcontext_addr, addr;
132  int regnum;
133 
134  if (*this_cache)
135  return *this_cache;
136 
137  cache = sparc_frame_cache (this_frame, this_cache);
138  gdb_assert (cache == *this_cache);
139 
140  cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
141 
142  /* The third argument is a pointer to an instance of `ucontext_t',
143  which has a member `uc_mcontext' that contains the saved
144  registers. */
145  regnum =
147  mcontext_addr = get_frame_register_unsigned (this_frame, regnum) + 40;
148 
149  cache->saved_regs[SPARC32_PSR_REGNUM].addr = mcontext_addr + 0 * 4;
150  cache->saved_regs[SPARC32_PC_REGNUM].addr = mcontext_addr + 1 * 4;
151  cache->saved_regs[SPARC32_NPC_REGNUM].addr = mcontext_addr + 2 * 4;
152  cache->saved_regs[SPARC32_Y_REGNUM].addr = mcontext_addr + 3 * 4;
153 
154  /* Since %g0 is always zero, keep the identity encoding. */
155  for (regnum = SPARC_G1_REGNUM, addr = mcontext_addr + 4 * 4;
156  regnum <= SPARC_O7_REGNUM; regnum++, addr += 4)
157  cache->saved_regs[regnum].addr = addr;
158 
159  if (get_frame_memory_unsigned (this_frame, mcontext_addr + 19 * 4, 4))
160  {
161  /* The register windows haven't been flushed. */
162  for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
163  trad_frame_set_unknown (cache->saved_regs, regnum);
164  }
165  else
166  {
167  addr = cache->saved_regs[SPARC_SP_REGNUM].addr;
168  addr = get_frame_memory_unsigned (this_frame, addr, 4);
169  for (regnum = SPARC_L0_REGNUM;
170  regnum <= SPARC_I7_REGNUM; regnum++, addr += 4)
171  cache->saved_regs[regnum].addr = addr;
172  }
173 
174  return cache;
175 }
176 
177 static void
179  void **this_cache,
180  struct frame_id *this_id)
181 {
182  struct sparc_frame_cache *cache =
183  sparc32_sol2_sigtramp_frame_cache (this_frame, this_cache);
184 
185  (*this_id) = frame_id_build (cache->base, cache->pc);
186 }
187 
188 static struct value *
190  void **this_cache,
191  int regnum)
192 {
193  struct sparc_frame_cache *cache =
194  sparc32_sol2_sigtramp_frame_cache (this_frame, this_cache);
195 
196  return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
197 }
198 
199 static int
201  struct frame_info *this_frame,
202  void **this_cache)
203 {
204  CORE_ADDR pc = get_frame_pc (this_frame);
205  const char *name;
206 
207  find_pc_partial_function (pc, &name, NULL, NULL);
208  if (sparc_sol2_pc_in_sigtramp (pc, name))
209  return 1;
210 
211  return 0;
212 }
213 
214 static const struct frame_unwind sparc32_sol2_sigtramp_frame_unwind =
215 {
220  NULL,
222 };
223 
224 /* Unglobalize NAME. */
225 
226 const char *
228 {
229  /* The Sun compilers (Sun ONE Studio, Forte Developer, Sun WorkShop,
230  SunPRO) convert file static variables into global values, a
231  process known as globalization. In order to do this, the
232  compiler will create a unique prefix and prepend it to each file
233  static variable. For static variables within a function, this
234  globalization prefix is followed by the function name (nested
235  static variables within a function are supposed to generate a
236  warning message, and are left alone). The procedure is
237  documented in the Stabs Interface Manual, which is distrubuted
238  with the compilers, although version 4.0 of the manual seems to
239  be incorrect in some places, at least for SPARC. The
240  globalization prefix is encoded into an N_OPT stab, with the form
241  "G=<prefix>". The globalization prefix always seems to start
242  with a dollar sign '$'; a dot '.' is used as a seperator. So we
243  simply strip everything up until the last dot. */
244 
245  if (name[0] == '$')
246  {
247  const char *p = strrchr (name, '.');
248  if (p)
249  return p + 1;
250  }
251 
252  return name;
253 }
254 
255 
256 void
258 {
259  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
260 
261  tdep->gregset = &sparc32_sol2_gregset;
262  tdep->sizeof_gregset = 152;
263 
265  tdep->sizeof_fpregset = 400;
266 
267  /* The Sun compilers (Sun ONE Studio, Forte Developer, Sun WorkShop, SunPRO)
268  compiler puts out 0 instead of the address in N_SO stabs. Starting with
269  SunPRO 3.0, the compiler does this for N_FUN stabs too. */
271 
272  /* The Sun compilers also do "globalization"; see the comment in
273  sparc_sol2_static_transform_name for more information. */
276 
277  /* Solaris has SVR4-style shared libraries... */
282 
283  /* ...which means that we need some special handling when doing
284  prologue analysis. */
285  tdep->plt_entry_size = 12;
286 
287  /* Solaris has kernel-assisted single-stepping support. */
288  set_gdbarch_software_single_step (gdbarch, NULL);
289 
290  frame_unwind_append_unwinder (gdbarch, &sparc32_sol2_sigtramp_frame_unwind);
291 
292  /* How to print LWP PTIDs from core files. */
294 }
295 
296 
297 /* Provide a prototype to silence -Wmissing-prototypes. */
298 void _initialize_sparc_sol2_tdep (void);
299 
300 void
302 {
303  gdbarch_register_osabi (bfd_arch_sparc, 0,
305 }
CORE_ADDR sol2_skip_solib_resolver(struct gdbarch *gdbarch, CORE_ADDR pc)
Definition: sol2-tdep.c:29
struct frame_id frame_id_build(CORE_ADDR stack_addr, CORE_ADDR code_addr)
Definition: frame.c:554
static int sparc32_sol2_sigtramp_frame_sniffer(const struct frame_unwind *self, struct frame_info *this_frame, void **this_cache)
void set_gdbarch_core_pid_to_str(struct gdbarch *gdbarch, gdbarch_core_pid_to_str_ftype core_pid_to_str)
Definition: gdbarch.c:3542
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
void sparc32_supply_gregset(const struct sparc_gregmap *gregmap, struct regcache *regcache, int regnum, const void *gregs)
Definition: sparc-tdep.c:1894
const char * sparc_sol2_static_transform_name(const char *name)
if(!(yy_init))
Definition: ada-lex.c:1072
void set_gdbarch_skip_trampoline_code(struct gdbarch *gdbarch, gdbarch_skip_trampoline_code_ftype skip_trampoline_code)
Definition: gdbarch.c:3084
const struct regset * gregset
Definition: sparc-tdep.h:61
static void sparc32_sol2_collect_core_gregset(const struct regset *regset, const struct regcache *regcache, int regnum, void *gregs, size_t len)
struct sparc_frame_cache * sparc_frame_cache(struct frame_info *this_frame, void **this_cache)
Definition: sparc-tdep.c:1098
struct link_map_offsets * svr4_ilp32_fetch_link_map_offsets(void)
Definition: solib-svr4.c:3149
void sparc32_collect_fpregset(const struct sparc_fpregmap *fpregmap, const struct regcache *regcache, int regnum, void *fpregs)
Definition: sparc-tdep.c:2034
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
struct gdbarch_tdep * gdbarch_tdep(struct gdbarch *gdbarch)
Definition: gdbarch.c:1402
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
void _initialize_sparc_sol2_tdep(void)
Definition: regset.h:34
const char *const name
Definition: aarch64-tdep.c:68
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 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 void sparc32_sol2_collect_core_fpregset(const struct regset *regset, const struct regcache *regcache, int regnum, void *fpregs, size_t len)
void sparc32_sol2_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
void sparc32_supply_fpregset(const struct sparc_fpregmap *fpregmap, struct regcache *regcache, int regnum, const void *fpregs)
Definition: sparc-tdep.c:2014
#define gdb_assert(expr)
Definition: gdb_assert.h:33
static struct value * sparc32_sol2_sigtramp_frame_prev_register(struct frame_info *this_frame, void **this_cache, int regnum)
void sparc32_collect_gregset(const struct sparc_gregmap *gregmap, const struct regcache *regcache, int regnum, void *gregs)
Definition: sparc-tdep.c:1959
int regnum
Definition: aarch64-tdep.c:69
ULONGEST get_frame_register_unsigned(struct frame_info *frame, int regnum)
Definition: frame.c:1194
void set_gdbarch_sofun_address_maybe_missing(struct gdbarch *gdbarch, int sofun_address_maybe_missing)
Definition: gdbarch.c:3857
Definition: value.c:172
void set_gdbarch_software_single_step(struct gdbarch *gdbarch, gdbarch_software_single_step_ftype software_single_step)
Definition: gdbarch.c:3026
struct trad_frame_saved_reg * trad_frame_alloc_saved_regs(struct frame_info *this_frame)
Definition: trad-frame.c:52
char * sol2_core_pid_to_str(struct gdbarch *gdbarch, ptid_t ptid)
Definition: sol2-tdep.c:44
unsigned char copied_regs_mask
Definition: sparc-tdep.h:167
static const struct regset sparc32_sol2_gregset
static struct sparc_frame_cache * sparc32_sol2_sigtramp_frame_cache(struct frame_info *this_frame, void **this_cache)
size_t sizeof_gregset
Definition: i386-tdep.h:61
static void sparc32_sol2_supply_core_fpregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *fpregs, size_t len)
void set_gdbarch_static_transform_name(struct gdbarch *gdbarch, gdbarch_static_transform_name_ftype static_transform_name)
Definition: gdbarch.c:3840
const struct regset * fpregset
Definition: i386-tdep.h:242
static void sparc32_sol2_supply_core_gregset(const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs, size_t len)
enum unwind_stop_reason default_frame_unwind_stop_reason(struct frame_info *this_frame, void **this_cache)
Definition: frame-unwind.c:180
int sparc_sol2_pc_in_sigtramp(CORE_ADDR pc, const char *name)
void trad_frame_set_unknown(struct trad_frame_saved_reg this_saved_regs[], int regnum)
Definition: trad-frame.c:126
static void sparc32_sol2_sigtramp_frame_this_id(struct frame_info *this_frame, void **this_cache, struct frame_id *this_id)
size_t plt_entry_size
Definition: sparc-tdep.h:71
void set_gdbarch_skip_solib_resolver(struct gdbarch *gdbarch, gdbarch_skip_solib_resolver_ftype skip_solib_resolver)
Definition: gdbarch.c:3101
static const struct regset sparc32_sol2_fpregset
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
const ULONGEST const LONGEST len
Definition: target.h:309