* config/i386/i386sol2.mt (TDEPFILES): Add i386-sol2-tdep.o and
[platform/upstream/binutils.git] / gdb / i386nbsd-tdep.c
1 /* 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
27 #include "i387-tdep.h"
28
29 /* Map a GDB register number to an offset in the reg structure.  */
30 static int regmap[] =
31 {
32   ( 0 * 4),             /* %eax */
33   ( 1 * 4),             /* %ecx */
34   ( 2 * 4),             /* %edx */
35   ( 3 * 4),             /* %ebx */
36   ( 4 * 4),             /* %esp */
37   ( 5 * 4),             /* %epb */
38   ( 6 * 4),             /* %esi */
39   ( 7 * 4),             /* %edi */
40   ( 8 * 4),             /* %eip */
41   ( 9 * 4),             /* %eflags */
42   (10 * 4),             /* %cs */
43   (11 * 4),             /* %ss */
44   (12 * 4),             /* %ds */
45   (13 * 4),             /* %es */
46   (14 * 4),             /* %fs */
47   (15 * 4),             /* %gs */
48 };
49
50 #define SIZEOF_STRUCT_REG       (16 * 4)
51
52 static void
53 i386nbsd_supply_reg (char *regs, int regno)
54 {
55   int i;
56
57   for (i = 0; i <= 15; i++)
58     if (regno == i || regno == -1)
59       supply_register (i, regs + regmap[i]);
60 }
61
62 static void
63 fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
64                       CORE_ADDR ignore)
65 {
66   char *regs, *fsave;
67
68   /* We get everything from one section.  */
69   if (which != 0)
70     return;
71
72   if (core_reg_size < (SIZEOF_STRUCT_REG + 108))
73     {
74       warning ("Wrong size register set in core file.");
75       return;
76     }
77
78   regs = core_reg_sect;
79   fsave = core_reg_sect + SIZEOF_STRUCT_REG;
80
81   /* Integer registers.  */
82   i386nbsd_supply_reg (regs, -1);
83
84   /* Floating point registers.  */
85   i387_supply_fsave (fsave);
86 }
87
88 static void
89 fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which,
90                          CORE_ADDR ignore)
91 {
92   switch (which)
93     {
94     case 0:  /* Integer registers.  */
95       if (core_reg_size != SIZEOF_STRUCT_REG)
96         warning ("Wrong size register set in core file.");
97       else
98         i386nbsd_supply_reg (core_reg_sect, -1);
99       break;
100
101     case 2:  /* Floating point registers.  */
102       if (core_reg_size != 108)
103         warning ("Wrong size FP register set in core file."); 
104       else
105         i387_supply_fsave (core_reg_sect);  
106       break;
107
108     case 3:  /* "Extended" floating point registers.  This is gdb-speak
109                 for SSE/SSE2. */
110       if (core_reg_size != 512)
111         warning ("Wrong size XMM register set in core file.");
112       else
113         i387_supply_fxsave (core_reg_sect);
114       break;
115
116     default:
117       /* Don't know what kind of register request this is; just ignore it.  */
118       break;
119     }
120 }
121
122 static struct core_fns i386nbsd_core_fns =
123 {
124   bfd_target_unknown_flavour,           /* core_flavour */
125   default_check_format,                 /* check_format */
126   default_core_sniffer,                 /* core_sniffer */
127   fetch_core_registers,                 /* core_read_registers */
128   NULL                                  /* next */
129 };
130
131 static struct core_fns i386nbsd_elfcore_fns =
132 {
133   bfd_target_elf_flavour,               /* core_flavour */
134   default_check_format,                 /* check_format */
135   default_core_sniffer,                 /* core_sniffer */
136   fetch_elfcore_registers,              /* core_read_registers */
137   NULL                                  /* next */
138 };
139
140 void
141 _initialize_i386nbsd_tdep (void)
142 {
143   add_core_fns (&i386nbsd_core_fns);
144   add_core_fns (&i386nbsd_elfcore_fns);
145 }