1 /* IBM RS/6000 host-dependent code for GDB, the GNU debugger.
2 Copyright 1986, 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
4 This file is part of GDB.
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.
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.
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. */
28 #include <sys/param.h>
32 #include <sys/ioctl.h>
35 #include <sys/ptrace.h>
46 exec_one_dummy_insn
PARAMS ((void));
48 /* Conversion from gdb-to-system special purpose register numbers.. */
50 static int special_regs
[] = {
61 fetch_inferior_registers (regno
)
65 extern char registers
[];
67 if (regno
< 0) { /* for all registers */
69 /* read 32 general purpose registers. */
71 for (ii
=0; ii
< 32; ++ii
)
72 *(int*)®isters
[REGISTER_BYTE (ii
)] =
73 ptrace (PT_READ_GPR
, inferior_pid
, (PTRACE_ARG3_TYPE
) ii
, 0, 0);
75 /* read general purpose floating point registers. */
77 for (ii
=0; ii
< 32; ++ii
)
78 ptrace (PT_READ_FPR
, inferior_pid
,
79 (PTRACE_ARG3_TYPE
) ®isters
[REGISTER_BYTE (FP0_REGNUM
+ii
)],
82 /* read special registers. */
83 for (ii
=0; ii
<= LAST_SP_REGNUM
-FIRST_SP_REGNUM
; ++ii
)
84 *(int*)®isters
[REGISTER_BYTE (FIRST_SP_REGNUM
+ii
)] =
85 ptrace (PT_READ_GPR
, inferior_pid
, (PTRACE_ARG3_TYPE
) special_regs
[ii
],
92 /* else an individual register is addressed. */
94 else if (regno
< FP0_REGNUM
) { /* a GPR */
95 *(int*)®isters
[REGISTER_BYTE (regno
)] =
96 ptrace (PT_READ_GPR
, inferior_pid
, (PTRACE_ARG3_TYPE
) regno
, 0, 0);
98 else if (regno
<= FPLAST_REGNUM
) { /* a FPR */
99 ptrace (PT_READ_FPR
, inferior_pid
,
100 (PTRACE_ARG3_TYPE
) ®isters
[REGISTER_BYTE (regno
)],
101 (regno
-FP0_REGNUM
+FPR0
), 0);
103 else if (regno
<= LAST_SP_REGNUM
) { /* a special register */
104 *(int*)®isters
[REGISTER_BYTE (regno
)] =
105 ptrace (PT_READ_GPR
, inferior_pid
,
106 (PTRACE_ARG3_TYPE
) special_regs
[regno
-FIRST_SP_REGNUM
], 0, 0);
109 fprintf (stderr
, "gdb error: register no %d not implemented.\n", regno
);
111 register_valid
[regno
] = 1;
114 /* Store our register values back into the inferior.
115 If REGNO is -1, do this for all registers.
116 Otherwise, REGNO specifies which register (so we can save time). */
119 store_inferior_registers (regno
)
122 extern char registers
[];
126 if (regno
== -1) { /* for all registers.. */
129 /* execute one dummy instruction (which is a breakpoint) in inferior
130 process. So give kernel a chance to do internal house keeping.
131 Otherwise the following ptrace(2) calls will mess up user stack
132 since kernel will get confused about the bottom of the stack (%sp) */
134 exec_one_dummy_insn ();
136 /* write general purpose registers first! */
137 for ( ii
=GPR0
; ii
<=GPR31
; ++ii
) {
138 ptrace (PT_WRITE_GPR
, inferior_pid
, (PTRACE_ARG3_TYPE
) ii
,
139 *(int*)®isters
[REGISTER_BYTE (ii
)], 0);
141 perror ("ptrace write_gpr"); errno
= 0;
145 /* write floating point registers now. */
146 for ( ii
=0; ii
< 32; ++ii
) {
147 ptrace (PT_WRITE_FPR
, inferior_pid
,
148 (PTRACE_ARG3_TYPE
) ®isters
[REGISTER_BYTE (FP0_REGNUM
+ii
)],
151 perror ("ptrace write_fpr"); errno
= 0;
155 /* write special registers. */
156 for (ii
=0; ii
<= LAST_SP_REGNUM
-FIRST_SP_REGNUM
; ++ii
) {
157 ptrace (PT_WRITE_GPR
, inferior_pid
,
158 (PTRACE_ARG3_TYPE
) special_regs
[ii
],
159 *(int*)®isters
[REGISTER_BYTE (FIRST_SP_REGNUM
+ii
)], 0);
161 perror ("ptrace write_gpr"); errno
= 0;
166 /* else, a specific register number is given... */
168 else if (regno
< FP0_REGNUM
) { /* a GPR */
170 ptrace (PT_WRITE_GPR
, inferior_pid
, (PTRACE_ARG3_TYPE
) regno
,
171 *(int*)®isters
[REGISTER_BYTE (regno
)], 0);
174 else if (regno
<= FPLAST_REGNUM
) { /* a FPR */
175 ptrace (PT_WRITE_FPR
, inferior_pid
,
176 (PTRACE_ARG3_TYPE
) ®isters
[REGISTER_BYTE (regno
)],
177 regno
-FP0_REGNUM
+FPR0
, 0);
180 else if (regno
<= LAST_SP_REGNUM
) { /* a special register */
182 ptrace (PT_WRITE_GPR
, inferior_pid
,
183 (PTRACE_ARG3_TYPE
) special_regs
[regno
-FIRST_SP_REGNUM
],
184 *(int*)®isters
[REGISTER_BYTE (regno
)], 0);
188 fprintf (stderr
, "Gdb error: register no %d not implemented.\n", regno
);
191 perror ("ptrace write"); errno
= 0;
196 fetch_core_registers (core_reg_sect
, core_reg_size
, which
, reg_addr
)
198 unsigned core_reg_size
;
200 unsigned int reg_addr
; /* Unused in this version */
202 /* fetch GPRs and special registers from the first register section
206 /* copy GPRs first. */
207 bcopy (core_reg_sect
, registers
, 32 * 4);
209 /* gdb's internal register template and bfd's register section layout
210 should share a common include file. FIXMEmgo */
211 /* then comes special registes. They are supposed to be in the same
212 order in gdb template and bfd `.reg' section. */
213 core_reg_sect
+= (32 * 4);
214 bcopy (core_reg_sect
, ®isters
[REGISTER_BYTE (FIRST_SP_REGNUM
)],
215 (LAST_SP_REGNUM
- FIRST_SP_REGNUM
+ 1) * 4);
218 /* fetch floating point registers from register section 2 in core bfd. */
220 bcopy (core_reg_sect
, ®isters
[REGISTER_BYTE (FP0_REGNUM
)], 32 * 8);
223 fprintf (stderr
, "Gdb error: unknown parameter to fetch_core_registers().\n");
227 /* Execute one dummy breakpoint instruction. This way we give the kernel
228 a chance to do some housekeeping and update inferior's internal data,
231 exec_one_dummy_insn ()
233 #define DUMMY_INSN_ADDR (TEXT_SEGMENT_BASE)+0x200
235 unsigned long shadow
;
236 unsigned int status
, pid
;
238 /* We plant one dummy breakpoint into DUMMY_INSN_ADDR address. We assume that
239 this address will never be executed again by the real code. */
241 target_insert_breakpoint (DUMMY_INSN_ADDR
, &shadow
);
244 ptrace (PT_CONTINUE
, inferior_pid
, (PTRACE_ARG3_TYPE
) DUMMY_INSN_ADDR
, 0, 0);
246 perror ("pt_continue");
249 pid
= wait (&status
);
250 } while (pid
!= inferior_pid
);
252 target_remove_breakpoint (DUMMY_INSN_ADDR
, &shadow
);
256 #else /* IBM6000_TARGET */
258 /* FIXME: Kludge this til we separate host vs. target vs. native code. */
261 fetch_inferior_registers (regno
)
267 store_inferior_registers (regno
)
273 fetch_core_registers (core_reg_sect
, core_reg_size
, which
, reg_addr
)
275 unsigned core_reg_size
;
277 unsigned int reg_addr
; /* Unused in this version */
281 #endif /* IBM6000_TARGET */
This page took 0.034477 seconds and 4 git commands to generate.