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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [alphanbsd-tdep.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* Target-dependent code for NetBSD/Alpha.
2
   Copyright 2002 Free Software Foundation, Inc.
3
   Contributed by Wasabi Systems, 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 2 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, write to the Free Software
19
   Foundation, Inc., 59 Temple Place - Suite 330,
20
   Boston, MA 02111-1307, USA.  */
21
 
22
#include "defs.h"
23
#include "gdbcore.h"
24
#include "frame.h"
25
#include "regcache.h"
26
#include "value.h"
27
 
28
#include "solib-svr4.h"
29
 
30
#include "alpha-tdep.h"
31
#include "alphabsd-tdep.h"
32
#include "nbsd-tdep.h"
33
 
34
static void
35
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
36
                      CORE_ADDR ignore)
37
{
38
  char *regs, *fpregs;
39
  int regno;
40
 
41
  /* Table to map a gdb register number to a trapframe register index.  */
42
  static const int regmap[] =
43
  {
44
     0,   1,   2,   3,
45
     4,   5,   6,   7,
46
     8,   9,  10,  11,
47
    12,  13,  14,  15,
48
    30,  31,  32,  16,
49
    17,  18,  19,  20,
50
    21,  22,  23,  24,
51
    25,  29,  26
52
  };
53
#define SIZEOF_TRAPFRAME (33 * 8)
54
 
55
  /* We get everything from one section.  */
56
  if (which != 0)
57
    return;
58
 
59
  regs = core_reg_sect;
60
  fpregs = core_reg_sect + SIZEOF_TRAPFRAME;
61
 
62
  if (core_reg_size < (SIZEOF_TRAPFRAME + SIZEOF_STRUCT_FPREG))
63
    {
64
      warning ("Wrong size register set in core file.");
65
      return;
66
    }
67
 
68
  /* Integer registers.  */
69
  for (regno = 0; regno < ALPHA_ZERO_REGNUM; regno++)
70
    supply_register (regno, regs + (regmap[regno] * 8));
71
  supply_register (ALPHA_ZERO_REGNUM, NULL);
72
  supply_register (FP_REGNUM, NULL);
73
  supply_register (PC_REGNUM, regs + (28 * 8));
74
 
75
  /* Floating point registers.  */
76
  alphabsd_supply_fpreg (fpregs, -1);
77
}
78
 
79
static void
80
fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which,
81
                         CORE_ADDR ignore)
82
{
83
  switch (which)
84
    {
85
    case 0:  /* Integer registers.  */
86
      if (core_reg_size != SIZEOF_STRUCT_REG)
87
        warning ("Wrong size register set in core file.");
88
      else
89
        alphabsd_supply_reg (core_reg_sect, -1);
90
      break;
91
 
92
    case 2:  /* Floating point registers.  */
93
      if (core_reg_size != SIZEOF_STRUCT_FPREG)
94
        warning ("Wrong size FP register set in core file.");
95
      else
96
        alphabsd_supply_fpreg (core_reg_sect, -1);
97
      break;
98
 
99
    default:
100
      /* Don't know what kind of register request this is; just ignore it.  */
101
      break;
102
    }
103
}
104
 
105
static struct core_fns alphanbsd_core_fns =
106
{
107
  bfd_target_unknown_flavour,           /* core_flavour */
108
  default_check_format,                 /* check_format */
109
  default_core_sniffer,                 /* core_sniffer */
110
  fetch_core_registers,                 /* core_read_registers */
111
  NULL                                  /* next */
112
};
113
 
114
static struct core_fns alphanbsd_elfcore_fns =
115
{
116
  bfd_target_elf_flavour,               /* core_flavour */
117
  default_check_format,                 /* check_format */
118
  default_core_sniffer,                 /* core_sniffer */
119
  fetch_elfcore_registers,              /* core_read_registers */
120
  NULL                                  /* next */
121
};
122
 
123
/* Under NetBSD/alpha, signal handler invocations can be identified by the
124
   designated code sequence that is used to return from a signal handler.
125
   In particular, the return address of a signal handler points to the
126
   following code sequence:
127
 
128
        ldq     a0, 0(sp)
129
        lda     sp, 16(sp)
130
        lda     v0, 295(zero)   # __sigreturn14
131
        call_pal callsys
132
 
133
   Each instruction has a unique encoding, so we simply attempt to match
134
   the instruction the PC is pointing to with any of the above instructions.
135
   If there is a hit, we know the offset to the start of the designated
136
   sequence and can then check whether we really are executing in the
137
   signal trampoline.  If not, -1 is returned, otherwise the offset from the
138
   start of the return sequence is returned.  */
