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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [sparc64-linux-tdep.c] - Blame information for rev 816

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

Line No. Rev Author Line
1 330 jeremybenn
/* Target-dependent code for GNU/Linux UltraSPARC.
2
 
3
   Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010
4
   Free Software Foundation, Inc.
5
 
6
   This file is part of GDB.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
 
21
#include "defs.h"
22
#include "frame.h"
23
#include "frame-unwind.h"
24
#include "dwarf2-frame.h"
25
#include "regset.h"
26
#include "regcache.h"
27
#include "gdbarch.h"
28
#include "gdbcore.h"
29
#include "osabi.h"
30
#include "solib-svr4.h"
31
#include "symtab.h"
32
#include "trad-frame.h"
33
#include "tramp-frame.h"
34
#include "xml-syscall.h"
35
 
36
/* The syscall's XML filename for sparc 64-bit.  */
37
#define XML_SYSCALL_FILENAME_SPARC64 "syscalls/sparc64-linux.xml"
38
 
39
#include "sparc64-tdep.h"
40
 
41
/* Signal trampoline support.  */
42
 
43
static void sparc64_linux_sigframe_init (const struct tramp_frame *self,
44
                                         struct frame_info *this_frame,
45
                                         struct trad_frame_cache *this_cache,
46
                                         CORE_ADDR func);
47
 
48
/* See sparc-linux-tdep.c for details.  Note that 64-bit binaries only
49
   use RT signals.  */
50
 
51
static const struct tramp_frame sparc64_linux_rt_sigframe =
52
{
53
  SIGTRAMP_FRAME,
54
  4,
55
  {
56
    { 0x82102065, -1 },         /* mov __NR_rt_sigreturn, %g1 */
57
    { 0x91d0206d, -1 },         /* ta  0x6d */
58
    { TRAMP_SENTINEL_INSN, -1 }
59
  },
60
  sparc64_linux_sigframe_init
61
};
62
 
63
static void
64
sparc64_linux_sigframe_init (const struct tramp_frame *self,
65
                             struct frame_info *this_frame,
66
                             struct trad_frame_cache *this_cache,
67
                             CORE_ADDR func)
68
{
69
  CORE_ADDR base, addr, sp_addr;
70
  int regnum;
71
 
72
  base = get_frame_register_unsigned (this_frame, SPARC_O1_REGNUM);
73
  base += 128;
74
 
75
  /* Offsets from <bits/sigcontext.h>.  */
76
 
77
  /* Since %g0 is always zero, keep the identity encoding.  */
78
  addr = base + 8;
79
  sp_addr = base + ((SPARC_SP_REGNUM - SPARC_G0_REGNUM) * 8);
80
  for (regnum = SPARC_G1_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++)
81
    {
82
      trad_frame_set_reg_addr (this_cache, regnum, addr);
83
      addr += 8;
84
    }
85
 
86
  trad_frame_set_reg_addr (this_cache, SPARC64_STATE_REGNUM, addr + 0);
87
  trad_frame_set_reg_addr (this_cache, SPARC64_PC_REGNUM, addr + 8);
88
  trad_frame_set_reg_addr (this_cache, SPARC64_NPC_REGNUM, addr + 16);
89
  trad_frame_set_reg_addr (this_cache, SPARC64_Y_REGNUM, addr + 24);
90
  trad_frame_set_reg_addr (this_cache, SPARC64_FPRS_REGNUM, addr + 28);
91
 
92
  base = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
93
  if (base & 1)
94
    base += BIAS;
95
 
96
  addr = get_frame_memory_unsigned (this_frame, sp_addr, 8);
97
  if (addr & 1)
98
    addr += BIAS;
99
 
100
  for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
101
    {
102
      trad_frame_set_reg_addr (this_cache, regnum, addr);
103
      addr += 8;
104
    }
105
  trad_frame_set_id (this_cache, frame_id_build (base, func));
106
}
107
 
108
/* Return the address of a system call's alternative return
109
   address.  */
110
 
111
static CORE_ADDR
112
sparc64_linux_step_trap (struct frame_info *frame, unsigned long insn)
113
{
114
  if (insn == 0x91d0206d)
115
    {
116
      struct gdbarch *gdbarch = get_frame_arch (frame);
117
      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
118
 
119
      ULONGEST sp = get_frame_register_unsigned (frame, SPARC_SP_REGNUM);
120
      if (sp & 1)
121
        sp += BIAS;
122
 
123
      /* The kernel puts the sigreturn registers on the stack,
124
         and this is where the signal unwinding state is take from
125
         when returning from a signal.
126
 
127
         A siginfo_t sits 192 bytes from the base of the stack.  This
128
         siginfo_t is 128 bytes, and is followed by the sigreturn
129
         register save area.  The saved PC sits at a 136 byte offset
130
         into there.  */
131
 
132
      return read_memory_unsigned_integer (sp + 192 + 128 + 136,
133
                                           8, byte_order);
134
    }
135
 
136
  return 0;
137
}
138
 
139
 
140
const struct sparc_gregset sparc64_linux_core_gregset =
141
{
142
  32 * 8,                       /* %tstate */
143
  33 * 8,                       /* %tpc */
144
  34 * 8,                       /* %tnpc */
145
  35 * 8,                       /* %y */
146
  -1,                           /* %wim */
147
  -1,                           /* %tbr */
148
  1 * 8,                        /* %g1 */
149
  16 * 8,                       /* %l0 */
150
  8,                            /* y size */
151
};
152
 
