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