]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/sun386-nat.c
import gdb-1999-07-07 post reformat
[thirdparty/binutils-gdb.git] / gdb / sun386-nat.c
CommitLineData
c906108c
SS
1/* Native support for Sun 386i's for GDB, the GNU debugger.
2 Copyright (C) 1986, 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
3 Changes for sun386i by Jean Daniel Fekete (jdf@litp.univ-p6-7.fr),
4 C2V Paris, April 89.
5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
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 2 of the License, or
11 (at your option) any later version.
c906108c 12
c5aa993b
JM
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.
c906108c 17
c5aa993b
JM
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
c906108c
SS
22
23#include "defs.h"
24#include "frame.h"
25#include "inferior.h"
26#include "gdbcore.h"
27
28#include <sys/param.h>
29#include <sys/dir.h>
30#include <sys/user.h>
31#include <signal.h>
32#include <sys/ioctl.h>
33#include <fcntl.h>
34
35#include <sys/ptrace.h>
36#include <machine/reg.h>
37
38#include <sys/file.h>
39#include "gdb_stat.h"
40#include <sys/core.h>
c906108c 41\f
c5aa993b 42
c906108c
SS
43/* Machine-dependent code which would otherwise be in corefile.c */
44/* Work with core files, for GDB. */
c906108c 45\f
c5aa993b 46
c906108c
SS
47void
48core_file_command (filename, from_tty)
49 char *filename;
50 int from_tty;
51{
52 int val;
c906108c
SS
53
54 /* Discard all vestiges of any previous core file
55 and mark data and stack spaces as empty. */
56
57 if (corefile)
58 free (corefile);
59 corefile = 0;
60
61 if (corechan >= 0)
62 close (corechan);
63 corechan = -1;
64
65 data_start = 0;
66 data_end = 0;
67 stack_start = STACK_END_ADDR;
68 stack_end = STACK_END_ADDR;
69
70 /* Now, if a new core file was specified, open it and digest it. */
71
72 if (filename)
73 {
74 filename = tilde_expand (filename);
75 make_cleanup (free, filename);
c5aa993b 76
c906108c
SS
77 if (have_inferior_p ())
78 error ("To look at a core file, you must kill the program with \"kill\".");
79 corechan = open (filename, O_RDONLY, 0);
80 if (corechan < 0)
81 perror_with_name (filename);
82
83 {
84 struct core corestr;
85
86 val = myread (corechan, &corestr, sizeof corestr);
87 if (val < 0)
88 perror_with_name (filename);
89 if (corestr.c_magic != CORE_MAGIC)
90 error ("\"%s\" does not appear to be a core dump file (magic 0x%x, expected 0x%x)",
91 filename, corestr.c_magic, (int) CORE_MAGIC);
92 else if (sizeof (struct core) != corestr.c_len)
c5aa993b
JM
93 error ("\"%s\" has an invalid struct core length (%d, expected %d)",
94 filename, corestr.c_len, (int) sizeof (struct core));
c906108c
SS
95
96 data_start = exec_data_start;
97 data_end = data_start + corestr.c_dsize;
98 stack_start = stack_end - corestr.c_ssize;
99 data_offset = sizeof corestr;
100 stack_offset = sizeof corestr + corestr.c_dsize;
101
102 memcpy (registers, &corestr.c_regs, sizeof corestr.c_regs);
103
104 memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)],
c5aa993b
JM
105 corestr.c_fpu.f_fpstatus.f_st,
106 sizeof corestr.c_fpu.f_fpstatus.f_st);
c906108c 107 memcpy (&registers[REGISTER_BYTE (FPC_REGNUM)],
c5aa993b
JM
108 &corestr.c_fpu.f_fpstatus.f_ctrl,
109 sizeof corestr.c_fpu.f_fpstatus -
110 sizeof corestr.c_fpu.f_fpstatus.f_st);
c906108c
SS
111
112 /* the struct aouthdr of sun coff is not the struct exec stored
113 in the core file. */
114 memcpy (&core_aouthdr, &corestr.c_aouthdr, sizeof (struct exec));
115#ifndef COFF_ENCAPSULATE
116 core_aouthdr.magic = corestr.c_aouthdr.a_info;
c5aa993b 117 core_aouthdr.vstamp = /*SUNVERSION */ 31252;
c906108c
SS
118#endif
119 printf_unfiltered ("Core file is from \"%s\".\n", corestr.c_cmdname);
120 if (corestr.c_signo > 0)
121 printf_unfiltered ("Program terminated with signal %d, %s.\n",
c5aa993b 122 corestr.c_signo, safe_strsignal (corestr.c_signo));
c906108c
SS
123 }
124 if (filename[0] == '/')
125 corefile = savestring (filename, strlen (filename));
126 else
127 {
128 corefile = concat (current_directory, "/", filename, NULL);
129 }
130
131 flush_cached_frames ();
132 select_frame (get_current_frame (), 0);
133
134 validate_files ();
135 }
136 else if (from_tty)
137 printf_unfiltered ("No core file now.\n");
138}
139
140i387_to_double (from, to)
141 char *from;
142 char *to;
143{
144 long *lp;
145 /* push extended mode on 387 stack, then pop in double mode
c5aa993b 146
c906108c
SS
147 * first, set exception masks so no error is generated -
148 * number will be rounded to inf or 0, if necessary
149 */
c5aa993b 150 asm ("pushl %eax"); /* grab a stack slot */
c906108c
SS
151 asm ("fstcw (%esp)"); /* get 387 control word */
152 asm ("movl (%esp),%eax"); /* save old value */
c5aa993b 153 asm ("orl $0x3f,%eax"); /* mask all exceptions */
c906108c
SS
154 asm ("pushl %eax");
155 asm ("fldcw (%esp)"); /* load new value into 387 */
c5aa993b 156
c906108c
SS
157 asm ("movl 8(%ebp),%eax");
158 asm ("fldt (%eax)"); /* push extended number on 387 stack */
159 asm ("fwait");
160 asm ("movl 12(%ebp),%eax");
161 asm ("fstpl (%eax)"); /* pop double */
162 asm ("fwait");
c5aa993b 163
c906108c 164 asm ("popl %eax"); /* flush modified control word */
c5aa993b 165 asm ("fnclex"); /* clear exceptions */
c906108c
SS
166 asm ("fldcw (%esp)"); /* restore original control word */
167 asm ("popl %eax"); /* flush saved copy */
168}
169
170double_to_i387 (from, to)
171 char *from;
172 char *to;
173{
174 /* push double mode on 387 stack, then pop in extended mode
175 * no errors are possible because every 64-bit pattern
176 * can be converted to an extended
177 */
178 asm ("movl 8(%ebp),%eax");
179 asm ("fldl (%eax)");
180 asm ("fwait");
181 asm ("movl 12(%ebp),%eax");
182 asm ("fstpt (%eax)");
183 asm ("fwait");
184}
185
186void
187fetch_inferior_registers (regno)
188 int regno;
189{
190 struct regs inferior_registers;
191 struct fp_state inferior_fp_registers;
c906108c
SS
192
193 registers_fetched ();
194
195 ptrace (PTRACE_GETREGS, inferior_pid,
c5aa993b 196 (PTRACE_ARG3_TYPE) & inferior_registers);
c906108c 197 ptrace (PTRACE_GETFPREGS, inferior_pid,
c5aa993b 198 (PTRACE_ARG3_TYPE) & inferior_fp_registers);
c906108c
SS
199
200 memcpy (registers, &inferior_registers, sizeof inferior_registers);
201
c5aa993b
JM
202 memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], inferior_fp_registers.f_st,
203 sizeof inferior_fp_registers.f_st);
c906108c 204 memcpy (&registers[REGISTER_BYTE (FPC_REGNUM)],
c5aa993b
JM
205 &inferior_fp_registers.f_ctrl,
206 sizeof inferior_fp_registers - sizeof inferior_fp_registers.f_st);
c906108c
SS
207}
208
209/* Store our register values back into the inferior.
210 If REGNO is -1, do this for all registers.
211 Otherwise, REGNO specifies which register (so we can save time). */
212
213void
214store_inferior_registers (regno)
215 int regno;
216{
217 struct regs inferior_registers;
218 struct fp_state inferior_fp_registers;
c906108c
SS
219
220 memcpy (&inferior_registers, registers, 20 * 4);
221
222 memcpy (inferior_fp_registers.f_st,
c5aa993b
JM
223 &registers[REGISTER_BYTE (FP0_REGNUM)],
224 sizeof inferior_fp_registers.f_st);
c906108c 225 memcpy (&inferior_fp_registers.f_ctrl,
c5aa993b
JM
226 &registers[REGISTER_BYTE (FPC_REGNUM)],
227 sizeof inferior_fp_registers - sizeof inferior_fp_registers.f_st);
228
c906108c
SS
229#ifdef PTRACE_FP_BUG
230 if (regno == FP_REGNUM || regno == -1)
231 /* Storing the frame pointer requires a gross hack, in which an
232 instruction that moves eax into ebp gets single-stepped. */
233 {
234 int stack = inferior_registers.r_reg[SP_REGNUM];
235 int stuff = ptrace (PTRACE_PEEKDATA, inferior_pid,
236 (PTRACE_ARG3_TYPE) stack);
237 int reg = inferior_registers.r_reg[EAX];
238 inferior_registers.r_reg[EAX] =
239 inferior_registers.r_reg[FP_REGNUM];
c5aa993b
JM
240 ptrace (PTRACE_SETREGS, inferior_pid,
241 (PTRACE_ARG3_TYPE) & inferior_registers);
c906108c
SS
242 ptrace (PTRACE_POKEDATA, inferior_pid, (PTRACE_ARG3_TYPE) stack,
243 0xc589);
244 ptrace (PTRACE_SINGLESTEP, inferior_pid, (PTRACE_ARG3_TYPE) stack,
245 0);
246 wait (0);
247 ptrace (PTRACE_POKEDATA, inferior_pid, (PTRACE_ARG3_TYPE) stack,
248 stuff);
249 inferior_registers.r_reg[EAX] = reg;
250 }
251#endif
252 ptrace (PTRACE_SETREGS, inferior_pid,
c5aa993b 253 (PTRACE_ARG3_TYPE) & inferior_registers);
c906108c 254 ptrace (PTRACE_SETFPREGS, inferior_pid,
c5aa993b 255 (PTRACE_ARG3_TYPE) & inferior_fp_registers);
c906108c 256}