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