1e93f7393Sniklas /* Native support for the SGI Iris running IRIX version 5, for GDB.
2*63addd46Skettenis
3*63addd46Skettenis Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
4*63addd46Skettenis 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
5*63addd46Skettenis
6e93f7393Sniklas Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
7e93f7393Sniklas and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
8e93f7393Sniklas Implemented for Irix 4.x by Garrett A. Wollman.
9e93f7393Sniklas Modified for Irix 5.x by Ian Lance Taylor.
10e93f7393Sniklas
11e93f7393Sniklas This file is part of GDB.
12e93f7393Sniklas
13e93f7393Sniklas This program is free software; you can redistribute it and/or modify
14e93f7393Sniklas it under the terms of the GNU General Public License as published by
15e93f7393Sniklas the Free Software Foundation; either version 2 of the License, or
16e93f7393Sniklas (at your option) any later version.
17e93f7393Sniklas
18e93f7393Sniklas This program is distributed in the hope that it will be useful,
19e93f7393Sniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
20e93f7393Sniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21e93f7393Sniklas GNU General Public License for more details.
22e93f7393Sniklas
23e93f7393Sniklas You should have received a copy of the GNU General Public License
24e93f7393Sniklas along with this program; if not, write to the Free Software
25b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
26b725ae77Skettenis Boston, MA 02111-1307, USA. */
27e93f7393Sniklas
28e93f7393Sniklas #include "defs.h"
29e93f7393Sniklas #include "inferior.h"
30e93f7393Sniklas #include "gdbcore.h"
31e93f7393Sniklas #include "target.h"
32b725ae77Skettenis #include "regcache.h"
33e93f7393Sniklas
34e93f7393Sniklas #include "gdb_string.h"
35e93f7393Sniklas #include <sys/time.h>
36e93f7393Sniklas #include <sys/procfs.h>
37e93f7393Sniklas #include <setjmp.h> /* For JB_XXX. */
38e93f7393Sniklas
39b725ae77Skettenis /* Prototypes for supply_gregset etc. */
40b725ae77Skettenis #include "gregset.h"
41b725ae77Skettenis #include "mips-tdep.h"
42b725ae77Skettenis
43b725ae77Skettenis static void fetch_core_registers (char *, unsigned int, int, CORE_ADDR);
44e93f7393Sniklas
45e93f7393Sniklas /* Size of elements in jmpbuf */
46e93f7393Sniklas
47e93f7393Sniklas #define JB_ELEMENT_SIZE 4
48e93f7393Sniklas
49e93f7393Sniklas /*
50e93f7393Sniklas * See the comment in m68k-tdep.c regarding the utility of these functions.
51e93f7393Sniklas *
52e93f7393Sniklas * These definitions are from the MIPS SVR4 ABI, so they may work for
53e93f7393Sniklas * any MIPS SVR4 target.
54e93f7393Sniklas */
55e93f7393Sniklas
56e93f7393Sniklas void
supply_gregset(gregset_t * gregsetp)57b725ae77Skettenis supply_gregset (gregset_t *gregsetp)
58e93f7393Sniklas {
59b725ae77Skettenis int regi;
60b725ae77Skettenis greg_t *regp = &(*gregsetp)[0];
61*63addd46Skettenis int gregoff = sizeof (greg_t) - mips_isa_regsize (current_gdbarch);
62b725ae77Skettenis static char zerobuf[32] = {0};
63e93f7393Sniklas
64e93f7393Sniklas for (regi = 0; regi <= CTX_RA; regi++)
65*63addd46Skettenis regcache_raw_supply (current_regcache, regi,
66*63addd46Skettenis (char *) (regp + regi) + gregoff);
67e93f7393Sniklas
68*63addd46Skettenis regcache_raw_supply (current_regcache, mips_regnum (current_gdbarch)->pc,
69b725ae77Skettenis (char *) (regp + CTX_EPC) + gregoff);
70*63addd46Skettenis regcache_raw_supply (current_regcache, mips_regnum (current_gdbarch)->hi,
71b725ae77Skettenis (char *) (regp + CTX_MDHI) + gregoff);
72*63addd46Skettenis regcache_raw_supply (current_regcache, mips_regnum (current_gdbarch)->lo,
73b725ae77Skettenis (char *) (regp + CTX_MDLO) + gregoff);
74*63addd46Skettenis regcache_raw_supply (current_regcache, mips_regnum (current_gdbarch)->cause,
75b725ae77Skettenis (char *) (regp + CTX_CAUSE) + gregoff);
76e93f7393Sniklas
77e93f7393Sniklas /* Fill inaccessible registers with zero. */
78*63addd46Skettenis regcache_raw_supply (current_regcache, mips_regnum (current_gdbarch)->badvaddr, zerobuf);
79e93f7393Sniklas }
80e93f7393Sniklas
81e93f7393Sniklas void
fill_gregset(gregset_t * gregsetp,int regno)82b725ae77Skettenis fill_gregset (gregset_t *gregsetp, int regno)
83e93f7393Sniklas {
84e93f7393Sniklas int regi;
85b725ae77Skettenis greg_t *regp = &(*gregsetp)[0];
86b725ae77Skettenis
87b725ae77Skettenis /* Under Irix6, if GDB is built with N32 ABI and is debugging an O32
88b725ae77Skettenis executable, we have to sign extend the registers to 64 bits before
89b725ae77Skettenis filling in the gregset structure. */
90e93f7393Sniklas
91e93f7393Sniklas for (regi = 0; regi <= CTX_RA; regi++)
92e93f7393Sniklas if ((regno == -1) || (regno == regi))
93b725ae77Skettenis *(regp + regi) =
94b725ae77Skettenis extract_signed_integer (&deprecated_registers[DEPRECATED_REGISTER_BYTE (regi)],
95*63addd46Skettenis register_size (current_gdbarch, regi));
96e93f7393Sniklas
97e93f7393Sniklas if ((regno == -1) || (regno == PC_REGNUM))
98b725ae77Skettenis *(regp + CTX_EPC) =
99b725ae77Skettenis extract_signed_integer (&deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->pc)],
100*63addd46Skettenis register_size (current_gdbarch, mips_regnum (current_gdbarch)->pc));
101e93f7393Sniklas
102b725ae77Skettenis if ((regno == -1) || (regno == mips_regnum (current_gdbarch)->cause))
103b725ae77Skettenis *(regp + CTX_CAUSE) =
104b725ae77Skettenis extract_signed_integer (&deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->cause)],
105*63addd46Skettenis register_size (current_gdbarch, mips_regnum (current_gdbarch)->cause));
106e93f7393Sniklas
107b725ae77Skettenis if ((regno == -1)
108b725ae77Skettenis || (regno == mips_regnum (current_gdbarch)->hi))
109b725ae77Skettenis *(regp + CTX_MDHI) =
110b725ae77Skettenis extract_signed_integer (&deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->hi)],
111*63addd46Skettenis register_size (current_gdbarch, mips_regnum (current_gdbarch)->hi));
112e93f7393Sniklas
113b725ae77Skettenis if ((regno == -1) || (regno == mips_regnum (current_gdbarch)->lo))
114b725ae77Skettenis *(regp + CTX_MDLO) =
115b725ae77Skettenis extract_signed_integer (&deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->lo)],
116*63addd46Skettenis register_size (current_gdbarch, mips_regnum (current_gdbarch)->lo));
117e93f7393Sniklas }
118e93f7393Sniklas
119e93f7393Sniklas /*
120e93f7393Sniklas * Now we do the same thing for floating-point registers.
121e93f7393Sniklas * We don't bother to condition on FP0_REGNUM since any
122e93f7393Sniklas * reasonable MIPS configuration has an R3010 in it.
123e93f7393Sniklas *
124e93f7393Sniklas * Again, see the comments in m68k-tdep.c.
125e93f7393Sniklas */
126e93f7393Sniklas
127e93f7393Sniklas void
supply_fpregset(fpregset_t * fpregsetp)128b725ae77Skettenis supply_fpregset (fpregset_t *fpregsetp)
129e93f7393Sniklas {
130b725ae77Skettenis int regi;
131b725ae77Skettenis static char zerobuf[32] = {0};
132b725ae77Skettenis
133b725ae77Skettenis /* FIXME, this is wrong for the N32 ABI which has 64 bit FP regs. */
134e93f7393Sniklas
135e93f7393Sniklas for (regi = 0; regi < 32; regi++)
136*63addd46Skettenis regcache_raw_supply (current_regcache, FP0_REGNUM + regi,
137e93f7393Sniklas (char *) &fpregsetp->fp_r.fp_regs[regi]);
138e93f7393Sniklas
139*63addd46Skettenis regcache_raw_supply (current_regcache,
140*63addd46Skettenis mips_regnum (current_gdbarch)->fp_control_status,
141b725ae77Skettenis (char *) &fpregsetp->fp_csr);
142e93f7393Sniklas
143b725ae77Skettenis /* FIXME: how can we supply FCRIR? SGI doesn't tell us. */
144*63addd46Skettenis regcache_raw_supply (current_regcache,
145*63addd46Skettenis mips_regnum (current_gdbarch)->fp_implementation_revision,
146b725ae77Skettenis zerobuf);
147e93f7393Sniklas }
148e93f7393Sniklas
149e93f7393Sniklas void
fill_fpregset(fpregset_t * fpregsetp,int regno)150b725ae77Skettenis fill_fpregset (fpregset_t *fpregsetp, int regno)
151e93f7393Sniklas {
152e93f7393Sniklas int regi;
153e93f7393Sniklas char *from, *to;
154e93f7393Sniklas
155b725ae77Skettenis /* FIXME, this is wrong for the N32 ABI which has 64 bit FP regs. */
156b725ae77Skettenis
157e93f7393Sniklas for (regi = FP0_REGNUM; regi < FP0_REGNUM + 32; regi++)
158e93f7393Sniklas {
159e93f7393Sniklas if ((regno == -1) || (regno == regi))
160e93f7393Sniklas {
161b725ae77Skettenis from = (char *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regi)];
162e93f7393Sniklas to = (char *) &(fpregsetp->fp_r.fp_regs[regi - FP0_REGNUM]);
163*63addd46Skettenis memcpy (to, from, register_size (current_gdbarch, regi));
164e93f7393Sniklas }
165e93f7393Sniklas }
166e93f7393Sniklas
167b725ae77Skettenis if ((regno == -1)
168b725ae77Skettenis || (regno == mips_regnum (current_gdbarch)->fp_control_status))
169b725ae77Skettenis fpregsetp->fp_csr = *(unsigned *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->fp_control_status)];
170e93f7393Sniklas }
171e93f7393Sniklas
172e93f7393Sniklas
173e93f7393Sniklas /* Figure out where the longjmp will land.
174e93f7393Sniklas We expect the first arg to be a pointer to the jmp_buf structure from which
175e93f7393Sniklas we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
176e93f7393Sniklas This routine returns true on success. */
177e93f7393Sniklas
178e93f7393Sniklas int
get_longjmp_target(CORE_ADDR * pc)179b725ae77Skettenis get_longjmp_target (CORE_ADDR *pc)
180e93f7393Sniklas {
181b725ae77Skettenis char *buf;
182e93f7393Sniklas CORE_ADDR jb_addr;
183e93f7393Sniklas
184b725ae77Skettenis buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
185e93f7393Sniklas jb_addr = read_register (A0_REGNUM);
186e93f7393Sniklas
187e93f7393Sniklas if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
188e93f7393Sniklas TARGET_PTR_BIT / TARGET_CHAR_BIT))
189e93f7393Sniklas return 0;
190e93f7393Sniklas
191b725ae77Skettenis *pc = extract_unsigned_integer (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
192e93f7393Sniklas
193e93f7393Sniklas return 1;
194e93f7393Sniklas }
195e93f7393Sniklas
196b725ae77Skettenis /* Provide registers to GDB from a core file.
197b725ae77Skettenis
198b725ae77Skettenis CORE_REG_SECT points to an array of bytes, which were obtained from
199b725ae77Skettenis a core file which BFD thinks might contain register contents.
200b725ae77Skettenis CORE_REG_SIZE is its size.
201b725ae77Skettenis
202b725ae77Skettenis Normally, WHICH says which register set corelow suspects this is:
203b725ae77Skettenis 0 --- the general-purpose register set
204b725ae77Skettenis 2 --- the floating-point register set
205b725ae77Skettenis However, for Irix 5, WHICH isn't used.
206b725ae77Skettenis
207b725ae77Skettenis REG_ADDR is also unused. */
208b725ae77Skettenis
209e93f7393Sniklas static void
fetch_core_registers(char * core_reg_sect,unsigned core_reg_size,int which,CORE_ADDR reg_addr)210b725ae77Skettenis fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
211b725ae77Skettenis int which, CORE_ADDR reg_addr)
212e93f7393Sniklas {
213*63addd46Skettenis if (core_reg_size == deprecated_register_bytes ())
214b725ae77Skettenis {
215b725ae77Skettenis memcpy ((char *) deprecated_registers, core_reg_sect, core_reg_size);
216b725ae77Skettenis }
217*63addd46Skettenis else if (mips_isa_regsize (current_gdbarch) == 4 &&
218*63addd46Skettenis core_reg_size == (2 * mips_isa_regsize (current_gdbarch)) * NUM_REGS)
219b725ae77Skettenis {
220b725ae77Skettenis /* This is a core file from a N32 executable, 64 bits are saved
221b725ae77Skettenis for all registers. */
222b725ae77Skettenis char *srcp = core_reg_sect;
223b725ae77Skettenis char *dstp = deprecated_registers;
224b725ae77Skettenis int regno;
225b725ae77Skettenis
226b725ae77Skettenis for (regno = 0; regno < NUM_REGS; regno++)
227b725ae77Skettenis {
228b725ae77Skettenis if (regno >= FP0_REGNUM && regno < (FP0_REGNUM + 32))
229b725ae77Skettenis {
230b725ae77Skettenis /* FIXME, this is wrong, N32 has 64 bit FP regs, but GDB
231b725ae77Skettenis currently assumes that they are 32 bit. */
232b725ae77Skettenis *dstp++ = *srcp++;
233b725ae77Skettenis *dstp++ = *srcp++;
234b725ae77Skettenis *dstp++ = *srcp++;
235b725ae77Skettenis *dstp++ = *srcp++;
236*63addd46Skettenis if (register_size (current_gdbarch, regno) == 4)
237b725ae77Skettenis {
238b725ae77Skettenis /* copying 4 bytes from eight bytes?
239b725ae77Skettenis I don't see how this can be right... */
240b725ae77Skettenis srcp += 4;
241b725ae77Skettenis }
242b725ae77Skettenis else
243b725ae77Skettenis {
244b725ae77Skettenis /* copy all 8 bytes (sizeof(double)) */
245b725ae77Skettenis *dstp++ = *srcp++;
246b725ae77Skettenis *dstp++ = *srcp++;
247b725ae77Skettenis *dstp++ = *srcp++;
248b725ae77Skettenis *dstp++ = *srcp++;
249b725ae77Skettenis }
250b725ae77Skettenis }
251b725ae77Skettenis else
252b725ae77Skettenis {
253b725ae77Skettenis srcp += 4;
254b725ae77Skettenis *dstp++ = *srcp++;
255b725ae77Skettenis *dstp++ = *srcp++;
256b725ae77Skettenis *dstp++ = *srcp++;
257b725ae77Skettenis *dstp++ = *srcp++;
258b725ae77Skettenis }
259b725ae77Skettenis }
260b725ae77Skettenis }
261b725ae77Skettenis else
262e93f7393Sniklas {
263e93f7393Sniklas warning ("wrong size gregset struct in core file");
264e93f7393Sniklas return;
265e93f7393Sniklas }
266e93f7393Sniklas
267b725ae77Skettenis deprecated_registers_fetched ();
268e93f7393Sniklas }
269e93f7393Sniklas
270e93f7393Sniklas /* Register that we are able to handle irix5 core file formats.
271e93f7393Sniklas This really is bfd_target_unknown_flavour */
272e93f7393Sniklas
273e93f7393Sniklas static struct core_fns irix5_core_fns =
274e93f7393Sniklas {
275b725ae77Skettenis bfd_target_unknown_flavour, /* core_flavour */
276b725ae77Skettenis default_check_format, /* check_format */
277b725ae77Skettenis default_core_sniffer, /* core_sniffer */
278b725ae77Skettenis fetch_core_registers, /* core_read_registers */
279b725ae77Skettenis NULL /* next */
280e93f7393Sniklas };
281e93f7393Sniklas
282e93f7393Sniklas void
_initialize_core_irix5(void)283b725ae77Skettenis _initialize_core_irix5 (void)
284e93f7393Sniklas {
285*63addd46Skettenis deprecated_add_core_fns (&irix5_core_fns);
286e93f7393Sniklas }
287