include nm.h in defs.h
[external/binutils.git] / gdb / rs6000-nat.c
1 /* IBM RS/6000 native-dependent code for GDB, the GNU debugger.
2    Copyright 1986, 1987, 1989, 1991, 1992 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 "inferior.h"
22 #include "target.h"
23
24 #include <sys/ptrace.h>
25 #include <sys/reg.h>
26
27 #include <sys/param.h>
28 #include <sys/dir.h>
29 #include <sys/user.h>
30 #include <signal.h>
31 #include <sys/ioctl.h>
32 #include <fcntl.h>
33
34 #include <a.out.h>
35 #include <sys/file.h>
36 #include <sys/stat.h>
37 #include <sys/core.h>
38
39 extern int errno;
40
41 static void
42 exec_one_dummy_insn PARAMS ((void));
43
44 /* Conversion from gdb-to-system special purpose register numbers.. */
45
46 static int special_regs[] = {
47   IAR,                          /* PC_REGNUM    */
48   MSR,                          /* PS_REGNUM    */
49   CR,                           /* CR_REGNUM    */
50   LR,                           /* LR_REGNUM    */
51   CTR,                          /* CTR_REGNUM   */
52   XER,                          /* XER_REGNUM   */
53   MQ                            /* MQ_REGNUM    */
54 };
55
56 void
57 fetch_inferior_registers (regno)
58   int regno;
59 {
60   int ii;
61   extern char registers[];
62
63   if (regno < 0) {                      /* for all registers */
64
65     /* read 32 general purpose registers. */
66
67     for (ii=0; ii < 32; ++ii)
68       *(int*)&registers[REGISTER_BYTE (ii)] = 
69         ptrace (PT_READ_GPR, inferior_pid, (PTRACE_ARG3_TYPE) ii, 0, 0);
70
71     /* read general purpose floating point registers. */
72
73     for (ii=0; ii < 32; ++ii)
74       ptrace (PT_READ_FPR, inferior_pid, 
75         (PTRACE_ARG3_TYPE) &registers [REGISTER_BYTE (FP0_REGNUM+ii)],
76               FPR0+ii, 0);
77
78     /* read special registers. */
79     for (ii=0; ii <= LAST_SP_REGNUM-FIRST_SP_REGNUM; ++ii)
80       *(int*)&registers[REGISTER_BYTE (FIRST_SP_REGNUM+ii)] = 
81         ptrace (PT_READ_GPR, inferior_pid, (PTRACE_ARG3_TYPE) special_regs[ii],
82                 0, 0);
83
84     registers_fetched ();
85     return;
86   }
87
88   /* else an individual register is addressed. */
89
90   else if (regno < FP0_REGNUM) {                /* a GPR */
91     *(int*)&registers[REGISTER_BYTE (regno)] =
92         ptrace (PT_READ_GPR, inferior_pid, (PTRACE_ARG3_TYPE) regno, 0, 0);
93   }
94   else if (regno <= FPLAST_REGNUM) {            /* a FPR */
95     ptrace (PT_READ_FPR, inferior_pid,
96         (PTRACE_ARG3_TYPE) &registers [REGISTER_BYTE (regno)],
97             (regno-FP0_REGNUM+FPR0), 0);
98   }
99   else if (regno <= LAST_SP_REGNUM) {           /* a special register */
100     *(int*)&registers[REGISTER_BYTE (regno)] =
101         ptrace (PT_READ_GPR, inferior_pid,
102                 (PTRACE_ARG3_TYPE) special_regs[regno-FIRST_SP_REGNUM], 0, 0);
103   }
104   else
105     fprintf (stderr, "gdb error: register no %d not implemented.\n", regno);
106
107   register_valid [regno] = 1;
108 }
109
110 /* Store our register values back into the inferior.
111    If REGNO is -1, do this for all registers.
112    Otherwise, REGNO specifies which register (so we can save time).  */
113
114 void
115 store_inferior_registers (regno)
116      int regno;
117 {
118   extern char registers[];
119
120   errno = 0;
121
122   if (regno == -1) {                    /* for all registers..  */
123       int ii;
124
125        /* execute one dummy instruction (which is a breakpoint) in inferior
126           process. So give kernel a chance to do internal house keeping.
127           Otherwise the following ptrace(2) calls will mess up user stack
128           since kernel will get confused about the bottom of the stack (%sp) */
129
130        exec_one_dummy_insn ();
131
132       /* write general purpose registers first! */
133       for ( ii=GPR0; ii<=GPR31; ++ii) {
134         ptrace (PT_WRITE_GPR, inferior_pid, (PTRACE_ARG3_TYPE) ii,
135                 *(int*)&registers[REGISTER_BYTE (ii)], 0);
136         if ( errno ) { 
137           perror ("ptrace write_gpr"); errno = 0;
138         }
139       }
140
141       /* write floating point registers now. */
142       for ( ii=0; ii < 32; ++ii) {
143         ptrace (PT_WRITE_FPR, inferior_pid, 
144                   (PTRACE_ARG3_TYPE) &registers[REGISTER_BYTE (FP0_REGNUM+ii)],
145                 FPR0+ii, 0);
146         if ( errno ) {
147           perror ("ptrace write_fpr"); errno = 0;
148         }
149       }
150
151       /* write special registers. */
152       for (ii=0; ii <= LAST_SP_REGNUM-FIRST_SP_REGNUM; ++ii) {
153         ptrace (PT_WRITE_GPR, inferior_pid,
154                 (PTRACE_ARG3_TYPE) special_regs[ii],
155                 *(int*)&registers[REGISTER_BYTE (FIRST_SP_REGNUM+ii)], 0);
156         if ( errno ) {
157           perror ("ptrace write_gpr"); errno = 0;
158         }
159       }
160   }
161
162   /* else, a specific register number is given... */
163
164   else if (regno < FP0_REGNUM) {                /* a GPR */
165
166     ptrace (PT_WRITE_GPR, inferior_pid, (PTRACE_ARG3_TYPE) regno,
167                 *(int*)&registers[REGISTER_BYTE (regno)], 0);
168   }
169
170   else if (regno <= FPLAST_REGNUM) {            /* a FPR */
171     ptrace (PT_WRITE_FPR, inferior_pid, 
172             (PTRACE_ARG3_TYPE) &registers[REGISTER_BYTE (regno)],
173             regno-FP0_REGNUM+FPR0, 0);
174   }
175
176   else if (regno <= LAST_SP_REGNUM) {           /* a special register */
177
178     ptrace (PT_WRITE_GPR, inferior_pid,
179             (PTRACE_ARG3_TYPE) special_regs [regno-FIRST_SP_REGNUM],
180             *(int*)&registers[REGISTER_BYTE (regno)], 0);
181   }
182
183   else
184     fprintf (stderr, "Gdb error: register no %d not implemented.\n", regno);
185
186   if ( errno ) {
187     perror ("ptrace write");  errno = 0;
188   }
189 }
190
191 /* Execute one dummy breakpoint instruction.  This way we give the kernel
192    a chance to do some housekeeping and update inferior's internal data,
193    including u_area. */
194 static void
195 exec_one_dummy_insn ()
196 {
197 #define DUMMY_INSN_ADDR (TEXT_SEGMENT_BASE)+0x200
198
199   unsigned long shadow;
200   unsigned int status, pid;
201
202   /* We plant one dummy breakpoint into DUMMY_INSN_ADDR address. We assume that
203      this address will never be executed again by the real code. */
204
205   target_insert_breakpoint (DUMMY_INSN_ADDR, &shadow);
206
207   errno = 0;
208   ptrace (PT_CONTINUE, inferior_pid, (PTRACE_ARG3_TYPE) DUMMY_INSN_ADDR, 0, 0);
209   if (errno)
210     perror ("pt_continue");
211
212   do {
213     pid = wait (&status);
214   } while (pid != inferior_pid);
215     
216   target_remove_breakpoint (DUMMY_INSN_ADDR, &shadow);
217 }
218
219 void
220 fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
221      char *core_reg_sect;
222      unsigned core_reg_size;
223      int which;
224      unsigned int reg_addr;     /* Unused in this version */
225 {
226   /* fetch GPRs and special registers from the first register section
227      in core bfd. */
228   if (which == 0) {
229
230     /* copy GPRs first. */
231     bcopy (core_reg_sect, registers, 32 * 4);
232
233     /* gdb's internal register template and bfd's register section layout
234        should share a common include file. FIXMEmgo */
235     /* then comes special registes. They are supposed to be in the same
236        order in gdb template and bfd `.reg' section. */
237     core_reg_sect += (32 * 4);
238     bcopy (core_reg_sect, &registers [REGISTER_BYTE (FIRST_SP_REGNUM)],
239                         (LAST_SP_REGNUM - FIRST_SP_REGNUM + 1) * 4);
240   }
241
242   /* fetch floating point registers from register section 2 in core bfd. */
243   else if (which == 2)
244     bcopy (core_reg_sect, &registers [REGISTER_BYTE (FP0_REGNUM)], 32 * 8);
245
246   else
247     fprintf (stderr, "Gdb error: unknown parameter to fetch_core_registers().\n");
248 }