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