752b370f40d53e24b9de406ad5025b443bf5c779
[deliverable/binutils-gdb.git] / gdb / hppab-nat.c
1 /* Machine-dependent hooks for the unix child process stratum. This
2 code is for the HP PA-RISC cpu.
3
4 Copyright 1986, 1987, 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
5
6 Contributed by the Center for Software Science at the
7 University of Utah (pa-gdb-bugs@cs.utah.edu).
8
9 This file is part of GDB.
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
24
25 #include "defs.h"
26 #include "inferior.h"
27
28 #ifndef PT_ATTACH
29 #define PT_ATTACH PTRACE_ATTACH
30 #endif
31 #ifndef PT_DETACH
32 #define PT_DETACH PTRACE_DETACH
33 #endif
34
35 /* This function simply calls ptrace with the given arguments.
36 It exists so that all calls to ptrace are isolated in this
37 machine-dependent file. */
38 #ifdef WANT_NATIVE_TARGET
39 int
40 call_ptrace (request, pid, addr, data)
41 int request, pid;
42 PTRACE_ARG3_TYPE addr;
43 int data;
44 {
45 return ptrace (request, pid, addr, data);
46 }
47 #endif /* WANT_NATIVE_TARGET */
48
49 #ifdef DEBUG_PTRACE
50 /* For the rest of the file, use an extra level of indirection */
51 /* This lets us breakpoint usefully on call_ptrace. */
52 #define ptrace call_ptrace
53 #endif
54
55 void
56 kill_inferior ()
57 {
58 if (inferior_pid == 0)
59 return;
60 ptrace (PT_KILL, inferior_pid, (PTRACE_ARG3_TYPE) 0, 0);
61 wait ((int *)0);
62 target_mourn_inferior ();
63 }
64
65 #ifdef ATTACH_DETACH
66 /* Nonzero if we are debugging an attached process rather than
67 an inferior. */
68 extern int attach_flag;
69
70 /* Start debugging the process whose number is PID. */
71 int
72 attach (pid)
73 int pid;
74 {
75 errno = 0;
76 ptrace (PT_ATTACH, pid, (PTRACE_ARG3_TYPE) 0, 0);
77 if (errno)
78 perror_with_name ("ptrace");
79 attach_flag = 1;
80 return pid;
81 }
82
83 /* Stop debugging the process whose number is PID
84 and continue it with signal number SIGNAL.
85 SIGNAL = 0 means just continue it. */
86
87 void
88 detach (signal)
89 int signal;
90 {
91 errno = 0;
92 ptrace (PT_DETACH, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal);
93 if (errno)
94 perror_with_name ("ptrace");
95 attach_flag = 0;
96 }
97 #endif /* ATTACH_DETACH */
98 \f
99
100
101 #if !defined (FETCH_INFERIOR_REGISTERS)
102
103 /* KERNEL_U_ADDR is the amount to subtract from u.u_ar0
104 to get the offset in the core file of the register values. */
105 #if defined (KERNEL_U_ADDR_BSD)
106 /* Get kernel_u_addr using BSD-style nlist(). */
107 CORE_ADDR kernel_u_addr;
108
109 #include <a.out.gnu.h> /* For struct nlist */
110
111 void
112 _initialize_kernel_u_addr ()
113 {
114 struct nlist names[2];
115
116 names[0].n_un.n_name = "_u";
117 names[1].n_un.n_name = NULL;
118 if (nlist ("/vmunix", names) == 0)
119 kernel_u_addr = names[0].n_value;
120 else
121 fatal ("Unable to get kernel u area address.");
122 }
123 #endif /* KERNEL_U_ADDR_BSD. */
124
125 #if defined (KERNEL_U_ADDR_HPUX)
126 /* Get kernel_u_addr using HPUX-style nlist(). */
127 CORE_ADDR kernel_u_addr;
128
129 struct hpnlist {
130 char * n_name;
131 long n_value;
132 unsigned char n_type;
133 unsigned char n_length;
134 short n_almod;
135 short n_unused;
136 };
137 static struct hpnlist nl[] = {{ "_u", -1, }, { (char *) 0, }};
138
139 /* read the value of the u area from the hp-ux kernel */
140 void _initialize_kernel_u_addr ()
141 {
142 struct user u;
143 nlist ("/hp-ux", &nl);
144 kernel_u_addr = nl[0].n_value;
145 }
146 #endif /* KERNEL_U_ADDR_HPUX. */
147
148 #if !defined (offsetof)
149 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
150 #endif
151
152 /* U_REGS_OFFSET is the offset of the registers within the u area. */
153 #if !defined (U_REGS_OFFSET)
154 #define U_REGS_OFFSET \
155 ptrace (PT_READ_U, inferior_pid, \
156 (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \
157 - KERNEL_U_ADDR
158 #endif
159
160 /* Registers we shouldn't try to fetch. */
161 #if !defined (CANNOT_FETCH_REGISTER)
162 #define CANNOT_FETCH_REGISTER(regno) 0
163 #endif
164
165 /* Fetch one register. */
166
167 static void
168 fetch_register (regno)
169 int regno;
170 {
171 register unsigned int regaddr;
172 char buf[MAX_REGISTER_RAW_SIZE];
173 char mess[128]; /* For messages */
174 register int i;
175
176 /* Offset of registers within the u area. */
177 unsigned int offset;
178
179 if (CANNOT_FETCH_REGISTER (regno))
180 {
181 bzero (buf, REGISTER_RAW_SIZE (regno)); /* Supply zeroes */
182 supply_register (regno, buf);
183 return;
184 }
185
186 offset = U_REGS_OFFSET;
187
188 regaddr = register_addr (regno, offset);
189 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
190 {
191 errno = 0;
192 *(int *) &buf[i] = ptrace (PT_RUREGS, inferior_pid,
193 (PTRACE_ARG3_TYPE) regaddr, 0);
194 regaddr += sizeof (int);
195 if (errno != 0)
196 {
197 sprintf (mess, "reading register %s (#%d)", reg_names[regno], regno);
198 perror_with_name (mess);
199 }
200 }
201 supply_register (regno, buf);
202 }
203
204 #endif /* !defined (FETCH_INFERIOR_REGISTERS). */
205 /* Fetch all registers, or just one, from the child process. */
206
207 #ifndef FETCH_INFERIOR_REGISTERS
208 void
209 fetch_inferior_registers (regno)
210 int regno;
211 {
212 if (regno == -1)
213 for (regno = 0; regno < NUM_REGS; regno++)
214 fetch_register (regno);
215 else
216 fetch_register (regno);
217 }
218
219 /* Registers we shouldn't try to store. */
220 #if !defined (CANNOT_STORE_REGISTER)
221 #define CANNOT_STORE_REGISTER(regno) 0
222 #endif
223
224 /* Store our register values back into the inferior.
225 If REGNO is -1, do this for all registers.
226 Otherwise, REGNO specifies which register (so we can save time). */
227
228 void
229 store_inferior_registers (regno)
230 int regno;
231 {
232 register unsigned int regaddr;
233 char buf[80];
234 extern char registers[];
235 register int i;
236
237 unsigned int offset = U_REGS_OFFSET;
238
239 if (regno >= 0)
240 {
241 regaddr = register_addr (regno, offset);
242 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int))
243 {
244 errno = 0;
245 ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
246 *(int *) &registers[REGISTER_BYTE (regno) + i]);
247 if (errno != 0)
248 {
249 sprintf (buf, "writing register number %d(%d)", regno, i);
250 perror_with_name (buf);
251 }
252 regaddr += sizeof(int);
253 }
254 }
255 else
256 {
257 for (regno = 0; regno < NUM_REGS; regno++)
258 {
259 if (CANNOT_STORE_REGISTER (regno))
260 continue;
261 regaddr = register_addr (regno, offset);
262 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int))
263 {
264 errno = 0;
265 ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
266 *(int *) &registers[REGISTER_BYTE (regno) + i]);
267 if (errno != 0)
268 {
269 sprintf (buf, "writing register number %d(%d)", regno, i);
270 perror_with_name (buf);
271 }
272 regaddr += sizeof(int);
273 }
274 }
275 }
276 return;
277 }
278 #endif /* !defined(FETCH_INFERIOR_REGISTERS) */
279
280 /* Resume execution of the inferior process.
281 If STEP is nonzero, single-step it.
282 If SIGNAL is nonzero, give it that signal. */
283
284 void
285 child_resume (step, signal)
286 int step;
287 int signal;
288 {
289 errno = 0;
290
291 /* An address of (PTRACE_ARG3_TYPE) 1 tells ptrace to continue from where
292 it was. (If GDB wanted it to start some other way, we have already
293 written a new PC value to the child.) */
294
295 if (step)
296 ptrace (PT_STEP, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal);
297 else
298 ptrace (PT_CONTINUE, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal);
299
300 if (errno)
301 perror_with_name ("ptrace");
302 }
303
304 /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
305 in the NEW_SUN_PTRACE case.
306 It ought to be straightforward. But it appears that writing did
307 not write the data that I specified. I cannot understand where
308 it got the data that it actually did write. */
309
310 /* Copy LEN bytes to or from inferior's memory starting at MEMADDR
311 to debugger memory starting at MYADDR. Copy to inferior if
312 WRITE is nonzero.
313
314 Returns the length copied, which is either the LEN argument or zero.
315 This xfer function does not do partial moves, since child_ops
316 doesn't allow memory operations to cross below us in the target stack
317 anyway. */
318
319 int
320 child_xfer_memory (memaddr, myaddr, len, write, target)
321 CORE_ADDR memaddr;
322 char *myaddr;
323 int len;
324 int write;
325 struct target_ops *target; /* ignored */
326 {
327 register int i;
328 /* Round starting address down to longword boundary. */
329 register CORE_ADDR addr = memaddr & - sizeof (int);
330 /* Round ending address up; get number of longwords that makes. */
331 register int count
332 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
333 /* Allocate buffer of that many longwords. */
334 register int *buffer = (int *) alloca (count * sizeof (int));
335
336 if (write)
337 {
338 /* Fill start and end extra bytes of buffer with existing memory data. */
339
340 if (addr != memaddr || len < (int)sizeof (int)) {
341 /* Need part of initial word -- fetch it. */
342 buffer[0] = ptrace (PT_READ_I, inferior_pid, (PTRACE_ARG3_TYPE) addr,
343 0);
344 }
345
346 if (count > 1) /* FIXME, avoid if even boundary */
347 {
348 buffer[count - 1]
349 = ptrace (PT_READ_I, inferior_pid,
350 (PTRACE_ARG3_TYPE) (addr + (count - 1) * sizeof (int)),
351 0);
352 }
353
354 /* Copy data to be written over corresponding part of buffer */
355
356 bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
357
358 /* Write the entire buffer. */
359
360 for (i = 0; i < count; i++, addr += sizeof (int))
361 {
362 errno = 0;
363 ptrace (PT_WRITE_D, inferior_pid, (PTRACE_ARG3_TYPE) addr,
364 buffer[i]);
365 if (errno)
366 {
367 /* Using the appropriate one (I or D) is necessary for
368 Gould NP1, at least. */
369 errno = 0;
370 ptrace (PT_WRITE_I, inferior_pid, (PTRACE_ARG3_TYPE) addr,
371 buffer[i]);
372 }
373 if (errno)
374 return 0;
375 }
376 }
377 else
378 {
379 /* Read all the longwords */
380 for (i = 0; i < count; i++, addr += sizeof (int))
381 {
382 errno = 0;
383 buffer[i] = ptrace (PT_READ_I, inferior_pid,
384 (PTRACE_ARG3_TYPE) addr, 0);
385 if (errno)
386 return 0;
387 QUIT;
388 }
389
390 /* Copy appropriate bytes out of the buffer. */
391 bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
392 }
393 return len;
394 }
395
This page took 0.059897 seconds and 4 git commands to generate.