* osabi.c (gdb_osabi_name): Add entry for GDB_OSABI_INTERIX.
[deliverable/binutils-gdb.git] / gdb / mips-linux-tdep.c
CommitLineData
75c9abc6 1/* Target-dependent code for GNU/Linux on MIPS processors.
2aa830e4
DJ
2 Copyright 2001 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21#include "defs.h"
22#include "gdbcore.h"
23#include "target.h"
24#include "solib-svr4.h"
25
26/* Copied from <asm/elf.h>. */
27#define ELF_NGREG 45
28#define ELF_NFPREG 33
29
30typedef unsigned char elf_greg_t[4];
31typedef elf_greg_t elf_gregset_t[ELF_NGREG];
32
33typedef unsigned char elf_fpreg_t[8];
34typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
35
36/* 0 - 31 are integer registers, 32 - 63 are fp registers. */
37#define FPR_BASE 32
38#define PC 64
39#define CAUSE 65
40#define BADVADDR 66
41#define MMHI 67
42#define MMLO 68
43#define FPC_CSR 69
44#define FPC_EIR 70
45
46#define EF_REG0 6
47#define EF_REG31 37
48#define EF_LO 38
49#define EF_HI 39
50#define EF_CP0_EPC 40
51#define EF_CP0_BADVADDR 41
52#define EF_CP0_STATUS 42
53#define EF_CP0_CAUSE 43
54
55#define EF_SIZE 180
56
57/* Figure out where the longjmp will land.
58 We expect the first arg to be a pointer to the jmp_buf structure from
bf072999
DJ
59 which we extract the pc (MIPS_LINUX_JB_PC) that we will land at. The pc
60 is copied into PC. This routine returns 1 on success. */
2aa830e4
DJ
61
62int
63mips_linux_get_longjmp_target (CORE_ADDR *pc)
64{
65 CORE_ADDR jb_addr;
66 char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
67
68 jb_addr = read_register (A0_REGNUM);
69
bf072999
DJ
70 if (target_read_memory (jb_addr
71 + MIPS_LINUX_JB_PC * MIPS_LINUX_JB_ELEMENT_SIZE,
72 buf, TARGET_PTR_BIT / TARGET_CHAR_BIT))
2aa830e4
DJ
73 return 0;
74
75 *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
76
77 return 1;
78}
79
80/* Unpack an elf_gregset_t into GDB's register cache. */
81
82void
83supply_gregset (elf_gregset_t *gregsetp)
84{
85 int regi;
86 elf_greg_t *regp = *gregsetp;
bf072999
DJ
87 char *zerobuf = alloca (MAX_REGISTER_RAW_SIZE);
88
89 memset (zerobuf, 0, MAX_REGISTER_RAW_SIZE);
2aa830e4
DJ
90
91 for (regi = EF_REG0; regi <= EF_REG31; regi++)
92 supply_register ((regi - EF_REG0), (char *)(regp + regi));
93
94 supply_register (LO_REGNUM, (char *)(regp + EF_LO));
95 supply_register (HI_REGNUM, (char *)(regp + EF_HI));
96
97 supply_register (PC_REGNUM, (char *)(regp + EF_CP0_EPC));
98 supply_register (BADVADDR_REGNUM, (char *)(regp + EF_CP0_BADVADDR));
99 supply_register (PS_REGNUM, (char *)(regp + EF_CP0_STATUS));
100 supply_register (CAUSE_REGNUM, (char *)(regp + EF_CP0_CAUSE));
101
102 /* Fill inaccessible registers with zero. */
103 supply_register (FP_REGNUM, zerobuf);
104 supply_register (UNUSED_REGNUM, zerobuf);
105 for (regi = FIRST_EMBED_REGNUM; regi < LAST_EMBED_REGNUM; regi++)
106 supply_register (regi, zerobuf);
107}
108
109/* Pack our registers (or one register) into an elf_gregset_t. */
110
111void
112fill_gregset (elf_gregset_t *gregsetp, int regno)
113{
114 int regaddr, regi;
115 elf_greg_t *regp = *gregsetp;
116 void *src, *dst;
117
118 if (regno == -1)
119 {
120 memset (regp, 0, sizeof (elf_gregset_t));
121 for (regi = 0; regi < 32; regi++)
122 fill_gregset (gregsetp, regi);
123 fill_gregset (gregsetp, LO_REGNUM);
124 fill_gregset (gregsetp, HI_REGNUM);
125 fill_gregset (gregsetp, PC_REGNUM);
126 fill_gregset (gregsetp, BADVADDR_REGNUM);
127 fill_gregset (gregsetp, PS_REGNUM);
128 fill_gregset (gregsetp, CAUSE_REGNUM);
129
130 return;
131 }
132
133 if (regno < 32)
134 {
135 src = &registers[REGISTER_BYTE (regno)];
136 dst = regp + regno + EF_REG0;
137 memcpy (dst, src, sizeof (elf_greg_t));
138 return;
139 }
140
141 regaddr = -1;
142 switch (regno)
143 {
144 case LO_REGNUM:
145 regaddr = EF_LO;
146 break;
147 case HI_REGNUM:
148 regaddr = EF_HI;
149 break;
150 case PC_REGNUM:
151 regaddr = EF_CP0_EPC;
152 break;
153 case BADVADDR_REGNUM:
154 regaddr = EF_CP0_BADVADDR;
155 break;
156 case PS_REGNUM:
157 regaddr = EF_CP0_STATUS;
158 break;
159 case CAUSE_REGNUM:
160 regaddr = EF_CP0_CAUSE;
161 break;
162 }
163
164 if (regaddr != -1)
165 {
166 src = &registers[REGISTER_BYTE (regno)];
167 dst = regp + regaddr;
168 memcpy (dst, src, sizeof (elf_greg_t));
169 }
170}
171
172/* Likewise, unpack an elf_fpregset_t. */
173
174void
175supply_fpregset (elf_fpregset_t *fpregsetp)
176{
177 register int regi;
bf072999
DJ
178 char *zerobuf = alloca (MAX_REGISTER_RAW_SIZE);
179
180 memset (zerobuf, 0, MAX_REGISTER_RAW_SIZE);
2aa830e4
DJ
181
182 for (regi = 0; regi < 32; regi++)
183 supply_register (FP0_REGNUM + regi,
184 (char *)(*fpregsetp + regi));
185
186 supply_register (FCRCS_REGNUM, (char *)(*fpregsetp + 32));
187
188 /* FIXME: how can we supply FCRIR_REGNUM? The ABI doesn't tell us. */
189 supply_register (FCRIR_REGNUM, zerobuf);
190}
191
192/* Likewise, pack one or all floating point registers into an
193 elf_fpregset_t. */
194
195void
196fill_fpregset (elf_fpregset_t *fpregsetp, int regno)
197{
198 char *from, *to;
199
200 if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32))
201 {
202 from = (char *) &registers[REGISTER_BYTE (regno)];
203 to = (char *) (*fpregsetp + regno - FP0_REGNUM);
204 memcpy (to, from, REGISTER_RAW_SIZE (regno - FP0_REGNUM));
205 }
206 else if (regno == FCRCS_REGNUM)
207 {
208 from = (char *) &registers[REGISTER_BYTE (regno)];
209 to = (char *) (*fpregsetp + 32);
210 memcpy (to, from, REGISTER_RAW_SIZE (regno));
211 }
212 else if (regno == -1)
213 {
214 int regi;
215
216 for (regi = 0; regi < 32; regi++)
217 fill_fpregset (fpregsetp, FP0_REGNUM + regi);
218 fill_fpregset(fpregsetp, FCRCS_REGNUM);
219 }
220}
221
222/* Map gdb internal register number to ptrace ``address''.
223 These ``addresses'' are normally defined in <asm/ptrace.h>. */
224
225CORE_ADDR
226register_addr (int regno, CORE_ADDR blockend)
227{
228 int regaddr;
229
230 if (regno < 0 || regno >= NUM_REGS)
231 error ("Bogon register number %d.", regno);
232
233 if (regno < 32)
234 regaddr = regno;
235 else if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32))
236 regaddr = FPR_BASE + (regno - FP0_REGNUM);
237 else if (regno == PC_REGNUM)
238 regaddr = PC;
239 else if (regno == CAUSE_REGNUM)
240 regaddr = CAUSE;
241 else if (regno == BADVADDR_REGNUM)
242 regaddr = BADVADDR;
243 else if (regno == LO_REGNUM)
244 regaddr = MMLO;
245 else if (regno == HI_REGNUM)
246 regaddr = MMHI;
247 else if (regno == FCRCS_REGNUM)
248 regaddr = FPC_CSR;
249 else if (regno == FCRIR_REGNUM)
250 regaddr = FPC_EIR;
251 else
252 error ("Unknowable register number %d.", regno);
253
254 return regaddr;
255}
256
257/* Use a local version of this function to get the correct types for
258 regsets, until multi-arch core support is ready. */
259
260static void
261fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
262 int which, CORE_ADDR reg_addr)
263{
264 elf_gregset_t gregset;
265 elf_fpregset_t fpregset;
266
267 if (which == 0)
268 {
269 if (core_reg_size != sizeof (gregset))
270 {
271 warning ("wrong size gregset struct in core file");
272 }
273 else
274 {
275 memcpy ((char *) &gregset, core_reg_sect, sizeof (gregset));
276 supply_gregset (&gregset);
277 }
278 }
279 else if (which == 2)
280 {
281 if (core_reg_size != sizeof (fpregset))
282 {
283 warning ("wrong size fpregset struct in core file");
284 }
285 else
286 {
287 memcpy ((char *) &fpregset, core_reg_sect, sizeof (fpregset));
288 supply_fpregset (&fpregset);
289 }
290 }
291}
292
293/* Register that we are able to handle ELF file formats using standard
294 procfs "regset" structures. */
295
296static struct core_fns regset_core_fns =
297{
298 bfd_target_elf_flavour, /* core_flavour */
299 default_check_format, /* check_format */
300 default_core_sniffer, /* core_sniffer */
301 fetch_core_registers, /* core_read_registers */
302 NULL /* next */
303};
304
305/* Fetch (and possibly build) an appropriate link_map_offsets
75c9abc6 306 structure for native GNU/Linux MIPS targets using the struct offsets
2aa830e4
DJ
307 defined in link.h (but without actual reference to that file).
308
75c9abc6
DJ
309 This makes it possible to access GNU/Linux MIPS shared libraries from a
310 GDB that was built on a different host platform (for cross debugging). */
2aa830e4
DJ
311
312struct link_map_offsets *
313mips_linux_svr4_fetch_link_map_offsets (void)
314{
315 static struct link_map_offsets lmo;
316 static struct link_map_offsets *lmp = NULL;
317
318 if (lmp == NULL)
319 {
320 lmp = &lmo;
321
322 lmo.r_debug_size = 8; /* The actual size is 20 bytes, but
323 this is all we need. */
324 lmo.r_map_offset = 4;
325 lmo.r_map_size = 4;
326
327 lmo.link_map_size = 20;
328
329 lmo.l_addr_offset = 0;
330 lmo.l_addr_size = 4;
331
332 lmo.l_name_offset = 4;
333 lmo.l_name_size = 4;
334
335 lmo.l_next_offset = 12;
336 lmo.l_next_size = 4;
337
338 lmo.l_prev_offset = 16;
339 lmo.l_prev_size = 4;
340 }
341
342 return lmp;
343}
344
345void
d1bacddc 346_initialize_mips_linux_tdep (void)
2aa830e4
DJ
347{
348 add_core_fns (&regset_core_fns);
349}
This page took 0.136966 seconds and 4 git commands to generate.