* x86-64-tdep.h: Tewak comment.
[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
32 /* Copied from <asm/elf.h>. */
33 #define ELF_NGREG 45
34 #define ELF_NFPREG 33
35
36 typedef unsigned char elf_greg_t[4];
37 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
38
39 typedef unsigned char elf_fpreg_t[8];
40 typedef 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
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. */
67
68 #define MIPS_LINUX_JB_ELEMENT_SIZE 4
69 #define MIPS_LINUX_JB_PC 0
70
71 static int
72 mips_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
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))
82 return 0;
83
84 *pc = extract_unsigned_integer (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
85
86 return 1;
87 }
88
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. */
91
92 static void
93 supply_32bit_reg (int regnum, const void *addr)
94 {
95 char buf[MAX_REGISTER_SIZE];
96 store_signed_integer (buf, DEPRECATED_REGISTER_RAW_SIZE (regnum),
97 extract_signed_integer (addr, 4));
98 supply_register (regnum, buf);
99 }
100
101 /* Unpack an elf_gregset_t into GDB's register cache. */
102
103 void
104 supply_gregset (elf_gregset_t *gregsetp)
105 {
106 int regi;
107 elf_greg_t *regp = *gregsetp;
108 char zerobuf[MAX_REGISTER_SIZE];
109
110 memset (zerobuf, 0, MAX_REGISTER_SIZE);
111
112 for (regi = EF_REG0; regi <= EF_REG31; regi++)
113 supply_32bit_reg ((regi - EF_REG0), (char *)(regp + regi));
114
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));
124 supply_32bit_reg (PS_REGNUM, (char *)(regp + EF_CP0_STATUS));
125 supply_32bit_reg (mips_regnum (current_gdbarch)->cause,
126 (char *)(regp + EF_CP0_CAUSE));
127
128 /* Fill inaccessible registers with zero. */
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
136 void
137 fill_gregset (elf_gregset_t *gregsetp, int regno)
138 {
139 int regaddr, regi;
140 elf_greg_t *regp = *gregsetp;
141 void *dst;
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);
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);
152 fill_gregset (gregsetp, PS_REGNUM);
153 fill_gregset (gregsetp, mips_regnum (current_gdbarch)->cause);
154
155 return;
156 }
157
158 if (regno < 32)
159 {
160 dst = regp + regno + EF_REG0;
161 regcache_collect (regno, dst);
162 return;
163 }
164
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;
179
180 if (regaddr != -1)
181 {
182 dst = regp + regaddr;
183 regcache_collect (regno, dst);
184 }
185 }
186
187 /* Likewise, unpack an elf_fpregset_t. */
188
189 void
190 supply_fpregset (elf_fpregset_t *fpregsetp)
191 {
192 int regi;
193 char zerobuf[MAX_REGISTER_SIZE];
194
195 memset (zerobuf, 0, MAX_REGISTER_SIZE);
196
197 for (regi = 0; regi < 32; regi++)
198 supply_register (FP0_REGNUM + regi,
199 (char *)(*fpregsetp + regi));
200
201 supply_register (mips_regnum (current_gdbarch)->fp_control_status,
202 (char *)(*fpregsetp + 32));
203
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);
207 }
208
209 /* Likewise, pack one or all floating point registers into an
210 elf_fpregset_t. */
211
212 void
213 fill_fpregset (elf_fpregset_t *fpregsetp, int regno)
214 {
215 char *from, *to;
216
217 if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32))
218 {
219 from = (char *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)];
220 to = (char *) (*fpregsetp + regno - FP0_REGNUM);
221 memcpy (to, from, DEPRECATED_REGISTER_RAW_SIZE (regno - FP0_REGNUM));
222 }
223 else if (regno == mips_regnum (current_gdbarch)->fp_control_status)
224 {
225 from = (char *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)];
226 to = (char *) (*fpregsetp + 32);
227 memcpy (to, from, DEPRECATED_REGISTER_RAW_SIZE (regno));
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);
235 fill_fpregset(fpregsetp, mips_regnum (current_gdbarch)->fp_control_status);
236 }
237 }
238
239 /* Map gdb internal register number to ptrace ``address''.
240 These ``addresses'' are normally defined in <asm/ptrace.h>. */
241
242 static CORE_ADDR
243 mips_linux_register_addr (int regno, CORE_ADDR blockend)
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;
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)
256 regaddr = PC;
257 else if (regno == mips_regnum (current_gdbarch)->cause)
258 regaddr = CAUSE;
259 else if (regno == mips_regnum (current_gdbarch)->badvaddr)
260 regaddr = BADVADDR;
261 else if (regno == mips_regnum (current_gdbarch)->lo)
262 regaddr = MMLO;
263 else if (regno == mips_regnum (current_gdbarch)->hi)
264 regaddr = MMHI;
265 else if (regno == mips_regnum (current_gdbarch)->fp_control_status)
266 regaddr = FPC_CSR;
267 else if (regno == mips_regnum (current_gdbarch)->fp_implementation_revision)
268 regaddr = FPC_EIR;
269 else
270 error ("Unknowable register number %d.", regno);
271
272 return regaddr;
273 }
274
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
283 static struct link_map_offsets *
284 mips_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
322 typedef unsigned char mips64_elf_greg_t[8];
323 typedef mips64_elf_greg_t mips64_elf_gregset_t[MIPS64_ELF_NGREG];
324
325 typedef unsigned char mips64_elf_fpreg_t[8];
326 typedef 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
358 static int
359 mips64_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
371 *pc = extract_unsigned_integer (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
372
373 return 1;
374 }
375
376 /* Unpack an elf_gregset_t into GDB's register cache. */
377
378 static void
379 mips64_supply_gregset (mips64_elf_gregset_t *gregsetp)
380 {
381 int regi;
382 mips64_elf_greg_t *regp = *gregsetp;
383 char zerobuf[MAX_REGISTER_SIZE];
384
385 memset (zerobuf, 0, MAX_REGISTER_SIZE);
386
387 for (regi = MIPS64_EF_REG0; regi <= MIPS64_EF_REG31; regi++)
388 supply_register ((regi - MIPS64_EF_REG0), (char *)(regp + regi));
389
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));
394
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));
399 supply_register (PS_REGNUM, (char *)(regp + MIPS64_EF_CP0_STATUS));
400 supply_register (mips_regnum (current_gdbarch)->cause,
401 (char *)(regp + MIPS64_EF_CP0_CAUSE));
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
411 static void
412 mips64_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);
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);
427 mips64_fill_gregset (gregsetp, PS_REGNUM);
428 mips64_fill_gregset (gregsetp, mips_regnum (current_gdbarch)->cause);
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
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;
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
464 static void
465 mips64_supply_fpregset (mips64_elf_fpregset_t *fpregsetp)
466 {
467 int regi;
468 char zerobuf[MAX_REGISTER_SIZE];
469
470 memset (zerobuf, 0, MAX_REGISTER_SIZE);
471
472 for (regi = 0; regi < 32; regi++)
473 supply_register (FP0_REGNUM + regi,
474 (char *)(*fpregsetp + regi));
475
476 supply_register (mips_regnum (current_gdbarch)->fp_control_status,
477 (char *)(*fpregsetp + 32));
478
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);
482 }
483
484 /* Likewise, pack one or all floating point registers into an
485 elf_fpregset_t. */
486
487 static void
488 mips64_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 {
494 from = (char *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)];
495 to = (char *) (*fpregsetp + regno - FP0_REGNUM);
496 memcpy (to, from, DEPRECATED_REGISTER_RAW_SIZE (regno - FP0_REGNUM));
497 }
498 else if (regno == mips_regnum (current_gdbarch)->fp_control_status)
499 {
500 from = (char *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)];
501 to = (char *) (*fpregsetp + 32);
502 memcpy (to, from, DEPRECATED_REGISTER_RAW_SIZE (regno));
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);
510 mips64_fill_fpregset(fpregsetp,
511 mips_regnum (current_gdbarch)->fp_control_status);
512 }
513 }
514
515
516 /* Map gdb internal register number to ptrace ``address''.
517 These ``addresses'' are normally defined in <asm/ptrace.h>. */
518
519 static CORE_ADDR
520 mips64_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;
529 else if ((regno >= mips_regnum (current_gdbarch)->fp0)
530 && (regno < mips_regnum (current_gdbarch)->fp0 + 32))
531 regaddr = MIPS64_FPR_BASE + (regno - FP0_REGNUM);
532 else if (regno == mips_regnum (current_gdbarch)->pc)
533 regaddr = MIPS64_PC;
534 else if (regno == mips_regnum (current_gdbarch)->cause)
535 regaddr = MIPS64_CAUSE;
536 else if (regno == mips_regnum (current_gdbarch)->badvaddr)
537 regaddr = MIPS64_BADVADDR;
538 else if (regno == mips_regnum (current_gdbarch)->lo)
539 regaddr = MIPS64_MMLO;
540 else if (regno == mips_regnum (current_gdbarch)->hi)
541 regaddr = MIPS64_MMHI;
542 else if (regno == mips_regnum (current_gdbarch)->fp_control_status)
543 regaddr = MIPS64_FPC_CSR;
544 else if (regno == mips_regnum (current_gdbarch)->fp_implementation_revision)
545 regaddr = MIPS64_FPC_EIR;
546 else
547 error ("Unknowable register number %d.", regno);
548
549 return regaddr;
550 }
551
552 /* Use a local version of this function to get the correct types for
553 regsets, until multi-arch core support is ready. */
554
555 static void
556 fetch_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;
561 mips64_elf_gregset_t gregset64;
562 mips64_elf_fpregset_t fpregset64;
563
564 if (which == 0)
565 {
566 if (core_reg_size == sizeof (gregset))
567 {
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);
575 }
576 else
577 {
578 warning ("wrong size gregset struct in core file");
579 }
580 }
581 else if (which == 2)
582 {
583 if (core_reg_size == sizeof (fpregset))
584 {
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);
592 }
593 else
594 {
595 warning ("wrong size fpregset struct in core file");
596 }
597 }
598 }
599
600 /* Register that we are able to handle ELF file formats using standard
601 procfs "regset" structures. */
602
603 static 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
613 structure for native GNU/Linux MIPS targets using the struct offsets
614 defined in link.h (but without actual reference to that file).
615
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). */
618
619 static struct link_map_offsets *
620 mips64_linux_svr4_fetch_link_map_offsets (void)
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
629 lmo.r_debug_size = 16; /* The actual size is 40 bytes, but
630 this is all we need. */
631 lmo.r_map_offset = 8;
632 lmo.r_map_size = 8;
633
634 lmo.link_map_size = 40;
635
636 lmo.l_addr_offset = 0;
637 lmo.l_addr_size = 8;
638
639 lmo.l_name_offset = 8;
640 lmo.l_name_size = 8;
641
642 lmo.l_next_offset = 24;
643 lmo.l_next_size = 8;
644
645 lmo.l_prev_offset = 32;
646 lmo.l_prev_size = 8;
647 }
648
649 return lmp;
650 }
651
652 /* Handle for obtaining pointer to the current register_addr() function
653 for a given architecture. */
654 static struct gdbarch_data *register_addr_data;
655
656 CORE_ADDR
657 register_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
667 static void
668 set_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
674 static void *
675 init_register_addr_data (struct gdbarch *gdbarch)
676 {
677 return 0;
678 }
679
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
692 static int
693 mips_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
762 int
763 mips_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
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. */
786
787 static CORE_ADDR
788 mips_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
800 static void
801 mips_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
802 {
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 }
833
834 set_gdbarch_skip_solib_resolver (gdbarch, mips_linux_skip_resolver);
835
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. */
838 set_gdbarch_in_solib_call_trampoline (gdbarch, mips_linux_in_dynsym_stub);
839 }
840
841 void
842 _initialize_mips_linux_tdep (void)
843 {
844 const struct bfd_arch_info *arch_info;
845
846 register_addr_data =
847 register_gdbarch_data (init_register_addr_data);
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
857 add_core_fns (&regset_core_fns);
858 }
This page took 0.048761 seconds and 4 git commands to generate.