]> Git Repo - binutils.git/blob - gdb/hp300ux-nat.c
* ser-unix.c (hardwire_noflush_set_tty_state): Don't muck with ICANON.
[binutils.git] / gdb / hp300ux-nat.c
1 /* HP/UX native interface for HP 300's, for GDB when running under Unix.
2    Copyright 1986, 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
3    
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #include "defs.h"
21 #include "frame.h"
22 #include "inferior.h"
23
24 /* Defining this means some system include files define some extra stuff.  */
25 #define WOPR
26 #include <sys/param.h>
27 #include <sys/dir.h>
28 #include <signal.h>
29 #include <sys/user.h>
30 #include <sys/ioctl.h>
31 #include <fcntl.h>
32
33 #include <sys/ptrace.h>
34 #include <sys/reg.h>
35 #include <sys/trap.h>
36
37 #include "gdbcore.h"
38
39 #include <sys/file.h>
40 #include <sys/stat.h>
41
42 /* Get kernel_u_addr using HPUX-style nlist().  */
43 CORE_ADDR kernel_u_addr;
44
45 struct hpnlist {
46         char *          n_name;
47         long            n_value;
48         unsigned char   n_type;
49         unsigned char   n_length;
50         short           n_almod;
51         short           n_unused;
52 };
53 static struct hpnlist nl[] = {{ "_u", -1, }, { (char *) 0, }};
54
55 /* read the value of the u area from the hp-ux kernel */
56 void
57 _initialize_hp300ux_nat ()
58 {
59 #ifndef HPUX_VERSION_5
60     nlist ("/hp-ux", nl);
61     kernel_u_addr = nl[0].n_value;
62 #else /* HPUX version 5.  */
63     kernel_u_addr = (CORE_ADDR) 0x0097900;
64 #endif
65 }
66
67 #define INFERIOR_AR0(u)                                                 \
68   ((ptrace                                                              \
69     (PT_RUAREA, inferior_pid,                                           \
70      (PTRACE_ARG3_TYPE) ((char *) &u.u_ar0 - (char *) &u), 0, 0))               \
71    - kernel_u_addr)
72
73 static void
74 fetch_inferior_register (regno, regaddr)
75      register int regno;
76      register unsigned int regaddr;
77 {
78 #ifndef HPUX_VERSION_5
79   if (regno == PS_REGNUM)
80     {
81       union { int i; short s[2]; } ps_val;
82       int regval;
83       
84       ps_val.i = (ptrace (PT_RUAREA, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
85                           0, 0));
86       regval = ps_val.s[0];
87       supply_register (regno, (char *)&regval);
88     }
89   else
90 #endif /* not HPUX_VERSION_5 */
91     {
92       char buf[MAX_REGISTER_RAW_SIZE];
93       register int i;
94       
95       for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
96         {
97           *(int *) &buf[i] = ptrace (PT_RUAREA, inferior_pid,
98                                      (PTRACE_ARG3_TYPE) regaddr, 0, 0);
99           regaddr += sizeof (int);
100         }
101       supply_register (regno, buf);
102     }
103   return;
104 }
105
106 static void
107 store_inferior_register_1 (regno, regaddr, val)
108      int regno;
109      unsigned int regaddr;
110      int val;
111 {
112   errno = 0;
113   ptrace (PT_WUAREA, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, val, 0);
114 #if 0
115   /* HP-UX randomly sets errno to non-zero for regno == 25.
116      However, the value is correctly written, so ignore errno. */
117   if (errno != 0)
118     {
119       char string_buf[64];
120       
121       sprintf (string_buf, "writing register number %d", regno);
122       perror_with_name (string_buf);
123     }
124 #endif
125   return;
126 }
127
128 static void
129 store_inferior_register (regno, regaddr)
130      register int regno;
131      register unsigned int regaddr;
132 {
133 #ifndef HPUX_VERSION_5
134   if (regno == PS_REGNUM)
135     {
136       union { int i; short s[2]; } ps_val;
137       
138       ps_val.i = (ptrace (PT_RUAREA, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
139                           0, 0));
140       ps_val.s[0] = (read_register (regno));
141       store_inferior_register_1 (regno, regaddr, ps_val.i);
142     }
143   else
144 #endif /* not HPUX_VERSION_5 */
145     {
146       char buf[MAX_REGISTER_RAW_SIZE];
147       register int i;
148       extern char registers[];
149       
150       for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
151         {
152           store_inferior_register_1
153             (regno, regaddr,
154              (*(int *) &registers[(REGISTER_BYTE (regno)) + i]));
155           regaddr += sizeof (int);
156         }
157     }
158   return;
159 }
160
161 void
162 fetch_inferior_registers (regno)
163      int regno;
164 {
165   struct user u;
166   register unsigned int ar0_offset;
167   
168   ar0_offset = (INFERIOR_AR0 (u));
169   if (regno == -1)
170     {
171       for (regno = 0; (regno < FP0_REGNUM); regno++)
172         fetch_inferior_register (regno, (REGISTER_ADDR (ar0_offset, regno)));
173       for (; (regno < NUM_REGS); regno++)
174         fetch_inferior_register (regno, (FP_REGISTER_ADDR (u, regno)));
175     }
176   else
177     fetch_inferior_register (regno,
178                              (regno < FP0_REGNUM
179                               ? REGISTER_ADDR (ar0_offset, regno)
180                               : FP_REGISTER_ADDR (u, regno)));
181 }
182
183 /* Store our register values back into the inferior.
184    If REGNO is -1, do this for all registers.
185    Otherwise, REGNO specifies which register (so we can save time).  */
186
187 void
188 store_inferior_registers (regno)
189      register int regno;
190 {
191   struct user u;
192   register unsigned int ar0_offset;
193   extern char registers[];
194
195   if (regno >= FP0_REGNUM)
196     {
197       store_inferior_register (regno, (FP_REGISTER_ADDR (u, regno)));
198       return;
199     }
200   
201   ar0_offset = (INFERIOR_AR0 (u));
202   if (regno >= 0)
203     {
204       store_inferior_register (regno, (REGISTER_ADDR (ar0_offset, regno)));
205       return;
206     }
207
208   for (regno = 0; (regno < FP0_REGNUM); regno++)
209     store_inferior_register (regno, (REGISTER_ADDR (ar0_offset, regno)));
210   for (; (regno < NUM_REGS); regno++)
211     store_inferior_register (regno, (FP_REGISTER_ADDR (u, regno)));
212   return;
213 }
214
215 \f
216 #if 0
217
218 /* This function is no longer used.  The version in coredep.c is used
219    instead.  */
220
221 /* Take the register values out of a core file and store
222    them where `read_register' will find them.  */
223
224 #ifdef HPUX_VERSION_5
225 #define e_PS e_regs[PS]
226 #define e_PC e_regs[PC]
227 #endif /* HPUX_VERSION_5 */
228
229 void
230 fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
231      char *core_reg_sect;
232      unsigned int core_reg_size;
233      int which;
234      unsigned int reg_addr;     /* Unused in this version */
235 {
236   int val, regno;
237   struct user u;
238   struct exception_stack *pes = (struct exception_stack *) core_reg_sect;
239 #define es (*pes)
240   char *buf;
241
242   if (which == 0) {
243     if (core_reg_size < 
244                   ((char *) &es.e_offset - (char *) &es.e_regs[R0]))
245           error ("Not enough registers in core file");
246     for (regno = 0; (regno < PS_REGNUM); regno++)
247       supply_register (regno, (char *) &es.e_regs[regno + R0]);
248     val = es.e_PS;
249     supply_register (regno++, (char *) &val);
250     supply_register (regno++, (char *) &es.e_PC);
251
252   } else if (which == 2) {
253
254     /* FIXME: This may not work if the float regs and control regs are
255        discontinuous.  */
256     for (regno = FP0_REGNUM, buf = core_reg_sect;
257          (regno < NUM_REGS);
258          buf += REGISTER_RAW_SIZE (regno), regno++)
259       {
260         supply_register (regno, buf);
261       }
262   }
263 }
264
265 #endif /* 0 */
266
267 int
268 getpagesize ()
269 {
270   return 4096;
271 }
This page took 0.040451 seconds and 4 git commands to generate.