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