* gas/i386/intel16.d: Ignore trailing text with #pass.
[deliverable/binutils-gdb.git] / gdb / mips-linux-tdep.c
CommitLineData
75c9abc6 1/* Target-dependent code for GNU/Linux on MIPS processors.
a094c6fb 2
c4c5b7ba 3 Copyright 2001, 2002, 2004 Free Software Foundation, Inc.
2aa830e4
DJ
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22#include "defs.h"
23#include "gdbcore.h"
24#include "target.h"
25#include "solib-svr4.h"
19ed69dd 26#include "osabi.h"
96f026fc 27#include "mips-tdep.h"
19ed69dd 28#include "gdb_string.h"
96f026fc 29#include "gdb_assert.h"
6de918a6 30#include "frame.h"
2fdf551c 31#include "regcache.h"
5792a79b
DJ
32#include "trad-frame.h"
33#include "tramp-frame.h"
2aa830e4
DJ
34
35/* Copied from <asm/elf.h>. */
36#define ELF_NGREG 45
37#define ELF_NFPREG 33
38
39typedef unsigned char elf_greg_t[4];
40typedef elf_greg_t elf_gregset_t[ELF_NGREG];
41
42typedef unsigned char elf_fpreg_t[8];
43typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
44
45/* 0 - 31 are integer registers, 32 - 63 are fp registers. */
46#define FPR_BASE 32
47#define PC 64
48#define CAUSE 65
49#define BADVADDR 66
50#define MMHI 67
51#define MMLO 68
52#define FPC_CSR 69
53#define FPC_EIR 70
54
55#define EF_REG0 6
56#define EF_REG31 37
57#define EF_LO 38
58#define EF_HI 39
59#define EF_CP0_EPC 40
60#define EF_CP0_BADVADDR 41
61#define EF_CP0_STATUS 42
62#define EF_CP0_CAUSE 43
63
64#define EF_SIZE 180
65
66/* Figure out where the longjmp will land.
67 We expect the first arg to be a pointer to the jmp_buf structure from
bf072999
DJ
68 which we extract the pc (MIPS_LINUX_JB_PC) that we will land at. The pc
69 is copied into PC. This routine returns 1 on success. */
2aa830e4 70
19ed69dd
KB
71#define MIPS_LINUX_JB_ELEMENT_SIZE 4
72#define MIPS_LINUX_JB_PC 0
73
74static int
2aa830e4
DJ
75mips_linux_get_longjmp_target (CORE_ADDR *pc)
76{
77 CORE_ADDR jb_addr;
78 char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
79
613e114f 80 jb_addr = read_register (MIPS_A0_REGNUM);
2aa830e4 81
bf072999
DJ
82 if (target_read_memory (jb_addr
83 + MIPS_LINUX_JB_PC * MIPS_LINUX_JB_ELEMENT_SIZE,
84 buf, TARGET_PTR_BIT / TARGET_CHAR_BIT))
2aa830e4
DJ
85 return 0;
86
7c0b4a20 87 *pc = extract_unsigned_integer (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
2aa830e4
DJ
88
89 return 1;
90}
91
4246e332 92/* Transform the bits comprising a 32-bit register to the right size
23a6d369
AC
93 for regcache_raw_supply(). This is needed when mips_isa_regsize()
94 is 8. */
96f026fc
KB
95
96static void
97supply_32bit_reg (int regnum, const void *addr)
98{
d9d9c31f 99 char buf[MAX_REGISTER_SIZE];
3acba339 100 store_signed_integer (buf, register_size (current_gdbarch, regnum),
96f026fc 101 extract_signed_integer (addr, 4));
23a6d369 102 regcache_raw_supply (current_regcache, regnum, buf);
96f026fc
KB
103}
104
2aa830e4
DJ
105/* Unpack an elf_gregset_t into GDB's register cache. */
106
107void
108supply_gregset (elf_gregset_t *gregsetp)
109{
110 int regi;
111 elf_greg_t *regp = *gregsetp;
d9d9c31f 112 char zerobuf[MAX_REGISTER_SIZE];
bf072999 113
d9d9c31f 114 memset (zerobuf, 0, MAX_REGISTER_SIZE);
2aa830e4
DJ
115
116 for (regi = EF_REG0; regi <= EF_REG31; regi++)
96f026fc 117 supply_32bit_reg ((regi - EF_REG0), (char *)(regp + regi));
2aa830e4 118
56cea623
AC
119 supply_32bit_reg (mips_regnum (current_gdbarch)->lo,
120 (char *)(regp + EF_LO));
121 supply_32bit_reg (mips_regnum (current_gdbarch)->hi,
122 (char *)(regp + EF_HI));
123
124 supply_32bit_reg (mips_regnum (current_gdbarch)->pc,
125 (char *)(regp + EF_CP0_EPC));
126 supply_32bit_reg (mips_regnum (current_gdbarch)->badvaddr,
127 (char *)(regp + EF_CP0_BADVADDR));
24e05951 128 supply_32bit_reg (MIPS_PS_REGNUM, (char *)(regp + EF_CP0_STATUS));
56cea623
AC
129 supply_32bit_reg (mips_regnum (current_gdbarch)->cause,
130 (char *)(regp + EF_CP0_CAUSE));
2aa830e4
DJ
131
132 /* Fill inaccessible registers with zero. */
613e114f 133 regcache_raw_supply (current_regcache, MIPS_UNUSED_REGNUM, zerobuf);
607fc93c 134 for (regi = MIPS_FIRST_EMBED_REGNUM; regi < MIPS_LAST_EMBED_REGNUM; regi++)
23a6d369 135 regcache_raw_supply (current_regcache, regi, zerobuf);
2aa830e4
DJ
136}
137
138/* Pack our registers (or one register) into an elf_gregset_t. */
139
140void
141fill_gregset (elf_gregset_t *gregsetp, int regno)
142{
143 int regaddr, regi;
144 elf_greg_t *regp = *gregsetp;
96f026fc 145 void *dst;
2aa830e4
DJ
146
147 if (regno == -1)
148 {
149 memset (regp, 0, sizeof (elf_gregset_t));
150 for (regi = 0; regi < 32; regi++)
151 fill_gregset (gregsetp, regi);
56cea623
AC
152 fill_gregset (gregsetp, mips_regnum (current_gdbarch)->lo);
153 fill_gregset (gregsetp, mips_regnum (current_gdbarch)->hi);
154 fill_gregset (gregsetp, mips_regnum (current_gdbarch)->pc);
155 fill_gregset (gregsetp, mips_regnum (current_gdbarch)->badvaddr);
24e05951 156 fill_gregset (gregsetp, MIPS_PS_REGNUM);
56cea623 157 fill_gregset (gregsetp, mips_regnum (current_gdbarch)->cause);
2aa830e4
DJ
158
159 return;
160 }
161
162 if (regno < 32)
163 {
2aa830e4 164 dst = regp + regno + EF_REG0;
822c9732 165 regcache_raw_collect (current_regcache, regno, dst);
2aa830e4
DJ
166 return;
167 }
168
56cea623
AC
169 if (regno == mips_regnum (current_gdbarch)->lo)
170 regaddr = EF_LO;
171 else if (regno == mips_regnum (current_gdbarch)->hi)
172 regaddr = EF_HI;
173 else if (regno == mips_regnum (current_gdbarch)->pc)
174 regaddr = EF_CP0_EPC;
175 else if (regno == mips_regnum (current_gdbarch)->badvaddr)
176 regaddr = EF_CP0_BADVADDR;
24e05951 177 else if (regno == MIPS_PS_REGNUM)
56cea623
AC
178 regaddr = EF_CP0_STATUS;
179 else if (regno == mips_regnum (current_gdbarch)->cause)
180 regaddr = EF_CP0_CAUSE;
181 else
182 regaddr = -1;
2aa830e4
DJ
183
184 if (regaddr != -1)
185 {
2aa830e4 186 dst = regp + regaddr;
822c9732 187 regcache_raw_collect (current_regcache, regno, dst);
2aa830e4
DJ
188 }
189}
190
191/* Likewise, unpack an elf_fpregset_t. */
192
193void
194supply_fpregset (elf_fpregset_t *fpregsetp)
195{
52f0bd74 196 int regi;
d9d9c31f 197 char zerobuf[MAX_REGISTER_SIZE];
bf072999 198
d9d9c31f 199 memset (zerobuf, 0, MAX_REGISTER_SIZE);
2aa830e4
DJ
200
201 for (regi = 0; regi < 32; regi++)
23a6d369
AC
202 regcache_raw_supply (current_regcache, FP0_REGNUM + regi,
203 (char *)(*fpregsetp + regi));
2aa830e4 204
23a6d369
AC
205 regcache_raw_supply (current_regcache,
206 mips_regnum (current_gdbarch)->fp_control_status,
207 (char *)(*fpregsetp + 32));
2aa830e4 208
56cea623 209 /* FIXME: how can we supply FCRIR? The ABI doesn't tell us. */
23a6d369
AC
210 regcache_raw_supply (current_regcache,
211 mips_regnum (current_gdbarch)->fp_implementation_revision,
212 zerobuf);
2aa830e4
DJ
213}
214
215/* Likewise, pack one or all floating point registers into an
216 elf_fpregset_t. */
217
218void
219fill_fpregset (elf_fpregset_t *fpregsetp, int regno)
220{
221 char *from, *to;
222
223 if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32))
224 {
2aa830e4 225 to = (char *) (*fpregsetp + regno - FP0_REGNUM);
2fdf551c 226 regcache_raw_collect (current_regcache, regno, to);
2aa830e4 227 }
56cea623 228 else if (regno == mips_regnum (current_gdbarch)->fp_control_status)
2aa830e4 229 {
2aa830e4 230 to = (char *) (*fpregsetp + 32);
2fdf551c 231 regcache_raw_collect (current_regcache, regno, to);
2aa830e4
DJ
232 }
233 else if (regno == -1)
234 {
235 int regi;
236
237 for (regi = 0; regi < 32; regi++)
238 fill_fpregset (fpregsetp, FP0_REGNUM + regi);
56cea623 239 fill_fpregset(fpregsetp, mips_regnum (current_gdbarch)->fp_control_status);
2aa830e4
DJ
240 }
241}
242
243/* Map gdb internal register number to ptrace ``address''.
244 These ``addresses'' are normally defined in <asm/ptrace.h>. */
245
96f026fc
KB
246static CORE_ADDR
247mips_linux_register_addr (int regno, CORE_ADDR blockend)
2aa830e4
DJ
248{
249 int regaddr;
250
251 if (regno < 0 || regno >= NUM_REGS)
252 error ("Bogon register number %d.", regno);
253
254 if (regno < 32)
255 regaddr = regno;
56cea623
AC
256 else if ((regno >= mips_regnum (current_gdbarch)->fp0)
257 && (regno < mips_regnum (current_gdbarch)->fp0 + 32))
258 regaddr = FPR_BASE + (regno - mips_regnum (current_gdbarch)->fp0);
259 else if (regno == mips_regnum (current_gdbarch)->pc)
2aa830e4 260 regaddr = PC;
56cea623 261 else if (regno == mips_regnum (current_gdbarch)->cause)
2aa830e4 262 regaddr = CAUSE;
56cea623 263 else if (regno == mips_regnum (current_gdbarch)->badvaddr)
2aa830e4 264 regaddr = BADVADDR;
56cea623 265 else if (regno == mips_regnum (current_gdbarch)->lo)
2aa830e4 266 regaddr = MMLO;
56cea623 267 else if (regno == mips_regnum (current_gdbarch)->hi)
2aa830e4 268 regaddr = MMHI;
56cea623 269 else if (regno == mips_regnum (current_gdbarch)->fp_control_status)
2aa830e4 270 regaddr = FPC_CSR;
56cea623 271 else if (regno == mips_regnum (current_gdbarch)->fp_implementation_revision)
2aa830e4
DJ
272 regaddr = FPC_EIR;
273 else
274 error ("Unknowable register number %d.", regno);
275
276 return regaddr;
277}
278
96f026fc
KB
279
280/* Fetch (and possibly build) an appropriate link_map_offsets
281 structure for native GNU/Linux MIPS targets using the struct offsets
282 defined in link.h (but without actual reference to that file).
283
284 This makes it possible to access GNU/Linux MIPS shared libraries from a
285 GDB that was built on a different host platform (for cross debugging). */
286
287static struct link_map_offsets *
288mips_linux_svr4_fetch_link_map_offsets (void)
289{
290 static struct link_map_offsets lmo;
291 static struct link_map_offsets *lmp = NULL;
292
293 if (lmp == NULL)
294 {
295 lmp = &lmo;
296
297 lmo.r_debug_size = 8; /* The actual size is 20 bytes, but
298 this is all we need. */
299 lmo.r_map_offset = 4;
300 lmo.r_map_size = 4;
301
302 lmo.link_map_size = 20;
303
304 lmo.l_addr_offset = 0;
305 lmo.l_addr_size = 4;
306
307 lmo.l_name_offset = 4;
308 lmo.l_name_size = 4;
309
310 lmo.l_next_offset = 12;
311 lmo.l_next_size = 4;
312
313 lmo.l_prev_offset = 16;
314 lmo.l_prev_size = 4;
315 }
316
317 return lmp;
318}
319
320/* Support for 64-bit ABIs. */
321
322/* Copied from <asm/elf.h>. */
323#define MIPS64_ELF_NGREG 45
324#define MIPS64_ELF_NFPREG 33
325
326typedef unsigned char mips64_elf_greg_t[8];
327typedef mips64_elf_greg_t mips64_elf_gregset_t[MIPS64_ELF_NGREG];
328
329typedef unsigned char mips64_elf_fpreg_t[8];
330typedef mips64_elf_fpreg_t mips64_elf_fpregset_t[MIPS64_ELF_NFPREG];
331
332/* 0 - 31 are integer registers, 32 - 63 are fp registers. */
333#define MIPS64_FPR_BASE 32
334#define MIPS64_PC 64
335#define MIPS64_CAUSE 65
336#define MIPS64_BADVADDR 66
337#define MIPS64_MMHI 67
338#define MIPS64_MMLO 68
339#define MIPS64_FPC_CSR 69
340#define MIPS64_FPC_EIR 70
341
342#define MIPS64_EF_REG0 0
343#define MIPS64_EF_REG31 31
344#define MIPS64_EF_LO 32
345#define MIPS64_EF_HI 33
346#define MIPS64_EF_CP0_EPC 34
347#define MIPS64_EF_CP0_BADVADDR 35
348#define MIPS64_EF_CP0_STATUS 36
349#define MIPS64_EF_CP0_CAUSE 37
350
351#define MIPS64_EF_SIZE 304
352
353/* Figure out where the longjmp will land.
354 We expect the first arg to be a pointer to the jmp_buf structure from
355 which we extract the pc (MIPS_LINUX_JB_PC) that we will land at. The pc
356 is copied into PC. This routine returns 1 on success. */
357
358/* Details about jmp_buf. */
359
360#define MIPS64_LINUX_JB_PC 0
361
362static int
363mips64_linux_get_longjmp_target (CORE_ADDR *pc)
364{
365 CORE_ADDR jb_addr;
366 void *buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
367 int element_size = TARGET_PTR_BIT == 32 ? 4 : 8;
368
613e114f 369 jb_addr = read_register (MIPS_A0_REGNUM);
96f026fc
KB
370
371 if (target_read_memory (jb_addr + MIPS64_LINUX_JB_PC * element_size,
372 buf, TARGET_PTR_BIT / TARGET_CHAR_BIT))
373 return 0;
374
7c0b4a20 375 *pc = extract_unsigned_integer (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
96f026fc
KB
376
377 return 1;
378}
379
380/* Unpack an elf_gregset_t into GDB's register cache. */
381
382static void
383mips64_supply_gregset (mips64_elf_gregset_t *gregsetp)
384{
385 int regi;
386 mips64_elf_greg_t *regp = *gregsetp;
d9d9c31f 387 char zerobuf[MAX_REGISTER_SIZE];
96f026fc 388
d9d9c31f 389 memset (zerobuf, 0, MAX_REGISTER_SIZE);
96f026fc
KB
390
391 for (regi = MIPS64_EF_REG0; regi <= MIPS64_EF_REG31; regi++)
23a6d369
AC
392 regcache_raw_supply (current_regcache, (regi - MIPS64_EF_REG0),
393 (char *)(regp + regi));
394
395 regcache_raw_supply (current_regcache, mips_regnum (current_gdbarch)->lo,
396 (char *)(regp + MIPS64_EF_LO));
397 regcache_raw_supply (current_regcache, mips_regnum (current_gdbarch)->hi,
398 (char *)(regp + MIPS64_EF_HI));
399
400 regcache_raw_supply (current_regcache, mips_regnum (current_gdbarch)->pc,
401 (char *)(regp + MIPS64_EF_CP0_EPC));
402 regcache_raw_supply (current_regcache, mips_regnum (current_gdbarch)->badvaddr,
403 (char *)(regp + MIPS64_EF_CP0_BADVADDR));
24e05951 404 regcache_raw_supply (current_regcache, MIPS_PS_REGNUM,
23a6d369
AC
405 (char *)(regp + MIPS64_EF_CP0_STATUS));
406 regcache_raw_supply (current_regcache, mips_regnum (current_gdbarch)->cause,
407 (char *)(regp + MIPS64_EF_CP0_CAUSE));
96f026fc
KB
408
409 /* Fill inaccessible registers with zero. */
613e114f 410 regcache_raw_supply (current_regcache, MIPS_UNUSED_REGNUM, zerobuf);
607fc93c 411 for (regi = MIPS_FIRST_EMBED_REGNUM; regi < MIPS_LAST_EMBED_REGNUM; regi++)
23a6d369 412 regcache_raw_supply (current_regcache, regi, zerobuf);
96f026fc
KB
413}
414
415/* Pack our registers (or one register) into an elf_gregset_t. */
416
417static void
418mips64_fill_gregset (mips64_elf_gregset_t *gregsetp, int regno)
419{
420 int regaddr, regi;
421 mips64_elf_greg_t *regp = *gregsetp;
422 void *src, *dst;
423
424 if (regno == -1)
425 {
426 memset (regp, 0, sizeof (mips64_elf_gregset_t));
427 for (regi = 0; regi < 32; regi++)
428 mips64_fill_gregset (gregsetp, regi);
56cea623
AC
429 mips64_fill_gregset (gregsetp, mips_regnum (current_gdbarch)->lo);
430 mips64_fill_gregset (gregsetp, mips_regnum (current_gdbarch)->hi);
431 mips64_fill_gregset (gregsetp, mips_regnum (current_gdbarch)->pc);
432 mips64_fill_gregset (gregsetp, mips_regnum (current_gdbarch)->badvaddr);
24e05951 433 mips64_fill_gregset (gregsetp, MIPS_PS_REGNUM);
56cea623 434 mips64_fill_gregset (gregsetp, mips_regnum (current_gdbarch)->cause);
96f026fc
KB
435
436 return;
437 }
438
439 if (regno < 32)
440 {
441 dst = regp + regno + MIPS64_EF_REG0;
822c9732 442 regcache_raw_collect (current_regcache, regno, dst);
96f026fc
KB
443 return;
444 }
445
56cea623
AC
446 if (regno == mips_regnum (current_gdbarch)->lo)
447 regaddr = MIPS64_EF_LO;
448 else if (regno == mips_regnum (current_gdbarch)->hi)
449 regaddr = MIPS64_EF_HI;
450 else if (regno == mips_regnum (current_gdbarch)->pc)
451 regaddr = MIPS64_EF_CP0_EPC;
452 else if (regno == mips_regnum (current_gdbarch)->badvaddr)
453 regaddr = MIPS64_EF_CP0_BADVADDR;
24e05951 454 else if (regno == MIPS_PS_REGNUM)
56cea623
AC
455 regaddr = MIPS64_EF_CP0_STATUS;
456 else if (regno == mips_regnum (current_gdbarch)->cause)
457 regaddr = MIPS64_EF_CP0_CAUSE;
458 else
459 regaddr = -1;
96f026fc
KB
460
461 if (regaddr != -1)
462 {
463 dst = regp + regaddr;
822c9732 464 regcache_raw_collect (current_regcache, regno, dst);
96f026fc
KB
465 }
466}
467
468/* Likewise, unpack an elf_fpregset_t. */
469
470static void
471mips64_supply_fpregset (mips64_elf_fpregset_t *fpregsetp)
472{
52f0bd74 473 int regi;
d9d9c31f 474 char zerobuf[MAX_REGISTER_SIZE];
96f026fc 475
d9d9c31f 476 memset (zerobuf, 0, MAX_REGISTER_SIZE);
96f026fc
KB
477
478 for (regi = 0; regi < 32; regi++)
23a6d369
AC
479 regcache_raw_supply (current_regcache, FP0_REGNUM + regi,
480 (char *)(*fpregsetp + regi));
96f026fc 481
23a6d369
AC
482 regcache_raw_supply (current_regcache,
483 mips_regnum (current_gdbarch)->fp_control_status,
484 (char *)(*fpregsetp + 32));
96f026fc 485
56cea623 486 /* FIXME: how can we supply FCRIR? The ABI doesn't tell us. */
23a6d369
AC
487 regcache_raw_supply (current_regcache,
488 mips_regnum (current_gdbarch)->fp_implementation_revision,
489 zerobuf);
96f026fc
KB
490}
491
492/* Likewise, pack one or all floating point registers into an
493 elf_fpregset_t. */
494
495static void
496mips64_fill_fpregset (mips64_elf_fpregset_t *fpregsetp, int regno)
497{
498 char *from, *to;
499
500 if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32))
501 {
96f026fc 502 to = (char *) (*fpregsetp + regno - FP0_REGNUM);
2fdf551c 503 regcache_raw_collect (current_regcache, regno, to);
96f026fc 504 }
56cea623 505 else if (regno == mips_regnum (current_gdbarch)->fp_control_status)
96f026fc 506 {
96f026fc 507 to = (char *) (*fpregsetp + 32);
2fdf551c 508 regcache_raw_collect (current_regcache, regno, to);
96f026fc
KB
509 }
510 else if (regno == -1)
511 {
512 int regi;
513
514 for (regi = 0; regi < 32; regi++)
515 mips64_fill_fpregset (fpregsetp, FP0_REGNUM + regi);
56cea623
AC
516 mips64_fill_fpregset(fpregsetp,
517 mips_regnum (current_gdbarch)->fp_control_status);
96f026fc
KB
518 }
519}
520
521
522/* Map gdb internal register number to ptrace ``address''.
523 These ``addresses'' are normally defined in <asm/ptrace.h>. */
524
525static CORE_ADDR
526mips64_linux_register_addr (int regno, CORE_ADDR blockend)
527{
528 int regaddr;
529
530 if (regno < 0 || regno >= NUM_REGS)
531 error ("Bogon register number %d.", regno);
532
533 if (regno < 32)
534 regaddr = regno;
56cea623
AC
535 else if ((regno >= mips_regnum (current_gdbarch)->fp0)
536 && (regno < mips_regnum (current_gdbarch)->fp0 + 32))
96f026fc 537 regaddr = MIPS64_FPR_BASE + (regno - FP0_REGNUM);
56cea623 538 else if (regno == mips_regnum (current_gdbarch)->pc)
96f026fc 539 regaddr = MIPS64_PC;
56cea623 540 else if (regno == mips_regnum (current_gdbarch)->cause)
96f026fc 541 regaddr = MIPS64_CAUSE;
56cea623 542 else if (regno == mips_regnum (current_gdbarch)->badvaddr)
96f026fc 543 regaddr = MIPS64_BADVADDR;
56cea623 544 else if (regno == mips_regnum (current_gdbarch)->lo)
96f026fc 545 regaddr = MIPS64_MMLO;
56cea623 546 else if (regno == mips_regnum (current_gdbarch)->hi)
96f026fc 547 regaddr = MIPS64_MMHI;
56cea623 548 else if (regno == mips_regnum (current_gdbarch)->fp_control_status)
96f026fc 549 regaddr = MIPS64_FPC_CSR;
56cea623 550 else if (regno == mips_regnum (current_gdbarch)->fp_implementation_revision)
96f026fc
KB
551 regaddr = MIPS64_FPC_EIR;
552 else
553 error ("Unknowable register number %d.", regno);
554
555 return regaddr;
556}
557
2aa830e4
DJ
558/* Use a local version of this function to get the correct types for
559 regsets, until multi-arch core support is ready. */
560
561static void
562fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
563 int which, CORE_ADDR reg_addr)
564{
565 elf_gregset_t gregset;
566 elf_fpregset_t fpregset;
96f026fc
KB
567 mips64_elf_gregset_t gregset64;
568 mips64_elf_fpregset_t fpregset64;
2aa830e4
DJ
569
570 if (which == 0)
571 {
96f026fc 572 if (core_reg_size == sizeof (gregset))
2aa830e4 573 {
96f026fc
KB
574 memcpy ((char *) &gregset, core_reg_sect, sizeof (gregset));
575 supply_gregset (&gregset);
576 }
577 else if (core_reg_size == sizeof (gregset64))
578 {
579 memcpy ((char *) &gregset64, core_reg_sect, sizeof (gregset64));
580 mips64_supply_gregset (&gregset64);
2aa830e4
DJ
581 }
582 else
583 {
96f026fc 584 warning ("wrong size gregset struct in core file");
2aa830e4
DJ
585 }
586 }
587 else if (which == 2)
588 {
96f026fc 589 if (core_reg_size == sizeof (fpregset))
2aa830e4 590 {
96f026fc
KB
591 memcpy ((char *) &fpregset, core_reg_sect, sizeof (fpregset));
592 supply_fpregset (&fpregset);
593 }
594 else if (core_reg_size == sizeof (fpregset64))
595 {
596 memcpy ((char *) &fpregset64, core_reg_sect, sizeof (fpregset64));
597 mips64_supply_fpregset (&fpregset64);
2aa830e4
DJ
598 }
599 else
600 {
96f026fc 601 warning ("wrong size fpregset struct in core file");
2aa830e4
DJ
602 }
603 }
604}
605
606/* Register that we are able to handle ELF file formats using standard
607 procfs "regset" structures. */
608
609static struct core_fns regset_core_fns =
610{
611 bfd_target_elf_flavour, /* core_flavour */
612 default_check_format, /* check_format */
613 default_core_sniffer, /* core_sniffer */
614 fetch_core_registers, /* core_read_registers */
615 NULL /* next */
616};
617
618/* Fetch (and possibly build) an appropriate link_map_offsets
75c9abc6 619 structure for native GNU/Linux MIPS targets using the struct offsets
2aa830e4
DJ
620 defined in link.h (but without actual reference to that file).
621
75c9abc6
DJ
622 This makes it possible to access GNU/Linux MIPS shared libraries from a
623 GDB that was built on a different host platform (for cross debugging). */
2aa830e4 624
19ed69dd 625static struct link_map_offsets *
96f026fc 626mips64_linux_svr4_fetch_link_map_offsets (void)
2aa830e4
DJ
627{
628 static struct link_map_offsets lmo;
629 static struct link_map_offsets *lmp = NULL;
630
631 if (lmp == NULL)
632 {
633 lmp = &lmo;
634
96f026fc 635 lmo.r_debug_size = 16; /* The actual size is 40 bytes, but
2aa830e4 636 this is all we need. */
96f026fc
KB
637 lmo.r_map_offset = 8;
638 lmo.r_map_size = 8;
2aa830e4 639
96f026fc 640 lmo.link_map_size = 40;
2aa830e4
DJ
641
642 lmo.l_addr_offset = 0;
96f026fc 643 lmo.l_addr_size = 8;
2aa830e4 644
96f026fc
KB
645 lmo.l_name_offset = 8;
646 lmo.l_name_size = 8;
2aa830e4 647
96f026fc
KB
648 lmo.l_next_offset = 24;
649 lmo.l_next_size = 8;
2aa830e4 650
96f026fc
KB
651 lmo.l_prev_offset = 32;
652 lmo.l_prev_size = 8;
2aa830e4
DJ
653 }
654
655 return lmp;
656}
657
96f026fc
KB
658/* Handle for obtaining pointer to the current register_addr() function
659 for a given architecture. */
660static struct gdbarch_data *register_addr_data;
661
662CORE_ADDR
663register_addr (int regno, CORE_ADDR blockend)
664{
665 CORE_ADDR (*register_addr_ptr) (int, CORE_ADDR) =
666 gdbarch_data (current_gdbarch, register_addr_data);
667
668 gdb_assert (register_addr_ptr != 0);
669
670 return register_addr_ptr (regno, blockend);
671}
672
673static void
674set_mips_linux_register_addr (struct gdbarch *gdbarch,
675 CORE_ADDR (*register_addr_ptr) (int, CORE_ADDR))
676{
030f20e1 677 deprecated_set_gdbarch_data (gdbarch, register_addr_data, register_addr_ptr);
96f026fc
KB
678}
679
680static void *
681init_register_addr_data (struct gdbarch *gdbarch)
682{
683 return 0;
684}
685
6de918a6
DJ
686/* Check the code at PC for a dynamic linker lazy resolution stub. Because
687 they aren't in the .plt section, we pattern-match on the code generated
688 by GNU ld. They look like this:
689
690 lw t9,0x8010(gp)
691 addu t7,ra
692 jalr t9,ra
693 addiu t8,zero,INDEX
694
695 (with the appropriate doubleword instructions for N64). Also return the
696 dynamic symbol index used in the last instruction. */
697
698static int
699mips_linux_in_dynsym_stub (CORE_ADDR pc, char *name)
700{
701 unsigned char buf[28], *p;
702 ULONGEST insn, insn1;
703 int n64 = (mips_abi (current_gdbarch) == MIPS_ABI_N64);
704
705 read_memory (pc - 12, buf, 28);
706
707 if (n64)
708 {
709 /* ld t9,0x8010(gp) */
710 insn1 = 0xdf998010;
711 }
712 else
713 {
714 /* lw t9,0x8010(gp) */
715 insn1 = 0x8f998010;
716 }
717
718 p = buf + 12;
719 while (p >= buf)
720 {
721 insn = extract_unsigned_integer (p, 4);
722 if (insn == insn1)
723 break;
724 p -= 4;
725 }
726 if (p < buf)
727 return 0;
728
729 insn = extract_unsigned_integer (p + 4, 4);
730 if (n64)
731 {
732 /* daddu t7,ra */
733 if (insn != 0x03e0782d)
734 return 0;
735 }
736 else
737 {
738 /* addu t7,ra */
739 if (insn != 0x03e07821)
740 return 0;
741 }
742
743 insn = extract_unsigned_integer (p + 8, 4);
744 /* jalr t9,ra */
745 if (insn != 0x0320f809)
746 return 0;
747
748 insn = extract_unsigned_integer (p + 12, 4);
749 if (n64)
750 {
751 /* daddiu t8,zero,0 */
752 if ((insn & 0xffff0000) != 0x64180000)
753 return 0;
754 }
755 else
756 {
757 /* addiu t8,zero,0 */
758 if ((insn & 0xffff0000) != 0x24180000)
759 return 0;
760 }
761
762 return (insn & 0xffff);
763}
764
765/* Return non-zero iff PC belongs to the dynamic linker resolution code
766 or to a stub. */
767
768int
769mips_linux_in_dynsym_resolve_code (CORE_ADDR pc)
770{
771 /* Check whether PC is in the dynamic linker. This also checks whether
772 it is in the .plt section, which MIPS does not use. */
773 if (in_solib_dynsym_resolve_code (pc))
774 return 1;
775
776 /* Pattern match for the stub. It would be nice if there were a more
777 efficient way to avoid this check. */
778 if (mips_linux_in_dynsym_stub (pc, NULL))
779 return 1;
780
781 return 0;
782}
783
784/* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c,
785 and glibc_skip_solib_resolver in glibc-tdep.c. The normal glibc
786 implementation of this triggers at "fixup" from the same objfile as
c4c5b7ba
AC
787 "_dl_runtime_resolve"; MIPS GNU/Linux can trigger at
788 "__dl_runtime_resolve" directly. An unresolved PLT entry will
789 point to _dl_runtime_resolve, which will first call
790 __dl_runtime_resolve, and then pass control to the resolved
791 function. */
6de918a6
DJ
792
793static CORE_ADDR
794mips_linux_skip_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
795{
796 struct minimal_symbol *resolver;
797
798 resolver = lookup_minimal_symbol ("__dl_runtime_resolve", NULL, NULL);
799
800 if (resolver && SYMBOL_VALUE_ADDRESS (resolver) == pc)
801 return frame_pc_unwind (get_current_frame ());
802
803 return 0;
804}
805
5792a79b
DJ
806/* Signal trampoline support. There are four supported layouts for a
807 signal frame: o32 sigframe, o32 rt_sigframe, n32 rt_sigframe, and
808 n64 rt_sigframe. We handle them all independently; not the most
809 efficient way, but simplest. First, declare all the unwinders. */
810
811static void mips_linux_o32_sigframe_init (const struct tramp_frame *self,
812 struct frame_info *next_frame,
813 struct trad_frame_cache *this_cache,
814 CORE_ADDR func);
815
816static void mips_linux_n32n64_sigframe_init (const struct tramp_frame *self,
817 struct frame_info *next_frame,
818 struct trad_frame_cache *this_cache,
819 CORE_ADDR func);
820
821#define MIPS_NR_LINUX 4000
822#define MIPS_NR_N64_LINUX 5000
823#define MIPS_NR_N32_LINUX 6000
824
825#define MIPS_NR_sigreturn MIPS_NR_LINUX + 119
826#define MIPS_NR_rt_sigreturn MIPS_NR_LINUX + 193
827#define MIPS_NR_N64_rt_sigreturn MIPS_NR_N64_LINUX + 211
828#define MIPS_NR_N32_rt_sigreturn MIPS_NR_N32_LINUX + 211
829
830#define MIPS_INST_LI_V0_SIGRETURN 0x24020000 + MIPS_NR_sigreturn
831#define MIPS_INST_LI_V0_RT_SIGRETURN 0x24020000 + MIPS_NR_rt_sigreturn
832#define MIPS_INST_LI_V0_N64_RT_SIGRETURN 0x24020000 + MIPS_NR_N64_rt_sigreturn
833#define MIPS_INST_LI_V0_N32_RT_SIGRETURN 0x24020000 + MIPS_NR_N32_rt_sigreturn
834#define MIPS_INST_SYSCALL 0x0000000c
835
2cd8546d
AC
836static const struct tramp_frame mips_linux_o32_sigframe = {
837 SIGTRAMP_FRAME,
5792a79b 838 4,
2cd8546d
AC
839 {
840 { MIPS_INST_LI_V0_SIGRETURN, -1 },
841 { MIPS_INST_SYSCALL, -1 },
842 { TRAMP_SENTINEL_INSN, -1 }
843 },
5792a79b
DJ
844 mips_linux_o32_sigframe_init
845};
846
2cd8546d
AC
847static const struct tramp_frame mips_linux_o32_rt_sigframe = {
848 SIGTRAMP_FRAME,
5792a79b 849 4,
2cd8546d
AC
850 {
851 { MIPS_INST_LI_V0_RT_SIGRETURN, -1 },
852 { MIPS_INST_SYSCALL, -1 },
853 { TRAMP_SENTINEL_INSN, -1 } },
5792a79b
DJ
854 mips_linux_o32_sigframe_init
855};
856
2cd8546d
AC
857static const struct tramp_frame mips_linux_n32_rt_sigframe = {
858 SIGTRAMP_FRAME,
5792a79b 859 4,
2cd8546d
AC
860 {
861 { MIPS_INST_LI_V0_N32_RT_SIGRETURN, -1 },
862 { MIPS_INST_SYSCALL, -1 },
863 { TRAMP_SENTINEL_INSN, -1 }
864 },
5792a79b
DJ
865 mips_linux_n32n64_sigframe_init
866};
867
2cd8546d
AC
868static const struct tramp_frame mips_linux_n64_rt_sigframe = {
869 SIGTRAMP_FRAME,
5792a79b
DJ
870 4,
871 { MIPS_INST_LI_V0_N64_RT_SIGRETURN, MIPS_INST_SYSCALL, TRAMP_SENTINEL_INSN },
872 mips_linux_n32n64_sigframe_init
873};
874
875/* *INDENT-OFF* */
876/* The unwinder for o32 signal frames. The legacy structures look
877 like this:
878
879 struct sigframe {
880 u32 sf_ass[4]; [argument save space for o32]
881 u32 sf_code[2]; [signal trampoline]
882 struct sigcontext sf_sc;
883 sigset_t sf_mask;
884 };
885
886 struct sigcontext {
887 unsigned int sc_regmask; [Unused]
888 unsigned int sc_status;
889 unsigned long long sc_pc;
890 unsigned long long sc_regs[32];
891 unsigned long long sc_fpregs[32];
892 unsigned int sc_ownedfp;
893 unsigned int sc_fpc_csr;
894 unsigned int sc_fpc_eir; [Unused]
895 unsigned int sc_used_math;
896 unsigned int sc_ssflags; [Unused]
897 [Alignment hole of four bytes]
898 unsigned long long sc_mdhi;
899 unsigned long long sc_mdlo;
900
901 unsigned int sc_cause; [Unused]
902 unsigned int sc_badvaddr; [Unused]
903
904 unsigned long sc_sigset[4]; [kernel's sigset_t]
905 };
906
907 The RT signal frames look like this:
908
909 struct rt_sigframe {
910 u32 rs_ass[4]; [argument save space for o32]
911 u32 rs_code[2] [signal trampoline]
912 struct siginfo rs_info;
913 struct ucontext rs_uc;
914 };
915
916 struct ucontext {
917 unsigned long uc_flags;
918 struct ucontext *uc_link;
919 stack_t uc_stack;
920 [Alignment hole of four bytes]
921 struct sigcontext uc_mcontext;
922 sigset_t uc_sigmask;
923 }; */
924/* *INDENT-ON* */
925
926#define SIGFRAME_CODE_OFFSET (4 * 4)
927#define SIGFRAME_SIGCONTEXT_OFFSET (6 * 4)
928
929#define RTSIGFRAME_SIGINFO_SIZE 128
930#define STACK_T_SIZE (3 * 4)
931#define UCONTEXT_SIGCONTEXT_OFFSET (2 * 4 + STACK_T_SIZE + 4)
932#define RTSIGFRAME_SIGCONTEXT_OFFSET (SIGFRAME_SIGCONTEXT_OFFSET \
933 + RTSIGFRAME_SIGINFO_SIZE \
934 + UCONTEXT_SIGCONTEXT_OFFSET)
935
936#define SIGCONTEXT_PC (1 * 8)
937#define SIGCONTEXT_REGS (2 * 8)
938#define SIGCONTEXT_FPREGS (34 * 8)
939#define SIGCONTEXT_FPCSR (66 * 8 + 4)
940#define SIGCONTEXT_HI (69 * 8)
941#define SIGCONTEXT_LO (70 * 8)
942#define SIGCONTEXT_CAUSE (71 * 8 + 0)
943#define SIGCONTEXT_BADVADDR (71 * 8 + 4)
944
945#define SIGCONTEXT_REG_SIZE 8
946
947static void
948mips_linux_o32_sigframe_init (const struct tramp_frame *self,
949 struct frame_info *next_frame,
950 struct trad_frame_cache *this_cache,
951 CORE_ADDR func)
952{
953 int ireg, reg_position;
954 CORE_ADDR sigcontext_base = func - SIGFRAME_CODE_OFFSET;
955 const struct mips_regnum *regs = mips_regnum (current_gdbarch);
956
957 if (self == &mips_linux_o32_sigframe)
958 sigcontext_base += SIGFRAME_SIGCONTEXT_OFFSET;
959 else
960 sigcontext_base += RTSIGFRAME_SIGCONTEXT_OFFSET;
961
962 /* I'm not proud of this hack. Eventually we will have the infrastructure
963 to indicate the size of saved registers on a per-frame basis, but
964 right now we don't; the kernel saves eight bytes but we only want
965 four. */
966 if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
967 sigcontext_base += 4;
968
969#if 0
970 trad_frame_set_reg_addr (this_cache, ORIG_ZERO_REGNUM + NUM_REGS,
971 sigcontext_base + SIGCONTEXT_REGS);
972#endif
973
974 for (ireg = 1; ireg < 32; ireg++)
4c7d22cb 975 trad_frame_set_reg_addr (this_cache, ireg + MIPS_ZERO_REGNUM + NUM_REGS,
5792a79b
DJ
976 sigcontext_base + SIGCONTEXT_REGS
977 + ireg * SIGCONTEXT_REG_SIZE);
978
979 for (ireg = 0; ireg < 32; ireg++)
980 trad_frame_set_reg_addr (this_cache, ireg + regs->fp0 + NUM_REGS,
981 sigcontext_base + SIGCONTEXT_FPREGS
982 + ireg * SIGCONTEXT_REG_SIZE);
983
984 trad_frame_set_reg_addr (this_cache, regs->pc + NUM_REGS,
985 sigcontext_base + SIGCONTEXT_PC);
986
987 trad_frame_set_reg_addr (this_cache, regs->fp_control_status + NUM_REGS,
988 sigcontext_base + SIGCONTEXT_FPCSR);
989 trad_frame_set_reg_addr (this_cache, regs->hi + NUM_REGS,
990 sigcontext_base + SIGCONTEXT_HI);
991 trad_frame_set_reg_addr (this_cache, regs->lo + NUM_REGS,
992 sigcontext_base + SIGCONTEXT_LO);
993 trad_frame_set_reg_addr (this_cache, regs->cause + NUM_REGS,
994 sigcontext_base + SIGCONTEXT_CAUSE);
995 trad_frame_set_reg_addr (this_cache, regs->badvaddr + NUM_REGS,
996 sigcontext_base + SIGCONTEXT_BADVADDR);
997
998 /* Choice of the bottom of the sigframe is somewhat arbitrary. */
999 trad_frame_set_id (this_cache,
1000 frame_id_build (func - SIGFRAME_CODE_OFFSET, func));
1001}
1002
1003/* *INDENT-OFF* */
1004/* For N32/N64 things look different. There is no non-rt signal frame.
1005
1006 struct rt_sigframe_n32 {
1007 u32 rs_ass[4]; [ argument save space for o32 ]
1008 u32 rs_code[2]; [ signal trampoline ]
1009 struct siginfo rs_info;
1010 struct ucontextn32 rs_uc;
1011 };
1012
1013 struct ucontextn32 {
1014 u32 uc_flags;
1015 s32 uc_link;
1016 stack32_t uc_stack;
1017 struct sigcontext uc_mcontext;
1018 sigset_t uc_sigmask; [ mask last for extensibility ]
1019 };
1020
1021 struct rt_sigframe_n32 {
1022 u32 rs_ass[4]; [ argument save space for o32 ]
1023 u32 rs_code[2]; [ signal trampoline ]
1024 struct siginfo rs_info;
1025 struct ucontext rs_uc;
1026 };
1027
1028 struct ucontext {
1029 unsigned long uc_flags;
1030 struct ucontext *uc_link;
1031 stack_t uc_stack;
1032 struct sigcontext uc_mcontext;
1033 sigset_t uc_sigmask; [ mask last for extensibility ]
1034 };
1035
1036 And the sigcontext is different (this is for both n32 and n64):
1037
1038 struct sigcontext {
1039 unsigned long long sc_regs[32];
1040 unsigned long long sc_fpregs[32];
1041 unsigned long long sc_mdhi;
1042 unsigned long long sc_mdlo;
1043 unsigned long long sc_pc;
1044 unsigned int sc_status;
1045 unsigned int sc_fpc_csr;
1046 unsigned int sc_fpc_eir;
1047 unsigned int sc_used_math;
1048 unsigned int sc_cause;
1049 unsigned int sc_badvaddr;
1050 }; */
1051/* *INDENT-ON* */
1052
1053#define N32_STACK_T_SIZE STACK_T_SIZE
1054#define N64_STACK_T_SIZE (2 * 8 + 4)
1055#define N32_UCONTEXT_SIGCONTEXT_OFFSET (2 * 4 + N32_STACK_T_SIZE + 4)
1056#define N64_UCONTEXT_SIGCONTEXT_OFFSET (2 * 8 + N64_STACK_T_SIZE + 4)
1057#define N32_SIGFRAME_SIGCONTEXT_OFFSET (SIGFRAME_SIGCONTEXT_OFFSET \
1058 + RTSIGFRAME_SIGINFO_SIZE \
1059 + N32_UCONTEXT_SIGCONTEXT_OFFSET)
1060#define N64_SIGFRAME_SIGCONTEXT_OFFSET (SIGFRAME_SIGCONTEXT_OFFSET \
1061 + RTSIGFRAME_SIGINFO_SIZE \
1062 + N64_UCONTEXT_SIGCONTEXT_OFFSET)
1063
1064#define N64_SIGCONTEXT_REGS (0 * 8)
1065#define N64_SIGCONTEXT_FPREGS (32 * 8)
1066#define N64_SIGCONTEXT_HI (64 * 8)
1067#define N64_SIGCONTEXT_LO (65 * 8)
1068#define N64_SIGCONTEXT_PC (66 * 8)
1069#define N64_SIGCONTEXT_FPCSR (67 * 8 + 1 * 4)
1070#define N64_SIGCONTEXT_FIR (67 * 8 + 2 * 4)
1071#define N64_SIGCONTEXT_CAUSE (67 * 8 + 4 * 4)
1072#define N64_SIGCONTEXT_BADVADDR (67 * 8 + 5 * 4)
1073
1074#define N64_SIGCONTEXT_REG_SIZE 8
1075
1076static void
1077mips_linux_n32n64_sigframe_init (const struct tramp_frame *self,
1078 struct frame_info *next_frame,
1079 struct trad_frame_cache *this_cache,
1080 CORE_ADDR func)
1081{
1082 int ireg, reg_position;
1083 CORE_ADDR sigcontext_base = func - SIGFRAME_CODE_OFFSET;
1084 const struct mips_regnum *regs = mips_regnum (current_gdbarch);
1085
1086 if (self == &mips_linux_n32_rt_sigframe)
1087 sigcontext_base += N32_SIGFRAME_SIGCONTEXT_OFFSET;
1088 else
1089 sigcontext_base += N64_SIGFRAME_SIGCONTEXT_OFFSET;
1090
1091#if 0
1092 trad_frame_set_reg_addr (this_cache, ORIG_ZERO_REGNUM + NUM_REGS,
1093 sigcontext_base + N64_SIGCONTEXT_REGS);
1094#endif
1095
1096 for (ireg = 1; ireg < 32; ireg++)
4c7d22cb 1097 trad_frame_set_reg_addr (this_cache, ireg + MIPS_ZERO_REGNUM + NUM_REGS,
5792a79b
DJ
1098 sigcontext_base + N64_SIGCONTEXT_REGS
1099 + ireg * N64_SIGCONTEXT_REG_SIZE);
1100
1101 for (ireg = 0; ireg < 32; ireg++)
1102 trad_frame_set_reg_addr (this_cache, ireg + regs->fp0 + NUM_REGS,
1103 sigcontext_base + N64_SIGCONTEXT_FPREGS
1104 + ireg * N64_SIGCONTEXT_REG_SIZE);
1105
1106 trad_frame_set_reg_addr (this_cache, regs->pc + NUM_REGS,
1107 sigcontext_base + N64_SIGCONTEXT_PC);
1108
1109 trad_frame_set_reg_addr (this_cache, regs->fp_control_status + NUM_REGS,
1110 sigcontext_base + N64_SIGCONTEXT_FPCSR);
1111 trad_frame_set_reg_addr (this_cache, regs->hi + NUM_REGS,
1112 sigcontext_base + N64_SIGCONTEXT_HI);
1113 trad_frame_set_reg_addr (this_cache, regs->lo + NUM_REGS,
1114 sigcontext_base + N64_SIGCONTEXT_LO);
1115 trad_frame_set_reg_addr (this_cache, regs->cause + NUM_REGS,
1116 sigcontext_base + N64_SIGCONTEXT_CAUSE);
1117 trad_frame_set_reg_addr (this_cache, regs->badvaddr + NUM_REGS,
1118 sigcontext_base + N64_SIGCONTEXT_BADVADDR);
1119
1120 /* Choice of the bottom of the sigframe is somewhat arbitrary. */
1121 trad_frame_set_id (this_cache,
1122 frame_id_build (func - SIGFRAME_CODE_OFFSET, func));
1123}
1124
1125/* Initialize one of the GNU/Linux OS ABIs. */
1126
19ed69dd
KB
1127static void
1128mips_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
1129{
96f026fc
KB
1130 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1131 enum mips_abi abi = mips_abi (gdbarch);
1132
1133 switch (abi)
1134 {
1135 case MIPS_ABI_O32:
1136 set_gdbarch_get_longjmp_target (gdbarch,
1137 mips_linux_get_longjmp_target);
1138 set_solib_svr4_fetch_link_map_offsets
1139 (gdbarch, mips_linux_svr4_fetch_link_map_offsets);
1140 set_mips_linux_register_addr (gdbarch, mips_linux_register_addr);
fb2be677
AC
1141 tramp_frame_prepend_unwinder (gdbarch, &mips_linux_o32_sigframe);
1142 tramp_frame_prepend_unwinder (gdbarch, &mips_linux_o32_rt_sigframe);
96f026fc
KB
1143 break;
1144 case MIPS_ABI_N32:
1145 set_gdbarch_get_longjmp_target (gdbarch,
1146 mips_linux_get_longjmp_target);
1147 set_solib_svr4_fetch_link_map_offsets
1148 (gdbarch, mips_linux_svr4_fetch_link_map_offsets);
1149 set_mips_linux_register_addr (gdbarch, mips64_linux_register_addr);
fb2be677 1150 tramp_frame_prepend_unwinder (gdbarch, &mips_linux_n32_rt_sigframe);
96f026fc
KB
1151 break;
1152 case MIPS_ABI_N64:
1153 set_gdbarch_get_longjmp_target (gdbarch,
1154 mips64_linux_get_longjmp_target);
1155 set_solib_svr4_fetch_link_map_offsets
1156 (gdbarch, mips64_linux_svr4_fetch_link_map_offsets);
1157 set_mips_linux_register_addr (gdbarch, mips64_linux_register_addr);
fb2be677 1158 tramp_frame_prepend_unwinder (gdbarch, &mips_linux_n64_rt_sigframe);
96f026fc
KB
1159 break;
1160 default:
1161 internal_error (__FILE__, __LINE__, "can't handle ABI");
1162 break;
1163 }
6de918a6
DJ
1164
1165 set_gdbarch_skip_solib_resolver (gdbarch, mips_linux_skip_resolver);
1166
0d0266c6 1167 set_gdbarch_software_single_step (gdbarch, mips_software_single_step);
19ed69dd
KB
1168}
1169
2aa830e4 1170void
d1bacddc 1171_initialize_mips_linux_tdep (void)
2aa830e4 1172{
96f026fc
KB
1173 const struct bfd_arch_info *arch_info;
1174
1175 register_addr_data =
030f20e1 1176 gdbarch_data_register_post_init (init_register_addr_data);
96f026fc
KB
1177
1178 for (arch_info = bfd_lookup_arch (bfd_arch_mips, 0);
1179 arch_info != NULL;
1180 arch_info = arch_info->next)
1181 {
1182 gdbarch_register_osabi (bfd_arch_mips, arch_info->mach, GDB_OSABI_LINUX,
1183 mips_linux_init_abi);
1184 }
1185
00e32a35 1186 deprecated_add_core_fns (&regset_core_fns);
2aa830e4 1187}
This page took 0.469381 seconds and 4 git commands to generate.