xref: /openbsd-src/gnu/usr.bin/binutils/gdb/irix5-nat.c (revision 63addd46c1e40ca0f49488ddcdc4ab598023b0c1)
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