More LynxOS support
[deliverable/binutils-gdb.git] / gdb / m68kly-nat.c
1 /* Native-dependent code for Motorola 680x0 running LynxOS.
2 Copyright 1986, 1987, 1989, 1991, 1993 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include "defs.h"
21 #include "frame.h"
22 #include "inferior.h"
23 #include "gdbcore.h"
24 #include "target.h"
25
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>
38 #include <sys/ptrace.h>
39 #include <kernel.h>
40 #include <conf.h>
41 #include <proc.h>
42 #include <errno.h>
43
44 /* Return the address in the core dump or inferior of register REGNO.
45 BLOCKEND is the address of the end of the user structure. */
46
47 static unsigned int
48 core_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
70 unsigned int
71 register_addr (regno, blockend)
72 int regno, blockend;
73 {
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;
91 }
92
93 #ifdef FETCH_INFERIOR_REGISTERS
94
95 /* Fetch one register. */
96
97 static void
98 fetch_register (regno, offset, bpid)
99 int regno, bpid;
100 unsigned int offset;
101 {
102 char buf[MAX_REGISTER_RAW_SIZE], mess[128];
103 unsigned int regaddr, i, ptrace_request;
104
105 ptrace_request = regno != SP_REGNUM ? PTRACE_PEEKDATA : PTRACE_PEEKUSP;
106 regaddr = register_addr (regno, offset);
107 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
108 {
109 errno = 0;
110 *(int *) &buf[i] = ptrace (ptrace_request, bpid,
111 (PTRACE_ARG3_TYPE) regaddr, 0);
112 if (errno != 0)
113 {
114 sprintf (mess, "reading register %s (#%d)", reg_names[regno], regno);
115 perror_with_name (mess);
116 }
117 regaddr += sizeof (int);
118 }
119 supply_register (regno, buf);
120 }
121
122 static void
123 store_register (regno, offset, bpid)
124 int regno, bpid;
125 unsigned int offset;
126 {
127 unsigned int i, regaddr, ptrace_request;
128 char mess[128];
129
130 ptrace_request = regno != SP_REGNUM ? PTRACE_POKEUSER : PTRACE_POKEUSP;
131 regaddr = register_addr (regno, offset);
132 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
133 {
134 errno = 0;
135 ptrace (ptrace_request, bpid, (PTRACE_ARG3_TYPE) regaddr,
136 *(int *) &registers[REGISTER_BYTE (regno) + i]);
137 if (errno != 0)
138 {
139 sprintf (mess, "writing register %s (#%d)", reg_names[regno], regno);
140 perror_with_name (mess);
141 }
142 regaddr += sizeof (int);
143 }
144 }
145
146 static unsigned int
147 fetch_offset (pid, write)
148 int pid, write;
149 {
150 struct st_entry s;
151 unsigned int specpage_off, offset = (char *) &s.ecp - (char *) &s;
152
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 }
172 return offset;
173 }
174
175 void
176 fetch_inferior_registers (regno)
177 int regno;
178 {
179 unsigned int offset = fetch_offset (inferior_pid, 0);
180
181 if (regno == -1)
182 {
183 for (regno = 0; regno < NUM_REGS; regno++)
184 fetch_register (regno, offset, inferior_pid);
185 }
186 else
187 fetch_register (regno, offset, inferior_pid);
188 }
189
190 void
191 store_inferior_registers (regno)
192 int regno;
193 {
194 unsigned int offset = fetch_offset (inferior_pid, 1);
195
196 if (regno == -1)
197 {
198 for (regno = 0; regno < NUM_REGS; regno++)
199 store_register (regno, offset, inferior_pid);
200 }
201 else
202 store_register (regno, offset, inferior_pid);
203 }
204
205 void
206 fetch_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
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
227 int
228 child_wait (pid, status)
229 int pid;
230 int *status;
231 {
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.051397 seconds and 5 git commands to generate.