2003-05-08 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / mips-nat.c
CommitLineData
c906108c 1/* Low level DECstation interface to ptrace, for GDB when running native.
b6ba6518
KB
2 Copyright 1988, 1989, 1991, 1992, 1993, 1995, 1996, 1999, 2000, 2001
3 Free Software Foundation, Inc.
c906108c
SS
4 Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
5 and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
6
c5aa993b 7 This file is part of GDB.
c906108c 8
c5aa993b
JM
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
c906108c 13
c5aa993b
JM
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
c906108c 18
c5aa993b
JM
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
c906108c
SS
23
24#include "defs.h"
25#include "inferior.h"
26#include "gdbcore.h"
4e052eda 27#include "regcache.h"
c906108c
SS
28#include <sys/ptrace.h>
29#include <sys/types.h>
30#include <sys/param.h>
31#include <sys/user.h>
32#undef JB_S0
33#undef JB_S1
34#undef JB_S2
35#undef JB_S3
36#undef JB_S4
37#undef JB_S5
38#undef JB_S6
39#undef JB_S7
40#undef JB_SP
41#undef JB_S8
42#undef JB_PC
43#undef JB_SR
44#undef NJBREGS
45#include <setjmp.h> /* For JB_XXX. */
46
47/* Size of elements in jmpbuf */
48
49#define JB_ELEMENT_SIZE 4
50
51/* Map gdb internal register number to ptrace ``address''.
52 These ``addresses'' are defined in DECstation <sys/ptrace.h> */
53
54#define REGISTER_PTRACE_ADDR(regno) \
55 (regno < 32 ? GPR_BASE + regno \
56 : regno == PC_REGNUM ? PC \
57 : regno == CAUSE_REGNUM ? CAUSE \
58 : regno == HI_REGNUM ? MMHI \
59 : regno == LO_REGNUM ? MMLO \
60 : regno == FCRCS_REGNUM ? FPC_CSR \
61 : regno == FCRIR_REGNUM ? FPC_EIR \
62 : regno >= FP0_REGNUM ? FPR_BASE + (regno - FP0_REGNUM) \
63 : 0)
64
a14ed312 65static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
c906108c
SS
66
67/* Get all registers from the inferior */
68
69void
fba45db2 70fetch_inferior_registers (int regno)
c906108c
SS
71{
72 register unsigned int regaddr;
123a958e 73 char buf[MAX_REGISTER_SIZE];
c906108c 74 register int i;
123a958e
AC
75 char zerobuf[MAX_REGISTER_SIZE];
76 memset (zerobuf, 0, MAX_REGISTER_SIZE);
c906108c 77
2b9e5f3f 78 deprecated_registers_fetched ();
c906108c
SS
79
80 for (regno = 1; regno < NUM_REGS; regno++)
81 {
82 regaddr = REGISTER_PTRACE_ADDR (regno);
83 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
c5aa993b 84 {
39f77062 85 *(int *) &buf[i] = ptrace (PT_READ_U, PIDGET (inferior_ptid),
c906108c 86 (PTRACE_ARG3_TYPE) regaddr, 0);
c5aa993b
JM
87 regaddr += sizeof (int);
88 }
c906108c
SS
89 supply_register (regno, buf);
90 }
91
92 supply_register (ZERO_REGNUM, zerobuf);
93 /* Frame ptr reg must appear to be 0; it is faked by stack handling code. */
0ba6dca9 94 supply_register (DEPRECATED_FP_REGNUM, zerobuf);
c906108c
SS
95}
96
97/* Store our register values back into the inferior.
98 If REGNO is -1, do this for all registers.
99 Otherwise, REGNO specifies which register (so we can save time). */
100
101void
fba45db2 102store_inferior_registers (int regno)
c906108c
SS
103{
104 register unsigned int regaddr;
105 char buf[80];
106
107 if (regno > 0)
108 {
109 if (regno == ZERO_REGNUM || regno == PS_REGNUM
110 || regno == BADVADDR_REGNUM || regno == CAUSE_REGNUM
0ba6dca9 111 || regno == FCRIR_REGNUM || regno == DEPRECATED_FP_REGNUM
c906108c
SS
112 || (regno >= FIRST_EMBED_REGNUM && regno <= LAST_EMBED_REGNUM))
113 return;
114 regaddr = REGISTER_PTRACE_ADDR (regno);
115 errno = 0;
39f77062 116 ptrace (PT_WRITE_U, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr,
c906108c
SS
117 read_register (regno));
118 if (errno != 0)
119 {
120 sprintf (buf, "writing register number %d", regno);
121 perror_with_name (buf);
122 }
123 }
124 else
125 {
126 for (regno = 0; regno < NUM_REGS; regno++)
127 store_inferior_registers (regno);
128 }
129}
130
131
132/* Figure out where the longjmp will land.
133 We expect the first arg to be a pointer to the jmp_buf structure from which
134 we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
135 This routine returns true on success. */
136
137int
fba45db2 138get_longjmp_target (CORE_ADDR *pc)
c906108c
SS
139{
140 CORE_ADDR jb_addr;
35fc8285 141 char *buf;
c906108c 142
35fc8285 143 buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
c906108c
SS
144 jb_addr = read_register (A0_REGNUM);
145
146 if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
147 TARGET_PTR_BIT / TARGET_CHAR_BIT))
148 return 0;
149
150 *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
151
152 return 1;
153}
154
155/* Extract the register values out of the core file and store
156 them where `read_register' will find them.
157
158 CORE_REG_SECT points to the register values themselves, read into memory.
159 CORE_REG_SIZE is the size of that area.
160 WHICH says which set of registers we are handling (0 = int, 2 = float
c5aa993b 161 on machines where they are discontiguous).
c906108c 162 REG_ADDR is the offset from u.u_ar0 to the register values relative to
c5aa993b
JM
163 core_reg_sect. This is used with old-fashioned core files to
164 locate the registers in a large upage-plus-stack ".reg" section.
165 Original upage address X is at location core_reg_sect+x+reg_addr.
c906108c
SS
166 */
167
168static void
fba45db2
KB
169fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
170 CORE_ADDR reg_addr)
c906108c
SS
171{
172 register int regno;
173 register unsigned int addr;
174 int bad_reg = -1;
c5aa993b 175 register reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */
c906108c 176
123a958e
AC
177 char zerobuf[MAX_REGISTER_SIZE];
178 memset (zerobuf, 0, MAX_REGISTER_SIZE);
6789195b
AC
179
180
c906108c
SS
181 /* If u.u_ar0 was an absolute address in the core file, relativize it now,
182 so we can use it as an offset into core_reg_sect. When we're done,
183 "register 0" will be at core_reg_sect+reg_ptr, and we can use
184 register_addr to offset to the other registers. If this is a modern
185 core file without a upage, reg_ptr will be zero and this is all a big
186 NOP. */
187 if (reg_ptr > core_reg_size)
188#ifdef KERNEL_U_ADDR
189 reg_ptr -= KERNEL_U_ADDR;
190#else
191 error ("Old mips core file can't be processed on this machine.");
192#endif
193
194 for (regno = 0; regno < NUM_REGS; regno++)
195 {
196 addr = register_addr (regno, reg_ptr);
c5aa993b
JM
197 if (addr >= core_reg_size)
198 {
199 if (bad_reg < 0)
200 bad_reg = regno;
201 }
202 else
203 {
204 supply_register (regno, core_reg_sect + addr);
205 }
c906108c
SS
206 }
207 if (bad_reg >= 0)
208 {
209 error ("Register %s not found in core file.", REGISTER_NAME (bad_reg));
210 }
211 supply_register (ZERO_REGNUM, zerobuf);
212 /* Frame ptr reg must appear to be 0; it is faked by stack handling code. */
0ba6dca9 213 supply_register (DEPRECATED_FP_REGNUM, zerobuf);
c906108c
SS
214}
215
216/* Return the address in the core dump or inferior of register REGNO.
217 BLOCKEND is the address of the end of the user structure. */
218
219CORE_ADDR
fba45db2 220register_addr (int regno, CORE_ADDR blockend)
c906108c
SS
221{
222 CORE_ADDR addr;
223
224 if (regno < 0 || regno >= NUM_REGS)
225 error ("Invalid register number %d.", regno);
226
227 REGISTER_U_ADDR (addr, blockend, regno);
228
229 return addr;
230}
c906108c 231\f
c5aa993b 232
c906108c
SS
233/* Register that we are able to handle mips core file formats.
234 FIXME: is this really bfd_target_unknown_flavour? */
235
236static struct core_fns mips_core_fns =
237{
2acceee2
JM
238 bfd_target_unknown_flavour, /* core_flavour */
239 default_check_format, /* check_format */
240 default_core_sniffer, /* core_sniffer */
241 fetch_core_registers, /* core_read_registers */
242 NULL /* next */
c906108c
SS
243};
244
245void
fba45db2 246_initialize_core_mips (void)
c906108c
SS
247{
248 add_core_fns (&mips_core_fns);
249}
This page took 0.299861 seconds and 4 git commands to generate.