]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ns32knbsd-nat.c
Phase 1 of the ptid_t changes.
[thirdparty/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) \
35 memcpy(&registers[REGISTER_BYTE(dst)], &src, sizeof(src))
36
37#define RS(src, dst) \
38 memcpy(&dst, &registers[REGISTER_BYTE(src)], sizeof(dst))
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);
61 RF (FP_REGNUM, inferior_registers.r_fp);
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]);
74 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);
93 RS (FP_REGNUM, inferior_registers.r_fp);
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);
153 RF (FP_REGNUM, core_reg->intreg.r_fp);
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]);
c906108c
SS
167 registers_fetched ();
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
SS
184{
185 add_core_fns (&nat_core_fns);
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
JM
225 RF (SP_REGNUM, dummy);
226 RF (FP_REGNUM, sf.sf_fp);
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]);
c906108c
SS
240 registers_fetched ();
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);
261 RF (FP_REGNUM, null);
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);
298 argp = enter_addr == 1 ? SAVED_PC_AFTER_CALL (fi) : FRAME_SAVED_PC (fi);
299 for (i = 0; i < 16; i++)
300 {
301 /*
302 * After a bsr gcc may emit the following instructions
303 * to remove the arguments from the stack:
304 * cmpqd 0,tos - to remove 4 bytes from the stack
305 * cmpd tos,tos - to remove 8 bytes from the stack
306 * adjsp[bwd] -n - to remove n bytes from the stack
307 * Gcc sometimes delays emitting these instructions and
308 * may even throw a branch between our feet.
309 */
310 inst = read_memory_integer (argp, 4);
311 args = read_memory_integer (argp + 2, 4);
312 if ((inst & 0xff) == 0xea)
313 { /* br */
314 args = ((inst >> 8) & 0xffffff) | (args << 24);
315 if (args & 0x80)
316 {
317 if (args & 0x40)
318 {
319 args = ntohl (args);
c906108c 320 }
c5aa993b
JM
321 else
322 {
323 args = ntohs (args & 0xffff);
324 if (args & 0x2000)
325 args |= 0xc000;
c906108c 326 }
c5aa993b
JM
327 }
328 else
329 {
330 args = args & 0xff;
331 if (args & 0x40)
332 args |= 0x80;
333 }
334 argp += args;
335 continue;
336 }
337 if ((inst & 0xffff) == 0xb81f) /* cmpqd 0,tos */
338 return (1);
339 else if ((inst & 0xffff) == 0xbdc7) /* cmpd tos,tos */
340 return (2);
341 else if ((inst & 0xfffc) == 0xa57c)
342 { /* adjsp[bwd] */
343 switch (inst & 3)
344 {
345 case 0:
346 args = ((args & 0xff) + 0x80);
347 break;
348 case 1:
349 args = ((ntohs (args) & 0xffff) + 0x8000);
350 break;
351 case 3:
352 args = -ntohl (args);
353 break;
354 default:
355 return (-1);
356 }
357 if (args / 4 > 10 || (args & 3) != 0)
358 continue;
359 return (args / 4);
c906108c 360 }
c5aa993b
JM
361 argp += 1;
362 }
363 return (-1);
c906108c 364}