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