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