Phase 1 of the ptid_t changes.
[deliverable/binutils-gdb.git] / gdb / m88k-nat.c
CommitLineData
c906108c 1/* Native-dependent Motorola 88xxx support for GDB, the GNU Debugger.
b6ba6518
KB
2 Copyright 1988, 1990, 1991, 1992, 1993, 1995, 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 "defs.h"
23#include "frame.h"
24#include "inferior.h"
4e052eda 25#include "regcache.h"
c906108c
SS
26
27#include <sys/types.h>
28#include <sys/param.h>
29#include <sys/dir.h>
30#include <signal.h>
31#include "gdbcore.h"
32#include <sys/user.h>
33
34#ifndef USER /* added to support BCS ptrace_user */
35#define USER ptrace_user
36#endif
37#include <sys/ioctl.h>
38#include <fcntl.h>
39#include <sys/file.h>
40#include "gdb_stat.h"
41
42#include "symtab.h"
43#include "setjmp.h"
44#include "value.h"
45
46#ifdef DELTA88
47#include <sys/ptrace.h>
48
49/* define offsets to the pc instruction offsets in ptrace_user struct */
50#define SXIP_OFFSET ((char *)&u.pt_sigframe.sig_sxip - (char *)&u)
51#define SNIP_OFFSET ((char *)&u.pt_sigframe.sig_snip - (char *)&u)
52#define SFIP_OFFSET ((char *)&u.pt_sigframe.sig_sfip - (char *)&u)
53#else
54/* define offsets to the pc instruction offsets in ptrace_user struct */
55#define SXIP_OFFSET ((char *)&u.pt_sigframe.dg_sigframe.sc_sxip - (char *)&u)
56#define SNIP_OFFSET ((char *)&u.pt_sigframe.dg_sigframe.sc_snip - (char *)&u)
57#define SFIP_OFFSET ((char *)&u.pt_sigframe.dg_sigframe.sc_sfip - (char *)&u)
58#endif
59
c5aa993b 60extern int have_symbol_file_p ();
c906108c
SS
61
62extern jmp_buf stack_jmp;
63
64extern int errno;
c906108c
SS
65
66void
afd64b4e 67fetch_inferior_registers (int regno)
c906108c
SS
68{
69 register unsigned int regaddr;
70 char buf[MAX_REGISTER_RAW_SIZE];
71 register int i;
72
73 struct USER u;
74 unsigned int offset;
75
c5aa993b
JM
76 offset = (char *) &u.pt_r0 - (char *) &u;
77 regaddr = offset; /* byte offset to r0; */
c906108c 78
39f77062 79/* offset = ptrace (3, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) offset, 0) - KERNEL_U_ADDR; */
c906108c
SS
80 for (regno = 0; regno < NUM_REGS; regno++)
81 {
c5aa993b
JM
82 /*regaddr = register_addr (regno, offset); */
83 /* 88k enhancement */
84
c906108c 85 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
c5aa993b 86 {
39f77062 87 *(int *) &buf[i] = ptrace (3, PIDGET (inferior_ptid),
c906108c 88 (PTRACE_ARG3_TYPE) regaddr, 0);
c5aa993b
JM
89 regaddr += sizeof (int);
90 }
c906108c
SS
91 supply_register (regno, buf);
92 }
c5aa993b 93 /* now load up registers 36 - 38; special pc registers */
39f77062 94 *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
c5aa993b
JM
95 (PTRACE_ARG3_TYPE) SXIP_OFFSET, 0);
96 supply_register (SXIP_REGNUM, buf);
39f77062 97 *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
c5aa993b
JM
98 (PTRACE_ARG3_TYPE) SNIP_OFFSET, 0);
99 supply_register (SNIP_REGNUM, buf);
39f77062 100 *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
c5aa993b
JM
101 (PTRACE_ARG3_TYPE) SFIP_OFFSET, 0);
102 supply_register (SFIP_REGNUM, buf);
c906108c
SS
103}
104
105/* Store our register values back into the inferior.
106 If REGNO is -1, do this for all registers.
107 Otherwise, REGNO specifies which register (so we can save time). */
108
109void
fba45db2 110store_inferior_registers (int regno)
c906108c
SS
111{
112 register unsigned int regaddr;
113 char buf[80];
114
115 struct USER u;
116
117 unsigned int offset = (char *) &u.pt_r0 - (char *) &u;
118
119 regaddr = offset;
120
121 /* Don't try to deal with EXIP_REGNUM or ENIP_REGNUM, because I think either
122 svr3 doesn't run on an 88110, or the kernel isolates the different (not
123 completely sure this is true, but seems to be. */
124 if (regno >= 0)
125 {
126 /* regaddr = register_addr (regno, offset); */
127 if (regno < PC_REGNUM)
c5aa993b 128 {
c906108c
SS
129 regaddr = offset + regno * sizeof (int);
130 errno = 0;
39f77062 131 ptrace (6, PIDGET (inferior_ptid),
c906108c
SS
132 (PTRACE_ARG3_TYPE) regaddr, read_register (regno));
133 if (errno != 0)
134 {
135 sprintf (buf, "writing register number %d", regno);
136 perror_with_name (buf);
137 }
138 }
139 else if (regno == SXIP_REGNUM)
39f77062 140 ptrace (6, PIDGET (inferior_ptid),
c5aa993b 141 (PTRACE_ARG3_TYPE) SXIP_OFFSET, read_register (regno));
c906108c 142 else if (regno == SNIP_REGNUM)
39f77062 143 ptrace (6, PIDGET (inferior_ptid),
c5aa993b 144 (PTRACE_ARG3_TYPE) SNIP_OFFSET, read_register (regno));
c906108c 145 else if (regno == SFIP_REGNUM)
39f77062 146 ptrace (6, PIDGET (inferior_ptid),
c5aa993b 147 (PTRACE_ARG3_TYPE) SFIP_OFFSET, read_register (regno));
c906108c
SS
148 else
149 printf_unfiltered ("Bad register number for store_inferior routine\n");
150 }
151 else
c5aa993b 152 {
c906108c
SS
153 for (regno = 0; regno < PC_REGNUM; regno++)
154 {
155 /* regaddr = register_addr (regno, offset); */
156 errno = 0;
157 regaddr = offset + regno * sizeof (int);
39f77062 158 ptrace (6, PIDGET (inferior_ptid),
c906108c
SS
159 (PTRACE_ARG3_TYPE) regaddr, read_register (regno));
160 if (errno != 0)
161 {
162 sprintf (buf, "writing register number %d", regno);
163 perror_with_name (buf);
164 }
165 }
39f77062 166 ptrace (6, PIDGET (inferior_ptid),
c5aa993b 167 (PTRACE_ARG3_TYPE) SXIP_OFFSET, read_register (SXIP_REGNUM));
39f77062 168 ptrace (6, PIDGET (inferior_ptid),
c5aa993b 169 (PTRACE_ARG3_TYPE) SNIP_OFFSET, read_register (SNIP_REGNUM));
39f77062 170 ptrace (6, PIDGET (inferior_ptid),
c5aa993b 171 (PTRACE_ARG3_TYPE) SFIP_OFFSET, read_register (SFIP_REGNUM));
c906108c
SS
172 }
173}
174
175
176/* blockend is the address of the end of the user structure */
fba45db2 177m88k_register_u_addr (int blockend, int regnum)
c906108c
SS
178{
179 struct USER u;
180 int ustart = blockend - sizeof (struct USER);
181 switch (regnum)
182 {
183 case 0:
184 case 1:
185 case 2:
186 case 3:
187 case 4:
188 case 5:
189 case 6:
190 case 7:
191 case 8:
192 case 9:
193 case 10:
194 case 11:
195 case 12:
196 case 13:
197 case 14:
198 case 15:
199 case 16:
200 case 17:
201 case 18:
202 case 19:
203 case 20:
204 case 21:
205 case 22:
206 case 23:
207 case 24:
208 case 25:
209 case 26:
210 case 27:
211 case 28:
212 case 29:
213 case 30:
214 case 31:
215 return (ustart + ((int) &u.pt_r0 - (int) &u) + REGISTER_SIZE * regnum);
c5aa993b
JM
216 case PSR_REGNUM:
217 return (ustart + ((int) &u.pt_psr - (int) &u));
218 case FPSR_REGNUM:
219 return (ustart + ((int) &u.pt_fpsr - (int) &u));
220 case FPCR_REGNUM:
221 return (ustart + ((int) &u.pt_fpcr - (int) &u));
222 case SXIP_REGNUM:
223 return (ustart + SXIP_OFFSET);
224 case SNIP_REGNUM:
225 return (ustart + SNIP_OFFSET);
226 case SFIP_REGNUM:
227 return (ustart + SFIP_OFFSET);
228 default:
229 if (regnum < NUM_REGS)
230 /* The register is one of those which is not defined...
231 give it zero */
232 return (ustart + ((int) &u.pt_r0 - (int) &u));
233 else
234 return (blockend + REGISTER_SIZE * regnum);
c906108c
SS
235 }
236}
237
238#ifdef USE_PROC_FS
239
240#include <sys/procfs.h>
241
c60c0f5f
MS
242/* Prototypes for supply_gregset etc. */
243#include "gregset.h"
244
c906108c 245/* Given a pointer to a general register set in /proc format (gregset_t *),
c5aa993b
JM
246 unpack the register contents and supply them as gdb's idea of the current
247 register values. */
c906108c
SS
248
249void
fba45db2 250supply_gregset (gregset_t *gregsetp)
c906108c 251{
c5aa993b
JM
252 register int regi;
253 register greg_t *regp = (greg_t *) gregsetp;
254
255 for (regi = 0; regi <= SP_REGNUM; regi++)
256 supply_register (regi, (char *) (regp + regi));
257
258 supply_register (SXIP_REGNUM, (char *) (regp + R_XIP));
259 supply_register (SNIP_REGNUM, (char *) (regp + R_NIP));
260 supply_register (SFIP_REGNUM, (char *) (regp + R_FIP));
261 supply_register (PSR_REGNUM, (char *) (regp + R_PSR));
262 supply_register (FPSR_REGNUM, (char *) (regp + R_FPSR));
263 supply_register (FPCR_REGNUM, (char *) (regp + R_FPCR));
c906108c
SS
264}
265
266void
fba45db2 267fill_gregset (gregset_t *gregsetp, int regno)
c906108c 268{
c5aa993b
JM
269 int regi;
270 register greg_t *regp = (greg_t *) gregsetp;
271
272 for (regi = 0; regi <= R_R31; regi++)
273 if ((regno == -1) || (regno == regi))
274 *(regp + regi) = *(int *) &registers[REGISTER_BYTE (regi)];
275
276 if ((regno == -1) || (regno == SXIP_REGNUM))
277 *(regp + R_XIP) = *(int *) &registers[REGISTER_BYTE (SXIP_REGNUM)];
278 if ((regno == -1) || (regno == SNIP_REGNUM))
279 *(regp + R_NIP) = *(int *) &registers[REGISTER_BYTE (SNIP_REGNUM)];
280 if ((regno == -1) || (regno == SFIP_REGNUM))
281 *(regp + R_FIP) = *(int *) &registers[REGISTER_BYTE (SFIP_REGNUM)];
282 if ((regno == -1) || (regno == PSR_REGNUM))
283 *(regp + R_PSR) = *(int *) &registers[REGISTER_BYTE (PSR_REGNUM)];
284 if ((regno == -1) || (regno == FPSR_REGNUM))
285 *(regp + R_FPSR) = *(int *) &registers[REGISTER_BYTE (FPSR_REGNUM)];
286 if ((regno == -1) || (regno == FPCR_REGNUM))
287 *(regp + R_FPCR) = *(int *) &registers[REGISTER_BYTE (FPCR_REGNUM)];
c906108c
SS
288}
289
290#endif /* USE_PROC_FS */
This page took 0.145435 seconds and 4 git commands to generate.