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