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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [sparc64nbsd-tdep.c] - Blame information for rev 841

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* Target-dependent code for NetBSD/sparc64.
2
 
3
   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4
   Free Software Foundation, Inc.
5
   Based on code 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 "osabi.h"
27
#include "regcache.h"
28
#include "regset.h"
29
#include "symtab.h"
30
#include "objfiles.h"
31
#include "solib-svr4.h"
32
#include "trad-frame.h"
33
 
34
#include "gdb_assert.h"
35
#include "gdb_string.h"
36
 
37
#include "sparc64-tdep.h"
38
#include "nbsd-tdep.h"
39
 
40
/* From <machine/reg.h>.  */
41
const struct sparc_gregset sparc64nbsd_gregset =
42
{
43
 
44
  1 * 8,                        /* %pc */
45
  2 * 8,                        /* %npc */
46
  3 * 8,                        /* %y */
47
  -1,                           /* %fprs */
48
  -1,
49
  5 * 8,                        /* %g1 */
50
  -1,                           /* %l0 */
51
  4                             /* sizeof (%y) */
52
};
53
 
54
 
55
static void
56
sparc64nbsd_supply_gregset (const struct regset *regset,
57
                            struct regcache *regcache,
58
                            int regnum, const void *gregs, size_t len)
59
{
60
  sparc64_supply_gregset (&sparc64nbsd_gregset, regcache, regnum, gregs);
61
}
62
 
63
static void
64
sparc64nbsd_supply_fpregset (const struct regset *regset,
65
                             struct regcache *regcache,
66
                             int regnum, const void *fpregs, size_t len)
67
{
68
  sparc64_supply_fpregset (regcache, regnum, fpregs);
69
}
70
 
71
 
72
/* Signal trampolines.  */
73
 
74
/* The following variables describe the location of an on-stack signal
75
   trampoline.  The current values correspond to the memory layout for
76
   NetBSD 1.3 and up.  These shouldn't be necessary for NetBSD 2.0 and
77
   up, since NetBSD uses signal trampolines provided by libc now.  */
78
 
79
static const CORE_ADDR sparc64nbsd_sigtramp_start = 0xffffffffffffdee4ULL;
80
static const CORE_ADDR sparc64nbsd_sigtramp_end = 0xffffffffffffe000ULL;
81
 
82
static int
83
sparc64nbsd_pc_in_sigtramp (CORE_ADDR pc, char *name)
84
{
85
  if (pc >= sparc64nbsd_sigtramp_start && pc < sparc64nbsd_sigtramp_end)
86
    return 1;
87
 
88
  return nbsd_pc_in_sigtramp (pc, name);
89
}
90
 
91
struct trad_frame_saved_reg *
92
sparc64nbsd_sigcontext_saved_regs (CORE_ADDR sigcontext_addr,
93
                                   struct frame_info *this_frame)
94
{
95
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
96
  struct trad_frame_saved_reg *saved_regs;
97
  CORE_ADDR addr, sp;
98
  int regnum, delta;
99
 
100
  saved_regs = trad_frame_alloc_saved_regs (this_frame);
101
 
102
  /* The registers are saved in bits and pieces scattered all over the
103
     place.  The code below records their location on the assumption
104
     that the part of the signal trampoline that saves the state has
105
     been executed.  */
106
 
107
  saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8;
108
  saved_regs[SPARC64_PC_REGNUM].addr = sigcontext_addr + 16;
109
  saved_regs[SPARC64_NPC_REGNUM].addr = sigcontext_addr + 24;
110
  saved_regs[SPARC64_STATE_REGNUM].addr = sigcontext_addr + 32;
111
  saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 40;
112
  saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 48;
113
 
114
  /* The remaining `global' registers and %y are saved in the `local'
115
     registers.  */
116
  delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM;
117
  for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
118
    saved_regs[regnum].realreg = regnum + delta;
119
  saved_regs[SPARC64_Y_REGNUM].realreg = SPARC_L1_REGNUM;
120
 
121
  /* The remaining `out' registers can be found in the current frame's
122
     `in' registers.  */
123
  delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM;
124
  for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
125
    saved_regs[regnum].realreg = regnum + delta;
126
  saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM;
127
 
128
  /* The `local' and `in' registers have been saved in the register
129
     save area.  */
130
  addr = saved_regs[SPARC_SP_REGNUM].addr;
131
  sp = get_frame_memory_unsigned (this_frame, addr, 8);
132
  for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS;
133
       regnum <= SPARC_I7_REGNUM; regnum++, addr += 8)
134
    saved_regs[regnum].addr = addr;
135
 
136
  /* Handle StackGhost.  */
137
  {
138
    ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);
139
 
140
    if (wcookie != 0)
