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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [gdb/] [sparc-sol2-tdep.c] - Blame information for rev 868

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

Line No. Rev Author Line
1 24 jeremybenn
/* Target-dependent code for Solaris SPARC.
2
 
3
   Copyright (C) 2003, 2004, 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 "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 "target.h"
29
#include "trad-frame.h"
30
 
31
#include "gdb_assert.h"
32
#include "gdb_string.h"
33
 
34
#include "sol2-tdep.h"
35
#include "sparc-tdep.h"
36
#include "solib-svr4.h"
37
 
38
/* From <sys/regset.h>.  */
39
const struct sparc_gregset sparc32_sol2_gregset =
40
{
41
  32 * 4,                       /* %psr */
42
  33 * 4,                       /* %pc */
43
  34 * 4,                       /* %npc */
44
  35 * 4,                       /* %y */
45
  36 * 4,                       /* %wim */
46
  37 * 4,                       /* %tbr */
47
  1 * 4,                        /* %g1 */
48
  16 * 4,                       /* %l0 */
49
};
50
 
51
 
52
/* The Solaris signal trampolines reside in libc.  For normal signals,
53
   the function `sigacthandler' is used.  This signal trampoline will
54
   call the signal handler using the System V calling convention,
55
   where the third argument is a pointer to an instance of
56
   `ucontext_t', which has a member `uc_mcontext' that contains the
57
   saved registers.  Incidentally, the kernel passes the `ucontext_t'
58
   pointer as the third argument of the signal trampoline too, and
59
   `sigacthandler' simply passes it on. However, if you link your
60
   program with "-L/usr/ucblib -R/usr/ucblib -lucb", the function
61
   `ucbsigvechandler' will be used, which invokes the using the BSD
62
   convention, where the third argument is a pointer to an instance of
63
   `struct sigcontext'.  It is the `ucbsigvechandler' function that
64
   converts the `ucontext_t' to a `sigcontext', and back.  Unless the
65
   signal handler modifies the `struct sigcontext' we can safely
66
   ignore this.  */
67
 
68
int
69
sparc_sol2_pc_in_sigtramp (CORE_ADDR pc, char *name)
70
{
71
  return (name && (strcmp (name, "sigacthandler") == 0
72
                   || strcmp (name, "ucbsigvechandler") == 0
73
                   || strcmp (name, "__sighndlr") == 0));
74
}
75
 
76
static struct sparc_frame_cache *
77
sparc32_sol2_sigtramp_frame_cache (struct frame_info *next_frame,
78
                                   void **this_cache)
79
{
80
  struct sparc_frame_cache *cache;
81
  CORE_ADDR mcontext_addr, addr;
82
  int regnum;
83
 
84
  if (*this_cache)
85
    return *this_cache;
86
 
87
  cache = sparc_frame_cache (next_frame, this_cache);
88
  gdb_assert (cache == *this_cache);
89
 
90
  cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
91
 
92
  /* The third argument is a pointer to an instance of `ucontext_t',
93
     which has a member `uc_mcontext' that contains the saved
94
     registers.  */
95
  regnum = (cache->frameless_p ? SPARC_O2_REGNUM : SPARC_I2_REGNUM);
96
  mcontext_addr = frame_unwind_register_unsigned (next_frame, regnum) + 40;
97
 
98
  cache->saved_regs[SPARC32_PSR_REGNUM].addr = mcontext_addr + 0 * 4;
99
  cache->saved_regs[SPARC32_PC_REGNUM].addr = mcontext_addr + 1 * 4;
100
  cache->saved_regs[SPARC32_NPC_REGNUM].addr = mcontext_addr + 2 * 4;
101
  cache->saved_regs[SPARC32_Y_REGNUM].addr = mcontext_addr + 3 * 4;
102
 
103
  /* Since %g0 is always zero, keep the identity encoding.  */
104
  for (regnum = SPARC_G1_REGNUM, addr = mcontext_addr + 4 * 4;
105
       regnum <= SPARC_O7_REGNUM; regnum++, addr += 4)
106
    cache->saved_regs[regnum].addr = addr;
107
 
108
  if (get_frame_memory_unsigned (next_frame, mcontext_addr + 19 * 4, 4))
109
    {
110
      /* The register windows haven't been flushed.  */
111
      for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
112
        trad_frame_set_unknown (cache->saved_regs, regnum);
113
    }
114
  else
115
    {
116
      addr = cache->saved_regs[SPARC_SP_REGNUM].addr;
117
      addr = get_frame_memory_unsigned (next_frame, addr, 4);
118
      for (regnum = SPARC_L0_REGNUM;
119
           regnum <= SPARC_I7_REGNUM; regnum++, addr += 4)
120
        cache->saved_regs[regnum].addr = addr;
121
    }
122
 
123
  return cache;
124
}
125
 
