* complaints.c: New file, code moved from utils.c.
[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
67 /* Start debugging the process whose number is PID. */
68 int
69 attach (pid)
70 int pid;
71 {
72 errno = 0;
73 ptrace (PT_ATTACH, pid, (PTRACE_ARG3_TYPE) 0, 0);
74 if (errno)
75 perror_with_name ("ptrace");
76 attach_flag = 1;
77 return pid;
78 }
79
80 /* Stop debugging the process whose number is PID
81 and continue it with signal number SIGNAL.
82 SIGNAL = 0 means just continue it. */
83
84 void
85 detach (signal)
86 int signal;
87 {
88 errno = 0;
89 ptrace (PT_DETACH, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal);
90 if (errno)
91 perror_with_name ("ptrace");
92 attach_flag = 0;
93 }
94 #endif /* ATTACH_DETACH */
95 \f
96
97
98 #if !defined (FETCH_INFERIOR_REGISTERS)
99
100 /* KERNEL_U_ADDR is the amount to subtract from u.u_ar0
101 to get the offset in the core file of the register values. */
102 #if defined (KERNEL_U_ADDR_BSD)
103 /* Get kernel_u_addr using BSD-style nlist(). */
104 CORE_ADDR kernel_u_addr;
105
106 #include <a.out.gnu.h> /* For struct nlist */
107
108 void
109 _initialize_kernel_u_addr ()
110 {
111 struct nlist names[2];
112
113 names[0].n_un.n_name = "_u";
114 names[1].n_un.n_name = NULL;
115 if (nlist ("/vmunix", names) == 0)
116 kernel_u_addr = names[0].n_value;
117 else
118 fatal ("Unable to get kernel u area address.");
119 }
120 #endif /* KERNEL_U_ADDR_BSD. */
121
122 #if defined (KERNEL_U_ADDR_HPUX)
123 /* Get kernel_u_addr using HPUX-style nlist(). */
124 CORE_ADDR kernel_u_addr;
125
126 struct hpnlist {
127 char * n_name;
128 long n_value;
129 unsigned char n_type;
130 unsigned char n_length;
131 short n_almod;
132 short n_unused;
133 };
134 static struct hpnlist nl[] = {{ "_u", -1, }, { (char *) 0, }};
135
136 /* read the value of the u area from the hp-ux kernel */
137 void _initialize_kernel_u_addr ()
138 {
139 struct user u;
140 nlist ("/hp-ux", &nl);
141 kernel_u_addr = nl[0].n_value;
142 }
143 #endif /* KERNEL_U_ADDR_HPUX. */
144
145 #if !defined (offsetof)
146 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
147 #endif
148
149 /* U_REGS_OFFSET is the offset of the registers within the u area. */
150 #if !defined (U_REGS_OFFSET)
151 #define U_REGS_OFFSET \
152 ptrace (PT_READ_U, inferior_pid, \
153 (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \
154 - KERNEL_U_ADDR
155 #endif
156
157 /* Registers we shouldn't try to fetch. */
158 #if !defined (CANNOT_FETCH_REGISTER)
159 #define CANNOT_FETCH_REGISTER(regno) 0
160 #endif
161
162 /* Fetch one register. */
163
164 static void
165 fetch_register (regno)
166 int regno;
167 {
168 register unsigned int regaddr;
169 char buf[MAX_REGISTER_RAW_SIZE];
170 char mess[128]; /* For messages */
171 register int i;
172
173 /* Offset of registers within the u area. */
174 unsigned int offset;
175
176 if (CANNOT_FETCH_REGISTER (regno))
177 {
178 bzero (buf, REGISTER_RAW_SIZE (regno)); /* Supply zeroes */
179 supply_register (regno, buf);
180 return;
181 }
182
183 offset = U_REGS_OFFSET;
184
185 regaddr = register_addr (regno, offset);
186 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
187 {
188 errno = 0;
189 *(int *) &buf[i] = ptrace (PT_RUREGS, inferior_pid,
190 (PTRACE_ARG3_TYPE) regaddr, 0);
191 regaddr += sizeof (int);
192 if (errno != 0)
193 {
194 sprintf (mess, "reading register %s (#%d)", reg_names[regno], regno);
195 perror_with_name (mess);
196 }
197 }
198 supply_register (regno, buf);
199 }
200
201 #endif /* !defined (FETCH_INFERIOR_REGISTERS). */
202 /* Fetch all registers, or just one, from the child process. */
203
204 #ifndef FETCH_INFERIOR_REGISTERS
205 void
206 fetch_inferior_registers (regno)
207 int regno;
208 {
209 if (regno == -1)
210 for (regno = 0; regno < NUM_REGS; regno++)
211 fetch_register (regno);
212 else
213 fetch_register (regno);
214 }
215
216 /* Registers we shouldn't try to store. */
217 #if !defined (CANNOT_STORE_REGISTER)
218 #define CANNOT_STORE_REGISTER(regno) 0
219 #endif
220
221 /* Store our register values back into the inferior.
222 If REGNO is -1, do this for all registers.
223 Otherwise, REGNO specifies which register (so we can save time). */
224
225 void
226 store_inferior_registers (regno)
227 int regno;
228 {
229 register unsigned int regaddr;
230 char buf[80];
231 extern char registers[];
232 register int i;
233
234 unsigned int offset = U_REGS_OFFSET;
235
236 if (regno >= 0)
237 {
238 regaddr = register_addr (regno, offset);
239 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int))
240 {
241 errno = 0;
242 ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
243 *(int *) &registers[REGISTER_BYTE (regno) + i]);
244 if (errno != 0)
245 {
246 sprintf (buf, "writing register number %d(%d)", regno, i);
247 perror_with_name (buf);
248 }
249 regaddr += sizeof(int);
250 }
251 }
252 else
253 {
254 for (regno = 0; regno < NUM_REGS; regno++)
255 {
256 if (CANNOT_STORE_REGISTER (regno))
257 continue;
258 regaddr = register_addr (regno, offset);
259 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int))
260 {
261 errno = 0;
262 ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
263 *(int *) &registers[REGISTER_BYTE (regno) + i]);
264 if (errno != 0)
265 {
266 sprintf (buf, "writing register number %d(%d)", regno, i);
267 perror_with_name (buf);
268 }
269 regaddr += sizeof(int);
270 }
271 }
272 }
273 return;
274 }
275 #endif /* !defined(FETCH_INFERIOR_REGISTERS) */
276
277 /* Resume execution of the inferior process.
278 If STEP is nonzero, single-step it.
279 If SIGNAL is nonzero, give it that signal. */
280
281 void
282 child_resume (step, signal)
283 int step;
284 int signal;
285 {
286 errno = 0;
287
288 /* An address of (PTRACE_ARG3_TYPE) 1 tells ptrace to continue from where
289 it was. (If GDB wanted it to start some other way, we have already
290 written a new PC value to the child.) */
291
292 if (step)
293 ptrace (PT_STEP, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal);
294 else
295 ptrace (PT_CONTINUE, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal);
296
297 if (errno)
298 perror_with_name ("ptrace");
299 }
300
301 /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
302 in the NEW_SUN_PTRACE case.
303 It ought to be straightforward. But it appears that writing did
304 not write the data that I specified. I cannot understand where
305 it got the data that it actually did write. */
306
307 /* Copy LEN bytes to or from inferior's memory starting at MEMADDR
308 to debugger memory starting at MYADDR. Copy to inferior if
309 WRITE is nonzero.
310
311 Returns the length copied, which is either the LEN argument or zero.
312 This xfer function does not do partial moves, since child_ops
313 doesn't allow memory operations to cross below us in the target stack
314 anyway. */
315
316 int
317 child_xfer_memory (memaddr, myaddr, len, write, target)
318 CORE_ADDR memaddr;
319 char *myaddr;
320 int len;
321 int write;
322 struct target_ops *target; /* ignored */
323 {
324 register int i;
325 /* Round starting address down to longword boundary. */
326 register CORE_ADDR addr = memaddr & - sizeof (int);
327 /* Round ending address up; get number of longwords that makes. */
328 register int count
329 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
330 /* Allocate buffer of that many longwords. */
331 register int *buffer = (int *) alloca (count * sizeof (int));
332
333 if (write)
334 {
335 /* Fill start and end extra bytes of buffer with existing memory data. */
336
337 if (addr != memaddr || len < (int)sizeof (int)) {
338 /* Need part of initial word -- fetch it. */
339 buffer[0] = ptrace (PT_READ_I, inferior_pid, (PTRACE_ARG3_TYPE) addr,
340 0);
341 }
342
343 if (count > 1) /* FIXME, avoid if even boundary */
344 {
345 buffer[count - 1]
346 = ptrace (PT_READ_I, inferior_pid,
347 (PTRACE_ARG3_TYPE) (addr + (count - 1) * sizeof (int)),
348 0);
349 }
350
351 /* Copy data to be written over corresponding part of buffer */
352
353 bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
354
355 /* Write the entire buffer. */
356
357 for (i = 0; i < count; i++, addr += sizeof (int))
358 {
359 errno = 0;
360 ptrace (PT_WRITE_D, inferior_pid, (PTRACE_ARG3_TYPE) addr,
361 buffer[i]);
362 if (errno)
363 {
364 /* Using the appropriate one (I or D) is necessary for
365 Gould NP1, at least. */
366 errno = 0;
367 ptrace (PT_WRITE_I, inferior_pid, (PTRACE_ARG3_TYPE) addr,
368 buffer[i]);
369 }
370 if (errno)
371 return 0;
372 }
373 }
374 else
375 {
376 /* Read all the longwords */
377 for (i = 0; i < count; i++, addr += sizeof (int))
378 {
379 errno = 0;
380 buffer[i] = ptrace (PT_READ_I, inferior_pid,
381 (PTRACE_ARG3_TYPE) addr, 0);
382 if (errno)
383 return 0;
384 QUIT;
385 }
386
387 /* Copy appropriate bytes out of the buffer. */
388 bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
389 }
390 return len;
391 }
392
This page took 0.041659 seconds and 4 git commands to generate.