2000-12-22 Fernando Nasser <fnasser@redhat.com>
[deliverable/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 47void
fba45db2 48core_file_command (char *filename, int from_tty)
c906108c
SS
49{
50 int val;
c906108c
SS
51
52 /* Discard all vestiges of any previous core file
53 and mark data and stack spaces as empty. */
54
55 if (corefile)
b8c9b27d 56 xfree (corefile);
c906108c
SS
57 corefile = 0;
58
59 if (corechan >= 0)
60 close (corechan);
61 corechan = -1;
62
63 data_start = 0;
64 data_end = 0;
65 stack_start = STACK_END_ADDR;
66 stack_end = STACK_END_ADDR;
67
68 /* Now, if a new core file was specified, open it and digest it. */
69
70 if (filename)
71 {
72 filename = tilde_expand (filename);
b8c9b27d 73 make_cleanup (xfree, filename);
c5aa993b 74
c906108c
SS
75 if (have_inferior_p ())
76 error ("To look at a core file, you must kill the program with \"kill\".");
77 corechan = open (filename, O_RDONLY, 0);
78 if (corechan < 0)
79 perror_with_name (filename);
80
81 {
82 struct core corestr;
83
84 val = myread (corechan, &corestr, sizeof corestr);
85 if (val < 0)
86 perror_with_name (filename);
87 if (corestr.c_magic != CORE_MAGIC)
88 error ("\"%s\" does not appear to be a core dump file (magic 0x%x, expected 0x%x)",
89 filename, corestr.c_magic, (int) CORE_MAGIC);
90 else if (sizeof (struct core) != corestr.c_len)
c5aa993b
JM
91 error ("\"%s\" has an invalid struct core length (%d, expected %d)",
92 filename, corestr.c_len, (int) sizeof (struct core));
c906108c
SS
93
94 data_start = exec_data_start;
95 data_end = data_start + corestr.c_dsize;
96 stack_start = stack_end - corestr.c_ssize;
97 data_offset = sizeof corestr;
98 stack_offset = sizeof corestr + corestr.c_dsize;
99
100 memcpy (registers, &corestr.c_regs, sizeof corestr.c_regs);
101
102 memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)],
c5aa993b
JM
103 corestr.c_fpu.f_fpstatus.f_st,
104 sizeof corestr.c_fpu.f_fpstatus.f_st);
c906108c 105 memcpy (&registers[REGISTER_BYTE (FPC_REGNUM)],
c5aa993b
JM
106 &corestr.c_fpu.f_fpstatus.f_ctrl,
107 sizeof corestr.c_fpu.f_fpstatus -
108 sizeof corestr.c_fpu.f_fpstatus.f_st);
c906108c
SS
109
110 /* the struct aouthdr of sun coff is not the struct exec stored
111 in the core file. */
112 memcpy (&core_aouthdr, &corestr.c_aouthdr, sizeof (struct exec));
113#ifndef COFF_ENCAPSULATE
114 core_aouthdr.magic = corestr.c_aouthdr.a_info;
c5aa993b 115 core_aouthdr.vstamp = /*SUNVERSION */ 31252;
c906108c
SS
116#endif
117 printf_unfiltered ("Core file is from \"%s\".\n", corestr.c_cmdname);
118 if (corestr.c_signo > 0)
119 printf_unfiltered ("Program terminated with signal %d, %s.\n",
c5aa993b 120 corestr.c_signo, safe_strsignal (corestr.c_signo));
c906108c
SS
121 }
122 if (filename[0] == '/')
123 corefile = savestring (filename, strlen (filename));
124 else
125 {
126 corefile = concat (current_directory, "/", filename, NULL);
127 }
128
129 flush_cached_frames ();
130 select_frame (get_current_frame (), 0);
131
132 validate_files ();
133 }
134 else if (from_tty)
135 printf_unfiltered ("No core file now.\n");
136}
137
fba45db2 138i387_to_double (char *from, char *to)
c906108c
SS
139{
140 long *lp;
141 /* push extended mode on 387 stack, then pop in double mode
c5aa993b 142
c906108c
SS
143 * first, set exception masks so no error is generated -
144 * number will be rounded to inf or 0, if necessary
145 */
c5aa993b 146 asm ("pushl %eax"); /* grab a stack slot */
c906108c
SS
147 asm ("fstcw (%esp)"); /* get 387 control word */
148 asm ("movl (%esp),%eax"); /* save old value */
c5aa993b 149 asm ("orl $0x3f,%eax"); /* mask all exceptions */
c906108c
SS
150 asm ("pushl %eax");
151 asm ("fldcw (%esp)"); /* load new value into 387 */
c5aa993b 152
c906108c
SS
153 asm ("movl 8(%ebp),%eax");
154 asm ("fldt (%eax)"); /* push extended number on 387 stack */
155 asm ("fwait");
156 asm ("movl 12(%ebp),%eax");
157 asm ("fstpl (%eax)"); /* pop double */
158 asm ("fwait");
c5aa993b 159
c906108c 160 asm ("popl %eax"); /* flush modified control word */
c5aa993b 161 asm ("fnclex"); /* clear exceptions */
c906108c
SS
162 asm ("fldcw (%esp)"); /* restore original control word */
163 asm ("popl %eax"); /* flush saved copy */
164}
165
fba45db2 166double_to_i387 (char *from, char *to)
c906108c
SS
167{
168 /* push double mode on 387 stack, then pop in extended mode
169 * no errors are possible because every 64-bit pattern
170 * can be converted to an extended
171 */
172 asm ("movl 8(%ebp),%eax");
173 asm ("fldl (%eax)");
174 asm ("fwait");
175 asm ("movl 12(%ebp),%eax");
176 asm ("fstpt (%eax)");
177 asm ("fwait");
178}
179
180void
fba45db2 181fetch_inferior_registers (int regno)
c906108c
SS
182{
183 struct regs inferior_registers;
184 struct fp_state inferior_fp_registers;
c906108c
SS
185
186 registers_fetched ();
187
188 ptrace (PTRACE_GETREGS, inferior_pid,
c5aa993b 189 (PTRACE_ARG3_TYPE) & inferior_registers);
c906108c 190 ptrace (PTRACE_GETFPREGS, inferior_pid,
c5aa993b 191 (PTRACE_ARG3_TYPE) & inferior_fp_registers);
c906108c
SS
192
193 memcpy (registers, &inferior_registers, sizeof inferior_registers);
194
c5aa993b
JM
195 memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], inferior_fp_registers.f_st,
196 sizeof inferior_fp_registers.f_st);
c906108c 197 memcpy (&registers[REGISTER_BYTE (FPC_REGNUM)],
c5aa993b
JM
198 &inferior_fp_registers.f_ctrl,
199 sizeof inferior_fp_registers - sizeof inferior_fp_registers.f_st);
c906108c
SS
200}
201
202/* Store our register values back into the inferior.
203 If REGNO is -1, do this for all registers.
204 Otherwise, REGNO specifies which register (so we can save time). */
205
206void
fba45db2 207store_inferior_registers (int regno)
c906108c
SS
208{
209 struct regs inferior_registers;
210 struct fp_state inferior_fp_registers;
c906108c
SS
211
212 memcpy (&inferior_registers, registers, 20 * 4);
213
214 memcpy (inferior_fp_registers.f_st,
c5aa993b
JM
215 &registers[REGISTER_BYTE (FP0_REGNUM)],
216 sizeof inferior_fp_registers.f_st);
c906108c 217 memcpy (&inferior_fp_registers.f_ctrl,
c5aa993b
JM
218 &registers[REGISTER_BYTE (FPC_REGNUM)],
219 sizeof inferior_fp_registers - sizeof inferior_fp_registers.f_st);
220
c906108c
SS
221#ifdef PTRACE_FP_BUG
222 if (regno == FP_REGNUM || regno == -1)
223 /* Storing the frame pointer requires a gross hack, in which an
224 instruction that moves eax into ebp gets single-stepped. */
225 {
226 int stack = inferior_registers.r_reg[SP_REGNUM];
227 int stuff = ptrace (PTRACE_PEEKDATA, inferior_pid,
228 (PTRACE_ARG3_TYPE) stack);
229 int reg = inferior_registers.r_reg[EAX];
230 inferior_registers.r_reg[EAX] =
231 inferior_registers.r_reg[FP_REGNUM];
c5aa993b
JM
232 ptrace (PTRACE_SETREGS, inferior_pid,
233 (PTRACE_ARG3_TYPE) & inferior_registers);
c906108c
SS
234 ptrace (PTRACE_POKEDATA, inferior_pid, (PTRACE_ARG3_TYPE) stack,
235 0xc589);
236 ptrace (PTRACE_SINGLESTEP, inferior_pid, (PTRACE_ARG3_TYPE) stack,
237 0);
238 wait (0);
239 ptrace (PTRACE_POKEDATA, inferior_pid, (PTRACE_ARG3_TYPE) stack,
240 stuff);
241 inferior_registers.r_reg[EAX] = reg;
242 }
243#endif
244 ptrace (PTRACE_SETREGS, inferior_pid,
c5aa993b 245 (PTRACE_ARG3_TYPE) & inferior_registers);
c906108c 246 ptrace (PTRACE_SETFPREGS, inferior_pid,
c5aa993b 247 (PTRACE_ARG3_TYPE) & inferior_fp_registers);
c906108c 248}
This page took 0.098945 seconds and 4 git commands to generate.