2004-02-12 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
92b3541e
KB
54static int
55register_ptrace_addr (int regno)
56{
57 return (regno < 32 ? GPR_BASE + regno
56cea623
AC
58 : regno == mips_regnum (current_gdbarch)->pc ? PC
59 : regno == mips_regnum (current_gdbarch)->cause ? CAUSE
60 : regno == mips_regnum (current_gdbarch)->hi ? MMHI
61 : regno == mips_regnum (current_gdbarch)->lo ? MMLO
62 : regno == mips_regnum (current_gdbarch)->fp_control_status ? FPC_CSR
63 : regno == mips_regnum (current_gdbarch)->fp_implementation_revision ? FPC_EIR
92b3541e
KB
64 : regno >= FP0_REGNUM ? FPR_BASE + (regno - FP0_REGNUM)
65 : 0);
66}
c906108c 67
a14ed312 68static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
c906108c
SS
69
70/* Get all registers from the inferior */
71
72void
fba45db2 73fetch_inferior_registers (int regno)
c906108c 74{
52f0bd74 75 unsigned int regaddr;
123a958e 76 char buf[MAX_REGISTER_SIZE];
52f0bd74 77 int i;
123a958e
AC
78 char zerobuf[MAX_REGISTER_SIZE];
79 memset (zerobuf, 0, MAX_REGISTER_SIZE);
c906108c 80
2b9e5f3f 81 deprecated_registers_fetched ();
c906108c
SS
82
83 for (regno = 1; regno < NUM_REGS; regno++)
84 {
92b3541e 85 regaddr = register_ptrace_addr (regno);
12c266ea 86 for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (int))
c5aa993b 87 {
39f77062 88 *(int *) &buf[i] = ptrace (PT_READ_U, PIDGET (inferior_ptid),
c906108c 89 (PTRACE_ARG3_TYPE) regaddr, 0);
c5aa993b
JM
90 regaddr += sizeof (int);
91 }
c906108c
SS
92 supply_register (regno, buf);
93 }
94
95 supply_register (ZERO_REGNUM, zerobuf);
96 /* Frame ptr reg must appear to be 0; it is faked by stack handling code. */
0ba6dca9 97 supply_register (DEPRECATED_FP_REGNUM, zerobuf);
c906108c
SS
98}
99
100/* Store our register values back into the inferior.
101 If REGNO is -1, do this for all registers.
102 Otherwise, REGNO specifies which register (so we can save time). */
103
104void
fba45db2 105store_inferior_registers (int regno)
c906108c 106{
52f0bd74 107 unsigned int regaddr;
c906108c
SS
108 char buf[80];
109
110 if (regno > 0)
111 {
112 if (regno == ZERO_REGNUM || regno == PS_REGNUM
56cea623
AC
113 || regno == mips_regnum (current_gdbarch)->badvaddr
114 || regno == mips_regnum (current_gdbarch)->cause
115 || regno == mips_regnum (current_gdbarch)->fp_implementation_revision
116 || regno == DEPRECATED_FP_REGNUM
c906108c
SS
117 || (regno >= FIRST_EMBED_REGNUM && regno <= LAST_EMBED_REGNUM))
118 return;
92b3541e 119 regaddr = register_ptrace_addr (regno);
c906108c 120 errno = 0;
39f77062 121 ptrace (PT_WRITE_U, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr,
c906108c
SS
122 read_register (regno));
123 if (errno != 0)
124 {
125 sprintf (buf, "writing register number %d", regno);
126 perror_with_name (buf);
127 }
128 }
129 else
130 {
131 for (regno = 0; regno < NUM_REGS; regno++)
132 store_inferior_registers (regno);
133 }
134}
135
136
137/* Figure out where the longjmp will land.
138 We expect the first arg to be a pointer to the jmp_buf structure from which
139 we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
140 This routine returns true on success. */
141
142int
fba45db2 143get_longjmp_target (CORE_ADDR *pc)
c906108c
SS
144{
145 CORE_ADDR jb_addr;
35fc8285 146 char *buf;
c906108c 147
35fc8285 148 buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
c906108c
SS
149 jb_addr = read_register (A0_REGNUM);
150
151 if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
152 TARGET_PTR_BIT / TARGET_CHAR_BIT))
153 return 0;
154
7c0b4a20 155 *pc = extract_unsigned_integer (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
c906108c
SS
156
157 return 1;
158}
159
160/* Extract the register values out of the core file and store
161 them where `read_register' will find them.
162
163 CORE_REG_SECT points to the register values themselves, read into memory.
164 CORE_REG_SIZE is the size of that area.
165 WHICH says which set of registers we are handling (0 = int, 2 = float
c5aa993b 166 on machines where they are discontiguous).
c906108c 167 REG_ADDR is the offset from u.u_ar0 to the register values relative to
c5aa993b
JM
168 core_reg_sect. This is used with old-fashioned core files to
169 locate the registers in a large upage-plus-stack ".reg" section.
170 Original upage address X is at location core_reg_sect+x+reg_addr.
c906108c
SS
171 */
172
173static void
fba45db2
KB
174fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
175 CORE_ADDR reg_addr)
c906108c 176{
52f0bd74
AC
177 int regno;
178 unsigned int addr;
c906108c 179 int bad_reg = -1;
52f0bd74 180 reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */
c906108c 181
123a958e
AC
182 char zerobuf[MAX_REGISTER_SIZE];
183 memset (zerobuf, 0, MAX_REGISTER_SIZE);
6789195b
AC
184
185
c906108c
SS
186 /* If u.u_ar0 was an absolute address in the core file, relativize it now,
187 so we can use it as an offset into core_reg_sect. When we're done,
188 "register 0" will be at core_reg_sect+reg_ptr, and we can use
189 register_addr to offset to the other registers. If this is a modern
190 core file without a upage, reg_ptr will be zero and this is all a big
191 NOP. */
192 if (reg_ptr > core_reg_size)
193#ifdef KERNEL_U_ADDR
194 reg_ptr -= KERNEL_U_ADDR;
195#else
196 error ("Old mips core file can't be processed on this machine.");
197#endif
198
199 for (regno = 0; regno < NUM_REGS; regno++)
200 {
201 addr = register_addr (regno, reg_ptr);
c5aa993b
JM
202 if (addr >= core_reg_size)
203 {
204 if (bad_reg < 0)
205 bad_reg = regno;
206 }
207 else
208 {
209 supply_register (regno, core_reg_sect + addr);
210 }
c906108c
SS
211 }
212 if (bad_reg >= 0)
213 {
214 error ("Register %s not found in core file.", REGISTER_NAME (bad_reg));
215 }
216 supply_register (ZERO_REGNUM, zerobuf);
217 /* Frame ptr reg must appear to be 0; it is faked by stack handling code. */
0ba6dca9 218 supply_register (DEPRECATED_FP_REGNUM, zerobuf);
c906108c
SS
219}
220
221/* Return the address in the core dump or inferior of register REGNO.
222 BLOCKEND is the address of the end of the user structure. */
223
224CORE_ADDR
fba45db2 225register_addr (int regno, CORE_ADDR blockend)
c906108c
SS
226{
227 CORE_ADDR addr;
228
229 if (regno < 0 || regno >= NUM_REGS)
230 error ("Invalid register number %d.", regno);
231
232 REGISTER_U_ADDR (addr, blockend, regno);
233
234 return addr;
235}
c906108c 236\f
c5aa993b 237
c906108c
SS
238/* Register that we are able to handle mips core file formats.
239 FIXME: is this really bfd_target_unknown_flavour? */
240
241static struct core_fns mips_core_fns =
242{
2acceee2
JM
243 bfd_target_unknown_flavour, /* core_flavour */
244 default_check_format, /* check_format */
245 default_core_sniffer, /* core_sniffer */
246 fetch_core_registers, /* core_read_registers */
247 NULL /* next */
c906108c
SS
248};
249
250void
fba45db2 251_initialize_core_mips (void)
c906108c
SS
252{
253 add_core_fns (&mips_core_fns);
254}
This page took 0.359998 seconds and 4 git commands to generate.