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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [gdb/] [sparcobsd-tdep.c] - Blame information for rev 24

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

Line No. Rev Author Line
1 24 jeremybenn
/* Target-dependent code for OpenBSD/sparc.
2
 
3
   Copyright (C) 2004, 2005, 2006, 2007, 2008 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 "gdb_assert.h"
31
 
32
#include "obsd-tdep.h"
33
#include "sparc-tdep.h"
34
#include "solib-svr4.h"
35
#include "bsd-uthread.h"
36
 
37
/* Signal trampolines.  */
38
 
39
/* The OpenBSD kernel maps the signal trampoline at some random
40
   location in user space, which means that the traditional BSD way of
41
   detecting it won't work.
42
 
43
   The signal trampoline will be mapped at an address that is page
44
   aligned.  We recognize the signal trampoline by looking for the
45
   sigreturn system call.  */
46
 
47
static const int sparc32obsd_page_size = 4096;
48
 
49
static int
50
sparc32obsd_pc_in_sigtramp (CORE_ADDR pc, char *name)
51
{
52
  CORE_ADDR start_pc = (pc & ~(sparc32obsd_page_size - 1));
53
  unsigned long insn;
54
 
55
  if (name)
56
    return 0;
57
 
58
  /* Check for "restore %g0, SYS_sigreturn, %g1".  */
59
  insn = sparc_fetch_instruction (start_pc + 0xec);
60
  if (insn != 0x83e82067)
61
    return 0;
62
 
63
  /* Check for "t ST_SYSCALL".  */
64
  insn = sparc_fetch_instruction (start_pc + 0xf4);
65
  if (insn != 0x91d02000)
66
    return 0;
67
 
68
  return 1;
69
}
70
 
71
static struct sparc_frame_cache *
72
sparc32obsd_frame_cache (struct frame_info *next_frame, void **this_cache)
73
{
74
  struct sparc_frame_cache *cache;
75
  CORE_ADDR addr;
76
 
77
  if (*this_cache)
78
    return *this_cache;
79
 
80
  cache = sparc_frame_cache (next_frame, this_cache);
81
  gdb_assert (cache == *this_cache);
82
 
83
  /* If we couldn't find the frame's function, we're probably dealing
84
     with an on-stack signal trampoline.  */
85
  if (cache->pc == 0)
86
    {
87
      cache->pc = frame_pc_unwind (next_frame);
88
      cache->pc &= ~(sparc32obsd_page_size - 1);
89
 
90
      /* Since we couldn't find the frame's function, the cache was
91
         initialized under the assumption that we're frameless.  */
92
      cache->frameless_p = 0;
93
      addr = frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM);
94
      cache->base = addr;
95
    }
96
 
97
  cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (next_frame);
98
 
99
  return cache;
100
}
101
 
102
static void
103
sparc32obsd_frame_this_id (struct frame_info *next_frame, void **this_cache,
104
                           struct frame_id *this_id)
105
{
106
  struct sparc_frame_cache *cache =
107
    sparc32obsd_frame_cache (next_frame, this_cache);
108
 
109
  (*this_id) = frame_id_build (cache->base, cache->pc);
110
}
111
 
112
static void
113
sparc32obsd_frame_prev_register (struct frame_info *next_frame,
114
                                 void **this_cache,
115
                                 int regnum, int *optimizedp,
116
                                 enum lval_type *lvalp, CORE_ADDR *addrp,
117
                                 int *realnump, gdb_byte *valuep)
118
{
119
  struct sparc_frame_cache *cache =
120
    sparc32obsd_frame_cache (next_frame, this_cache);
121
 
122
  trad_frame_get_prev_register (next_frame, cache->saved_regs, regnum,
123
                                optimizedp, lvalp, addrp, realnump, valuep);
124
}
125
 
126
static const struct frame_unwind sparc32obsd_frame_unwind =
127
{
128
  SIGTRAMP_FRAME,
129
  sparc32obsd_frame_this_id,
130
  sparc32obsd_frame_prev_register
131
};
132
 
133
static const struct frame_unwind *
134
sparc32obsd_sigtramp_frame_sniffer (struct frame_info *next_frame)
135
{
136
  CORE_ADDR pc = frame_pc_unwind (next_frame);
137
  char *name;
138
 
139
  find_pc_partial_function (pc, &name, NULL, NULL);
140
  if (sparc32obsd_pc_in_sigtramp (pc, name))
141
    return &sparc32obsd_frame_unwind;
142
 
143
  return NULL;
144
}
145
 
146
 
