2004-03-15 Andrew Cagney <cagney@redhat.com>
[platform/upstream/binutils.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   deprecated_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     gdbarch_data_register_post_init (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 }