153
 
154
static void
155
sparc64_linux_supply_core_gregset (const struct regset *regset,
156
                                   struct regcache *regcache,
157
                                   int regnum, const void *gregs, size_t len)
158
{
159
  sparc64_supply_gregset (&sparc64_linux_core_gregset, regcache, regnum, gregs);
160
}
161
 
162
static void
163
sparc64_linux_collect_core_gregset (const struct regset *regset,
164
                                    const struct regcache *regcache,
165
                                    int regnum, void *gregs, size_t len)
166
{
167
  sparc64_collect_gregset (&sparc64_linux_core_gregset, regcache, regnum, gregs);
168
}
169
 
170
static void
171
sparc64_linux_supply_core_fpregset (const struct regset *regset,
172
                                    struct regcache *regcache,
173
                                    int regnum, const void *fpregs, size_t len)
174
{
175
  sparc64_supply_fpregset (regcache, regnum, fpregs);
176
}
177
 
178
static void
179
sparc64_linux_collect_core_fpregset (const struct regset *regset,
180
                                     const struct regcache *regcache,
181
                                     int regnum, void *fpregs, size_t len)
182
{
183
  sparc64_collect_fpregset (regcache, regnum, fpregs);
184
}
185
 
186
/* Set the program counter for process PTID to PC.  */
187
 
188
#define TSTATE_SYSCALL  0x0000000000000020ULL
189
 
190
static void
191
sparc64_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
192
{
193
  struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
194
  ULONGEST state;
195
 
196
  regcache_cooked_write_unsigned (regcache, tdep->pc_regnum, pc);
197
  regcache_cooked_write_unsigned (regcache, tdep->npc_regnum, pc + 4);
198
 
199
  /* Clear the "in syscall" bit to prevent the kernel from
200
     messing with the PCs we just installed, if we happen to be
201
     within an interrupted system call that the kernel wants to
202
     restart.
203
 
204
     Note that after we return from the dummy call, the TSTATE et al.
205
     registers will be automatically restored, and the kernel
206
     continues to restart the system call at this point.  */
207
  regcache_cooked_read_unsigned (regcache, SPARC64_STATE_REGNUM, &state);
208
  state &= ~TSTATE_SYSCALL;
209
  regcache_cooked_write_unsigned (regcache, SPARC64_STATE_REGNUM, state);
210
}
211
 
212
static LONGEST
213
sparc64_linux_get_syscall_number (struct gdbarch *gdbarch,
214
                                  ptid_t ptid)
215
{
216
  struct regcache *regcache = get_thread_regcache (ptid);
217
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
218
  /* The content of a register.  */
219
  gdb_byte buf[8];
220
  /* The result.  */
221
  LONGEST ret;
222
 
223
  /* Getting the system call number from the register.
224
     When dealing with the sparc architecture, this information
225
     is stored at the %g1 register.  */
226
  regcache_cooked_read (regcache, SPARC_G1_REGNUM, buf);
227
 
228
  ret = extract_signed_integer (buf, 8, byte_order);
229
 
230
  return ret;
231
}
232
 
233
 
234
 
235
static void
236
sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
237
{
238
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
239
 
240
  tdep->gregset = regset_alloc (gdbarch, sparc64_linux_supply_core_gregset,
241
                                sparc64_linux_collect_core_gregset);
242
  tdep->sizeof_gregset = 288;
243
 
244
  tdep->fpregset = regset_alloc (gdbarch, sparc64_linux_supply_core_fpregset,
245
                                 sparc64_linux_collect_core_fpregset);
246
  tdep->sizeof_fpregset = 280;
247
 
248
  tramp_frame_prepend_unwinder (gdbarch, &sparc64_linux_rt_sigframe);
249
 
250
  /* Hook in the DWARF CFI frame unwinder.  */
251
  dwarf2_append_unwinders (gdbarch);
252
 
253
  sparc64_init_abi (info, gdbarch);
254
 
255
  /* GNU/Linux has SVR4-style shared libraries...  */
256
  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
257
  set_solib_svr4_fetch_link_map_offsets
258
    (gdbarch, svr4_lp64_fetch_link_map_offsets);
259
 
260
  /* ...which means that we need some special handling when doing
261
     prologue analysis.  */
262
  tdep->plt_entry_size = 16;
263
 
264
  /* Enable TLS support.  */
265
  set_gdbarch_fetch_tls_load_module_address (gdbarch,
266
                                             svr4_fetch_objfile_link_map);
267
 
268
  /* Make sure we can single-step over signal return system calls.  */
269
  tdep->step_trap = sparc64_linux_step_trap;
270
 
271
  set_gdbarch_write_pc (gdbarch, sparc64_linux_write_pc);
272
 
273
  /* Functions for 'catch syscall'.  */
274
  set_xml_syscall_file_name (XML_SYSCALL_FILENAME_SPARC64);
275
  set_gdbarch_get_syscall_number (gdbarch,
276
                                  sparc64_linux_get_syscall_number);
277
}
278
 
279
 
280
/* Provide a prototype to silence -Wmissing-prototypes.  */
281
extern void _initialize_sparc64_linux_tdep (void);
282
 
283
void
284
_initialize_sparc64_linux_tdep (void)
285
{
286
  gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
287
                          GDB_OSABI_LINUX, sparc64_linux_init_abi);
288
}

powered by: WebSVN 2.1.0

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