Update/correct copyright notices.
[deliverable/binutils-gdb.git] / gdb / sun386-nat.c
CommitLineData
c906108c 1/* Native support for Sun 386i's for GDB, the GNU debugger.
b6ba6518
KB
2 Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1995, 1999, 2000, 2001
3 Free Software Foundation, Inc.
c906108c
SS
4 Changes for sun386i by Jean Daniel Fekete (jdf@litp.univ-p6-7.fr),
5 C2V Paris, April 89.
6
c5aa993b 7 This file is part of GDB.
c906108c 8
c5aa993b
JM
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
c906108c 13
c5aa993b
JM
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
c906108c 18
c5aa993b
JM
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
c906108c
SS
23
24#include "defs.h"
25#include "frame.h"
26#include "inferior.h"
27#include "gdbcore.h"
4e052eda 28#include "regcache.h"
c906108c
SS
29
30#include <sys/param.h>
31#include <sys/dir.h>
32#include <sys/user.h>
33#include <signal.h>
34#include <sys/ioctl.h>
35#include <fcntl.h>
36
37#include <sys/ptrace.h>
38#include <machine/reg.h>
39
40#include <sys/file.h>
41#include "gdb_stat.h"
42#include <sys/core.h>
c906108c 43\f
c5aa993b 44
c906108c
SS
45/* Machine-dependent code which would otherwise be in corefile.c */
46/* Work with core files, for GDB. */
c906108c 47\f
c5aa993b 48
c906108c 49void
fba45db2 50core_file_command (char *filename, int from_tty)
c906108c
SS
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)
b8c9b27d 58 xfree (corefile);
c906108c
SS
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);
b8c9b27d 75 make_cleanup (xfree, 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
fba45db2 140i387_to_double (char *from, char *to)
c906108c
SS
141{
142 long *lp;
143 /* push extended mode on 387 stack, then pop in double mode
c5aa993b 144
c906108c
SS
145 * first, set exception masks so no error is generated -
146 * number will be rounded to inf or 0, if necessary
147 */
c5aa993b 148 asm ("pushl %eax"); /* grab a stack slot */
c906108c
SS
149 asm ("fstcw (%esp)"); /* get 387 control word */
150 asm ("movl (%esp),%eax"); /* save old value */
c5aa993b 151 asm ("orl $0x3f,%eax"); /* mask all exceptions */
c906108c
SS
152 asm ("pushl %eax");
153 asm ("fldcw (%esp)"); /* load new value into 387 */
c5aa993b 154
c906108c
SS
155 asm ("movl 8(%ebp),%eax");
156 asm ("fldt (%eax)"); /* push extended number on 387 stack */
157 asm ("fwait");
158 asm ("movl 12(%ebp),%eax");
159 asm ("fstpl (%eax)"); /* pop double */
160 asm ("fwait");
c5aa993b 161
c906108c 162 asm ("popl %eax"); /* flush modified control word */
c5aa993b 163 asm ("fnclex"); /* clear exceptions */
c906108c
SS
164 asm ("fldcw (%esp)"); /* restore original control word */
165 asm ("popl %eax"); /* flush saved copy */
166}
167
fba45db2 168double_to_i387 (char *from, char *to)
c906108c
SS
169{
170 /* push double mode on 387 stack, then pop in extended mode
171 * no errors are possible because every 64-bit pattern
172 * can be converted to an extended
173 */
174 asm ("movl 8(%ebp),%eax");
175 asm ("fldl (%eax)");
176 asm ("fwait");
177 asm ("movl 12(%ebp),%eax");
178 asm ("fstpt (%eax)");
179 asm ("fwait");
180}
181
182void
fba45db2 183fetch_inferior_registers (int regno)
c906108c
SS
184{
185 struct regs inferior_registers;
186 struct fp_state inferior_fp_registers;
c906108c
SS
187
188 registers_fetched ();
189
190 ptrace (PTRACE_GETREGS, inferior_pid,
c5aa993b 191 (PTRACE_ARG3_TYPE) & inferior_registers);
c906108c 192 ptrace (PTRACE_GETFPREGS, inferior_pid,
c5aa993b 193 (PTRACE_ARG3_TYPE) & inferior_fp_registers);
c906108c
SS
194
195 memcpy (registers, &inferior_registers, sizeof inferior_registers);
196
c5aa993b
JM
197 memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], inferior_fp_registers.f_st,
198 sizeof inferior_fp_registers.f_st);
c906108c 199 memcpy (&registers[REGISTER_BYTE (FPC_REGNUM)],
c5aa993b
JM
200 &inferior_fp_registers.f_ctrl,
201 sizeof inferior_fp_registers - sizeof inferior_fp_registers.f_st);
c906108c
SS
202}
203
204/* Store our register values back into the inferior.
205 If REGNO is -1, do this for all registers.
206 Otherwise, REGNO specifies which register (so we can save time). */
207
208void
fba45db2 209store_inferior_registers (int regno)
c906108c
SS
210{
211 struct regs inferior_registers;
212 struct fp_state inferior_fp_registers;
c906108c
SS
213
214 memcpy (&inferior_registers, registers, 20 * 4);
215
216 memcpy (inferior_fp_registers.f_st,
c5aa993b
JM
217 &registers[REGISTER_BYTE (FP0_REGNUM)],
218 sizeof inferior_fp_registers.f_st);
c906108c 219 memcpy (&inferior_fp_registers.f_ctrl,
c5aa993b
JM
220 &registers[REGISTER_BYTE (FPC_REGNUM)],
221 sizeof inferior_fp_registers - sizeof inferior_fp_registers.f_st);
222
c906108c
SS
223#ifdef PTRACE_FP_BUG
224 if (regno == FP_REGNUM || regno == -1)
225 /* Storing the frame pointer requires a gross hack, in which an
226 instruction that moves eax into ebp gets single-stepped. */
227 {
228 int stack = inferior_registers.r_reg[SP_REGNUM];
229 int stuff = ptrace (PTRACE_PEEKDATA, inferior_pid,
230 (PTRACE_ARG3_TYPE) stack);
231 int reg = inferior_registers.r_reg[EAX];
232 inferior_registers.r_reg[EAX] =
233 inferior_registers.r_reg[FP_REGNUM];
c5aa993b
JM
234 ptrace (PTRACE_SETREGS, inferior_pid,
235 (PTRACE_ARG3_TYPE) & inferior_registers);
c906108c
SS
236 ptrace (PTRACE_POKEDATA, inferior_pid, (PTRACE_ARG3_TYPE) stack,
237 0xc589);
238 ptrace (PTRACE_SINGLESTEP, inferior_pid, (PTRACE_ARG3_TYPE) stack,
239 0);
240 wait (0);
241 ptrace (PTRACE_POKEDATA, inferior_pid, (PTRACE_ARG3_TYPE) stack,
242 stuff);
243 inferior_registers.r_reg[EAX] = reg;
244 }
245#endif
246 ptrace (PTRACE_SETREGS, inferior_pid,
c5aa993b 247 (PTRACE_ARG3_TYPE) & inferior_registers);
c906108c 248 ptrace (PTRACE_SETFPREGS, inferior_pid,
c5aa993b 249 (PTRACE_ARG3_TYPE) & inferior_fp_registers);
c906108c 250}
This page took 0.11026 seconds and 4 git commands to generate.