]> Git Repo - binutils.git/blob - gdb/hppah-nat.c
* hppah-nat.c: Eliminate <sys/user.h> and other unnecessary stuff,
[binutils.git] / gdb / hppah-nat.c
1 /* Machine-dependent hooks for the unix child process stratum, for HPUX PA-RISC.
2
3    Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993
4    Free Software Foundation, Inc.
5
6    Contributed by the Center for Software Science at the
7    University of Utah ([email protected]).
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
26 #include "defs.h"
27 #include "inferior.h"
28 #include "target.h"
29 #include <sys/ptrace.h>
30
31 extern CORE_ADDR text_end;
32
33 static void fetch_register ();
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 int
39 call_ptrace (request, pid, addr, data)
40      int request, pid;
41      PTRACE_ARG3_TYPE addr;
42      int data;
43 {
44   return ptrace (request, pid, addr, data, 0);
45 }
46
47 void
48 kill_inferior ()
49 {
50   if (inferior_pid == 0)
51     return;
52   ptrace (PT_EXIT, inferior_pid, (PTRACE_ARG3_TYPE) 0, 0, 0);
53   wait ((int *)0);
54   target_mourn_inferior ();
55 }
56
57 /* Start debugging the process whose number is PID.  */
58 int
59 attach (pid)
60      int pid;
61 {
62   errno = 0;
63   ptrace (PT_ATTACH, pid, (PTRACE_ARG3_TYPE) 0, 0, 0);
64   if (errno)
65     perror_with_name ("ptrace");
66   attach_flag = 1;
67   return pid;
68 }
69
70 /* Stop debugging the process whose number is PID
71    and continue it with signal number SIGNAL.
72    SIGNAL = 0 means just continue it.  */
73
74 void
75 detach (signal)
76      int signal;
77 {
78   errno = 0;
79   ptrace (PT_DETACH, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal, 0);
80   if (errno)
81     perror_with_name ("ptrace");
82   attach_flag = 0;
83 }
84
85 /* Fetch all registers, or just one, from the child process.  */
86
87 void
88 fetch_inferior_registers (regno)
89      int regno;
90 {
91   if (regno == -1)
92     for (regno = 0; regno < NUM_REGS; regno++)
93       fetch_register (regno);
94   else
95     fetch_register (regno);
96 }
97
98 /* Store our register values back into the inferior.
99    If REGNO is -1, do this for all registers.
100    Otherwise, REGNO specifies which register (so we can save time).  */
101
102 void
103 store_inferior_registers (regno)
104      int regno;
105 {
106   register unsigned int regaddr;
107   char buf[80];
108   extern char registers[];
109   register int i;
110   unsigned int offset = U_REGS_OFFSET;
111   int scratch;
112
113   if (regno >= 0)
114     {
115       regaddr = register_addr (regno, offset);
116       errno = 0;
117       if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM)
118         {
119           scratch = *(int *) &registers[REGISTER_BYTE (regno)] | 0x3;
120           ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
121                   scratch, 0);
122           if (errno != 0)
123             {
124               sprintf (buf, "writing register number %d(%d)", regno, i);
125               perror_with_name (buf);
126             }
127         }
128       else
129         for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int))
130           {
131             errno = 0;
132             ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
133                     *(int *) &registers[REGISTER_BYTE (regno) + i], 0);
134             if (errno != 0)
135               {
136                 sprintf (buf, "writing register number %d(%d)", regno, i);
137                 perror_with_name (buf);
138               }
139             regaddr += sizeof(int);
140           }
141     }
142   else
143     {
144       for (regno = 0; regno < NUM_REGS; regno++)
145         {
146           if (CANNOT_STORE_REGISTER (regno))
147             continue;
148           regaddr = register_addr (regno, offset);
149           errno = 0;
150           if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM)
151             {
152               scratch = *(int *) &registers[REGISTER_BYTE (regno)] | 0x3;
153               ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
154                       scratch, 0);
155               if (errno != 0)
156                 {
157                   sprintf (buf, "writing register number %d(%d)", regno, i);
158                   perror_with_name (buf);
159                 }
160             }
161           else
162             for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int))
163               {
164                 errno = 0;
165                 ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
166                         *(int *) &registers[REGISTER_BYTE (regno) + i], 0);
167                 if (errno != 0)
168                   {
169                     sprintf (buf, "writing register number %d(%d)", regno, i);
170                     perror_with_name (buf);
171                   }
172                 regaddr += sizeof(int);
173               }
174         }
175     }
176   return;
177 }
178
179 /* Fetch one register.  */
180
181 static void
182 fetch_register (regno)
183      int regno;
184 {
185   register unsigned int regaddr;
186   char buf[MAX_REGISTER_RAW_SIZE];
187   char mess[128];                               /* For messages */
188   register int i;
189
190   /* Offset of registers within the u area.  */
191   unsigned int offset;
192
193   offset = U_REGS_OFFSET;
194
195   regaddr = register_addr (regno, offset);
196   for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
197     {
198       errno = 0;
199       *(int *) &buf[i] = ptrace (PT_RUREGS, inferior_pid,
200                                  (PTRACE_ARG3_TYPE) regaddr, 0, 0);
201       regaddr += sizeof (int);
202       if (errno != 0)
203         {
204           sprintf (mess, "reading register %s (#%d)", reg_names[regno], regno);
205           perror_with_name (mess);
206         }
207     }
208   if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM)
209     buf[3] &= ~0x3;
210   supply_register (regno, buf);
211 }
212
213 /* Resume execution of the inferior process.
214    If STEP is nonzero, single-step it.
215    If SIGNAL is nonzero, give it that signal.  */
216
217 void
218 child_resume (step, signal)
219      int step;
220      int signal;
221 {
222   errno = 0;
223
224   /* An address of (PTRACE_ARG3_TYPE) 1 tells ptrace to continue from where
225      it was. (If GDB wanted it to start some other way, we have already
226      written a new PC value to the child.)  */
227
228   if (step)
229     ptrace (PT_SINGLE, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal, 0);
230   else
231     ptrace (PT_CONTIN, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal, 0);
232
233   if (errno)
234     perror_with_name ("ptrace");
235 }
236
237 /* Copy LEN bytes to or from inferior's memory starting at MEMADDR
238    to debugger memory starting at MYADDR.   Copy to inferior if
239    WRITE is nonzero.
240   
241    Returns the length copied, which is either the LEN argument or zero.
242    This xfer function does not do partial moves, since child_ops
243    doesn't allow memory operations to cross below us in the target stack
244    anyway.  */
245
246 int
247 child_xfer_memory (memaddr, myaddr, len, write, target)
248      CORE_ADDR memaddr;
249      char *myaddr;
250      int len;
251      int write;
252      struct target_ops *target;         /* ignored */
253 {
254   register int i;
255   /* Round starting address down to longword boundary.  */
256   register CORE_ADDR addr = memaddr & - sizeof (int);
257   /* Round ending address up; get number of longwords that makes.  */
258   register int count
259     = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
260   /* Allocate buffer of that many longwords.  */
261   register int *buffer = (int *) alloca (count * sizeof (int));
262
263   if (write)
264     {
265       /* Fill start and end extra bytes of buffer with existing memory data.  */
266
267       if (addr != memaddr || len < (int)sizeof (int)) {
268         /* Need part of initial word -- fetch it.  */
269         buffer[0] = ptrace (addr < text_end ? PT_RIUSER : PT_RDUSER, 
270                             inferior_pid, (PTRACE_ARG3_TYPE) addr, 0, 0);
271       }
272
273       if (count > 1)            /* FIXME, avoid if even boundary */
274         {
275           buffer[count - 1]
276             = ptrace (addr < text_end ? PT_RIUSER : PT_RDUSER, inferior_pid,
277                       (PTRACE_ARG3_TYPE) (addr + (count - 1) * sizeof (int)),
278                       0, 0);
279         }
280
281       /* Copy data to be written over corresponding part of buffer */
282
283       bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
284
285       /* Write the entire buffer.  */
286
287       for (i = 0; i < count; i++, addr += sizeof (int))
288         {
289 /* The HP-UX kernel crashes if you use PT_WDUSER to write into the text
290    segment.  FIXME -- does it work to write into the data segment using
291    WIUSER, or do these idiots really expect us to figure out which segment
292    the address is in, so we can use a separate system call for it??!  */
293           errno = 0;
294           ptrace (addr < text_end ? PT_WIUSER : PT_WDUSER, inferior_pid, 
295                   (PTRACE_ARG3_TYPE) addr,
296                   buffer[i], 0);
297           if (errno)
298             return 0;
299         }
300     }
301   else
302     {
303       /* Read all the longwords */
304       for (i = 0; i < count; i++, addr += sizeof (int))
305         {
306           errno = 0;
307           buffer[i] = ptrace (addr < text_end ? PT_RIUSER : PT_RDUSER, 
308                               inferior_pid, (PTRACE_ARG3_TYPE) addr, 0, 0);
309           if (errno)
310             return 0;
311           QUIT;
312         }
313
314       /* Copy appropriate bytes out of the buffer.  */
315       bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
316     }
317   return len;
318 }
This page took 0.040837 seconds and 4 git commands to generate.