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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [i386nbsd-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/i386, for GDB.
2
   Copyright 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001, 2002
3
   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 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 "gdbtypes.h"
24
#include "gdbcore.h"
25
#include "regcache.h"
26
#include "arch-utils.h"
27
 
28
#include "i386-tdep.h"
29
#include "i387-tdep.h"
30
#include "nbsd-tdep.h"
31
 
32
#include "solib-svr4.h"
33
 
34
/* Map a GDB register number to an offset in the reg structure.  */
35
static int regmap[] =
36
{
37
  ( 0 * 4),              /* %eax */
38
  ( 1 * 4),             /* %ecx */
39
  ( 2 * 4),             /* %edx */
40
  ( 3 * 4),             /* %ebx */
41
  ( 4 * 4),             /* %esp */
42
  ( 5 * 4),             /* %epb */
43
  ( 6 * 4),             /* %esi */
44
  ( 7 * 4),             /* %edi */
45
  ( 8 * 4),             /* %eip */
46
  ( 9 * 4),             /* %eflags */
47
  (10 * 4),             /* %cs */
48
  (11 * 4),             /* %ss */
49
  (12 * 4),             /* %ds */
50
  (13 * 4),             /* %es */
51
  (14 * 4),             /* %fs */
52
  (15 * 4),             /* %gs */
53
};
54
 
55
#define SIZEOF_STRUCT_REG       (16 * 4)
56
 
57
static void
58
i386nbsd_supply_reg (char *regs, int regno)
59
{
60
  int i;
61
 
62
  for (i = 0; i <= 15; i++)
63
    if (regno == i || regno == -1)
64
      supply_register (i, regs + regmap[i]);
65
}
66
 
67
static void
68
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
69
                      CORE_ADDR ignore)
70
{
71
  char *regs, *fsave;
72
 
73
  /* We get everything from one section.  */
74
  if (which != 0)
75
    return;
76
 
77
  if (core_reg_size < (SIZEOF_STRUCT_REG + 108))
78
    {
79
      warning ("Wrong size register set in core file.");
80
      return;
81
    }
82
 
83
  regs = core_reg_sect;
84
  fsave = core_reg_sect + SIZEOF_STRUCT_REG;
85
 
86
  /* Integer registers.  */
87
  i386nbsd_supply_reg (regs, -1);
88
 
89
  /* Floating point registers.  */
90
  i387_supply_fsave (fsave);
91
}
92
 
93
static void
94
fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size,
95
                         int which, CORE_ADDR ignore)
96
{
97
  switch (which)
98
    {
99
    case 0:  /* Integer registers.  */
100
      if (core_reg_size != SIZEOF_STRUCT_REG)
101
        warning ("Wrong size register set in core file.");
102
      else
103
        i386nbsd_supply_reg (core_reg_sect, -1);
104
      break;
105
 
106
    case 2:  /* Floating point registers.  */
107
      if (core_reg_size != 108)
108
        warning ("Wrong size FP register set in core file.");
109
      else
110
        i387_supply_fsave (core_reg_sect);
111
      break;
112
 
113
    case 3:  /* "Extended" floating point registers.  This is gdb-speak
114
                for SSE/SSE2. */
115
      if (core_reg_size != 512)
116
        warning ("Wrong size XMM register set in core file.");
117
      else
118
        i387_supply_fxsave (core_reg_sect);
119
      break;
120
 
121
    default:
122
      /* Don't know what kind of register request this is; just ignore it.  */
123
      break;
124
    }
125
}
126
 
127
static struct core_fns i386nbsd_core_fns =
128
{
129
  bfd_target_unknown_flavour,           /* core_flavour */
130
  default_check_format,                 /* check_format */
131
  default_core_sniffer,                 /* core_sniffer */
132
  fetch_core_registers,                 /* core_read_registers */
133
  NULL                                  /* next */
134
};
135
 
136
static struct core_fns i386nbsd_elfcore_fns =
137
{
138
  bfd_target_elf_flavour,               /* core_flavour */
139
  default_check_format,                 /* check_format */
140
  default_core_sniffer,                 /* core_sniffer */
141
  fetch_elfcore_registers,              /* core_read_registers */
142
  NULL                                  /* next */
143
};
144
 
145
/* Under NetBSD/i386, signal handler invocations can be identified by the
146
   designated code sequence that is used to return from a signal handler.
147
   In particular, the return address of a signal handler points to the
148
   following code sequence:
149
 
150
        leal    0x10(%esp), %eax
151
        pushl   %eax
152
        pushl   %eax
153
        movl    $0x127, %eax            # __sigreturn14
154
        int     $0x80
155
 
156
   Each instruction has a unique encoding, so we simply attempt to match
157
   the instruction the PC is pointing to with any of the above instructions.
158
   If there is a hit, we know the offset to the start of the designated
159
   sequence and can then check whether we really are executing in the
160
   signal trampoline.  If not, -1 is returned, otherwise the offset from the
161
   start of the return sequence is returned.  */
162
#define RETCODE_INSN1           0x8d
163
#define RETCODE_INSN2           0x50
164
#define RETCODE_INSN3           0x50
165
#define RETCODE_INSN4           0xb8
166
#define RETCODE_INSN5           0xcd
167
 
