2004-04-30 H.J. Lu <hongjiu.lu@intel.com>
[deliverable/binutils-gdb.git] / gdb / ns32knbsd-nat.c
CommitLineData
c906108c 1/* Functions specific to running gdb native on an ns32k running NetBSD
b6ba6518
KB
2 Copyright 1989, 1992, 1993, 1994, 1996, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
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.
c906108c 11
c5aa993b
JM
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.
c906108c 16
c5aa993b
JM
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. */
c906108c
SS
21
22#include <sys/types.h>
23#include <sys/ptrace.h>
24#include <machine/reg.h>
25#include <machine/frame.h>
26#include <machine/pcb.h>
27
28#include "defs.h"
29#include "inferior.h"
30#include "target.h"
31#include "gdbcore.h"
4e052eda 32#include "regcache.h"
c906108c
SS
33
34#define RF(dst, src) \
62700349 35 memcpy(&deprecated_registers[DEPRECATED_REGISTER_BYTE(dst)], &src, sizeof(src))
c906108c
SS
36
37#define RS(src, dst) \
62700349 38 memcpy(&dst, &deprecated_registers[DEPRECATED_REGISTER_BYTE(src)], sizeof(dst))
c906108c
SS
39
40void
fba45db2 41fetch_inferior_registers (int regno)
c906108c
SS
42{
43 struct reg inferior_registers;
44 struct fpreg inferior_fpregisters;
45
39f77062 46 ptrace (PT_GETREGS, PIDGET (inferior_ptid),
c5aa993b 47 (PTRACE_ARG3_TYPE) & inferior_registers, 0);
39f77062 48 ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
c5aa993b
JM
49 (PTRACE_ARG3_TYPE) & inferior_fpregisters, 0);
50
51 RF (R0_REGNUM + 0, inferior_registers.r_r0);
52 RF (R0_REGNUM + 1, inferior_registers.r_r1);
53 RF (R0_REGNUM + 2, inferior_registers.r_r2);
54 RF (R0_REGNUM + 3, inferior_registers.r_r3);
55 RF (R0_REGNUM + 4, inferior_registers.r_r4);
56 RF (R0_REGNUM + 5, inferior_registers.r_r5);
57 RF (R0_REGNUM + 6, inferior_registers.r_r6);
58 RF (R0_REGNUM + 7, inferior_registers.r_r7);
59
60 RF (SP_REGNUM, inferior_registers.r_sp);
0ba6dca9 61 RF (DEPRECATED_FP_REGNUM, inferior_registers.r_fp);
c5aa993b
JM
62 RF (PC_REGNUM, inferior_registers.r_pc);
63 RF (PS_REGNUM, inferior_registers.r_psr);
64
65 RF (FPS_REGNUM, inferior_fpregisters.r_fsr);
66 RF (FP0_REGNUM + 0, inferior_fpregisters.r_freg[0]);
67 RF (FP0_REGNUM + 2, inferior_fpregisters.r_freg[2]);
68 RF (FP0_REGNUM + 4, inferior_fpregisters.r_freg[4]);
69 RF (FP0_REGNUM + 6, inferior_fpregisters.r_freg[6]);
70 RF (LP0_REGNUM + 1, inferior_fpregisters.r_freg[1]);
71 RF (LP0_REGNUM + 3, inferior_fpregisters.r_freg[3]);
72 RF (LP0_REGNUM + 5, inferior_fpregisters.r_freg[5]);
73 RF (LP0_REGNUM + 7, inferior_fpregisters.r_freg[7]);
2b9e5f3f 74 deprecated_registers_fetched ();
c906108c
SS
75}
76
77void
fba45db2 78store_inferior_registers (int regno)
c906108c
SS
79{
80 struct reg inferior_registers;
81 struct fpreg inferior_fpregisters;
82
c5aa993b
JM
83 RS (R0_REGNUM + 0, inferior_registers.r_r0);
84 RS (R0_REGNUM + 1, inferior_registers.r_r1);
85 RS (R0_REGNUM + 2, inferior_registers.r_r2);
86 RS (R0_REGNUM + 3, inferior_registers.r_r3);
87 RS (R0_REGNUM + 4, inferior_registers.r_r4);
88 RS (R0_REGNUM + 5, inferior_registers.r_r5);
89 RS (R0_REGNUM + 6, inferior_registers.r_r6);
90 RS (R0_REGNUM + 7, inferior_registers.r_r7);
91
92 RS (SP_REGNUM, inferior_registers.r_sp);
0ba6dca9 93 RS (DEPRECATED_FP_REGNUM, inferior_registers.r_fp);
c5aa993b
JM
94 RS (PC_REGNUM, inferior_registers.r_pc);
95 RS (PS_REGNUM, inferior_registers.r_psr);
96
97 RS (FPS_REGNUM, inferior_fpregisters.r_fsr);
98 RS (FP0_REGNUM + 0, inferior_fpregisters.r_freg[0]);
99 RS (FP0_REGNUM + 2, inferior_fpregisters.r_freg[2]);
100 RS (FP0_REGNUM + 4, inferior_fpregisters.r_freg[4]);
101 RS (FP0_REGNUM + 6, inferior_fpregisters.r_freg[6]);
102 RS (LP0_REGNUM + 1, inferior_fpregisters.r_freg[1]);
103 RS (LP0_REGNUM + 3, inferior_fpregisters.r_freg[3]);
104 RS (LP0_REGNUM + 5, inferior_fpregisters.r_freg[5]);
105 RS (LP0_REGNUM + 7, inferior_fpregisters.r_freg[7]);
c906108c 106
39f77062 107 ptrace (PT_SETREGS, PIDGET (inferior_ptid),
c5aa993b 108 (PTRACE_ARG3_TYPE) & inferior_registers, 0);
39f77062 109 ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
c5aa993b 110 (PTRACE_ARG3_TYPE) & inferior_fpregisters, 0);
c906108c
SS
111}
112\f
113
114/* XXX - Add this to machine/regs.h instead? */
c5aa993b
JM
115struct coreregs
116{
c906108c
SS
117 struct reg intreg;
118 struct fpreg freg;
119};
120
697ec6c4 121/* Get registers from a core file. REG_ADDR is unused. */
c906108c 122static void
697ec6c4
KB
123fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
124 unsigned int reg_addr)
c906108c
SS
125{
126 struct coreregs *core_reg;
127
c5aa993b 128 core_reg = (struct coreregs *) core_reg_sect;
c906108c
SS
129
130 /*
131 * We have *all* registers
132 * in the first core section.
133 * Ignore which.
134 */
135
c5aa993b
JM
136 if (core_reg_size < sizeof (*core_reg))
137 {
138 fprintf_unfiltered (gdb_stderr, "Couldn't read regs from core file\n");
139 return;
140 }
c906108c
SS
141
142 /* Integer registers */
c5aa993b
JM
143 RF (R0_REGNUM + 0, core_reg->intreg.r_r0);
144 RF (R0_REGNUM + 1, core_reg->intreg.r_r1);
145 RF (R0_REGNUM + 2, core_reg->intreg.r_r2);
146 RF (R0_REGNUM + 3, core_reg->intreg.r_r3);
147 RF (R0_REGNUM + 4, core_reg->intreg.r_r4);
148 RF (R0_REGNUM + 5, core_reg->intreg.r_r5);
149 RF (R0_REGNUM + 6, core_reg->intreg.r_r6);
150 RF (R0_REGNUM + 7, core_reg->intreg.r_r7);
151
152 RF (SP_REGNUM, core_reg->intreg.r_sp);
0ba6dca9 153 RF (DEPRECATED_FP_REGNUM, core_reg->intreg.r_fp);
c5aa993b
JM
154 RF (PC_REGNUM, core_reg->intreg.r_pc);
155 RF (PS_REGNUM, core_reg->intreg.r_psr);
c906108c
SS
156
157 /* Floating point registers */
c5aa993b
JM
158 RF (FPS_REGNUM, core_reg->freg.r_fsr);
159 RF (FP0_REGNUM + 0, core_reg->freg.r_freg[0]);
160 RF (FP0_REGNUM + 2, core_reg->freg.r_freg[2]);
161 RF (FP0_REGNUM + 4, core_reg->freg.r_freg[4]);
162 RF (FP0_REGNUM + 6, core_reg->freg.r_freg[6]);
163 RF (LP0_REGNUM + 1, core_reg->freg.r_freg[1]);
164 RF (LP0_REGNUM + 3, core_reg->freg.r_freg[3]);
165 RF (LP0_REGNUM + 5, core_reg->freg.r_freg[5]);
166 RF (LP0_REGNUM + 7, core_reg->freg.r_freg[7]);
2b9e5f3f 167 deprecated_registers_fetched ();
c906108c
SS
168}
169
170/* Register that we are able to handle ns32knbsd core file formats.
171 FIXME: is this really bfd_target_unknown_flavour? */
172
173static struct core_fns nat_core_fns =
174{
2acceee2
JM
175 bfd_target_unknown_flavour, /* core_flavour */
176 default_check_format, /* check_format */
177 default_core_sniffer, /* core_sniffer */
178 fetch_core_registers, /* core_read_registers */
179 NULL /* next */
c906108c
SS
180};
181
182void
fba45db2 183_initialize_ns32knbsd_nat (void)
c906108c 184{
00e32a35 185 deprecated_add_core_fns (&nat_core_fns);
c906108c
SS
186}
187\f
188
189/*
190 * kernel_u_size() is not helpful on NetBSD because
191 * the "u" struct is NOT in the core dump file.
192 */
193
194#ifdef FETCH_KCORE_REGISTERS
195/*
196 * Get registers from a kernel crash dump or live kernel.
197 * Called by kcore-nbsd.c:get_kcore_registers().
198 */
199void
fba45db2 200fetch_kcore_registers (struct pcb *pcb)
c906108c
SS
201{
202 struct switchframe sf;
203 struct reg intreg;
204 int dummy;
205
206 /* Integer registers */
c5aa993b
JM
207 if (target_read_memory ((CORE_ADDR) pcb->pcb_ksp, (char *) &sf, sizeof sf))
208 error ("Cannot read integer registers.");
c906108c
SS
209
210 /* We use the psr at kernel entry */
c5aa993b
JM
211 if (target_read_memory ((CORE_ADDR) pcb->pcb_onstack, (char *) &intreg, sizeof intreg))
212 error ("Cannot read processor status register.");
c906108c
SS
213
214 dummy = 0;
c5aa993b
JM
215 RF (R0_REGNUM + 0, dummy);
216 RF (R0_REGNUM + 1, dummy);
217 RF (R0_REGNUM + 2, dummy);
218 RF (R0_REGNUM + 3, sf.sf_r3);
219 RF (R0_REGNUM + 4, sf.sf_r4);
220 RF (R0_REGNUM + 5, sf.sf_r5);
221 RF (R0_REGNUM + 6, sf.sf_r6);
222 RF (R0_REGNUM + 7, sf.sf_r7);
c906108c
SS
223
224 dummy = pcb->pcb_kfp + 8;
c5aa993b 225 RF (SP_REGNUM, dummy);
0ba6dca9 226 RF (DEPRECATED_FP_REGNUM, sf.sf_fp);
c5aa993b
JM
227 RF (PC_REGNUM, sf.sf_pc);
228 RF (PS_REGNUM, intreg.r_psr);
c906108c
SS
229
230 /* Floating point registers */
c5aa993b
JM
231 RF (FPS_REGNUM, pcb->pcb_fsr);
232 RF (FP0_REGNUM + 0, pcb->pcb_freg[0]);
233 RF (FP0_REGNUM + 2, pcb->pcb_freg[2]);
234 RF (FP0_REGNUM + 4, pcb->pcb_freg[4]);
235 RF (FP0_REGNUM + 6, pcb->pcb_freg[6]);
236 RF (LP0_REGNUM + 1, pcb->pcb_freg[1]);
237 RF (LP0_REGNUM + 3, pcb->pcb_freg[3]);
238 RF (LP0_REGNUM + 5, pcb->pcb_freg[5]);
239 RF (LP0_REGNUM + 7, pcb->pcb_freg[7]);
2b9e5f3f 240 deprecated_registers_fetched ();
c906108c 241}
c5aa993b 242#endif /* FETCH_KCORE_REGISTERS */
c906108c
SS
243
244void
fba45db2 245clear_regs (void)
c906108c
SS
246{
247 double zero = 0.0;
248 int null = 0;
c5aa993b 249
c906108c 250 /* Integer registers */
c5aa993b
JM
251 RF (R0_REGNUM + 0, null);
252 RF (R0_REGNUM + 1, null);
253 RF (R0_REGNUM + 2, null);
254 RF (R0_REGNUM + 3, null);
255 RF (R0_REGNUM + 4, null);
256 RF (R0_REGNUM + 5, null);
257 RF (R0_REGNUM + 6, null);
258 RF (R0_REGNUM + 7, null);
259
260 RF (SP_REGNUM, null);
0ba6dca9 261 RF (DEPRECATED_FP_REGNUM, null);
c5aa993b
JM
262 RF (PC_REGNUM, null);
263 RF (PS_REGNUM, null);
c906108c
SS
264
265 /* Floating point registers */
c5aa993b
JM
266 RF (FPS_REGNUM, zero);
267 RF (FP0_REGNUM + 0, zero);
268 RF (FP0_REGNUM + 2, zero);
269 RF (FP0_REGNUM + 4, zero);
270 RF (FP0_REGNUM + 6, zero);
271 RF (LP0_REGNUM + 0, zero);
272 RF (LP0_REGNUM + 1, zero);
273 RF (LP0_REGNUM + 2, zero);
274 RF (LP0_REGNUM + 3, zero);
c906108c
SS
275 return;
276}
277
278/* Return number of args passed to a frame.
279 Can return -1, meaning no way to tell. */
280
281int
fba45db2 282frame_num_args (struct frame_info *fi)
c906108c 283{
c5aa993b
JM
284 CORE_ADDR enter_addr;
285 CORE_ADDR argp;
286 int inst;
287 int args;
288 int i;
289
290 if (read_memory_integer (fi->frame, 4) == 0 && fi->pc < 0x10000)
291 {
292 /* main is always called with three args */
293 return (3);
294 }
295 enter_addr = ns32k_get_enter_addr (fi->pc);
296 if (enter_addr = 0)
297 return (-1);
6913c89a
AC
298 argp = (enter_addr == 1
299 ? DEPRECATED_SAVED_PC_AFTER_CALL (fi)
300 : DEPRECATED_FRAME_SAVED_PC (fi));
c5aa993b
JM
301 for (i = 0; i < 16; i++)
302 {
303 /*
304 * After a bsr gcc may emit the following instructions
305 * to remove the arguments from the stack:
306 * cmpqd 0,tos - to remove 4 bytes from the stack
307 * cmpd tos,tos - to remove 8 bytes from the stack
308 * adjsp[bwd] -n - to remove n bytes from the stack
309 * Gcc sometimes delays emitting these instructions and
310 * may even throw a branch between our feet.
311 */
312 inst = read_memory_integer (argp, 4);
313 args = read_memory_integer (argp + 2, 4);
314 if ((inst & 0xff) == 0xea)
315 { /* br */
316 args = ((inst >> 8) & 0xffffff) | (args << 24);
317 if (args & 0x80)
318 {
319 if (args & 0x40)
320 {
321 args = ntohl (args);
c906108c 322 }
c5aa993b
JM
323 else
324 {
325 args = ntohs (args & 0xffff);
326 if (args & 0x2000)
327 args |= 0xc000;
c906108c 328 }
c5aa993b
JM
329 }
330 else
331 {
332 args = args & 0xff;
333 if (args & 0x40)
334 args |= 0x80;
335 }
336 argp += args;
337 continue;
338 }
339 if ((inst & 0xffff) == 0xb81f) /* cmpqd 0,tos */
340 return (1);
341 else if ((inst & 0xffff) == 0xbdc7) /* cmpd tos,tos */
342 return (2);
343 else if ((inst & 0xfffc) == 0xa57c)
344 { /* adjsp[bwd] */
345 switch (inst & 3)
346 {
347 case 0:
348 args = ((args & 0xff) + 0x80);
349 break;
350 case 1:
351 args = ((ntohs (args) & 0xffff) + 0x8000);
352 break;
353 case 3:
354 args = -ntohl (args);
355 break;
356 default:
357 return (-1);
358 }
359 if (args / 4 > 10 || (args & 3) != 0)
360 continue;
361 return (args / 4);
c906108c 362 }
c5aa993b
JM
363 argp += 1;
364 }
365 return (-1);
c906108c 366}
This page took 0.389164 seconds and 4 git commands to generate.