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