OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [sparcnbsd-tdep.c] - Blame information for rev 842

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* Target-dependent code for NetBSD/sparc.
2
 
3
   Copyright (C) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010
4
   Free Software Foundation, Inc.
5
   Contributed by Wasabi Systems, Inc.
6
 
7
   This file is part of GDB.
8
 
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
 
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21
 
22
#include "defs.h"
23
#include "frame.h"
24
#include "frame-unwind.h"
25
#include "gdbcore.h"
26
#include "gdbtypes.h"
27
#include "osabi.h"
28
#include "regcache.h"
29
#include "regset.h"
30
#include "solib-svr4.h"
31
#include "symtab.h"
32
#include "trad-frame.h"
33
 
34
#include "gdb_assert.h"
35
#include "gdb_string.h"
36
 
37
#include "sparc-tdep.h"
38
#include "nbsd-tdep.h"
39
 
40
/* Macros to extract fields from SPARC instructions.  */
41
#define X_RS1(i) (((i) >> 14) & 0x1f)
42
#define X_RS2(i) ((i) & 0x1f)
43
#define X_I(i) (((i) >> 13) & 1)
44
 
45
const struct sparc_gregset sparc32nbsd_gregset =
46
{
47
 
48
  1 * 4,                        /* %pc */
49
  2 * 4,                        /* %npc */
50
  3 * 4,                        /* %y */
51
  -1,                           /* %wim */
52
  -1,                           /* %tbr */
53
  5 * 4,                        /* %g1 */
54
  -1                            /* %l0 */
55
};
56
 
57
static void
58
sparc32nbsd_supply_gregset (const struct regset *regset,
59
                            struct regcache *regcache,
60
                            int regnum, const void *gregs, size_t len)
61
{
62
  sparc32_supply_gregset (&sparc32nbsd_gregset, regcache, regnum, gregs);
63
 
64
  /* Traditional NetBSD core files don't use multiple register sets.
65
     Instead, the general-purpose and floating-point registers are
66
     lumped together in a single section.  */
67
  if (len >= 212)
68
    sparc32_supply_fpregset (regcache, regnum, (const char *) gregs + 80);
69
}
70
 
71
static void
72
sparc32nbsd_supply_fpregset (const struct regset *regset,
73
                             struct regcache *regcache,
74
                             int regnum, const void *fpregs, size_t len)
75
{
76
  sparc32_supply_fpregset (regcache, regnum, fpregs);
77
}
78
 
79
 
80
/* Signal trampolines.  */
81
 
82
/* The following variables describe the location of an on-stack signal
83
   trampoline.  The current values correspond to the memory layout for
84
   NetBSD 1.3 and up.  These shouldn't be necessary for NetBSD 2.0 and
85
   up, since NetBSD uses signal trampolines provided by libc now.  */
86
 
87
static const CORE_ADDR sparc32nbsd_sigtramp_start = 0xeffffef0;
88
static const CORE_ADDR sparc32nbsd_sigtramp_end = 0xeffffff0;
89
 
90
static int
91
sparc32nbsd_pc_in_sigtramp (CORE_ADDR pc, char *name)
92
{
93
  if (pc >= sparc32nbsd_sigtramp_start && pc < sparc32nbsd_sigtramp_end)
94
    return 1;
95
 
96
  return nbsd_pc_in_sigtramp (pc, name);
97
}
98
 
99
struct trad_frame_saved_reg *
100
sparc32nbsd_sigcontext_saved_regs (struct frame_info *this_frame)
101
{
102
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
103
  struct trad_frame_saved_reg *saved_regs;
104
  CORE_ADDR addr, sigcontext_addr;
105
  int regnum, delta;
106
  ULONGEST psr;
107
 
108
  saved_regs = trad_frame_alloc_saved_regs (this_frame);
109
 
110
  /* We find the appropriate instance of `struct sigcontext' at a
111
     fixed offset in the signal frame.  */
112
  addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
113
  sigcontext_addr = addr + 64 + 16;
114
 
115
  /* The registers are saved in bits and pieces scattered all over the
116
     place.  The code below records their location on the assumption
117
     that the part of the signal trampoline that saves the state has
118
     been executed.  */
119
 
120
  saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8;
121
  saved_regs[SPARC32_PC_REGNUM].addr = sigcontext_addr + 12;
122
  saved_regs[SPARC32_NPC_REGNUM].addr = sigcontext_addr + 16;
123
  saved_regs[SPARC32_PSR_REGNUM].addr = sigcontext_addr + 20;
124
  saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 24;
125
  saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 28;
126
 
127
  /* The remaining `global' registers and %y are saved in the `local'
128
     registers.  */
129
  delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM;
130
  for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
131
    saved_regs[regnum].realreg = regnum + delta;
132
  saved_regs[SPARC32_Y_REGNUM].realreg = SPARC_L1_REGNUM;
133
 
134
  /* The remaining `out' registers can be found in the current frame's
135
     `in' registers.  */
136
  delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM;
137
  for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
138
    saved_regs[regnum].realreg = regnum + delta;
139
  saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM;
140
 
141
  /* The `local' and `in' registers have been saved in the register
142
     save area.  */
143
  addr = saved_regs[SPARC_SP_REGNUM].addr;
144
  addr = get_frame_memory_unsigned (this_frame, addr, 4);
145
  for (regnum = SPARC_L0_REGNUM;
146
       regnum <= SPARC_I7_REGNUM; regnum++, addr += 4)
147
    saved_regs[regnum].addr = addr;
148
 
149
  /* Handle StackGhost.  */
150
  {
151
    ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
152
 
153
    if (wcookie != 0)
154
      {
155
        ULONGEST i7;
156
 
157
        addr = saved_regs[SPARC_I7_REGNUM].addr;
158
        i7 = get_frame_memory_unsigned (this_frame, addr, 4);
159
        trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie);
160
      }
161
  }
