xref: /openbsd-src/gnu/usr.bin/binutils/gdb/i386nbsd-nat.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /* Functions specific to running gdb native on an i386 running NetBSD
2    Copyright 1989, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
3 
4 This file is part of GDB.
5 
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19 
20 #include <sys/types.h>
21 #include <sys/ptrace.h>
22 #include <machine/reg.h>
23 #include <machine/frame.h>
24 #include <machine/pcb.h>
25 
26 #include "defs.h"
27 #include "inferior.h"
28 #include "target.h"
29 #include "gdbcore.h"
30 
31 void
32 fetch_inferior_registers (regno)
33      int regno;
34 {
35   struct reg inferior_registers;
36 
37   ptrace (PT_GETREGS, inferior_pid,
38 	  (PTRACE_ARG3_TYPE) &inferior_registers, 0);
39   memcpy (&registers[REGISTER_BYTE (0)], &inferior_registers,
40 	  sizeof(inferior_registers));
41 
42   /* FIXME: FP regs? */
43   registers_fetched ();
44 }
45 
46 void
47 store_inferior_registers (regno)
48      int regno;
49 {
50   struct reg inferior_registers;
51 
52   memcpy (&inferior_registers, &registers[REGISTER_BYTE (0)],
53 	  sizeof(inferior_registers));
54   ptrace (PT_SETREGS, inferior_pid,
55 	  (PTRACE_ARG3_TYPE) &inferior_registers, 0);
56 
57   /* FIXME: FP regs? */
58 }
59 
60 
61 /* XXX - Add this to machine/regs.h instead? */
62 struct md_core {
63   struct reg intreg;
64   struct fpreg freg;
65 };
66 
67 static struct fpreg i386_fp_registers;
68 static int i386_fp_read = 0;
69 
70 static void
71 fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
72      char *core_reg_sect;
73      unsigned core_reg_size;
74      int which;
75      unsigned int reg_addr;	/* Unused in this version */
76 {
77   struct md_core *core_reg;
78 
79   core_reg = (struct md_core *)core_reg_sect;
80 
81   /* We get everything from the .reg section. */
82   if (which != 0)
83     return;
84 
85   if (core_reg_size < sizeof(struct reg)) {
86     fprintf_unfiltered (gdb_stderr, "Couldn't read regs from core file\n");
87     return;
88   }
89 
90   /* Integer registers */
91   memcpy(&registers[REGISTER_BYTE (0)],
92 	 &core_reg->intreg, sizeof(struct reg));
93 
94   /* Floating point registers */
95   i386_fp_registers = core_reg->freg;
96   i386_fp_read = 1;
97 
98   registers_fetched ();
99 }
100 
101 /* Register that we are able to handle i386nbsd core file formats.
102    FIXME: is this really bfd_target_unknown_flavour? */
103 
104 static struct core_fns nat_core_fns =
105 {
106   bfd_target_unknown_flavour,
107   fetch_core_registers,
108   NULL
109 };
110 
111 void
112 _initialize_i386nbsd_nat ()
113 {
114   add_core_fns (&nat_core_fns);
115 }
116 
117 
118 /*
119  * kernel_u_size() is not helpful on NetBSD because
120  * the "u" struct is NOT in the core dump file.
121  */
122 
123 #ifdef	FETCH_KCORE_REGISTERS
124 /*
125  * Get registers from a kernel crash dump or live kernel.
126  * Called by kcore-nbsd.c:get_kcore_registers().
127  */
128 void
129 fetch_kcore_registers (pcb)
130      struct pcb *pcb;
131 {
132   int i, regno, regs[4];
133 
134   /*
135    * get the register values out of the sys pcb and
136    * store them where `read_register' will find them.
137    */
138   if (target_read_memory(pcb->pcb_tss.tss_esp+4,
139 			 (char *)regs, sizeof(regs)))
140     error("Cannot read ebx, esi, and edi.");
141   for (i = 0, regno = 0; regno < 3; regno++)
142     supply_register(regno, (char *)&i);
143   supply_register(3, (char *)&regs[2]);
144   supply_register(4, (char *)&pcb->pcb_tss.tss_esp);
145   supply_register(5, (char *)&pcb->pcb_tss.tss_ebp);
146   supply_register(6, (char *)&regs[1]);
147   supply_register(7, (char *)&regs[0]);
148   supply_register(8, (char *)&regs[3]);
149   for (i = 0, regno = 9; regno < 10; regno++)
150     supply_register(regno, (char *)&i);
151 #if 0
152   i = 0x08;
153   supply_register(10, (char *)&i);
154   i = 0x10;
155   supply_register(11, (char *)&i);
156 #endif
157 
158   /* The kernel does not use the FPU, so ignore it. */
159   registers_fetched ();
160 }
161 #endif	/* FETCH_KCORE_REGISTERS */
162 
163 #ifdef FLOAT_INFO
164 #include "language.h"			/* for local_hex_string */
165 #include "floatformat.h"
166 
167 #include <sys/param.h>
168 #include <sys/dir.h>
169 #include <signal.h>
170 #include <sys/ioctl.h>
171 #include <fcntl.h>
172 
173 #include <a.out.h>
174 
175 #include <sys/time.h>
176 #include <sys/resource.h>
177 #include <sys/uio.h>
178 #define curpcb Xcurpcb	/* XXX avoid leaking declaration from pcb.h */
179 #include <sys/user.h>
180 #undef curpcb
181 #include <sys/file.h>
182 #include "gdb_stat.h"
183 #include <sys/ptrace.h>
184 
185 extern void print_387_control_word ();		/* i387-tdep.h */
186 extern void print_387_status_word ();
187 
188 struct env387
189 {
190   unsigned short control;
191   unsigned short r0;
192   unsigned short status;
193   unsigned short r1;
194   unsigned short tag;
195   unsigned short r2;
196   unsigned long eip;
197   unsigned short code_seg;
198   unsigned short opcode;
199   unsigned long operand;
200   unsigned short operand_seg;
201   unsigned short r3;
202   unsigned char regs[8][10];
203 };
204 
205 static void
206 print_387_status (status, ep)
207      unsigned short status;
208      struct env387 *ep;
209 {
210   int i;
211   int bothstatus;
212   int top;
213   int fpreg;
214 
215   bothstatus = ((status != 0) && (ep->status != 0));
216   if (status != 0)
217     {
218       if (bothstatus)
219 	printf_unfiltered ("u: ");
220       print_387_status_word ((unsigned int)status);
221     }
222 
223   if (ep->status != 0)
224     {
225       if (bothstatus)
226 	printf_unfiltered ("e: ");
227       print_387_status_word ((unsigned int)ep->status);
228     }
229 
230   print_387_control_word ((unsigned int)ep->control);
231   printf_unfiltered ("last exception: ");
232   printf_unfiltered ("opcode %s; ", local_hex_string(ep->opcode));
233   printf_unfiltered ("pc %s:", local_hex_string(ep->code_seg));
234   printf_unfiltered ("%s; ", local_hex_string(ep->eip));
235   printf_unfiltered ("operand %s", local_hex_string(ep->operand_seg));
236   printf_unfiltered (":%s\n", local_hex_string(ep->operand));
237 
238   top = (ep->status >> 11) & 7;
239 
240   printf_unfiltered ("regno     tag  msb              lsb  value\n");
241   for (fpreg = 7; fpreg >= 0; fpreg--)
242     {
243       double val;
244 
245       printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : "  ", fpreg);
246 
247       switch ((ep->tag >> (fpreg * 2)) & 3)
248 	{
249 	case 0: printf_unfiltered ("valid "); break;
250 	case 1: printf_unfiltered ("zero  "); break;
251 	case 2: printf_unfiltered ("trap  "); break;
252 	case 3: printf_unfiltered ("empty "); break;
253 	}
254       for (i = 9; i >= 0; i--)
255 	printf_unfiltered ("%02x", ep->regs[fpreg][i]);
256 
257       floatformat_to_double(&floatformat_i387_ext, (char *) ep->regs[fpreg],
258 			      &val);
259       printf_unfiltered ("  %g\n", val);
260     }
261 }
262 
263 i386_float_info ()
264 {
265   extern int inferior_pid;
266 
267   if (inferior_pid)
268     {
269       ptrace (PT_GETFPREGS, inferior_pid, (PTRACE_ARG3_TYPE) &i386_fp_registers,
270 	      0);
271     }
272   else if (!i386_fp_read)
273     {
274       error ("The program has no floating point registers now.");
275     }
276 
277   print_387_status (0, (struct env387 *) &i386_fp_registers);
278 }
279 #endif
280