* Makefile.in (CC_FOR_TARGET): Test for existence of gcc/xgcc, not
[deliverable/binutils-gdb.git] / gdb / m68kly-nat.c
CommitLineData
9bebe500
SS
1/* Native-dependent code for Motorola 680x0 running LynxOS.
2 Copyright 1986, 1987, 1989, 1991, 1993 Free Software Foundation, Inc.
25286543
SG
3
4This file is part of GDB.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include "defs.h"
21#include "frame.h"
22#include "inferior.h"
9bebe500 23#include "gdbcore.h"
25286543
SG
24#include "target.h"
25
9bebe500
SS
26#include <sys/param.h>
27#include <sys/dir.h>
28#include <signal.h>
29#include <sys/types.h>
30#include <itimer.h>
31#include <mem.h>
32#include <sys/time.h>
33#include <resource.h>
34#include <sys/ioctl.h>
35#include <fcntl.h>
36#include <sys/file.h>
37#include <sys/stat.h>
25286543 38#include <sys/ptrace.h>
9bebe500
SS
39#include <kernel.h>
40#include <conf.h>
41#include <proc.h>
42#include <errno.h>
25286543
SG
43
44/* Return the address in the core dump or inferior of register REGNO.
9bebe500 45 BLOCKEND is the address of the end of the user structure. */
25286543
SG
46
47static unsigned int
9bebe500
SS
48core_register_addr (regno, blockend)
49 unsigned int regno, blockend;
50{
51 struct st_entry s;
52 unsigned int offset;
53
54 if (regno >= 0 && regno <= FP_REGNUM)
55 offset = (char *) &s.ec.regs[regno] - (char *) &s;
56 else if (regno == SP_REGNUM)
57 offset = (char *) &s.stackp - (char *) &s;
58 else if (regno == PS_REGNUM)
59 offset = (char *) &s.ec.status - (char *) &s;
60 else if (regno == PC_REGNUM)
61 offset = (char *) &s.ec.pc - (char *) &s;
62 else if (regno >= FP0_REGNUM && regno <= (FPC_REGNUM - 1))
63 offset = (char *) &s.ec.fregs[(regno - FP0_REGNUM) * 3] - (char *) &s;
64 else if (regno >= FPC_REGNUM && regno <= FPI_REGNUM)
65 offset = (char *) &s.ec.fcregs[regno - FPC_REGNUM] - (char *) &s;
66
67 return blockend + offset;
68}
69
70unsigned int
25286543
SG
71register_addr (regno, blockend)
72 int regno, blockend;
73{
9bebe500
SS
74 struct st_entry s;
75 unsigned int offset;
76
77 if (regno >= 0 && regno <= FP_REGNUM)
78 offset = (char *) &s.ec.regs[regno] - (char *) &s.ec;
79 else if (regno == SP_REGNUM)
80 offset = (char *) &s.stackp - (char *) &s;
81 else if (regno == PS_REGNUM)
82 offset = (char *) &s.ec.status - (char *) &s.ec;
83 else if (regno == PC_REGNUM)
84 offset = (char *) &s.ec.pc - (char *) &s.ec;
85 else if (regno >= FP0_REGNUM && regno <= (FPC_REGNUM - 1))
86 offset = (char *) &s.ec.fregs[(regno - FP0_REGNUM) * 3] - (char *) &s.ec;
87 else if (regno >= FPC_REGNUM && regno <= FPI_REGNUM)
88 offset = (char *) &s.ec.fcregs[regno - FPC_REGNUM] - (char *) &s.ec;
89
90 return blockend + offset;
25286543
SG
91}
92
9bebe500
SS
93#ifdef FETCH_INFERIOR_REGISTERS
94
95/* Fetch one register. */
25286543
SG
96
97static void
98fetch_register (regno, offset, bpid)
99 int regno, bpid;
100 unsigned int offset;
101{
9bebe500
SS
102 char buf[MAX_REGISTER_RAW_SIZE], mess[128];
103 unsigned int regaddr, i, ptrace_request;
25286543 104
9bebe500 105 ptrace_request = regno != SP_REGNUM ? PTRACE_PEEKDATA : PTRACE_PEEKUSP;
25286543
SG
106 regaddr = register_addr (regno, offset);
107 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
108 {
109 errno = 0;
9bebe500 110 *(int *) &buf[i] = ptrace (ptrace_request, bpid,
25286543 111 (PTRACE_ARG3_TYPE) regaddr, 0);
25286543 112 if (errno != 0)
9bebe500 113 {
25286543
SG
114 sprintf (mess, "reading register %s (#%d)", reg_names[regno], regno);
115 perror_with_name (mess);
9bebe500
SS
116 }
117 regaddr += sizeof (int);
25286543
SG
118 }
119 supply_register (regno, buf);
120}
121
25286543
SG
122static void
123store_register (regno, offset, bpid)
124 int regno, bpid;
125 unsigned int offset;
126{
9bebe500 127 unsigned int i, regaddr, ptrace_request;
25286543 128 char mess[128];
25286543 129
9bebe500 130 ptrace_request = regno != SP_REGNUM ? PTRACE_POKEUSER : PTRACE_POKEUSP;
25286543 131 regaddr = register_addr (regno, offset);
9bebe500 132 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
25286543
SG
133 {
134 errno = 0;
9bebe500 135 ptrace (ptrace_request, bpid, (PTRACE_ARG3_TYPE) regaddr,
25286543
SG
136 *(int *) &registers[REGISTER_BYTE (regno) + i]);
137 if (errno != 0)
9bebe500
SS
138 {
139 sprintf (mess, "writing register %s (#%d)", reg_names[regno], regno);
25286543
SG
140 perror_with_name (mess);
141 }
9bebe500 142 regaddr += sizeof (int);
25286543
SG
143 }
144}
145
25286543 146static unsigned int
9bebe500
SS
147fetch_offset (pid, write)
148 int pid, write;
25286543
SG
149{
150 struct st_entry s;
151 unsigned int specpage_off, offset = (char *) &s.ecp - (char *) &s;
152
9bebe500
SS
153 if (write)
154 {
155 errno = 0;
156 specpage_off = ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE) 0, 0);
157 if (errno != 0)
158 perror_with_name ("ptrace");
159 errno = 0;
160 offset = ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE) offset, 0)
161 - specpage_off;
162 if (errno != 0)
163 perror_with_name ("ptrace");
164 }
165 else
166 {
167 errno = 0;
168 offset = ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE) offset, 0);
169 if (errno != 0)
170 perror_with_name ("ptrace");
171 }
25286543
SG
172 return offset;
173}
174
25286543
SG
175void
176fetch_inferior_registers (regno)
177 int regno;
178{
9bebe500
SS
179 unsigned int offset = fetch_offset (inferior_pid, 0);
180
25286543
SG
181 if (regno == -1)
182 {
183 for (regno = 0; regno < NUM_REGS; regno++)
9bebe500 184 fetch_register (regno, offset, inferior_pid);
25286543 185 }
9bebe500 186 else
25286543
SG
187 fetch_register (regno, offset, inferior_pid);
188}
189
25286543
SG
190void
191store_inferior_registers (regno)
192 int regno;
193{
9bebe500 194 unsigned int offset = fetch_offset (inferior_pid, 1);
25286543
SG
195
196 if (regno == -1)
197 {
9bebe500 198 for (regno = 0; regno < NUM_REGS; regno++)
25286543
SG
199 store_register (regno, offset, inferior_pid);
200 }
201 else
202 store_register (regno, offset, inferior_pid);
203}
204
9bebe500
SS
205void
206fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
207 char *core_reg_sect;
208 unsigned core_reg_size;
209 int which;
210 unsigned int reg_addr; /* Unused in this version */
211{
212 unsigned int regno;
213
214 for (regno = 0; regno < NUM_REGS; regno++)
215 {
216 unsigned int addr;
217
218 addr = core_register_addr (regno, (unsigned) 0);
219 supply_register (regno, core_reg_sect + addr);
220 }
221}
222#endif /* FETCH_INFERIOR_REGISTERS */
223
25286543
SG
224/* Wait for child to do something. Return pid of child, or -1 in case
225 of error; store status through argument pointer STATUS. */
226
227int
de43d7d0
SG
228child_wait (pid, status)
229 int pid;
25286543
SG
230 int *status;
231{
25286543
SG
232 int save_errno;
233 int thread;
234
235 while (1)
236 {
237 int sig;
238
239 if (attach_flag)
240 set_sigint_trap(); /* Causes SIGINT to be passed on to the
241 attached process. */
242 pid = wait (status);
243 save_errno = errno;
244
245 if (attach_flag)
246 clear_sigint_trap();
247
248 if (pid == -1)
249 {
250 if (save_errno == EINTR)
251 continue;
252 fprintf (stderr, "Child process unexpectedly missing: %s.\n",
253 safe_strerror (save_errno));
254 *status = 42; /* Claim it exited with signal 42 */
255 return -1;
256 }
257
258 if (pid != PIDGET (inferior_pid)) /* Some other process?!? */
259 continue;
260
261/* thread = WIFTID (*status);*/
262 thread = *status >> 16;
263
264 /* Initial thread value can only be acquired via wait, so we have to
265 resort to this hack. */
266
267 if (TIDGET (inferior_pid) == 0)
268 {
269 inferior_pid = BUILDPID (inferior_pid, thread);
270 add_thread (inferior_pid);
271 }
272
273 pid = BUILDPID (pid, thread);
274
275 return pid;
276 }
277}
This page took 0.055642 seconds and 4 git commands to generate.