168
#define RETCODE_INSN2_OFF       4
169
#define RETCODE_INSN3_OFF       5
170
#define RETCODE_INSN4_OFF       6
171
#define RETCODE_INSN5_OFF       11
172
 
173
static const unsigned char sigtramp_retcode[] =
174
{
175
  RETCODE_INSN1, 0x44, 0x24, 0x10,
176
  RETCODE_INSN2,
177
  RETCODE_INSN3,
178
  RETCODE_INSN4, 0x27, 0x01, 0x00, 0x00,
179
  RETCODE_INSN5, 0x80,
180
};
181
 
182
static LONGEST
183
i386nbsd_sigtramp_offset (CORE_ADDR pc)
184
{
185
  unsigned char ret[sizeof(sigtramp_retcode)], insn;
186
  LONGEST off;
187
  int i;
188
 
189
  if (read_memory_nobpt (pc, &insn, 1) != 0)
190
    return -1;
191
 
192
  switch (insn)
193
    {
194
    case RETCODE_INSN1:
195
      off = 0;
196
      break;
197
 
198
    case RETCODE_INSN2:
199
      /* INSN2 and INSN3 are the same.  Read at the location of PC+1
200
         to determine if we're actually looking at INSN2 or INSN3.  */
201
      if (read_memory_nobpt (pc + 1, &insn, 1) != 0)
202
        return -1;
203
 
204
      if (insn == RETCODE_INSN3)
205
        off = RETCODE_INSN2_OFF;
206
      else
207
        off = RETCODE_INSN3_OFF;
208
      break;
209
 
210
    case RETCODE_INSN4:
211
      off = RETCODE_INSN4_OFF;
212
      break;
213
 
214
    case RETCODE_INSN5:
215
      off = RETCODE_INSN5_OFF;
216
      break;
217
 
218
    default:
219
      return -1;
220
    }
221
 
222
  pc -= off;
223
 
224
  if (read_memory_nobpt (pc, (char *) ret, sizeof (ret)) != 0)
225
    return -1;
226
 
227
  if (memcmp (ret, sigtramp_retcode, sizeof (ret)) == 0)
228
    return off;
229
 
230
  return -1;
231
}
232
 
233
static int
234
i386nbsd_pc_in_sigtramp (CORE_ADDR pc, char *name)
235
{
236
 
237
  return (nbsd_pc_in_sigtramp (pc, name)
238
          || i386nbsd_sigtramp_offset (pc) >= 0);
239
}
240
 
241
/* From <machine/signal.h>.  */
242
int i386nbsd_sc_pc_offset = 44;
243
int i386nbsd_sc_sp_offset = 56;
244
 
245
static void
246
i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
247
{
248
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
249
 
250
  /* Obviously NetBSD is BSD-based.  */
251
  i386bsd_init_abi (info, gdbarch);
252
 
253
  /* NetBSD has different signal trampoline conventions.  */
254
  set_gdbarch_pc_in_sigtramp (gdbarch, i386nbsd_pc_in_sigtramp);
255
 
256
  /* NetBSD uses -freg-struct-return by default.  */
257
  tdep->struct_return = reg_struct_return;
258
 
259
  /* NetBSD has a `struct sigcontext' that's different from the
260
     origional 4.3 BSD.  */
261
  tdep->sc_pc_offset = i386nbsd_sc_pc_offset;
262
  tdep->sc_sp_offset = i386nbsd_sc_sp_offset;
263
}
264
 
265
/* NetBSD ELF.  */
266
static void
267
i386nbsdelf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
268
{
269
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
270
 
271
  /* It's still NetBSD.  */
272
  i386nbsd_init_abi (info, gdbarch);
273
 
274
  /* But ELF-based.  */
275
  i386_elf_init_abi (info, gdbarch);
276
 
277
  /* NetBSD ELF uses SVR4-style shared libraries.  */
278
  set_gdbarch_in_solib_call_trampoline (gdbarch,
279
                                        generic_in_solib_call_trampoline);
280
  set_solib_svr4_fetch_link_map_offsets (gdbarch,
281
                                 nbsd_ilp32_solib_svr4_fetch_link_map_offsets);
282
 
283
  /* NetBSD ELF uses -fpcc-struct-return by default.  */
284
  tdep->struct_return = pcc_struct_return;
285
 
286
  /* We support the SSE registers on NetBSD ELF.  */
287
  tdep->num_xmm_regs = I386_NUM_XREGS - 1;
288
  set_gdbarch_num_regs (gdbarch, I386_NUM_GREGS + I386_NUM_FREGS
289
                        + I386_NUM_XREGS);
290
}
291
 
292
void
293
_initialize_i386nbsd_tdep (void)
294
{
295
  add_core_fns (&i386nbsd_core_fns);
296
  add_core_fns (&i386nbsd_elfcore_fns);
297
 
298
  gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_NETBSD_AOUT,
299
                          i386nbsd_init_abi);
300
  gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_NETBSD_ELF,
301
                          i386nbsdelf_init_abi);
302
}

powered by: WebSVN 2.1.0

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