162
 
163
  /* The floating-point registers are only saved if the EF bit in %prs
164
     has been set.  */
165
 
166
#define PSR_EF  0x00001000
167
 
168
  addr = saved_regs[SPARC32_PSR_REGNUM].addr;
169
  psr = get_frame_memory_unsigned (this_frame, addr, 4);
170
  if (psr & PSR_EF)
171
    {
172
      CORE_ADDR sp;
173
 
174
      sp = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
175
      saved_regs[SPARC32_FSR_REGNUM].addr = sp + 96;
176
      for (regnum = SPARC_F0_REGNUM, addr = sp + 96 + 8;
177
           regnum <= SPARC_F31_REGNUM; regnum++, addr += 4)
178
        saved_regs[regnum].addr = addr;
179
    }
180
 
181
  return saved_regs;
182
}
183
 
184
static struct sparc_frame_cache *
185
sparc32nbsd_sigcontext_frame_cache (struct frame_info *this_frame,
186
                                    void **this_cache)
187
{
188
  struct sparc_frame_cache *cache;
189
  CORE_ADDR addr;
190
 
191
  if (*this_cache)
192
    return *this_cache;
193
 
194
  cache = sparc_frame_cache (this_frame, this_cache);
195
  gdb_assert (cache == *this_cache);
196
 
197
  /* If we couldn't find the frame's function, we're probably dealing
198
     with an on-stack signal trampoline.  */
199
  if (cache->pc == 0)
200
    {
201
      cache->pc = sparc32nbsd_sigtramp_start;
202
 
203
      /* Since we couldn't find the frame's function, the cache was
204
         initialized under the assumption that we're frameless.  */
205
      cache->frameless_p = 0;
206
      addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
207
      cache->base = addr;
208
    }
209
 
210
  cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (this_frame);
211
 
212
  return cache;
213
}
214
 
215
static void
216
sparc32nbsd_sigcontext_frame_this_id (struct frame_info *this_frame,
217
                                      void **this_cache,
218
                                      struct frame_id *this_id)
219
{
220
  struct sparc_frame_cache *cache =
221
    sparc32nbsd_sigcontext_frame_cache (this_frame, this_cache);
222
 
223
  (*this_id) = frame_id_build (cache->base, cache->pc);
224
}
225
 
226
static struct value *
227
sparc32nbsd_sigcontext_frame_prev_register (struct frame_info *this_frame,
228
                                            void **this_cache, int regnum)
229
{
230
  struct sparc_frame_cache *cache =
231
    sparc32nbsd_sigcontext_frame_cache (this_frame, this_cache);
232
 
233
  return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
234
}
235
 
236
static int
237
sparc32nbsd_sigcontext_frame_sniffer (const struct frame_unwind *self,
238
                                      struct frame_info *this_frame,
239
                                      void **this_cache)
240
{
241
  CORE_ADDR pc = get_frame_pc (this_frame);
242
  char *name;
243
 
244
  find_pc_partial_function (pc, &name, NULL, NULL);
245
  if (sparc32nbsd_pc_in_sigtramp (pc, name))
246
    {
247
      if (name == NULL || strncmp (name, "__sigtramp_sigcontext", 21))
248
        return 1;
249
    }
250
 
251
  return 0;
252
}
253
 
254
static const struct frame_unwind sparc32nbsd_sigcontext_frame_unwind =
255
{
256
  SIGTRAMP_FRAME,
257
  sparc32nbsd_sigcontext_frame_this_id,
258
  sparc32nbsd_sigcontext_frame_prev_register,
259
  NULL,
260
  sparc32nbsd_sigcontext_frame_sniffer
261
};
262
 
