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