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