263
/* Return the address of a system call's alternative return
264
   address.  */
265
 
266
CORE_ADDR
267
sparcnbsd_step_trap (struct frame_info *frame, unsigned long insn)
268
{
269
  if ((X_I (insn) == 0 && X_RS1 (insn) == 0 && X_RS2 (insn) == 0)
270
      || (X_I (insn) == 1 && X_RS1 (insn) == 0 && (insn & 0x7f) == 0))
271
    {
272
      /* "New" system call.  */
273
      ULONGEST number = get_frame_register_unsigned (frame, SPARC_G1_REGNUM);
274
 
275
      if (number & 0x400)
276
        return get_frame_register_unsigned (frame, SPARC_G2_REGNUM);
277
      if (number & 0x800)
278
        return get_frame_register_unsigned (frame, SPARC_G7_REGNUM);
279
    }
280
 
281
  return 0;
282
}
283
 
284
 
285
static void
286
sparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
287
{
288
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
289
 
290
  /* NetBSD doesn't support the 128-bit `long double' from the psABI.  */
291
  set_gdbarch_long_double_bit (gdbarch, 64);
292
  set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
293
 
294
  tdep->gregset = regset_alloc (gdbarch, sparc32nbsd_supply_gregset, NULL);
295
  tdep->sizeof_gregset = 20 * 4;
296
 
297
  tdep->fpregset = regset_alloc (gdbarch, sparc32nbsd_supply_fpregset, NULL);
298
  tdep->sizeof_fpregset = 33 * 4;
299
 
300
  /* Make sure we can single-step "new" syscalls.  */
301
  tdep->step_trap = sparcnbsd_step_trap;
302
 
303
  frame_unwind_append_unwinder (gdbarch, &sparc32nbsd_sigcontext_frame_unwind);
304
}
305
 
306
static void
307
sparc32nbsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
308
{
309
  sparc32nbsd_init_abi (info, gdbarch);
310
}
311
 
312
void
313
sparc32nbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
314
{
315
  sparc32nbsd_init_abi (info, gdbarch);
316
 
317
  set_solib_svr4_fetch_link_map_offsets
318
    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
319
}
320
 
321
static enum gdb_osabi
322
sparcnbsd_aout_osabi_sniffer (bfd *abfd)
323
{
324
  if (strcmp (bfd_get_target (abfd), "a.out-sparc-netbsd") == 0)
325
    return GDB_OSABI_NETBSD_AOUT;
326
 
327
  return GDB_OSABI_UNKNOWN;
328
}
329
 
330
/* OpenBSD uses the traditional NetBSD core file format, even for
331
   ports that use ELF.  Therefore, if the default OS ABI is OpenBSD
332
   ELF, we return that instead of NetBSD a.out.  This is mainly for
333
   the benfit of OpenBSD/sparc64, which inherits the sniffer below
334
   since we include this file for an OpenBSD/sparc64 target.  For
335
   OpenBSD/sparc, the NetBSD a.out OS ABI is probably similar enough
336
   to both the OpenBSD a.out and the OpenBSD ELF OS ABI.  */
337
#if defined (GDB_OSABI_DEFAULT) && (GDB_OSABI_DEFAULT == GDB_OSABI_OPENBSD_ELF)
338
#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF
339
#else
340
#define GDB_OSABI_NETBSD_CORE GDB_OSABI_NETBSD_AOUT
341
#endif
342
 
343
static enum gdb_osabi
344
sparcnbsd_core_osabi_sniffer (bfd *abfd)
345
{
346
  if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
347
    return GDB_OSABI_NETBSD_CORE;
348
 
349
  return GDB_OSABI_UNKNOWN;
350
}
351
 
352
 
353
/* Provide a prototype to silence -Wmissing-prototypes.  */
354
void _initialize_sparcnbsd_tdep (void);
355
 
356
void
357
_initialize_sparcnbsd_tdep (void)
358
{
359
  gdbarch_register_osabi_sniffer (bfd_arch_sparc, bfd_target_aout_flavour,
360
                                  sparcnbsd_aout_osabi_sniffer);
361
 
362
  /* BFD doesn't set a flavour for NetBSD style a.out core files.  */
363
  gdbarch_register_osabi_sniffer (bfd_arch_sparc, bfd_target_unknown_flavour,
364
                                  sparcnbsd_core_osabi_sniffer);
365
 
366
  gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_NETBSD_AOUT,
367
                          sparc32nbsd_aout_init_abi);
368
  gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_NETBSD_ELF,
369
                          sparc32nbsd_elf_init_abi);
370
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.