*** empty log message ***
[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"
2aa830e4
DJ
31
32/* Copied from <asm/elf.h>. */
33#define ELF_NGREG 45
34#define ELF_NFPREG 33
35
36typedef unsigned char elf_greg_t[4];
37typedef elf_greg_t elf_gregset_t[ELF_NGREG];
38
39typedef unsigned char elf_fpreg_t[8];
40typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
41
42/* 0 - 31 are integer registers, 32 - 63 are fp registers. */
43#define FPR_BASE 32
44#define PC 64
45#define CAUSE 65
46#define BADVADDR 66
47#define MMHI 67
48#define MMLO 68
49#define FPC_CSR 69
50#define FPC_EIR 70
51
52#define EF_REG0 6
53#define EF_REG31 37
54#define EF_LO 38
55#define EF_HI 39
56#define EF_CP0_EPC 40
57#define EF_CP0_BADVADDR 41
58#define EF_CP0_STATUS 42
59#define EF_CP0_CAUSE 43
60
61#define EF_SIZE 180
62
63/* Figure out where the longjmp will land.
64 We expect the first arg to be a pointer to the jmp_buf structure from
bf072999
DJ
65 which we extract the pc (MIPS_LINUX_JB_PC) that we will land at. The pc
66 is copied into PC. This routine returns 1 on success. */
2aa830e4 67
19ed69dd
KB
68#define MIPS_LINUX_JB_ELEMENT_SIZE 4
69#define MIPS_LINUX_JB_PC 0
70
71static int
2aa830e4
DJ
72mips_linux_get_longjmp_target (CORE_ADDR *pc)
73{
74 CORE_ADDR jb_addr;
75 char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
76
77 jb_addr = read_register (A0_REGNUM);
78
bf072999
DJ
79 if (target_read_memory (jb_addr
80 + MIPS_LINUX_JB_PC * MIPS_LINUX_JB_ELEMENT_SIZE,
81 buf, TARGET_PTR_BIT / TARGET_CHAR_BIT))
2aa830e4
DJ
82 return 0;
83
7c0b4a20 84 *pc = extract_unsigned_integer (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
2aa830e4
DJ
85
86 return 1;
87}
88
4246e332
AC
89/* Transform the bits comprising a 32-bit register to the right size
90 for supply_register(). This is needed when mips_regsize() is 8. */
96f026fc
KB
91
92static void
93supply_32bit_reg (int regnum, const void *addr)
94{
d9d9c31f 95 char buf[MAX_REGISTER_SIZE];
12c266ea 96 store_signed_integer (buf, DEPRECATED_REGISTER_RAW_SIZE (regnum),
96f026fc
KB
97 extract_signed_integer (addr, 4));
98 supply_register (regnum, buf);
99}
100
2aa830e4
DJ
101/* Unpack an elf_gregset_t into GDB's register cache. */
102
103void
104supply_gregset (elf_gregset_t *gregsetp)
105{
106 int regi;
107 elf_greg_t *regp = *gregsetp;
d9d9c31f 108 char zerobuf[MAX_REGISTER_SIZE];
bf072999 109
d9d9c31f 110 memset (zerobuf, 0, MAX_REGISTER_SIZE);
2aa830e4
DJ
111
112 for (regi = EF_REG0; regi <= EF_REG31; regi++)
96f026fc 113 supply_32bit_reg ((regi - EF_REG0), (char *)(regp + regi));
2aa830e4 114
56cea623
AC
115 supply_32bit_reg (mips_regnum (current_gdbarch)->lo,
116 (char *)(regp + EF_LO));
117 supply_32bit_reg (mips_regnum (current_gdbarch)->hi,
118 (char *)(regp + EF_HI));
119
120 supply_32bit_reg (mips_regnum (current_gdbarch)->pc,
121 (char *)(regp + EF_CP0_EPC));
122 supply_32bit_reg (mips_regnum (current_gdbarch)->badvaddr,
123 (char *)(regp + EF_CP0_BADVADDR));
96f026fc 124 supply_32bit_reg (PS_REGNUM, (char *)(regp + EF_CP0_STATUS));
56cea623
AC
125 supply_32bit_reg (mips_regnum (current_gdbarch)->cause,
126 (char *)(regp + EF_CP0_CAUSE));
2aa830e4
DJ
127
128 /* Fill inaccessible registers with zero. */
2aa830e4
DJ
129 supply_register (UNUSED_REGNUM, zerobuf);
130 for (regi = FIRST_EMBED_REGNUM; regi < LAST_EMBED_REGNUM; regi++)
131 supply_register (regi, zerobuf);
132}
133
134/* Pack our registers (or one register) into an elf_gregset_t. */
135
136void
137fill_gregset (elf_gregset_t *gregsetp, int regno)
138{
139 int regaddr, regi;
140 elf_greg_t *regp = *gregsetp;
96f026fc 141 void *dst;
2aa830e4
DJ
142
143 if (regno == -1)
144 {
145 memset (regp, 0, sizeof (elf_gregset_t));
146 for (regi = 0; regi < 32; regi++)
147 fill_gregset (gregsetp, regi);
56cea623
AC
148 fill_gregset (gregsetp, mips_regnum (current_gdbarch)->lo);
149 fill_gregset (gregsetp, mips_regnum (current_gdbarch)->hi);
150 fill_gregset (gregsetp, mips_regnum (current_gdbarch)->pc);
151 fill_gregset (gregsetp, mips_regnum (current_gdbarch)->badvaddr);
2aa830e4 152 fill_gregset (gregsetp, PS_REGNUM);
56cea623 153 fill_gregset (gregsetp, mips_regnum (current_gdbarch)->cause);
2aa830e4
DJ
154
155 return;
156 }
157
158 if (regno < 32)
159 {
2aa830e4 160 dst = regp + regno + EF_REG0;
96f026fc 161 regcache_collect (regno, dst);
2aa830e4
DJ
162 return;
163 }
164
56cea623
AC
165 if (regno == mips_regnum (current_gdbarch)->lo)
166 regaddr = EF_LO;
167 else if (regno == mips_regnum (current_gdbarch)->hi)
168 regaddr = EF_HI;
169 else if (regno == mips_regnum (current_gdbarch)->pc)
170 regaddr = EF_CP0_EPC;
171 else if (regno == mips_regnum (current_gdbarch)->badvaddr)
172 regaddr = EF_CP0_BADVADDR;
173 else if (regno == PS_REGNUM)
174 regaddr = EF_CP0_STATUS;
175 else if (regno == mips_regnum (current_gdbarch)->cause)
176 regaddr = EF_CP0_CAUSE;
177 else
178 regaddr = -1;
2aa830e4
DJ
179
180 if (regaddr != -1)
181 {
2aa830e4 182 dst = regp + regaddr;
96f026fc 183 regcache_collect (regno, dst);
2aa830e4
DJ
184 }
185}
186
187/* Likewise, unpack an elf_fpregset_t. */
188
189void
190supply_fpregset (elf_fpregset_t *fpregsetp)
191{
52f0bd74 192 int regi;
d9d9c31f 193 char zerobuf[MAX_REGISTER_SIZE];
bf072999 194
d9d9c31f 195 memset (zerobuf, 0, MAX_REGISTER_SIZE);
2aa830e4
DJ
196
197 for (regi = 0; regi < 32; regi++)
198 supply_register (FP0_REGNUM + regi,
199 (char *)(*fpregsetp + regi));
200
56cea623
AC
201 supply_register (mips_regnum (current_gdbarch)->fp_control_status,
202 (char *)(*fpregsetp + 32));
2aa830e4 203
56cea623
AC
204 /* FIXME: how can we supply FCRIR? The ABI doesn't tell us. */
205 supply_register (mips_regnum (current_gdbarch)->fp_implementation_revision,
206 zerobuf);
2aa830e4
DJ
207}
208
209/* Likewise, pack one or all floating point registers into an
210 elf_fpregset_t. */
211
212void
213fill_fpregset (elf_fpregset_t *fpregsetp, int regno)
214{
215 char *from, *to;
216
217 if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32))
218 {
62700349 219 from = (char *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)];
2aa830e4 220 to = (char *) (*fpregsetp + regno - FP0_REGNUM);
12c266ea 221 memcpy (to, from, DEPRECATED_REGISTER_RAW_SIZE (regno - FP0_REGNUM));
2aa830e4 222 }
56cea623 223 else if (regno == mips_regnum (current_gdbarch)->fp_control_status)
2aa830e4 224 {
62700349 225 from = (char *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)];
2aa830e4 226 to = (char *) (*fpregsetp + 32);
12c266ea 227 memcpy (to, from, DEPRECATED_REGISTER_RAW_SIZE (regno));
2aa830e4
DJ
228 }
229 else if (regno == -1)
230 {
231 int regi;
232
233 for (regi = 0; regi < 32; regi++)
234 fill_fpregset (fpregsetp, FP0_REGNUM + regi);
56cea623 235 fill_fpregset(fpregsetp, mips_regnum (current_gdbarch)->fp_control_status);
2aa830e4
DJ
236 }
237}
238
239/* Map gdb internal register number to ptrace ``address''.
240 These ``addresses'' are normally defined in <asm/ptrace.h>. */
241
96f026fc
KB
242static CORE_ADDR
243mips_linux_register_addr (int regno, CORE_ADDR blockend)
2aa830e4
DJ
244{
245 int regaddr;
246
247 if (regno < 0 || regno >= NUM_REGS)
248 error ("Bogon register number %d.", regno);
249
250 if (regno < 32)
251 regaddr = regno;
56cea623
AC
252 else if ((regno >= mips_regnum (current_gdbarch)->fp0)
253 && (regno < mips_regnum (current_gdbarch)->fp0 + 32))
254 regaddr = FPR_BASE + (regno - mips_regnum (current_gdbarch)->fp0);
255 else if (regno == mips_regnum (current_gdbarch)->pc)
2aa830e4 256 regaddr = PC;
56cea623 257 else if (regno == mips_regnum (current_gdbarch)->cause)
2aa830e4 258 regaddr = CAUSE;
56cea623 259 else if (regno == mips_regnum (current_gdbarch)->badvaddr)
2aa830e4 260 regaddr = BADVADDR;
56cea623 261 else if (regno == mips_regnum (current_gdbarch)->lo)
2aa830e4 262 regaddr = MMLO;
56cea623 263 else if (regno == mips_regnum (current_gdbarch)->hi)
2aa830e4 264 regaddr = MMHI;
56cea623 265 else if (regno == mips_regnum (current_gdbarch)->fp_control_status)
2aa830e4 266 regaddr = FPC_CSR;
56cea623 267 else if (regno == mips_regnum (current_gdbarch)->fp_implementation_revision)
2aa830e4
DJ
268 regaddr = FPC_EIR;
269 else
270 error ("Unknowable register number %d.", regno);
271
272 return regaddr;
273}
274
96f026fc
KB
275
276/* Fetch (and possibly build) an appropriate link_map_offsets
277 structure for native GNU/Linux MIPS targets using the struct offsets
278 defined in link.h (but without actual reference to that file).
279
280 This makes it possible to access GNU/Linux MIPS shared libraries from a
281 GDB that was built on a different host platform (for cross debugging). */
282
283static struct link_map_offsets *
284mips_linux_svr4_fetch_link_map_offsets (void)
285{
286 static struct link_map_offsets lmo;
287 static struct link_map_offsets *lmp = NULL;
288
289 if (lmp == NULL)
290 {
291 lmp = &lmo;
292
293 lmo.r_debug_size = 8; /* The actual size is 20 bytes, but
294 this is all we need. */
295 lmo.r_map_offset = 4;
296 lmo.r_map_size = 4;
297
298 lmo.link_map_size = 20;
299
300 lmo.l_addr_offset = 0;
301 lmo.l_addr_size = 4;
302
303 lmo.l_name_offset = 4;
304 lmo.l_name_size = 4;
305
306 lmo.l_next_offset = 12;
307 lmo.l_next_size = 4;
308
309 lmo.l_prev_offset = 16;
310 lmo.l_prev_size = 4;
311 }
312
313 return lmp;
314}
315
316/* Support for 64-bit ABIs. */
317
318/* Copied from <asm/elf.h>. */
319#define MIPS64_ELF_NGREG 45
320#define MIPS64_ELF_NFPREG 33
321
322typedef unsigned char mips64_elf_greg_t[8];
323typedef mips64_elf_greg_t mips64_elf_gregset_t[MIPS64_ELF_NGREG];
324
325typedef unsigned char mips64_elf_fpreg_t[8];
326typedef mips64_elf_fpreg_t mips64_elf_fpregset_t[MIPS64_ELF_NFPREG];
327
328/* 0 - 31 are integer registers, 32 - 63 are fp registers. */
329#define MIPS64_FPR_BASE 32
330#define MIPS64_PC 64
331#define MIPS64_CAUSE 65
332#define MIPS64_BADVADDR 66
333#define MIPS64_MMHI 67
334#define MIPS64_MMLO 68
335#define MIPS64_FPC_CSR 69
336#define MIPS64_FPC_EIR 70
337
338#define MIPS64_EF_REG0 0
339#define MIPS64_EF_REG31 31
340#define MIPS64_EF_LO 32
341#define MIPS64_EF_HI 33
342#define MIPS64_EF_CP0_EPC 34
343#define MIPS64_EF_CP0_BADVADDR 35
344#define MIPS64_EF_CP0_STATUS 36
345#define MIPS64_EF_CP0_CAUSE 37
346
347#define MIPS64_EF_SIZE 304
348
349/* Figure out where the longjmp will land.
350 We expect the first arg to be a pointer to the jmp_buf structure from
351 which we extract the pc (MIPS_LINUX_JB_PC) that we will land at. The pc
352 is copied into PC. This routine returns 1 on success. */
353
354/* Details about jmp_buf. */
355
356#define MIPS64_LINUX_JB_PC 0
357
358static int
359mips64_linux_get_longjmp_target (CORE_ADDR *pc)
360{
361 CORE_ADDR jb_addr;
362 void *buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
363 int element_size = TARGET_PTR_BIT == 32 ? 4 : 8;
364
365 jb_addr = read_register (A0_REGNUM);
366
367 if (target_read_memory (jb_addr + MIPS64_LINUX_JB_PC * element_size,
368 buf, TARGET_PTR_BIT / TARGET_CHAR_BIT))
369 return 0;
370
7c0b4a20 371 *pc = extract_unsigned_integer (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
96f026fc
KB
372
373 return 1;
374}
375
376/* Unpack an elf_gregset_t into GDB's register cache. */
377
378static void
379mips64_supply_gregset (mips64_elf_gregset_t *gregsetp)
380{
381 int regi;
382 mips64_elf_greg_t *regp = *gregsetp;
d9d9c31f 383 char zerobuf[MAX_REGISTER_SIZE];
96f026fc 384
d9d9c31f 385 memset (zerobuf, 0, MAX_REGISTER_SIZE);
96f026fc
KB
386
387 for (regi = MIPS64_EF_REG0; regi <= MIPS64_EF_REG31; regi++)
388 supply_register ((regi - MIPS64_EF_REG0), (char *)(regp + regi));
389
56cea623
AC
390 supply_register (mips_regnum (current_gdbarch)->lo,
391 (char *)(regp + MIPS64_EF_LO));
392 supply_register (mips_regnum (current_gdbarch)->hi,
393 (char *)(regp + MIPS64_EF_HI));
96f026fc 394
56cea623
AC
395 supply_register (mips_regnum (current_gdbarch)->pc,
396 (char *)(regp + MIPS64_EF_CP0_EPC));
397 supply_register (mips_regnum (current_gdbarch)->badvaddr,
398 (char *)(regp + MIPS64_EF_CP0_BADVADDR));
96f026fc 399 supply_register (PS_REGNUM, (char *)(regp + MIPS64_EF_CP0_STATUS));
56cea623
AC
400 supply_register (mips_regnum (current_gdbarch)->cause,
401 (char *)(regp + MIPS64_EF_CP0_CAUSE));
96f026fc
KB
402
403 /* Fill inaccessible registers with zero. */
404 supply_register (UNUSED_REGNUM, zerobuf);
405 for (regi = FIRST_EMBED_REGNUM; regi < LAST_EMBED_REGNUM; regi++)
406 supply_register (regi, zerobuf);
407}
408
409/* Pack our registers (or one register) into an elf_gregset_t. */
410
411static void
412mips64_fill_gregset (mips64_elf_gregset_t *gregsetp, int regno)
413{
414 int regaddr, regi;
415 mips64_elf_greg_t *regp = *gregsetp;
416 void *src, *dst;
417
418 if (regno == -1)
419 {
420 memset (regp, 0, sizeof (mips64_elf_gregset_t));
421 for (regi = 0; regi < 32; regi++)
422 mips64_fill_gregset (gregsetp, regi);
56cea623
AC
423 mips64_fill_gregset (gregsetp, mips_regnum (current_gdbarch)->lo);
424 mips64_fill_gregset (gregsetp, mips_regnum (current_gdbarch)->hi);
425 mips64_fill_gregset (gregsetp, mips_regnum (current_gdbarch)->pc);
426 mips64_fill_gregset (gregsetp, mips_regnum (current_gdbarch)->badvaddr);
96f026fc 427 mips64_fill_gregset (gregsetp, PS_REGNUM);
56cea623 428 mips64_fill_gregset (gregsetp, mips_regnum (current_gdbarch)->cause);
96f026fc
KB
429
430 return;
431 }
432
433 if (regno < 32)
434 {
435 dst = regp + regno + MIPS64_EF_REG0;
436 regcache_collect (regno, dst);
437 return;
438 }
439
56cea623
AC
440 if (regno == mips_regnum (current_gdbarch)->lo)
441 regaddr = MIPS64_EF_LO;
442 else if (regno == mips_regnum (current_gdbarch)->hi)
443 regaddr = MIPS64_EF_HI;
444 else if (regno == mips_regnum (current_gdbarch)->pc)
445 regaddr = MIPS64_EF_CP0_EPC;
446 else if (regno == mips_regnum (current_gdbarch)->badvaddr)
447 regaddr = MIPS64_EF_CP0_BADVADDR;
448 else if (regno == PS_REGNUM)
449 regaddr = MIPS64_EF_CP0_STATUS;
450 else if (regno == mips_regnum (current_gdbarch)->cause)
451 regaddr = MIPS64_EF_CP0_CAUSE;
452 else
453 regaddr = -1;
96f026fc
KB
454
455 if (regaddr != -1)
456 {
457 dst = regp + regaddr;
458 regcache_collect (regno, dst);
459 }
460}
461
462/* Likewise, unpack an elf_fpregset_t. */
463
464static void
465mips64_supply_fpregset (mips64_elf_fpregset_t *fpregsetp)
466{
52f0bd74 467 int regi;
d9d9c31f 468 char zerobuf[MAX_REGISTER_SIZE];
96f026fc 469
d9d9c31f 470 memset (zerobuf, 0, MAX_REGISTER_SIZE);
96f026fc
KB
471
472 for (regi = 0; regi < 32; regi++)
473 supply_register (FP0_REGNUM + regi,
474 (char *)(*fpregsetp + regi));
475
56cea623
AC
476 supply_register (mips_regnum (current_gdbarch)->fp_control_status,
477 (char *)(*fpregsetp + 32));
96f026fc 478
56cea623
AC
479 /* FIXME: how can we supply FCRIR? The ABI doesn't tell us. */
480 supply_register (mips_regnum (current_gdbarch)->fp_implementation_revision,
481 zerobuf);
96f026fc
KB
482}
483
484/* Likewise, pack one or all floating point registers into an
485 elf_fpregset_t. */
486
487static void
488mips64_fill_fpregset (mips64_elf_fpregset_t *fpregsetp, int regno)
489{
490 char *from, *to;
491
492 if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32))
493 {
62700349 494 from = (char *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)];
96f026fc 495 to = (char *) (*fpregsetp + regno - FP0_REGNUM);
12c266ea 496 memcpy (to, from, DEPRECATED_REGISTER_RAW_SIZE (regno - FP0_REGNUM));
96f026fc 497 }
56cea623 498 else if (regno == mips_regnum (current_gdbarch)->fp_control_status)
96f026fc 499 {
62700349 500 from = (char *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)];
96f026fc 501 to = (char *) (*fpregsetp + 32);
12c266ea 502 memcpy (to, from, DEPRECATED_REGISTER_RAW_SIZE (regno));
96f026fc
KB
503 }
504 else if (regno == -1)
505 {
506 int regi;
507
508 for (regi = 0; regi < 32; regi++)
509 mips64_fill_fpregset (fpregsetp, FP0_REGNUM + regi);
56cea623
AC
510 mips64_fill_fpregset(fpregsetp,
511 mips_regnum (current_gdbarch)->fp_control_status);
96f026fc
KB
512 }
513}
514
515
516/* Map gdb internal register number to ptrace ``address''.
517 These ``addresses'' are normally defined in <asm/ptrace.h>. */
518
519static CORE_ADDR
520mips64_linux_register_addr (int regno, CORE_ADDR blockend)
521{
522 int regaddr;
523
524 if (regno < 0 || regno >= NUM_REGS)
525 error ("Bogon register number %d.", regno);
526
527 if (regno < 32)
528 regaddr = regno;
56cea623
AC
529 else if ((regno >= mips_regnum (current_gdbarch)->fp0)
530 && (regno < mips_regnum (current_gdbarch)->fp0 + 32))
96f026fc 531 regaddr = MIPS64_FPR_BASE + (regno - FP0_REGNUM);
56cea623 532 else if (regno == mips_regnum (current_gdbarch)->pc)
96f026fc 533 regaddr = MIPS64_PC;
56cea623 534 else if (regno == mips_regnum (current_gdbarch)->cause)
96f026fc 535 regaddr = MIPS64_CAUSE;
56cea623 536 else if (regno == mips_regnum (current_gdbarch)->badvaddr)
96f026fc 537 regaddr = MIPS64_BADVADDR;
56cea623 538 else if (regno == mips_regnum (current_gdbarch)->lo)
96f026fc 539 regaddr = MIPS64_MMLO;
56cea623 540 else if (regno == mips_regnum (current_gdbarch)->hi)
96f026fc 541 regaddr = MIPS64_MMHI;
56cea623 542 else if (regno == mips_regnum (current_gdbarch)->fp_control_status)
96f026fc 543 regaddr = MIPS64_FPC_CSR;
56cea623 544 else if (regno == mips_regnum (current_gdbarch)->fp_implementation_revision)
96f026fc
KB
545 regaddr = MIPS64_FPC_EIR;
546 else
547 error ("Unknowable register number %d.", regno);
548
549 return regaddr;
550}
551
2aa830e4
DJ
552/* Use a local version of this function to get the correct types for
553 regsets, until multi-arch core support is ready. */
554
555static void
556fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
557 int which, CORE_ADDR reg_addr)
558{
559 elf_gregset_t gregset;
560 elf_fpregset_t fpregset;
96f026fc
KB
561 mips64_elf_gregset_t gregset64;
562 mips64_elf_fpregset_t fpregset64;
2aa830e4
DJ
563
564 if (which == 0)
565 {
96f026fc 566 if (core_reg_size == sizeof (gregset))
2aa830e4 567 {
96f026fc
KB
568 memcpy ((char *) &gregset, core_reg_sect, sizeof (gregset));
569 supply_gregset (&gregset);
570 }
571 else if (core_reg_size == sizeof (gregset64))
572 {
573 memcpy ((char *) &gregset64, core_reg_sect, sizeof (gregset64));
574 mips64_supply_gregset (&gregset64);
2aa830e4
DJ
575 }
576 else
577 {
96f026fc 578 warning ("wrong size gregset struct in core file");
2aa830e4
DJ
579 }
580 }
581 else if (which == 2)
582 {
96f026fc 583 if (core_reg_size == sizeof (fpregset))
2aa830e4 584 {
96f026fc
KB
585 memcpy ((char *) &fpregset, core_reg_sect, sizeof (fpregset));
586 supply_fpregset (&fpregset);
587 }
588 else if (core_reg_size == sizeof (fpregset64))
589 {
590 memcpy ((char *) &fpregset64, core_reg_sect, sizeof (fpregset64));
591 mips64_supply_fpregset (&fpregset64);
2aa830e4
DJ
592 }
593 else
594 {
96f026fc 595 warning ("wrong size fpregset struct in core file");
2aa830e4
DJ
596 }
597 }
598}
599
600/* Register that we are able to handle ELF file formats using standard
601 procfs "regset" structures. */
602
603static struct core_fns regset_core_fns =
604{
605 bfd_target_elf_flavour, /* core_flavour */
606 default_check_format, /* check_format */
607 default_core_sniffer, /* core_sniffer */
608 fetch_core_registers, /* core_read_registers */
609 NULL /* next */
610};
611
612/* Fetch (and possibly build) an appropriate link_map_offsets
75c9abc6 613 structure for native GNU/Linux MIPS targets using the struct offsets
2aa830e4
DJ
614 defined in link.h (but without actual reference to that file).
615
75c9abc6
DJ
616 This makes it possible to access GNU/Linux MIPS shared libraries from a
617 GDB that was built on a different host platform (for cross debugging). */
2aa830e4 618
19ed69dd 619static struct link_map_offsets *
96f026fc 620mips64_linux_svr4_fetch_link_map_offsets (void)
2aa830e4
DJ
621{
622 static struct link_map_offsets lmo;
623 static struct link_map_offsets *lmp = NULL;
624
625 if (lmp == NULL)
626 {
627 lmp = &lmo;
628
96f026fc 629 lmo.r_debug_size = 16; /* The actual size is 40 bytes, but
2aa830e4 630 this is all we need. */
96f026fc
KB
631 lmo.r_map_offset = 8;
632 lmo.r_map_size = 8;
2aa830e4 633
96f026fc 634 lmo.link_map_size = 40;
2aa830e4
DJ
635
636 lmo.l_addr_offset = 0;
96f026fc 637 lmo.l_addr_size = 8;
2aa830e4 638
96f026fc
KB
639 lmo.l_name_offset = 8;
640 lmo.l_name_size = 8;
2aa830e4 641
96f026fc
KB
642 lmo.l_next_offset = 24;
643 lmo.l_next_size = 8;
2aa830e4 644
96f026fc
KB
645 lmo.l_prev_offset = 32;
646 lmo.l_prev_size = 8;
2aa830e4
DJ
647 }
648
649 return lmp;
650}
651
96f026fc
KB
652/* Handle for obtaining pointer to the current register_addr() function
653 for a given architecture. */
654static struct gdbarch_data *register_addr_data;
655
656CORE_ADDR
657register_addr (int regno, CORE_ADDR blockend)
658{
659 CORE_ADDR (*register_addr_ptr) (int, CORE_ADDR) =
660 gdbarch_data (current_gdbarch, register_addr_data);
661
662 gdb_assert (register_addr_ptr != 0);
663
664 return register_addr_ptr (regno, blockend);
665}
666
667static void
668set_mips_linux_register_addr (struct gdbarch *gdbarch,
669 CORE_ADDR (*register_addr_ptr) (int, CORE_ADDR))
670{
671 set_gdbarch_data (gdbarch, register_addr_data, register_addr_ptr);
672}
673
674static void *
675init_register_addr_data (struct gdbarch *gdbarch)
676{
677 return 0;
678}
679
6de918a6
DJ
680/* Check the code at PC for a dynamic linker lazy resolution stub. Because
681 they aren't in the .plt section, we pattern-match on the code generated
682 by GNU ld. They look like this:
683
684 lw t9,0x8010(gp)
685 addu t7,ra
686 jalr t9,ra
687 addiu t8,zero,INDEX
688
689 (with the appropriate doubleword instructions for N64). Also return the
690 dynamic symbol index used in the last instruction. */
691
692static int
693mips_linux_in_dynsym_stub (CORE_ADDR pc, char *name)
694{
695 unsigned char buf[28], *p;
696 ULONGEST insn, insn1;
697 int n64 = (mips_abi (current_gdbarch) == MIPS_ABI_N64);
698
699 read_memory (pc - 12, buf, 28);
700
701 if (n64)
702 {
703 /* ld t9,0x8010(gp) */
704 insn1 = 0xdf998010;
705 }
706 else
707 {
708 /* lw t9,0x8010(gp) */
709 insn1 = 0x8f998010;
710 }
711
712 p = buf + 12;
713 while (p >= buf)
714 {
715 insn = extract_unsigned_integer (p, 4);
716 if (insn == insn1)
717 break;
718 p -= 4;
719 }
720 if (p < buf)
721 return 0;
722
723 insn = extract_unsigned_integer (p + 4, 4);
724 if (n64)
725 {
726 /* daddu t7,ra */
727 if (insn != 0x03e0782d)
728 return 0;
729 }
730 else
731 {
732 /* addu t7,ra */
733 if (insn != 0x03e07821)
734 return 0;
735 }
736
737 insn = extract_unsigned_integer (p + 8, 4);
738 /* jalr t9,ra */
739 if (insn != 0x0320f809)
740 return 0;
741
742 insn = extract_unsigned_integer (p + 12, 4);
743 if (n64)
744 {
745 /* daddiu t8,zero,0 */
746 if ((insn & 0xffff0000) != 0x64180000)
747 return 0;
748 }
749 else
750 {
751 /* addiu t8,zero,0 */
752 if ((insn & 0xffff0000) != 0x24180000)
753 return 0;
754 }
755
756 return (insn & 0xffff);
757}
758
759/* Return non-zero iff PC belongs to the dynamic linker resolution code
760 or to a stub. */
761
762int
763mips_linux_in_dynsym_resolve_code (CORE_ADDR pc)
764{
765 /* Check whether PC is in the dynamic linker. This also checks whether
766 it is in the .plt section, which MIPS does not use. */
767 if (in_solib_dynsym_resolve_code (pc))
768 return 1;
769
770 /* Pattern match for the stub. It would be nice if there were a more
771 efficient way to avoid this check. */
772 if (mips_linux_in_dynsym_stub (pc, NULL))
773 return 1;
774
775 return 0;
776}
777
778/* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c,
779 and glibc_skip_solib_resolver in glibc-tdep.c. The normal glibc
780 implementation of this triggers at "fixup" from the same objfile as
c4c5b7ba
AC
781 "_dl_runtime_resolve"; MIPS GNU/Linux can trigger at
782 "__dl_runtime_resolve" directly. An unresolved PLT entry will
783 point to _dl_runtime_resolve, which will first call
784 __dl_runtime_resolve, and then pass control to the resolved
785 function. */
6de918a6
DJ
786
787static CORE_ADDR
788mips_linux_skip_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
789{
790 struct minimal_symbol *resolver;
791
792 resolver = lookup_minimal_symbol ("__dl_runtime_resolve", NULL, NULL);
793
794 if (resolver && SYMBOL_VALUE_ADDRESS (resolver) == pc)
795 return frame_pc_unwind (get_current_frame ());
796
797 return 0;
798}
799
19ed69dd
KB
800static void
801mips_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
802{
96f026fc
KB
803 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
804 enum mips_abi abi = mips_abi (gdbarch);
805
806 switch (abi)
807 {
808 case MIPS_ABI_O32:
809 set_gdbarch_get_longjmp_target (gdbarch,
810 mips_linux_get_longjmp_target);
811 set_solib_svr4_fetch_link_map_offsets
812 (gdbarch, mips_linux_svr4_fetch_link_map_offsets);
813 set_mips_linux_register_addr (gdbarch, mips_linux_register_addr);
814 break;
815 case MIPS_ABI_N32:
816 set_gdbarch_get_longjmp_target (gdbarch,
817 mips_linux_get_longjmp_target);
818 set_solib_svr4_fetch_link_map_offsets
819 (gdbarch, mips_linux_svr4_fetch_link_map_offsets);
820 set_mips_linux_register_addr (gdbarch, mips64_linux_register_addr);
821 break;
822 case MIPS_ABI_N64:
823 set_gdbarch_get_longjmp_target (gdbarch,
824 mips64_linux_get_longjmp_target);
825 set_solib_svr4_fetch_link_map_offsets
826 (gdbarch, mips64_linux_svr4_fetch_link_map_offsets);
827 set_mips_linux_register_addr (gdbarch, mips64_linux_register_addr);
828 break;
829 default:
830 internal_error (__FILE__, __LINE__, "can't handle ABI");
831 break;
832 }
6de918a6
DJ
833
834 set_gdbarch_skip_solib_resolver (gdbarch, mips_linux_skip_resolver);
835
c4c5b7ba
AC
836 /* This overrides the MIPS16 stub support from mips-tdep. But no
837 one uses MIPS16 on GNU/Linux yet, so this isn't much of a loss. */
6de918a6 838 set_gdbarch_in_solib_call_trampoline (gdbarch, mips_linux_in_dynsym_stub);
19ed69dd
KB
839}
840
2aa830e4 841void
d1bacddc 842_initialize_mips_linux_tdep (void)
2aa830e4 843{
96f026fc
KB
844 const struct bfd_arch_info *arch_info;
845
846 register_addr_data =
1062ca82 847 register_gdbarch_data (init_register_addr_data);
96f026fc
KB
848
849 for (arch_info = bfd_lookup_arch (bfd_arch_mips, 0);
850 arch_info != NULL;
851 arch_info = arch_info->next)
852 {
853 gdbarch_register_osabi (bfd_arch_mips, arch_info->mach, GDB_OSABI_LINUX,
854 mips_linux_init_abi);
855 }
856
2aa830e4
DJ
857 add_core_fns (&regset_core_fns);
858}
This page took 0.333842 seconds and 4 git commands to generate.