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