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

Subversion Repositories openrisc

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

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* Target-dependent code for NetBSD/sparc.
2
 
3
   Copyright (C) 2002, 2003, 2004, 2006, 2007, 2008
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 *next_frame)
101
{
102
  struct trad_frame_saved_reg *saved_regs;
103
  CORE_ADDR addr, sigcontext_addr;
104
  int regnum, delta;
105
  ULONGEST psr;
106
 
107
  saved_regs = trad_frame_alloc_saved_regs (next_frame);
108
 
109
  /* We find the appropriate instance of `struct sigcontext' at a
110
     fixed offset in the signal frame.  */
111
  addr = frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM);
112
  sigcontext_addr = addr + 64 + 16;
113
 
114
  /* The registers are saved in bits and pieces scattered all over the
115
     place.  The code below records their location on the assumption
116
     that the part of the signal trampoline that saves the state has
117
     been executed.  */
118
 
119
  saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8;
120
  saved_regs[SPARC32_PC_REGNUM].addr = sigcontext_addr + 12;
121
  saved_regs[SPARC32_NPC_REGNUM].addr = sigcontext_addr + 16;
122
  saved_regs[SPARC32_PSR_REGNUM].addr = sigcontext_addr + 20;
123
  saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 24;
124
  saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 28;
125
 
126
  /* The remaining `global' registers and %y are saved in the `local'
127
     registers.  */
128
  delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM;
129
  for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
130
    saved_regs[regnum].realreg = regnum + delta;
131
  saved_regs[SPARC32_Y_REGNUM].realreg = SPARC_L1_REGNUM;
132
 
133
  /* The remaining `out' registers can be found in the current frame's
134
     `in' registers.  */
135
  delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM;
136
  for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
137
    saved_regs[regnum].realreg = regnum + delta;
138
  saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM;
139
 
140
  /* The `local' and `in' registers have been saved in the register
141
     save area.  */
142
  addr = saved_regs[SPARC_SP_REGNUM].addr;
143
  addr = get_frame_memory_unsigned (next_frame, addr, 4);
144
  for (regnum = SPARC_L0_REGNUM;
145
       regnum <= SPARC_I7_REGNUM; regnum++, addr += 4)
146
    saved_regs[regnum].addr = addr;
147
 
148
  /* Handle StackGhost.  */
149
  {
150
    ULONGEST wcookie = sparc_fetch_wcookie ();
151
 
152
    if (wcookie != 0)
153
      {
154
        ULONGEST i7;
155
 
156
        addr = saved_regs[SPARC_I7_REGNUM].addr;
157
        i7 = get_frame_memory_unsigned (next_frame, addr, 4);
158
        trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie);
159
      }
160
  }
161
 
162
  /* The floating-point registers are only saved if the EF bit in %prs
163
     has been set.  */
164
 
165
#define PSR_EF  0x00001000
166
 
167
  addr = saved_regs[SPARC32_PSR_REGNUM].addr;
168
  psr = get_frame_memory_unsigned (next_frame, addr, 4);
169
  if (psr & PSR_EF)
170
    {
171
      CORE_ADDR sp;
172
 
173
      sp = frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM);
174
      saved_regs[SPARC32_FSR_REGNUM].addr = sp + 96;
175
      for (regnum = SPARC_F0_REGNUM, addr = sp + 96 + 8;
176
           regnum <= SPARC_F31_REGNUM; regnum++, addr += 4)
177
        saved_regs[regnum].addr = addr;
178
    }
179
 
180
  return saved_regs;
181
}
182
 
183
static struct sparc_frame_cache *
184
sparc32nbsd_sigcontext_frame_cache (struct frame_info *next_frame,
185
                                    void **this_cache)
186
{
187
  struct sparc_frame_cache *cache;
188
  CORE_ADDR addr;
189
 
190
  if (*this_cache)
191
    return *this_cache;
192
 
193
  cache = sparc_frame_cache (next_frame, this_cache);
194
  gdb_assert (cache == *this_cache);
195
 
196
  /* If we couldn't find the frame's function, we're probably dealing
197
     with an on-stack signal trampoline.  */
198
  if (cache->pc == 0)
199
    {
200
      cache->pc = sparc32nbsd_sigtramp_start;
201
 
202
      /* Since we couldn't find the frame's function, the cache was
203
         initialized under the assumption that we're frameless.  */
204
      cache->frameless_p = 0;
205
      addr = frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM);
206
      cache->base = addr;
207
    }
208
 
209
  cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (next_frame);
210
 
211
  return cache;
212
}
213
 
214
static void
215
sparc32nbsd_sigcontext_frame_this_id (struct frame_info *next_frame,
216
                                      void **this_cache,
217
                                      struct frame_id *this_id)
218
{
219
  struct sparc_frame_cache *cache =
220
    sparc32nbsd_sigcontext_frame_cache (next_frame, this_cache);
221
 
222
  (*this_id) = frame_id_build (cache->base, cache->pc);
223
}
224
 
225
static void
226
sparc32nbsd_sigcontext_frame_prev_register (struct frame_info *next_frame,
227
                                            void **this_cache,
228
                                            int regnum, int *optimizedp,
229
                                            enum lval_type *lvalp,
230
                                            CORE_ADDR *addrp,
231
                                            int *realnump, gdb_byte *valuep)
232
{
233
  struct sparc_frame_cache *cache =
234
    sparc32nbsd_sigcontext_frame_cache (next_frame, this_cache);
235
 
236
  trad_frame_get_prev_register (next_frame, cache->saved_regs, regnum,
237
                                optimizedp, lvalp, addrp, realnump, valuep);
238
}
239
 
240
static const struct frame_unwind sparc32nbsd_sigcontext_frame_unwind =
241
{
242
  SIGTRAMP_FRAME,
243
  sparc32nbsd_sigcontext_frame_this_id,
244
  sparc32nbsd_sigcontext_frame_prev_register
245
};
246
 
247
static const struct frame_unwind *
248
sparc32nbsd_sigtramp_frame_sniffer (struct frame_info *next_frame)
249
{
250
  CORE_ADDR pc = frame_pc_unwind (next_frame);
251
  char *name;
252
 
253
  find_pc_partial_function (pc, &name, NULL, NULL);
254
  if (sparc32nbsd_pc_in_sigtramp (pc, name))
255
    {
256
      if (name == NULL || strncmp (name, "__sigtramp_sigcontext", 21))
257
        return &sparc32nbsd_sigcontext_frame_unwind;
258
    }
259
 
260
  return NULL;
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_sniffer (gdbarch, sparc32nbsd_sigtramp_frame_sniffer);
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_sparnbsd_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.