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