139
static const unsigned char sigtramp_retcode[] =
140
{
141
  0x00, 0x00, 0x1e, 0xa6,       /* ldq a0, 0(sp) */
142
  0x10, 0x00, 0xde, 0x23,       /* lda sp, 16(sp) */
143
  0x27, 0x01, 0x1f, 0x20,       /* lda v0, 295(zero) */
144
  0x83, 0x00, 0x00, 0x00,       /* call_pal callsys */
145
};
146
#define RETCODE_NWORDS          4
147
#define RETCODE_SIZE            (RETCODE_NWORDS * 4)
148
 
149
LONGEST
150
alphanbsd_sigtramp_offset (CORE_ADDR pc)
151
{
152
  unsigned char ret[RETCODE_SIZE], w[4];
153
  LONGEST off;
154
  int i;
155
 
156
  if (read_memory_nobpt (pc, (char *) w, 4) != 0)
157
    return -1;
158
 
159
  for (i = 0; i < RETCODE_NWORDS; i++)
160
    {
161
      if (memcmp (w, sigtramp_retcode + (i * 4), 4) == 0)
162
        break;
163
    }
164
  if (i == RETCODE_NWORDS)
165
    return (-1);
166
 
167
  off = i * 4;
168
  pc -= off;
169
 
170
  if (read_memory_nobpt (pc, (char *) ret, sizeof (ret)) != 0)
171
    return -1;
172
 
173
  if (memcmp (ret, sigtramp_retcode, RETCODE_SIZE) == 0)
174
    return off;
175
 
176
  return -1;
177
}
178
 
179
static int
180
alphanbsd_pc_in_sigtramp (CORE_ADDR pc, char *func_name)
181
{
182
  return (nbsd_pc_in_sigtramp (pc, func_name)
183
          || alphanbsd_sigtramp_offset (pc) >= 0);
184
}
185
 
186
static CORE_ADDR
187
alphanbsd_sigcontext_addr (struct frame_info *frame)
188
{
189
  /* FIXME: This is not correct for all versions of NetBSD/alpha.
190
     We will probably need to disassemble the trampoline to figure
191
     out which trampoline frame type we have.  */
192
  return frame->frame;
193
}
194
 
195
static CORE_ADDR
196
alphanbsd_skip_sigtramp_frame (struct frame_info *frame, CORE_ADDR pc)
197
{
198
  char *name;
199
 
200
  /* FIXME: This is not correct for all versions of NetBSD/alpha.
201
     We will probably need to disassemble the trampoline to figure
202
     out which trampoline frame type we have.  */
203
  find_pc_partial_function (pc, &name, (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
204
  if (PC_IN_SIGTRAMP (pc, name))
205
    return frame->frame;
206
  return 0;
207
}
208
 
209
static void
210
alphanbsd_init_abi (struct gdbarch_info info,
211
                    struct gdbarch *gdbarch)
212
{
213
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
214
 
215
  set_gdbarch_pc_in_sigtramp (gdbarch, alphanbsd_pc_in_sigtramp);
216
 
217
  /* NetBSD/alpha does not provide single step support via ptrace(2); we
218
     must use software single-stepping.  */
219
  set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
220
 
221
  set_solib_svr4_fetch_link_map_offsets (gdbarch,
222
                                 nbsd_lp64_solib_svr4_fetch_link_map_offsets);
223
 
224
  tdep->skip_sigtramp_frame = alphanbsd_skip_sigtramp_frame;
225
  tdep->dynamic_sigtramp_offset = alphanbsd_sigtramp_offset;
226
  tdep->sigcontext_addr = alphanbsd_sigcontext_addr;
227
 
228
  tdep->jb_pc = 2;
229
  tdep->jb_elt_size = 8;
230
}
231
 
232
void
233
_initialize_alphanbsd_tdep (void)
234
{
235
  gdbarch_register_osabi (bfd_arch_alpha, GDB_OSABI_NETBSD_ELF,
236
                          alphanbsd_init_abi);
237
 
238
  add_core_fns (&alphanbsd_core_fns);
239
  add_core_fns (&alphanbsd_elfcore_fns);
240
}

powered by: WebSVN 2.1.0

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