]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/irix5-nat.c
gdb/
[thirdparty/binutils-gdb.git] / gdb / irix5-nat.c
CommitLineData
c906108c 1/* Native support for the SGI Iris running IRIX version 5, for GDB.
1b13c4f6 2
0b302171
JB
3 Copyright (C) 1988-1996, 1998-2002, 2004, 2006-2012 Free Software
4 Foundation, Inc.
1b13c4f6 5
c906108c
SS
6 Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
7 and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
8 Implemented for Irix 4.x by Garrett A. Wollman.
9 Modified for Irix 5.x by Ian Lance Taylor.
10
c5aa993b 11 This file is part of GDB.
c906108c 12
c5aa993b
JM
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
a9762ec7 15 the Free Software Foundation; either version 3 of the License, or
c5aa993b 16 (at your option) any later version.
c906108c 17
c5aa993b
JM
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
c906108c 22
c5aa993b 23 You should have received a copy of the GNU General Public License
a9762ec7 24 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
25
26#include "defs.h"
27#include "inferior.h"
28#include "gdbcore.h"
29#include "target.h"
4e052eda 30#include "regcache.h"
d1a7880c 31#include "procfs.h"
c906108c
SS
32
33#include "gdb_string.h"
34#include <sys/time.h>
35#include <sys/procfs.h>
36#include <setjmp.h> /* For JB_XXX. */
37
1777feb0 38/* Prototypes for supply_gregset etc. */
c60c0f5f 39#include "gregset.h"
b639a770 40#include "mips-tdep.h"
c60c0f5f 41
9eefc95f
UW
42static void fetch_core_registers (struct regcache *, char *,
43 unsigned int, int, CORE_ADDR);
c906108c 44
c906108c
SS
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
c5aa993b 53void
7f7fe91e 54supply_gregset (struct regcache *regcache, const gregset_t *gregsetp)
c906108c 55{
52f0bd74 56 int regi;
7f7fe91e 57 const greg_t *regp = &(*gregsetp)[0];
d611717a
UW
58 struct gdbarch *gdbarch = get_regcache_arch (regcache);
59 int gregoff = sizeof (greg_t) - mips_isa_regsize (gdbarch);
466d7106 60 static char zerobuf[32] = {0};
c906108c 61
c5aa993b 62 for (regi = 0; regi <= CTX_RA; regi++)
7f7fe91e
UW
63 regcache_raw_supply (regcache, regi,
64 (const char *) (regp + regi) + gregoff);
65
d611717a 66 regcache_raw_supply (regcache, mips_regnum (gdbarch)->pc,
7f7fe91e 67 (const char *) (regp + CTX_EPC) + gregoff);
d611717a 68 regcache_raw_supply (regcache, mips_regnum (gdbarch)->hi,
7f7fe91e 69 (const char *) (regp + CTX_MDHI) + gregoff);
d611717a 70 regcache_raw_supply (regcache, mips_regnum (gdbarch)->lo,
7f7fe91e 71 (const char *) (regp + CTX_MDLO) + gregoff);
d611717a 72 regcache_raw_supply (regcache, mips_regnum (gdbarch)->cause,
7f7fe91e 73 (const char *) (regp + CTX_CAUSE) + gregoff);
c906108c
SS
74
75 /* Fill inaccessible registers with zero. */
d611717a 76 regcache_raw_supply (regcache, mips_regnum (gdbarch)->badvaddr, zerobuf);
c906108c
SS
77}
78
79void
7f7fe91e 80fill_gregset (const struct regcache *regcache, gregset_t *gregsetp, int regno)
c906108c 81{
6a1872e4 82 int regi, size;
52f0bd74 83 greg_t *regp = &(*gregsetp)[0];
6a1872e4 84 gdb_byte buf[MAX_REGISTER_SIZE];
d611717a 85 struct gdbarch *gdbarch = get_regcache_arch (regcache);
e17a4113 86 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
c906108c
SS
87
88 /* Under Irix6, if GDB is built with N32 ABI and is debugging an O32
89 executable, we have to sign extend the registers to 64 bits before
90 filling in the gregset structure. */
91
92 for (regi = 0; regi <= CTX_RA; regi++)
93 if ((regno == -1) || (regno == regi))
44ed547b 94 {
d611717a 95 size = register_size (gdbarch, regi);
7f7fe91e 96 regcache_raw_collect (regcache, regi, buf);
e17a4113 97 *(regp + regi) = extract_signed_integer (buf, size, byte_order);
44ed547b 98 }
c906108c 99
e4b97d48 100 if ((regno == -1) || (regno == mips_regnum (gdbarch)->pc))
44ed547b 101 {
d611717a
UW
102 regi = mips_regnum (gdbarch)->pc;
103 size = register_size (gdbarch, regi);
7f7fe91e 104 regcache_raw_collect (regcache, regi, buf);
e17a4113 105 *(regp + CTX_EPC) = extract_signed_integer (buf, size, byte_order);
44ed547b 106 }
c906108c 107
d611717a 108 if ((regno == -1) || (regno == mips_regnum (gdbarch)->cause))
44ed547b 109 {
d611717a
UW
110 regi = mips_regnum (gdbarch)->cause;
111 size = register_size (gdbarch, regi);
7f7fe91e 112 regcache_raw_collect (regcache, regi, buf);
e17a4113 113 *(regp + CTX_CAUSE) = extract_signed_integer (buf, size, byte_order);
44ed547b 114 }
c906108c 115
d611717a 116 if ((regno == -1) || (regno == mips_regnum (gdbarch)->hi))
44ed547b 117 {
d611717a
UW
118 regi = mips_regnum (gdbarch)->hi;
119 size = register_size (gdbarch, regi);
7f7fe91e 120 regcache_raw_collect (regcache, regi, buf);
e17a4113 121 *(regp + CTX_MDHI) = extract_signed_integer (buf, size, byte_order);
44ed547b 122 }
c906108c 123
d611717a 124 if ((regno == -1) || (regno == mips_regnum (gdbarch)->lo))
44ed547b 125 {
d611717a
UW
126 regi = mips_regnum (gdbarch)->lo;
127 size = register_size (gdbarch, regi);
7f7fe91e 128 regcache_raw_collect (regcache, regi, buf);
e17a4113 129 *(regp + CTX_MDLO) = extract_signed_integer (buf, size, byte_order);
44ed547b 130 }
c906108c
SS
131}
132
133/*
134 * Now we do the same thing for floating-point registers.
3e8c568d 135 * We don't bother to condition on gdbarch_fp0_regnum since any
c906108c
SS
136 * reasonable MIPS configuration has an R3010 in it.
137 *
138 * Again, see the comments in m68k-tdep.c.
139 */
140
141void
7f7fe91e 142supply_fpregset (struct regcache *regcache, const fpregset_t *fpregsetp)
c906108c 143{
52f0bd74 144 int regi;
466d7106 145 static char zerobuf[32] = {0};
6d1eba4c 146 char fsrbuf[8];
d611717a 147 struct gdbarch *gdbarch = get_regcache_arch (regcache);
c906108c 148
1777feb0 149 /* FIXME, this is wrong for the N32 ABI which has 64 bit FP regs. */
c906108c
SS
150
151 for (regi = 0; regi < 32; regi++)
d611717a 152 regcache_raw_supply (regcache, gdbarch_fp0_regnum (gdbarch) + regi,
043b6510 153 (const char *) &fpregsetp->__fp_r.__fp_regs[regi]);
c906108c 154
6d1eba4c
JB
155 /* We can't supply the FSR register directly to the regcache,
156 because there is a size issue: On one hand, fpregsetp->fp_csr
157 is 32bits long, while the regcache expects a 64bits long value.
158 So we use a buffer of the correct size and copy into it the register
159 value at the proper location. */
160 memset (fsrbuf, 0, 4);
043b6510 161 memcpy (fsrbuf + 4, &fpregsetp->__fp_csr, 4);
6d1eba4c 162
7f7fe91e 163 regcache_raw_supply (regcache,
d611717a 164 mips_regnum (gdbarch)->fp_control_status, fsrbuf);
c906108c 165
1777feb0 166 /* FIXME: how can we supply FCRIR? SGI doesn't tell us. */
7f7fe91e 167 regcache_raw_supply (regcache,
d611717a 168 mips_regnum (gdbarch)->fp_implementation_revision,
23a6d369 169 zerobuf);
c906108c
SS
170}
171
172void
1777feb0
MS
173fill_fpregset (const struct regcache *regcache,
174 fpregset_t *fpregsetp, int regno)
c906108c
SS
175{
176 int regi;
177 char *from, *to;
d611717a 178 struct gdbarch *gdbarch = get_regcache_arch (regcache);
c906108c 179
1777feb0 180 /* FIXME, this is wrong for the N32 ABI which has 64 bit FP regs. */
c906108c 181
d611717a
UW
182 for (regi = gdbarch_fp0_regnum (gdbarch);
183 regi < gdbarch_fp0_regnum (gdbarch) + 32; regi++)
c906108c
SS
184 {
185 if ((regno == -1) || (regno == regi))
186 {
043b6510
JB
187 const int fp0_regnum = gdbarch_fp0_regnum (gdbarch);
188
189 to = (char *) &(fpregsetp->__fp_r.__fp_regs[regi - fp0_regnum]);
7f7fe91e 190 regcache_raw_collect (regcache, regi, to);
c906108c
SS
191 }
192 }
193
6d1eba4c 194 if (regno == -1
d611717a 195 || regno == mips_regnum (gdbarch)->fp_control_status)
6d1eba4c
JB
196 {
197 char fsrbuf[8];
198
199 /* We can't fill the FSR register directly from the regcache,
200 because there is a size issue: On one hand, fpregsetp->fp_csr
201 is 32bits long, while the regcache expects a 64bits long buffer.
202 So we use a buffer of the correct size and copy the register
203 value from that buffer. */
7f7fe91e 204 regcache_raw_collect (regcache,
d611717a 205 mips_regnum (gdbarch)->fp_control_status, fsrbuf);
6d1eba4c 206
043b6510 207 memcpy (&fpregsetp->__fp_csr, fsrbuf + 4, 4);
6d1eba4c 208 }
c906108c
SS
209}
210
211
16bce26c
KB
212/* Provide registers to GDB from a core file.
213
214 CORE_REG_SECT points to an array of bytes, which were obtained from
215 a core file which BFD thinks might contain register contents.
216 CORE_REG_SIZE is its size.
217
218 Normally, WHICH says which register set corelow suspects this is:
219 0 --- the general-purpose register set
220 2 --- the floating-point register set
221 However, for Irix 5, WHICH isn't used.
222
223 REG_ADDR is also unused. */
224
c906108c 225static void
9eefc95f
UW
226fetch_core_registers (struct regcache *regcache,
227 char *core_reg_sect, unsigned core_reg_size,
16bce26c 228 int which, CORE_ADDR reg_addr)
c906108c 229{
f6e1bffc 230 char *srcp = core_reg_sect;
d611717a
UW
231 struct gdbarch *gdbarch = get_regcache_arch (regcache);
232 int regsize = mips_isa_regsize (gdbarch);
f6e1bffc
JB
233 int regno;
234
f58b68aa
DJ
235 /* If regsize is 8, this is a N32 or N64 core file.
236 If regsize is 4, this is an O32 core file. */
d611717a 237 if (core_reg_size != regsize * gdbarch_num_regs (gdbarch))
c906108c 238 {
8a3fe4f8 239 warning (_("wrong size gregset struct in core file"));
c906108c
SS
240 return;
241 }
f58b68aa 242
d611717a 243 for (regno = 0; regno < gdbarch_num_regs (gdbarch); regno++)
f58b68aa 244 {
9eefc95f 245 regcache_raw_supply (regcache, regno, srcp);
f58b68aa
DJ
246 srcp += regsize;
247 }
c906108c 248}
c5aa993b 249
c906108c 250/* Register that we are able to handle irix5 core file formats.
1777feb0 251 This really is bfd_target_unknown_flavour. */
c906108c
SS
252
253static struct core_fns irix5_core_fns =
254{
2acceee2
JM
255 bfd_target_unknown_flavour, /* core_flavour */
256 default_check_format, /* check_format */
257 default_core_sniffer, /* core_sniffer */
258 fetch_core_registers, /* core_read_registers */
259 NULL /* next */
c906108c
SS
260};
261
d1a7880c
PA
262/* Provide a prototype to silence -Wmissing-prototypes. */
263extern initialize_file_ftype _initialize_irix5_nat;
264
c906108c 265void
d1a7880c 266_initialize_irix5_nat (void)
c906108c 267{
d1a7880c
PA
268 struct target_ops *t;
269
270 t = procfs_target ();
271 procfs_use_watchpoints (t);
272 add_target (t);
273
00e32a35 274 deprecated_add_core_fns (&irix5_core_fns);
c906108c 275}