141
      {
142
        ULONGEST i7;
143
 
144
        addr = saved_regs[SPARC_I7_REGNUM].addr;
145
        i7 = get_frame_memory_unsigned (this_frame, addr, 8);
146
        trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie);
147
      }
148
  }
149
 
150
  /* TODO: Handle the floating-point registers.  */
151
 
152
  return saved_regs;
153
}
154
 
155
static struct sparc_frame_cache *
156
sparc64nbsd_sigcontext_frame_cache (struct frame_info *this_frame,
157
                                    void **this_cache)
158
{
159
  struct sparc_frame_cache *cache;
160
  CORE_ADDR addr;
161
 
162
  if (*this_cache)
163
    return *this_cache;
164
 
165
  cache = sparc_frame_cache (this_frame, this_cache);
166
  gdb_assert (cache == *this_cache);
167
 
168
  /* If we couldn't find the frame's function, we're probably dealing
169
     with an on-stack signal trampoline.  */
170
  if (cache->pc == 0)
171
    {
172
      cache->pc = sparc64nbsd_sigtramp_start;
173
 
174
      /* Since we couldn't find the frame's function, the cache was
175
         initialized under the assumption that we're frameless.  */
176
      cache->frameless_p = 0;
177
      addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
178
      if (addr & 1)
179
        addr += BIAS;
180
      cache->base = addr;
181
    }
182
 
183
  /* We find the appropriate instance of `struct sigcontext' at a
184
     fixed offset in the signal frame.  */
185
  addr = cache->base + 128 + 8;
186
  cache->saved_regs = sparc64nbsd_sigcontext_saved_regs (addr, this_frame);
187
 
188
  return cache;
189
}
190
 
191
static void
192
sparc64nbsd_sigcontext_frame_this_id (struct frame_info *this_frame,
193
                                      void **this_cache,
194
                                      struct frame_id *this_id)
195
{
196
  struct sparc_frame_cache *cache =
197
    sparc64nbsd_sigcontext_frame_cache (this_frame, this_cache);
198
 
199
  (*this_id) = frame_id_build (cache->base, cache->pc);
200
}
201
 
202
static struct value *
203
sparc64nbsd_sigcontext_frame_prev_register (struct frame_info *this_frame,
204
                                            void **this_cache, int regnum)
205
{
206
  struct sparc_frame_cache *cache =
207
    sparc64nbsd_sigcontext_frame_cache (this_frame, this_cache);
208
 
209
  return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
210
}
211
 
212
static int
213
sparc64nbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
214
                                    struct frame_info *this_frame,
215
                                    void **this_cache)
216
{
217
  CORE_ADDR pc = get_frame_pc (this_frame);
218
  char *name;
219
 
220
  find_pc_partial_function (pc, &name, NULL, NULL);
221
  if (sparc64nbsd_pc_in_sigtramp (pc, name))
222
    {
223
      if (name == NULL || strncmp (name, "__sigtramp_sigcontext", 21))
224
        return 1;
225
    }
226
 
227
  return 0;
228
}
229
 
230
static const struct frame_unwind sparc64nbsd_sigcontext_frame_unwind =
231
{
232
  SIGTRAMP_FRAME,
233
  sparc64nbsd_sigcontext_frame_this_id,
234
  sparc64nbsd_sigcontext_frame_prev_register,
235
  NULL,
236
  sparc64nbsd_sigtramp_frame_sniffer
237
};
238
 
239
 
240
static void
241
sparc64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
242
{
243
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
244
 
245
  tdep->gregset = regset_alloc (gdbarch, sparc64nbsd_supply_gregset, NULL);
246
  tdep->sizeof_gregset = 160;
247
 
248
  tdep->fpregset = regset_alloc (gdbarch, sparc64nbsd_supply_fpregset, NULL);
249
  tdep->sizeof_fpregset = 272;
250
 
251
  /* Make sure we can single-step "new" syscalls.  */
252
  tdep->step_trap = sparcnbsd_step_trap;
253
 
254
  frame_unwind_append_unwinder (gdbarch, &sparc64nbsd_sigcontext_frame_unwind);
255
 
256
  sparc64_init_abi (info, gdbarch);
257
 
258
  /* NetBSD/sparc64 has SVR4-style shared libraries.  */
259
  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
260
  set_solib_svr4_fetch_link_map_offsets
261
    (gdbarch, svr4_lp64_fetch_link_map_offsets);
262
}
263
 
264
 
265
/* Provide a prototype to silence -Wmissing-prototypes.  */
266
void _initialize_sparc64nbsd_tdep (void);
267
 
268
void
269
_initialize_sparc64nbsd_tdep (void)
270
{
271
  gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
272
                          GDB_OSABI_NETBSD_ELF, sparc64nbsd_init_abi);
273
}

powered by: WebSVN 2.1.0

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