147
/* Offset wthin the thread structure where we can find %fp and %i7.  */
148
#define SPARC32OBSD_UTHREAD_FP_OFFSET   128
149
#define SPARC32OBSD_UTHREAD_PC_OFFSET   132
150
 
151
static void
152
sparc32obsd_supply_uthread (struct regcache *regcache,
153
                            int regnum, CORE_ADDR addr)
154
{
155
  CORE_ADDR fp, fp_addr = addr + SPARC32OBSD_UTHREAD_FP_OFFSET;
156
  gdb_byte buf[4];
157
 
158
  gdb_assert (regnum >= -1);
159
 
160
  fp = read_memory_unsigned_integer (fp_addr, 4);
161
  if (regnum == SPARC_SP_REGNUM || regnum == -1)
162
    {
163
      store_unsigned_integer (buf, 4, fp);
164
      regcache_raw_supply (regcache, SPARC_SP_REGNUM, buf);
165
 
166
      if (regnum == SPARC_SP_REGNUM)
167
        return;
168
    }
169
 
170
  if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM
171
      || regnum == -1)
172
    {
173
      CORE_ADDR i7, i7_addr = addr + SPARC32OBSD_UTHREAD_PC_OFFSET;
174
 
175
      i7 = read_memory_unsigned_integer (i7_addr, 4);
176
      if (regnum == SPARC32_PC_REGNUM || regnum == -1)
177
        {
178
          store_unsigned_integer (buf, 4, i7 + 8);
179
          regcache_raw_supply (regcache, SPARC32_PC_REGNUM, buf);
180
        }
181
      if (regnum == SPARC32_NPC_REGNUM || regnum == -1)
182
        {
183
          store_unsigned_integer (buf, 4, i7 + 12);
184
          regcache_raw_supply (regcache, SPARC32_NPC_REGNUM, buf);
185
        }
186
 
187
      if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM)
188
        return;
189
    }
190
 
191
  sparc_supply_rwindow (regcache, fp, regnum);
192
}
193
 
194
static void
195
sparc32obsd_collect_uthread(const struct regcache *regcache,
196
                            int regnum, CORE_ADDR addr)
197
{
198
  CORE_ADDR sp;
199
  gdb_byte buf[4];
200
 
201
  gdb_assert (regnum >= -1);
202
 
203
  if (regnum == SPARC_SP_REGNUM || regnum == -1)
204
    {
205
      CORE_ADDR fp_addr = addr + SPARC32OBSD_UTHREAD_FP_OFFSET;
206
 
207
      regcache_raw_collect (regcache, SPARC_SP_REGNUM, buf);
208
      write_memory (fp_addr,buf, 4);
209
    }
210
 
211
  if (regnum == SPARC32_PC_REGNUM || regnum == -1)
212
    {
213
      CORE_ADDR i7, i7_addr = addr + SPARC32OBSD_UTHREAD_PC_OFFSET;
214
 
215
      regcache_raw_collect (regcache, SPARC32_PC_REGNUM, buf);
216
      i7 = extract_unsigned_integer (buf, 4) - 8;
217
      write_memory_unsigned_integer (i7_addr, 4, i7);
218
 
219
      if (regnum == SPARC32_PC_REGNUM)
220
        return;
221
    }
222
 
223
  regcache_raw_collect (regcache, SPARC_SP_REGNUM, buf);
224
  sp = extract_unsigned_integer (buf, 4);
225
  sparc_collect_rwindow (regcache, sp, regnum);
226
}
227
 
228
 
229
static void
230
sparc32obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
231
{
232
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
233
 
234
  /* OpenBSD/sparc is very similar to NetBSD/sparc ELF.  */
235
  sparc32nbsd_elf_init_abi (info, gdbarch);
236
 
237
  set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
238
 
239
  frame_unwind_append_sniffer (gdbarch, sparc32obsd_sigtramp_frame_sniffer);
240
 
241
  /* OpenBSD provides a user-level threads implementation.  */
242
  bsd_uthread_set_supply_uthread (gdbarch, sparc32obsd_supply_uthread);
243
  bsd_uthread_set_collect_uthread (gdbarch, sparc32obsd_collect_uthread);
244
}
245
 
246
 
247
/* Provide a prototype to silence -Wmissing-prototypes.  */
248
void _initialize_sparc32obsd_tdep (void);
249
 
250
void
251
_initialize_sparc32obsd_tdep (void)
252
{
253
  gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_OPENBSD_ELF,
254
                          sparc32obsd_init_abi);
255
}

powered by: WebSVN 2.1.0

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