126
static void
127
sparc32_sol2_sigtramp_frame_this_id (struct frame_info *next_frame,
128
                                     void **this_cache,
129
                                     struct frame_id *this_id)
130
{
131
  struct sparc_frame_cache *cache =
132
    sparc32_sol2_sigtramp_frame_cache (next_frame, this_cache);
133
 
134
  (*this_id) = frame_id_build (cache->base, cache->pc);
135
}
136
 
137
static void
138
sparc32_sol2_sigtramp_frame_prev_register (struct frame_info *next_frame,
139
                                           void **this_cache,
140
                                           int regnum, int *optimizedp,
141
                                           enum lval_type *lvalp,
142
                                           CORE_ADDR *addrp,
143
                                           int *realnump, gdb_byte *valuep)
144
{
145
  struct sparc_frame_cache *cache =
146
    sparc32_sol2_sigtramp_frame_cache (next_frame, this_cache);
147
 
148
  trad_frame_get_prev_register (next_frame, cache->saved_regs, regnum,
149
                                optimizedp, lvalp, addrp, realnump, valuep);
150
}
151
 
152
static const struct frame_unwind sparc32_sol2_sigtramp_frame_unwind =
153
{
154
  SIGTRAMP_FRAME,
155
  sparc32_sol2_sigtramp_frame_this_id,
156
  sparc32_sol2_sigtramp_frame_prev_register
157
};
158
 
159
static const struct frame_unwind *
160
sparc32_sol2_sigtramp_frame_sniffer (struct frame_info *next_frame)
161
{
162
  CORE_ADDR pc = frame_pc_unwind (next_frame);
163
  char *name;
164
 
165
  find_pc_partial_function (pc, &name, NULL, NULL);
166
  if (sparc_sol2_pc_in_sigtramp (pc, name))
167
    return &sparc32_sol2_sigtramp_frame_unwind;
168
 
169
  return NULL;
170
}
171
 
172
/* Unglobalize NAME.  */
173
 
174
char *
175
sparc_sol2_static_transform_name (char *name)
176
{
177
  /* The Sun compilers (Sun ONE Studio, Forte Developer, Sun WorkShop,
178
     SunPRO) convert file static variables into global values, a
179
     process known as globalization.  In order to do this, the
180
     compiler will create a unique prefix and prepend it to each file
181
     static variable.  For static variables within a function, this
182
     globalization prefix is followed by the function name (nested
183
     static variables within a function are supposed to generate a
184
     warning message, and are left alone).  The procedure is
185
     documented in the Stabs Interface Manual, which is distrubuted
186
     with the compilers, although version 4.0 of the manual seems to
187
     be incorrect in some places, at least for SPARC.  The
188
     globalization prefix is encoded into an N_OPT stab, with the form
189
     "G=<prefix>".  The globalization prefix always seems to start
190
     with a dollar sign '$'; a dot '.' is used as a seperator.  So we
191
     simply strip everything up until the last dot.  */
192
 
193
  if (name[0] == '$')
194
    {
195
      char *p = strrchr (name, '.');
196
      if (p)
197
        return p + 1;
198
    }
199
 
200
  return name;
201
}
202
 
203
 
204
void
205
sparc32_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
206
{
207
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
208
 
209
  /* The Sun compilers (Sun ONE Studio, Forte Developer, Sun WorkShop, SunPRO)
210
     compiler puts out 0 instead of the address in N_SO stabs.  Starting with
211
     SunPRO 3.0, the compiler does this for N_FUN stabs too.  */
212
  set_gdbarch_sofun_address_maybe_missing (gdbarch, 1);
213
 
214
  /* The Sun compilers also do "globalization"; see the comment in
215
     sparc_sol2_static_transform_name for more information.  */
216
  set_gdbarch_static_transform_name
217
    (gdbarch, sparc_sol2_static_transform_name);
218
 
219
  /* Solaris has SVR4-style shared libraries...  */
220
  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
221
  set_gdbarch_skip_solib_resolver (gdbarch, sol2_skip_solib_resolver);
222
  set_solib_svr4_fetch_link_map_offsets
223
    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
224
 
225
  /* ...which means that we need some special handling when doing
226
     prologue analysis.  */
227
  tdep->plt_entry_size = 12;
228
 
229
  /* Solaris has kernel-assisted single-stepping support.  */
230
  set_gdbarch_software_single_step (gdbarch, NULL);
231
 
232
  frame_unwind_append_sniffer (gdbarch, sparc32_sol2_sigtramp_frame_sniffer);
233
}
234
 
235
 
236
/* Provide a prototype to silence -Wmissing-prototypes.  */
237
void _initialize_sparc_sol2_tdep (void);
238
 
239
void
240
_initialize_sparc_sol2_tdep (void)
241
{
242
  gdbarch_register_osabi (bfd_arch_sparc, 0,
243
                          GDB_OSABI_SOLARIS, sparc32_sol2_init_abi);
244
}

powered by: WebSVN 2.1.0

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