bfd/
[external/binutils.git] / bfd / elf32-mips.c
1 /* MIPS-specific support for 32-bit ELF
2    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3    2003, 2004, 2005, 2007 Free Software Foundation, Inc.
4
5    Most of the information added by Ian Lance Taylor, Cygnus Support,
6    <ian@cygnus.com>.
7    N32/64 ABI support added by Mark Mitchell, CodeSourcery, LLC.
8    <mark@codesourcery.com>
9    Traditional MIPS targets support added by Koundinya.K, Dansk Data
10    Elektronik & Operations Research Group. <kk@ddeorg.soft.net>
11
12    This file is part of BFD, the Binary File Descriptor library.
13
14    This program is free software; you can redistribute it and/or modify
15    it under the terms of the GNU General Public License as published by
16    the Free Software Foundation; either version 3 of the License, or
17    (at your option) any later version.
18
19    This program is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22    GNU General Public License for more details.
23
24    You should have received a copy of the GNU General Public License
25    along with this program; if not, write to the Free Software
26    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
27    MA 02110-1301, USA.  */
28
29
30 /* This file handles MIPS ELF targets.  SGI Irix 5 uses a slightly
31    different MIPS ELF from other targets.  This matters when linking.
32    This file supports both, switching at runtime.  */
33
34 #include "sysdep.h"
35 #include "bfd.h"
36 #include "libbfd.h"
37 #include "bfdlink.h"
38 #include "genlink.h"
39 #include "elf-bfd.h"
40 #include "elfxx-mips.h"
41 #include "elf/mips.h"
42 #include "elf-vxworks.h"
43
44 /* Get the ECOFF swapping routines.  */
45 #include "coff/sym.h"
46 #include "coff/symconst.h"
47 #include "coff/internal.h"
48 #include "coff/ecoff.h"
49 #include "coff/mips.h"
50 #define ECOFF_SIGNED_32
51 #include "ecoffswap.h"
52
53 static bfd_reloc_status_type gprel32_with_gp
54   (bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma);
55 static bfd_reloc_status_type mips_elf_gprel32_reloc
56   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
57 static bfd_reloc_status_type mips32_64bit_reloc
58   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
59 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
60   (bfd *, bfd_reloc_code_real_type);
61 static reloc_howto_type *mips_elf32_rtype_to_howto
62   (unsigned int, bfd_boolean);
63 static void mips_info_to_howto_rel
64   (bfd *, arelent *, Elf_Internal_Rela *);
65 static void mips_info_to_howto_rela
66   (bfd *, arelent *, Elf_Internal_Rela *);
67 static bfd_boolean mips_elf_sym_is_global
68   (bfd *, asymbol *);
69 static bfd_boolean mips_elf32_object_p
70   (bfd *);
71 static bfd_boolean mips_elf_is_local_label_name
72   (bfd *, const char *);
73 static bfd_reloc_status_type mips16_gprel_reloc
74   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
75 static bfd_reloc_status_type mips_elf_final_gp
76   (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
77 static bfd_boolean mips_elf_assign_gp
78   (bfd *, bfd_vma *);
79 static bfd_boolean elf32_mips_grok_prstatus
80   (bfd *, Elf_Internal_Note *);
81 static bfd_boolean elf32_mips_grok_psinfo
82   (bfd *, Elf_Internal_Note *);
83 static irix_compat_t elf32_mips_irix_compat
84   (bfd *);
85
86 extern const bfd_target bfd_elf32_bigmips_vec;
87 extern const bfd_target bfd_elf32_littlemips_vec;
88
89 /* Nonzero if ABFD is using the N32 ABI.  */
90 #define ABI_N32_P(abfd) \
91   ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
92
93 /* Whether we are trying to be compatible with IRIX at all.  */
94 #define SGI_COMPAT(abfd) \
95   (elf32_mips_irix_compat (abfd) != ict_none)
96
97 /* The number of local .got entries we reserve.  */
98 #define MIPS_RESERVED_GOTNO (2)
99
100 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
101    from smaller values.  Start with zero, widen, *then* decrement.  */
102 #define MINUS_ONE       (((bfd_vma)0) - 1)
103
104 /* The relocation table used for SHT_REL sections.  */
105
106 static reloc_howto_type elf_mips_howto_table_rel[] =
107 {
108   /* No relocation.  */
109   HOWTO (R_MIPS_NONE,           /* type */
110          0,                     /* rightshift */
111          0,                     /* size (0 = byte, 1 = short, 2 = long) */
112          0,                     /* bitsize */
113          FALSE,                 /* pc_relative */
114          0,                     /* bitpos */
115          complain_overflow_dont, /* complain_on_overflow */
116          _bfd_mips_elf_generic_reloc, /* special_function */
117          "R_MIPS_NONE",         /* name */
118          FALSE,                 /* partial_inplace */
119          0,                     /* src_mask */
120          0,                     /* dst_mask */
121          FALSE),                /* pcrel_offset */
122
123   /* 16 bit relocation.  */
124   HOWTO (R_MIPS_16,             /* type */
125          0,                     /* rightshift */
126          2,                     /* size (0 = byte, 1 = short, 2 = long) */
127          16,                    /* bitsize */
128          FALSE,                 /* pc_relative */
129          0,                     /* bitpos */
130          complain_overflow_signed, /* complain_on_overflow */
131          _bfd_mips_elf_generic_reloc, /* special_function */
132          "R_MIPS_16",           /* name */
133          TRUE,                  /* partial_inplace */
134          0x0000ffff,            /* src_mask */
135          0x0000ffff,            /* dst_mask */
136          FALSE),                /* pcrel_offset */
137
138   /* 32 bit relocation.  */
139   HOWTO (R_MIPS_32,             /* type */
140          0,                     /* rightshift */
141          2,                     /* size (0 = byte, 1 = short, 2 = long) */
142          32,                    /* bitsize */
143          FALSE,                 /* pc_relative */
144          0,                     /* bitpos */
145          complain_overflow_dont, /* complain_on_overflow */
146          _bfd_mips_elf_generic_reloc, /* special_function */
147          "R_MIPS_32",           /* name */
148          TRUE,                  /* partial_inplace */
149          0xffffffff,            /* src_mask */
150          0xffffffff,            /* dst_mask */
151          FALSE),                /* pcrel_offset */
152
153   /* 32 bit symbol relative relocation.  */
154   HOWTO (R_MIPS_REL32,          /* type */
155          0,                     /* rightshift */
156          2,                     /* size (0 = byte, 1 = short, 2 = long) */
157          32,                    /* bitsize */
158          FALSE,                 /* pc_relative */
159          0,                     /* bitpos */
160          complain_overflow_dont, /* complain_on_overflow */
161          _bfd_mips_elf_generic_reloc, /* special_function */
162          "R_MIPS_REL32",        /* name */
163          TRUE,                  /* partial_inplace */
164          0xffffffff,            /* src_mask */
165          0xffffffff,            /* dst_mask */
166          FALSE),                /* pcrel_offset */
167
168   /* 26 bit jump address.  */
169   HOWTO (R_MIPS_26,             /* type */
170          2,                     /* rightshift */
171          2,                     /* size (0 = byte, 1 = short, 2 = long) */
172          26,                    /* bitsize */
173          FALSE,                 /* pc_relative */
174          0,                     /* bitpos */
175          complain_overflow_dont, /* complain_on_overflow */
176                                 /* This needs complex overflow
177                                    detection, because the upper four
178                                    bits must match the PC + 4.  */
179          _bfd_mips_elf_generic_reloc, /* special_function */
180          "R_MIPS_26",           /* name */
181          TRUE,                  /* partial_inplace */
182          0x03ffffff,            /* src_mask */
183          0x03ffffff,            /* dst_mask */
184          FALSE),                /* pcrel_offset */
185
186   /* High 16 bits of symbol value.  */
187   HOWTO (R_MIPS_HI16,           /* type */
188          16,                    /* rightshift */
189          2,                     /* size (0 = byte, 1 = short, 2 = long) */
190          16,                    /* bitsize */
191          FALSE,                 /* pc_relative */
192          0,                     /* bitpos */
193          complain_overflow_dont, /* complain_on_overflow */
194          _bfd_mips_elf_hi16_reloc, /* special_function */
195          "R_MIPS_HI16",         /* name */
196          TRUE,                  /* partial_inplace */
197          0x0000ffff,            /* src_mask */
198          0x0000ffff,            /* dst_mask */
199          FALSE),                /* pcrel_offset */
200
201   /* Low 16 bits of symbol value.  */
202   HOWTO (R_MIPS_LO16,           /* type */
203          0,                     /* rightshift */
204          2,                     /* size (0 = byte, 1 = short, 2 = long) */
205          16,                    /* bitsize */
206          FALSE,                 /* pc_relative */
207          0,                     /* bitpos */
208          complain_overflow_dont, /* complain_on_overflow */
209          _bfd_mips_elf_lo16_reloc, /* special_function */
210          "R_MIPS_LO16",         /* name */
211          TRUE,                  /* partial_inplace */
212          0x0000ffff,            /* src_mask */
213          0x0000ffff,            /* dst_mask */
214          FALSE),                /* pcrel_offset */
215
216   /* GP relative reference.  */
217   HOWTO (R_MIPS_GPREL16,        /* type */
218          0,                     /* rightshift */
219          2,                     /* size (0 = byte, 1 = short, 2 = long) */
220          16,                    /* bitsize */
221          FALSE,                 /* pc_relative */
222          0,                     /* bitpos */
223          complain_overflow_signed, /* complain_on_overflow */
224          _bfd_mips_elf32_gprel16_reloc, /* special_function */
225          "R_MIPS_GPREL16",      /* name */
226          TRUE,                  /* partial_inplace */
227          0x0000ffff,            /* src_mask */
228          0x0000ffff,            /* dst_mask */
229          FALSE),                /* pcrel_offset */
230
231   /* Reference to literal section.  */
232   HOWTO (R_MIPS_LITERAL,        /* type */
233          0,                     /* rightshift */
234          2,                     /* size (0 = byte, 1 = short, 2 = long) */
235          16,                    /* bitsize */
236          FALSE,                 /* pc_relative */
237          0,                     /* bitpos */
238          complain_overflow_signed, /* complain_on_overflow */
239          _bfd_mips_elf32_gprel16_reloc, /* special_function */
240          "R_MIPS_LITERAL",      /* name */
241          TRUE,                  /* partial_inplace */
242          0x0000ffff,            /* src_mask */
243          0x0000ffff,            /* dst_mask */
244          FALSE),                /* pcrel_offset */
245
246   /* Reference to global offset table.  */
247   HOWTO (R_MIPS_GOT16,          /* type */
248          0,                     /* rightshift */
249          2,                     /* size (0 = byte, 1 = short, 2 = long) */
250          16,                    /* bitsize */
251          FALSE,                 /* pc_relative */
252          0,                     /* bitpos */
253          complain_overflow_signed, /* complain_on_overflow */
254          _bfd_mips_elf_got16_reloc, /* special_function */
255          "R_MIPS_GOT16",        /* name */
256          TRUE,                  /* partial_inplace */
257          0x0000ffff,            /* src_mask */
258          0x0000ffff,            /* dst_mask */
259          FALSE),                /* pcrel_offset */
260
261   /* 16 bit PC relative reference.  Note that the ABI document has a typo
262      and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
263      We do the right thing here.  */
264   HOWTO (R_MIPS_PC16,           /* type */
265          2,                     /* rightshift */
266          2,                     /* size (0 = byte, 1 = short, 2 = long) */
267          16,                    /* bitsize */
268          TRUE,                  /* pc_relative */
269          0,                     /* bitpos */
270          complain_overflow_signed, /* complain_on_overflow */
271          _bfd_mips_elf_generic_reloc, /* special_function */
272          "R_MIPS_PC16",         /* name */
273          TRUE,                  /* partial_inplace */
274          0x0000ffff,            /* src_mask */
275          0x0000ffff,            /* dst_mask */
276          TRUE),                 /* pcrel_offset */
277
278   /* 16 bit call through global offset table.  */
279   HOWTO (R_MIPS_CALL16,         /* type */
280          0,                     /* rightshift */
281          2,                     /* size (0 = byte, 1 = short, 2 = long) */
282          16,                    /* bitsize */
283          FALSE,                 /* pc_relative */
284          0,                     /* bitpos */
285          complain_overflow_signed, /* complain_on_overflow */
286          _bfd_mips_elf_generic_reloc, /* special_function */
287          "R_MIPS_CALL16",       /* name */
288          TRUE,                  /* partial_inplace */
289          0x0000ffff,            /* src_mask */
290          0x0000ffff,            /* dst_mask */
291          FALSE),                /* pcrel_offset */
292
293   /* 32 bit GP relative reference.  */
294   HOWTO (R_MIPS_GPREL32,        /* type */
295          0,                     /* rightshift */
296          2,                     /* size (0 = byte, 1 = short, 2 = long) */
297          32,                    /* bitsize */
298          FALSE,                 /* pc_relative */
299          0,                     /* bitpos */
300          complain_overflow_dont, /* complain_on_overflow */
301          mips_elf_gprel32_reloc, /* special_function */
302          "R_MIPS_GPREL32",      /* name */
303          TRUE,                  /* partial_inplace */
304          0xffffffff,            /* src_mask */
305          0xffffffff,            /* dst_mask */
306          FALSE),                /* pcrel_offset */
307
308   /* The remaining relocs are defined on Irix 5, although they are
309      not defined by the ABI.  */
310   EMPTY_HOWTO (13),
311   EMPTY_HOWTO (14),
312   EMPTY_HOWTO (15),
313
314   /* A 5 bit shift field.  */
315   HOWTO (R_MIPS_SHIFT5,         /* type */
316          0,                     /* rightshift */
317          2,                     /* size (0 = byte, 1 = short, 2 = long) */
318          5,                     /* bitsize */
319          FALSE,                 /* pc_relative */
320          6,                     /* bitpos */
321          complain_overflow_bitfield, /* complain_on_overflow */
322          _bfd_mips_elf_generic_reloc, /* special_function */
323          "R_MIPS_SHIFT5",       /* name */
324          TRUE,                  /* partial_inplace */
325          0x000007c0,            /* src_mask */
326          0x000007c0,            /* dst_mask */
327          FALSE),                /* pcrel_offset */
328
329   /* A 6 bit shift field.  */
330   /* FIXME: This is not handled correctly; a special function is
331      needed to put the most significant bit in the right place.  */
332   HOWTO (R_MIPS_SHIFT6,         /* type */
333          0,                     /* rightshift */
334          2,                     /* size (0 = byte, 1 = short, 2 = long) */
335          6,                     /* bitsize */
336          FALSE,                 /* pc_relative */
337          6,                     /* bitpos */
338          complain_overflow_bitfield, /* complain_on_overflow */
339          _bfd_mips_elf_generic_reloc, /* special_function */
340          "R_MIPS_SHIFT6",       /* name */
341          TRUE,                  /* partial_inplace */
342          0x000007c4,            /* src_mask */
343          0x000007c4,            /* dst_mask */
344          FALSE),                /* pcrel_offset */
345
346   /* A 64 bit relocation.  */
347   HOWTO (R_MIPS_64,             /* type */
348          0,                     /* rightshift */
349          4,                     /* size (0 = byte, 1 = short, 2 = long) */
350          64,                    /* bitsize */
351          FALSE,                 /* pc_relative */
352          0,                     /* bitpos */
353          complain_overflow_dont, /* complain_on_overflow */
354          mips32_64bit_reloc,    /* special_function */
355          "R_MIPS_64",           /* name */
356          TRUE,                  /* partial_inplace */
357          MINUS_ONE,             /* src_mask */
358          MINUS_ONE,             /* dst_mask */
359          FALSE),                /* pcrel_offset */
360
361   /* Displacement in the global offset table.  */
362   HOWTO (R_MIPS_GOT_DISP,       /* type */
363          0,                     /* rightshift */
364          2,                     /* size (0 = byte, 1 = short, 2 = long) */
365          16,                    /* bitsize */
366          FALSE,                 /* pc_relative */
367          0,                     /* bitpos */
368          complain_overflow_signed, /* complain_on_overflow */
369          _bfd_mips_elf_generic_reloc, /* special_function */
370          "R_MIPS_GOT_DISP",     /* name */
371          TRUE,                  /* partial_inplace */
372          0x0000ffff,            /* src_mask */
373          0x0000ffff,            /* dst_mask */
374          FALSE),                /* pcrel_offset */
375
376   /* Displacement to page pointer in the global offset table.  */
377   HOWTO (R_MIPS_GOT_PAGE,       /* type */
378          0,                     /* rightshift */
379          2,                     /* size (0 = byte, 1 = short, 2 = long) */
380          16,                    /* bitsize */
381          FALSE,                 /* pc_relative */
382          0,                     /* bitpos */
383          complain_overflow_signed, /* complain_on_overflow */
384          _bfd_mips_elf_generic_reloc, /* special_function */
385          "R_MIPS_GOT_PAGE",     /* name */
386          TRUE,                  /* partial_inplace */
387          0x0000ffff,            /* src_mask */
388          0x0000ffff,            /* dst_mask */
389          FALSE),                /* pcrel_offset */
390
391   /* Offset from page pointer in the global offset table.  */
392   HOWTO (R_MIPS_GOT_OFST,       /* type */
393          0,                     /* rightshift */
394          2,                     /* size (0 = byte, 1 = short, 2 = long) */
395          16,                    /* bitsize */
396          FALSE,                 /* pc_relative */
397          0,                     /* bitpos */
398          complain_overflow_signed, /* complain_on_overflow */
399          _bfd_mips_elf_generic_reloc, /* special_function */
400          "R_MIPS_GOT_OFST",     /* name */
401          TRUE,                  /* partial_inplace */
402          0x0000ffff,            /* src_mask */
403          0x0000ffff,            /* dst_mask */
404          FALSE),                /* pcrel_offset */
405
406   /* High 16 bits of displacement in global offset table.  */
407   HOWTO (R_MIPS_GOT_HI16,       /* type */
408          0,                     /* rightshift */
409          2,                     /* size (0 = byte, 1 = short, 2 = long) */
410          16,                    /* bitsize */
411          FALSE,                 /* pc_relative */
412          0,                     /* bitpos */
413          complain_overflow_dont, /* complain_on_overflow */
414          _bfd_mips_elf_generic_reloc, /* special_function */
415          "R_MIPS_GOT_HI16",     /* name */
416          TRUE,                  /* partial_inplace */
417          0x0000ffff,            /* src_mask */
418          0x0000ffff,            /* dst_mask */
419          FALSE),                /* pcrel_offset */
420
421   /* Low 16 bits of displacement in global offset table.  */
422   HOWTO (R_MIPS_GOT_LO16,       /* type */
423          0,                     /* rightshift */
424          2,                     /* size (0 = byte, 1 = short, 2 = long) */
425          16,                    /* bitsize */
426          FALSE,                 /* pc_relative */
427          0,                     /* bitpos */
428          complain_overflow_dont, /* complain_on_overflow */
429          _bfd_mips_elf_generic_reloc, /* special_function */
430          "R_MIPS_GOT_LO16",     /* name */
431          TRUE,                  /* partial_inplace */
432          0x0000ffff,            /* src_mask */
433          0x0000ffff,            /* dst_mask */
434          FALSE),                /* pcrel_offset */
435
436   /* 64 bit subtraction.  Used in the N32 ABI.  */
437   HOWTO (R_MIPS_SUB,            /* type */
438          0,                     /* rightshift */
439          4,                     /* size (0 = byte, 1 = short, 2 = long) */
440          64,                    /* bitsize */
441          FALSE,                 /* pc_relative */
442          0,                     /* bitpos */
443          complain_overflow_dont, /* complain_on_overflow */
444          _bfd_mips_elf_generic_reloc, /* special_function */
445          "R_MIPS_SUB",          /* name */
446          TRUE,                  /* partial_inplace */
447          MINUS_ONE,             /* src_mask */
448          MINUS_ONE,             /* dst_mask */
449          FALSE),                /* pcrel_offset */
450
451   /* Used to cause the linker to insert and delete instructions?  */
452   EMPTY_HOWTO (R_MIPS_INSERT_A),
453   EMPTY_HOWTO (R_MIPS_INSERT_B),
454   EMPTY_HOWTO (R_MIPS_DELETE),
455
456   /* Get the higher value of a 64 bit addend.  */
457   HOWTO (R_MIPS_HIGHER,         /* type */
458          0,                     /* rightshift */
459          2,                     /* size (0 = byte, 1 = short, 2 = long) */
460          16,                    /* bitsize */
461          FALSE,                 /* pc_relative */
462          0,                     /* bitpos */
463          complain_overflow_dont, /* complain_on_overflow */
464          _bfd_mips_elf_generic_reloc, /* special_function */
465          "R_MIPS_HIGHER",       /* name */
466          TRUE,                  /* partial_inplace */
467          0x0000ffff,            /* src_mask */
468          0x0000ffff,            /* dst_mask */
469          FALSE),                /* pcrel_offset */
470
471   /* Get the highest value of a 64 bit addend.  */
472   HOWTO (R_MIPS_HIGHEST,        /* type */
473          0,                     /* rightshift */
474          2,                     /* size (0 = byte, 1 = short, 2 = long) */
475          16,                    /* bitsize */
476          FALSE,                 /* pc_relative */
477          0,                     /* bitpos */
478          complain_overflow_dont, /* complain_on_overflow */
479          _bfd_mips_elf_generic_reloc, /* special_function */
480          "R_MIPS_HIGHEST",      /* name */
481          TRUE,                  /* partial_inplace */
482          0x0000ffff,            /* src_mask */
483          0x0000ffff,            /* dst_mask */
484          FALSE),                /* pcrel_offset */
485
486   /* High 16 bits of displacement in global offset table.  */
487   HOWTO (R_MIPS_CALL_HI16,      /* type */
488          0,                     /* rightshift */
489          2,                     /* size (0 = byte, 1 = short, 2 = long) */
490          16,                    /* bitsize */
491          FALSE,                 /* pc_relative */
492          0,                     /* bitpos */
493          complain_overflow_dont, /* complain_on_overflow */
494          _bfd_mips_elf_generic_reloc, /* special_function */
495          "R_MIPS_CALL_HI16",    /* name */
496          TRUE,                  /* partial_inplace */
497          0x0000ffff,            /* src_mask */
498          0x0000ffff,            /* dst_mask */
499          FALSE),                /* pcrel_offset */
500
501   /* Low 16 bits of displacement in global offset table.  */
502   HOWTO (R_MIPS_CALL_LO16,      /* type */
503          0,                     /* rightshift */
504          2,                     /* size (0 = byte, 1 = short, 2 = long) */
505          16,                    /* bitsize */
506          FALSE,                 /* pc_relative */
507          0,                     /* bitpos */
508          complain_overflow_dont, /* complain_on_overflow */
509          _bfd_mips_elf_generic_reloc, /* special_function */
510          "R_MIPS_CALL_LO16",    /* name */
511          TRUE,                  /* partial_inplace */
512          0x0000ffff,            /* src_mask */
513          0x0000ffff,            /* dst_mask */
514          FALSE),                /* pcrel_offset */
515
516   /* Section displacement.  */
517   HOWTO (R_MIPS_SCN_DISP,       /* type */
518          0,                     /* rightshift */
519          2,                     /* size (0 = byte, 1 = short, 2 = long) */
520          32,                    /* bitsize */
521          FALSE,                 /* pc_relative */
522          0,                     /* bitpos */
523          complain_overflow_dont, /* complain_on_overflow */
524          _bfd_mips_elf_generic_reloc, /* special_function */
525          "R_MIPS_SCN_DISP",     /* name */
526          TRUE,                  /* partial_inplace */
527          0xffffffff,            /* src_mask */
528          0xffffffff,            /* dst_mask */
529          FALSE),                /* pcrel_offset */
530
531   EMPTY_HOWTO (R_MIPS_REL16),
532   EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
533   EMPTY_HOWTO (R_MIPS_PJUMP),
534   EMPTY_HOWTO (R_MIPS_RELGOT),
535
536   /* Protected jump conversion.  This is an optimization hint.  No
537      relocation is required for correctness.  */
538   HOWTO (R_MIPS_JALR,           /* type */
539          0,                     /* rightshift */
540          2,                     /* size (0 = byte, 1 = short, 2 = long) */
541          32,                    /* bitsize */
542          FALSE,                 /* pc_relative */
543          0,                     /* bitpos */
544          complain_overflow_dont, /* complain_on_overflow */
545          _bfd_mips_elf_generic_reloc, /* special_function */
546          "R_MIPS_JALR",         /* name */
547          FALSE,                 /* partial_inplace */
548          0x00000000,            /* src_mask */
549          0x00000000,            /* dst_mask */
550          FALSE),                /* pcrel_offset */
551
552   /* TLS GD/LD dynamic relocations.  */
553   HOWTO (R_MIPS_TLS_DTPMOD32,   /* type */
554          0,                     /* rightshift */
555          2,                     /* size (0 = byte, 1 = short, 2 = long) */
556          32,                    /* bitsize */
557          FALSE,                 /* pc_relative */
558          0,                     /* bitpos */
559          complain_overflow_dont, /* complain_on_overflow */
560          _bfd_mips_elf_generic_reloc, /* special_function */
561          "R_MIPS_TLS_DTPMOD32", /* name */
562          TRUE,                  /* partial_inplace */
563          0xffffffff,            /* src_mask */
564          0xffffffff,            /* dst_mask */
565          FALSE),                /* pcrel_offset */
566
567   HOWTO (R_MIPS_TLS_DTPREL32,   /* type */
568          0,                     /* rightshift */
569          2,                     /* size (0 = byte, 1 = short, 2 = long) */
570          32,                    /* bitsize */
571          FALSE,                 /* pc_relative */
572          0,                     /* bitpos */
573          complain_overflow_dont, /* complain_on_overflow */
574          _bfd_mips_elf_generic_reloc, /* special_function */
575          "R_MIPS_TLS_DTPREL32", /* name */
576          TRUE,                  /* partial_inplace */
577          0xffffffff,            /* src_mask */
578          0xffffffff,            /* dst_mask */
579          FALSE),                /* pcrel_offset */
580
581   EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
582   EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
583
584   /* TLS general dynamic variable reference.  */
585   HOWTO (R_MIPS_TLS_GD,         /* type */
586          0,                     /* rightshift */
587          2,                     /* size (0 = byte, 1 = short, 2 = long) */
588          16,                    /* bitsize */
589          FALSE,                 /* pc_relative */
590          0,                     /* bitpos */
591          complain_overflow_signed, /* complain_on_overflow */
592          _bfd_mips_elf_generic_reloc, /* special_function */
593          "R_MIPS_TLS_GD",       /* name */
594          TRUE,                  /* partial_inplace */
595          0x0000ffff,            /* src_mask */
596          0x0000ffff,            /* dst_mask */
597          FALSE),                /* pcrel_offset */
598
599   /* TLS local dynamic variable reference.  */
600   HOWTO (R_MIPS_TLS_LDM,        /* type */
601          0,                     /* rightshift */
602          2,                     /* size (0 = byte, 1 = short, 2 = long) */
603          16,                    /* bitsize */
604          FALSE,                 /* pc_relative */
605          0,                     /* bitpos */
606          complain_overflow_signed, /* complain_on_overflow */
607          _bfd_mips_elf_generic_reloc, /* special_function */
608          "R_MIPS_TLS_LDM",      /* name */
609          TRUE,                  /* partial_inplace */
610          0x0000ffff,            /* src_mask */
611          0x0000ffff,            /* dst_mask */
612          FALSE),                /* pcrel_offset */
613
614   /* TLS local dynamic offset.  */
615   HOWTO (R_MIPS_TLS_DTPREL_HI16,        /* type */
616          0,                     /* rightshift */
617          2,                     /* size (0 = byte, 1 = short, 2 = long) */
618          16,                    /* bitsize */
619          FALSE,                 /* pc_relative */
620          0,                     /* bitpos */
621          complain_overflow_signed, /* complain_on_overflow */
622          _bfd_mips_elf_generic_reloc, /* special_function */
623          "R_MIPS_TLS_DTPREL_HI16",      /* name */
624          TRUE,                  /* partial_inplace */
625          0x0000ffff,            /* src_mask */
626          0x0000ffff,            /* dst_mask */
627          FALSE),                /* pcrel_offset */
628
629   /* TLS local dynamic offset.  */
630   HOWTO (R_MIPS_TLS_DTPREL_LO16,        /* type */
631          0,                     /* rightshift */
632          2,                     /* size (0 = byte, 1 = short, 2 = long) */
633          16,                    /* bitsize */
634          FALSE,                 /* pc_relative */
635          0,                     /* bitpos */
636          complain_overflow_signed, /* complain_on_overflow */
637          _bfd_mips_elf_generic_reloc, /* special_function */
638          "R_MIPS_TLS_DTPREL_LO16",      /* name */
639          TRUE,                  /* partial_inplace */
640          0x0000ffff,            /* src_mask */
641          0x0000ffff,            /* dst_mask */
642          FALSE),                /* pcrel_offset */
643
644   /* TLS thread pointer offset.  */
645   HOWTO (R_MIPS_TLS_GOTTPREL,   /* type */
646          0,                     /* rightshift */
647          2,                     /* size (0 = byte, 1 = short, 2 = long) */
648          16,                    /* bitsize */
649          FALSE,                 /* pc_relative */
650          0,                     /* bitpos */
651          complain_overflow_signed, /* complain_on_overflow */
652          _bfd_mips_elf_generic_reloc, /* special_function */
653          "R_MIPS_TLS_GOTTPREL", /* name */
654          TRUE,                  /* partial_inplace */
655          0x0000ffff,            /* src_mask */
656          0x0000ffff,            /* dst_mask */
657          FALSE),                /* pcrel_offset */
658
659   /* TLS IE dynamic relocations.  */
660   HOWTO (R_MIPS_TLS_TPREL32,    /* type */
661          0,                     /* rightshift */
662          2,                     /* size (0 = byte, 1 = short, 2 = long) */
663          32,                    /* bitsize */
664          FALSE,                 /* pc_relative */
665          0,                     /* bitpos */
666          complain_overflow_dont, /* complain_on_overflow */
667          _bfd_mips_elf_generic_reloc, /* special_function */
668          "R_MIPS_TLS_TPREL32",  /* name */
669          TRUE,                  /* partial_inplace */
670          0xffffffff,            /* src_mask */
671          0xffffffff,            /* dst_mask */
672          FALSE),                /* pcrel_offset */
673
674   EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
675
676   /* TLS thread pointer offset.  */
677   HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
678          0,                     /* rightshift */
679          2,                     /* size (0 = byte, 1 = short, 2 = long) */
680          16,                    /* bitsize */
681          FALSE,                 /* pc_relative */
682          0,                     /* bitpos */
683          complain_overflow_signed, /* complain_on_overflow */
684          _bfd_mips_elf_generic_reloc, /* special_function */
685          "R_MIPS_TLS_TPREL_HI16", /* name */
686          TRUE,                  /* partial_inplace */
687          0x0000ffff,            /* src_mask */
688          0x0000ffff,            /* dst_mask */
689          FALSE),                /* pcrel_offset */
690
691   /* TLS thread pointer offset.  */
692   HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
693          0,                     /* rightshift */
694          2,                     /* size (0 = byte, 1 = short, 2 = long) */
695          16,                    /* bitsize */
696          FALSE,                 /* pc_relative */
697          0,                     /* bitpos */
698          complain_overflow_signed, /* complain_on_overflow */
699          _bfd_mips_elf_generic_reloc, /* special_function */
700          "R_MIPS_TLS_TPREL_LO16", /* name */
701          TRUE,                  /* partial_inplace */
702          0x0000ffff,            /* src_mask */
703          0x0000ffff,            /* dst_mask */
704          FALSE),                /* pcrel_offset */
705
706   /* 32 bit relocation with no addend.  */
707   HOWTO (R_MIPS_GLOB_DAT,       /* type */
708          0,                     /* rightshift */
709          2,                     /* size (0 = byte, 1 = short, 2 = long) */
710          32,                    /* bitsize */
711          FALSE,                 /* pc_relative */
712          0,                     /* bitpos */
713          complain_overflow_dont, /* complain_on_overflow */
714          _bfd_mips_elf_generic_reloc, /* special_function */
715          "R_MIPS_GLOB_DAT",     /* name */
716          FALSE,                 /* partial_inplace */
717          0x0,                   /* src_mask */
718          0xffffffff,            /* dst_mask */
719          FALSE),                /* pcrel_offset */
720 };
721
722 /* The reloc used for BFD_RELOC_CTOR when doing a 64 bit link.  This
723    is a hack to make the linker think that we need 64 bit values.  */
724 static reloc_howto_type elf_mips_ctor64_howto =
725   HOWTO (R_MIPS_64,             /* type */
726          0,                     /* rightshift */
727          4,                     /* size (0 = byte, 1 = short, 2 = long) */
728          32,                    /* bitsize */
729          FALSE,                 /* pc_relative */
730          0,                     /* bitpos */
731          complain_overflow_signed, /* complain_on_overflow */
732          mips32_64bit_reloc,    /* special_function */
733          "R_MIPS_64",           /* name */
734          TRUE,                  /* partial_inplace */
735          0xffffffff,            /* src_mask */
736          0xffffffff,            /* dst_mask */
737          FALSE);                /* pcrel_offset */
738
739 static reloc_howto_type elf_mips16_howto_table_rel[] =
740 {
741   /* The reloc used for the mips16 jump instruction.  */
742   HOWTO (R_MIPS16_26,           /* type */
743          2,                     /* rightshift */
744          2,                     /* size (0 = byte, 1 = short, 2 = long) */
745          26,                    /* bitsize */
746          FALSE,                 /* pc_relative */
747          0,                     /* bitpos */
748          complain_overflow_dont, /* complain_on_overflow */
749                                 /* This needs complex overflow
750                                    detection, because the upper four
751                                    bits must match the PC.  */
752          _bfd_mips_elf_generic_reloc, /* special_function */
753          "R_MIPS16_26",         /* name */
754          TRUE,                  /* partial_inplace */
755          0x3ffffff,             /* src_mask */
756          0x3ffffff,             /* dst_mask */
757          FALSE),                /* pcrel_offset */
758
759   /* The reloc used for the mips16 gprel instruction.  */
760   HOWTO (R_MIPS16_GPREL,        /* type */
761          0,                     /* rightshift */
762          2,                     /* size (0 = byte, 1 = short, 2 = long) */
763          16,                    /* bitsize */
764          FALSE,                 /* pc_relative */
765          0,                     /* bitpos */
766          complain_overflow_signed, /* complain_on_overflow */
767          mips16_gprel_reloc,    /* special_function */
768          "R_MIPS16_GPREL",      /* name */
769          TRUE,                  /* partial_inplace */
770          0x0000ffff,            /* src_mask */
771          0x0000ffff,            /* dst_mask */
772          FALSE),                /* pcrel_offset */
773
774   /* A MIPS16 reference to the global offset table.  */
775   HOWTO (R_MIPS16_GOT16,        /* type */
776          0,                     /* rightshift */
777          2,                     /* size (0 = byte, 1 = short, 2 = long) */
778          16,                    /* bitsize */
779          FALSE,                 /* pc_relative */
780          0,                     /* bitpos */
781          complain_overflow_dont, /* complain_on_overflow */
782          _bfd_mips_elf_got16_reloc, /* special_function */
783          "R_MIPS16_GOT16",      /* name */
784          TRUE,                  /* partial_inplace */
785          0x0000ffff,            /* src_mask */
786          0x0000ffff,            /* dst_mask */
787          FALSE),                /* pcrel_offset */
788
789   /* A MIPS16 call through the global offset table.  */
790   HOWTO (R_MIPS16_CALL16,       /* type */
791          0,                     /* rightshift */
792          2,                     /* size (0 = byte, 1 = short, 2 = long) */
793          16,                    /* bitsize */
794          FALSE,                 /* pc_relative */
795          0,                     /* bitpos */
796          complain_overflow_dont, /* complain_on_overflow */
797          _bfd_mips_elf_generic_reloc, /* special_function */
798          "R_MIPS16_CALL16",     /* name */
799          TRUE,                  /* partial_inplace */
800          0x0000ffff,            /* src_mask */
801          0x0000ffff,            /* dst_mask */
802          FALSE),                /* pcrel_offset */
803
804   /* MIPS16 high 16 bits of symbol value.  */
805   HOWTO (R_MIPS16_HI16,         /* type */
806          16,                    /* rightshift */
807          2,                     /* size (0 = byte, 1 = short, 2 = long) */
808          16,                    /* bitsize */
809          FALSE,                 /* pc_relative */
810          0,                     /* bitpos */
811          complain_overflow_dont, /* complain_on_overflow */
812          _bfd_mips_elf_hi16_reloc, /* special_function */
813          "R_MIPS16_HI16",       /* name */
814          TRUE,                  /* partial_inplace */
815          0x0000ffff,            /* src_mask */
816          0x0000ffff,            /* dst_mask */
817          FALSE),                /* pcrel_offset */
818
819   /* MIPS16 low 16 bits of symbol value.  */
820   HOWTO (R_MIPS16_LO16,         /* type */
821          0,                     /* rightshift */
822          2,                     /* size (0 = byte, 1 = short, 2 = long) */
823          16,                    /* bitsize */
824          FALSE,                 /* pc_relative */
825          0,                     /* bitpos */
826          complain_overflow_dont, /* complain_on_overflow */
827          _bfd_mips_elf_lo16_reloc, /* special_function */
828          "R_MIPS16_LO16",       /* name */
829          TRUE,                  /* partial_inplace */
830          0x0000ffff,            /* src_mask */
831          0x0000ffff,            /* dst_mask */
832          FALSE),                /* pcrel_offset */
833 };
834
835 /* 16 bit offset for pc-relative branches.  */
836 static reloc_howto_type elf_mips_gnu_rel16_s2 =
837   HOWTO (R_MIPS_GNU_REL16_S2,   /* type */
838          2,                     /* rightshift */
839          2,                     /* size (0 = byte, 1 = short, 2 = long) */
840          16,                    /* bitsize */
841          TRUE,                  /* pc_relative */
842          0,                     /* bitpos */
843          complain_overflow_signed, /* complain_on_overflow */
844          _bfd_mips_elf_generic_reloc, /* special_function */
845          "R_MIPS_GNU_REL16_S2", /* name */
846          TRUE,                  /* partial_inplace */
847          0xffff,                /* src_mask */
848          0xffff,                /* dst_mask */
849          TRUE);                 /* pcrel_offset */
850
851 /* 32 bit pc-relative.  This was a GNU extension used by embedded-PIC.
852    It was co-opted by mips-linux for exception-handling data.  It is no
853    longer used, but should continue to be supported by the linker for
854    backward compatibility.  (GCC stopped using it in May, 2004.)  */
855 static reloc_howto_type elf_mips_gnu_pcrel32 =
856   HOWTO (R_MIPS_PC32,           /* type */
857          0,                     /* rightshift */
858          2,                     /* size (0 = byte, 1 = short, 2 = long) */
859          32,                    /* bitsize */
860          TRUE,                  /* pc_relative */
861          0,                     /* bitpos */
862          complain_overflow_signed, /* complain_on_overflow */
863          _bfd_mips_elf_generic_reloc, /* special_function */
864          "R_MIPS_PC32",         /* name */
865          TRUE,                  /* partial_inplace */
866          0xffffffff,            /* src_mask */
867          0xffffffff,            /* dst_mask */
868          TRUE);                 /* pcrel_offset */
869
870 /* GNU extension to record C++ vtable hierarchy */
871 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
872   HOWTO (R_MIPS_GNU_VTINHERIT,  /* type */
873          0,                     /* rightshift */
874          2,                     /* size (0 = byte, 1 = short, 2 = long) */
875          0,                     /* bitsize */
876          FALSE,                 /* pc_relative */
877          0,                     /* bitpos */
878          complain_overflow_dont, /* complain_on_overflow */
879          NULL,                  /* special_function */
880          "R_MIPS_GNU_VTINHERIT", /* name */
881          FALSE,                 /* partial_inplace */
882          0,                     /* src_mask */
883          0,                     /* dst_mask */
884          FALSE);                /* pcrel_offset */
885
886 /* GNU extension to record C++ vtable member usage */
887 static reloc_howto_type elf_mips_gnu_vtentry_howto =
888   HOWTO (R_MIPS_GNU_VTENTRY,    /* type */
889          0,                     /* rightshift */
890          2,                     /* size (0 = byte, 1 = short, 2 = long) */
891          0,                     /* bitsize */
892          FALSE,                 /* pc_relative */
893          0,                     /* bitpos */
894          complain_overflow_dont, /* complain_on_overflow */
895          _bfd_elf_rel_vtable_reloc_fn, /* special_function */
896          "R_MIPS_GNU_VTENTRY",  /* name */
897          FALSE,                 /* partial_inplace */
898          0,                     /* src_mask */
899          0,                     /* dst_mask */
900          FALSE);                /* pcrel_offset */
901
902 /* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
903    dangerous relocation.  */
904
905 static bfd_boolean
906 mips_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
907 {
908   unsigned int count;
909   asymbol **sym;
910   unsigned int i;
911
912   /* If we've already figured out what GP will be, just return it.  */
913   *pgp = _bfd_get_gp_value (output_bfd);
914   if (*pgp)
915     return TRUE;
916
917   count = bfd_get_symcount (output_bfd);
918   sym = bfd_get_outsymbols (output_bfd);
919
920   /* The linker script will have created a symbol named `_gp' with the
921      appropriate value.  */
922   if (sym == NULL)
923     i = count;
924   else
925     {
926       for (i = 0; i < count; i++, sym++)
927         {
928           register const char *name;
929
930           name = bfd_asymbol_name (*sym);
931           if (*name == '_' && strcmp (name, "_gp") == 0)
932             {
933               *pgp = bfd_asymbol_value (*sym);
934               _bfd_set_gp_value (output_bfd, *pgp);
935               break;
936             }
937         }
938     }
939
940   if (i >= count)
941     {
942       /* Only get the error once.  */
943       *pgp = 4;
944       _bfd_set_gp_value (output_bfd, *pgp);
945       return FALSE;
946     }
947
948   return TRUE;
949 }
950
951 /* We have to figure out the gp value, so that we can adjust the
952    symbol value correctly.  We look up the symbol _gp in the output
953    BFD.  If we can't find it, we're stuck.  We cache it in the ELF
954    target data.  We don't need to adjust the symbol value for an
955    external symbol if we are producing relocatable output.  */
956
957 static bfd_reloc_status_type
958 mips_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
959                    char **error_message, bfd_vma *pgp)
960 {
961   if (bfd_is_und_section (symbol->section)
962       && ! relocatable)
963     {
964       *pgp = 0;
965       return bfd_reloc_undefined;
966     }
967
968   *pgp = _bfd_get_gp_value (output_bfd);
969   if (*pgp == 0
970       && (! relocatable
971           || (symbol->flags & BSF_SECTION_SYM) != 0))
972     {
973       if (relocatable)
974         {
975           /* Make up a value.  */
976           *pgp = symbol->section->output_section->vma + 0x4000;
977           _bfd_set_gp_value (output_bfd, *pgp);
978         }
979       else if (!mips_elf_assign_gp (output_bfd, pgp))
980         {
981           *error_message =
982             (char *) _("GP relative relocation when _gp not defined");
983           return bfd_reloc_dangerous;
984         }
985     }
986
987   return bfd_reloc_ok;
988 }
989
990 /* Do a R_MIPS_GPREL16 relocation.  This is a 16 bit value which must
991    become the offset from the gp register.  This function also handles
992    R_MIPS_LITERAL relocations, although those can be handled more
993    cleverly because the entries in the .lit8 and .lit4 sections can be
994    merged.  */
995
996 bfd_reloc_status_type
997 _bfd_mips_elf32_gprel16_reloc (bfd *abfd, arelent *reloc_entry,
998                                asymbol *symbol, void *data,
999                                asection *input_section, bfd *output_bfd,
1000                                char **error_message)
1001 {
1002   bfd_boolean relocatable;
1003   bfd_reloc_status_type ret;
1004   bfd_vma gp;
1005
1006   /* R_MIPS_LITERAL relocations are defined for local symbols only.  */
1007   if (reloc_entry->howto->type == R_MIPS_LITERAL
1008       && output_bfd != NULL
1009       && (symbol->flags & BSF_SECTION_SYM) == 0
1010       && (symbol->flags & BSF_LOCAL) != 0)
1011     {
1012       *error_message = (char *)
1013         _("literal relocation occurs for an external symbol");
1014       return bfd_reloc_outofrange;
1015     }
1016
1017   if (output_bfd != NULL)
1018     relocatable = TRUE;
1019   else
1020     {
1021       relocatable = FALSE;
1022       output_bfd = symbol->section->output_section->owner;
1023     }
1024
1025   ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
1026                            &gp);
1027   if (ret != bfd_reloc_ok)
1028     return ret;
1029
1030   return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1031                                         input_section, relocatable,
1032                                         data, gp);
1033 }
1034
1035 /* Do a R_MIPS_GPREL32 relocation.  This is a 32 bit value which must
1036    become the offset from the gp register.  */
1037
1038 static bfd_reloc_status_type
1039 mips_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1040                         void *data, asection *input_section, bfd *output_bfd,
1041                         char **error_message)
1042 {
1043   bfd_boolean relocatable;
1044   bfd_reloc_status_type ret;
1045   bfd_vma gp;
1046
1047   /* R_MIPS_GPREL32 relocations are defined for local symbols only.  */
1048   if (output_bfd != NULL
1049       && (symbol->flags & BSF_SECTION_SYM) == 0
1050       && (symbol->flags & BSF_LOCAL) != 0)
1051     {
1052       *error_message = (char *)
1053         _("32bits gp relative relocation occurs for an external symbol");
1054       return bfd_reloc_outofrange;
1055     }
1056
1057   if (output_bfd != NULL)
1058     relocatable = TRUE;
1059   else
1060     {
1061       relocatable = FALSE;
1062       output_bfd = symbol->section->output_section->owner;
1063     }
1064
1065   ret = mips_elf_final_gp (output_bfd, symbol, relocatable,
1066                            error_message, &gp);
1067   if (ret != bfd_reloc_ok)
1068     return ret;
1069
1070   return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
1071                           relocatable, data, gp);
1072 }
1073
1074 static bfd_reloc_status_type
1075 gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
1076                  asection *input_section, bfd_boolean relocatable,
1077                  void *data, bfd_vma gp)
1078 {
1079   bfd_vma relocation;
1080   bfd_vma val;
1081
1082   if (bfd_is_com_section (symbol->section))
1083     relocation = 0;
1084   else
1085     relocation = symbol->value;
1086
1087   relocation += symbol->section->output_section->vma;
1088   relocation += symbol->section->output_offset;
1089
1090   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
1091     return bfd_reloc_outofrange;
1092
1093   /* Set val to the offset into the section or symbol.  */
1094   val = reloc_entry->addend;
1095
1096   if (reloc_entry->howto->partial_inplace)
1097     val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1098
1099   /* Adjust val for the final section location and GP value.  If we
1100      are producing relocatable output, we don't want to do this for
1101      an external symbol.  */
1102   if (! relocatable
1103       || (symbol->flags & BSF_SECTION_SYM) != 0)
1104     val += relocation - gp;
1105
1106   if (reloc_entry->howto->partial_inplace)
1107     bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
1108   else
1109     reloc_entry->addend = val;
1110
1111   if (relocatable)
1112     reloc_entry->address += input_section->output_offset;
1113
1114   return bfd_reloc_ok;
1115 }
1116
1117 /* Handle a 64 bit reloc in a 32 bit MIPS ELF file.  These are
1118    generated when addresses are 64 bits.  The upper 32 bits are a simple
1119    sign extension.  */
1120
1121 static bfd_reloc_status_type
1122 mips32_64bit_reloc (bfd *abfd, arelent *reloc_entry,
1123                     asymbol *symbol ATTRIBUTE_UNUSED,
1124                     void *data, asection *input_section,
1125                     bfd *output_bfd, char **error_message)
1126 {
1127   bfd_reloc_status_type r;
1128   arelent reloc32;
1129   unsigned long val;
1130   bfd_size_type addr;
1131
1132   /* Do a normal 32 bit relocation on the lower 32 bits.  */
1133   reloc32 = *reloc_entry;
1134   if (bfd_big_endian (abfd))
1135     reloc32.address += 4;
1136   reloc32.howto = &elf_mips_howto_table_rel[R_MIPS_32];
1137   r = bfd_perform_relocation (abfd, &reloc32, data, input_section,
1138                               output_bfd, error_message);
1139
1140   /* Sign extend into the upper 32 bits.  */
1141   val = bfd_get_32 (abfd, (bfd_byte *) data + reloc32.address);
1142   if ((val & 0x80000000) != 0)
1143     val = 0xffffffff;
1144   else
1145     val = 0;
1146   addr = reloc_entry->address;
1147   if (bfd_little_endian (abfd))
1148     addr += 4;
1149   bfd_put_32 (abfd, val, (bfd_byte *) data + addr);
1150
1151   return r;
1152 }
1153
1154 /* Handle a mips16 GP relative reloc.  */
1155
1156 static bfd_reloc_status_type
1157 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1158                     void *data, asection *input_section, bfd *output_bfd,
1159                     char **error_message)
1160 {
1161   bfd_boolean relocatable;
1162   bfd_reloc_status_type ret;
1163   bfd_byte *location;
1164   bfd_vma gp;
1165
1166   /* If we're relocating, and this is an external symbol, we don't want
1167      to change anything.  */
1168   if (output_bfd != NULL
1169       && (symbol->flags & BSF_SECTION_SYM) == 0
1170       && (symbol->flags & BSF_LOCAL) != 0)
1171     {
1172       reloc_entry->address += input_section->output_offset;
1173       return bfd_reloc_ok;
1174     }
1175
1176   if (output_bfd != NULL)
1177     relocatable = TRUE;
1178   else
1179     {
1180       relocatable = FALSE;
1181       output_bfd = symbol->section->output_section->owner;
1182     }
1183
1184   ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
1185                            &gp);
1186   if (ret != bfd_reloc_ok)
1187     return ret;
1188
1189   location = (bfd_byte *) data + reloc_entry->address;
1190   _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
1191                                    location);
1192   ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1193                                        input_section, relocatable,
1194                                        data, gp);
1195   _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
1196                                  location);
1197
1198   return ret;
1199 }
1200
1201 /* A mapping from BFD reloc types to MIPS ELF reloc types.  */
1202
1203 struct elf_reloc_map {
1204   bfd_reloc_code_real_type bfd_val;
1205   enum elf_mips_reloc_type elf_val;
1206 };
1207
1208 static const struct elf_reloc_map mips_reloc_map[] =
1209 {
1210   { BFD_RELOC_NONE, R_MIPS_NONE },
1211   { BFD_RELOC_16, R_MIPS_16 },
1212   { BFD_RELOC_32, R_MIPS_32 },
1213   /* There is no BFD reloc for R_MIPS_REL32.  */
1214   { BFD_RELOC_64, R_MIPS_64 },
1215   { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1216   { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1217   { BFD_RELOC_LO16, R_MIPS_LO16 },
1218   { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
1219   { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1220   { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
1221   { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
1222   { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
1223   { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
1224   { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1225   { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1226   { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
1227   { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1228   { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1229   { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1230   { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
1231   { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
1232   { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
1233   { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
1234   { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
1235   { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
1236   { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
1237   { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
1238   { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
1239   { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
1240   { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
1241   { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
1242   { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
1243   { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
1244   { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
1245 };
1246
1247 static const struct elf_reloc_map mips16_reloc_map[] =
1248 {
1249   { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
1250   { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
1251   { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
1252   { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
1253   { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
1254   { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
1255 };
1256
1257 /* Given a BFD reloc type, return a howto structure.  */
1258
1259 static reloc_howto_type *
1260 bfd_elf32_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
1261 {
1262   unsigned int i;
1263   reloc_howto_type *howto_table = elf_mips_howto_table_rel;
1264   reloc_howto_type *howto16_table = elf_mips16_howto_table_rel;
1265
1266   for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
1267        i++)
1268     {
1269       if (mips_reloc_map[i].bfd_val == code)
1270         return &howto_table[(int) mips_reloc_map[i].elf_val];
1271     }
1272
1273   for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
1274        i++)
1275     {
1276       if (mips16_reloc_map[i].bfd_val == code)
1277         return &howto16_table[(int) mips16_reloc_map[i].elf_val];
1278     }
1279
1280   switch (code)
1281     {
1282     default:
1283       bfd_set_error (bfd_error_bad_value);
1284       return NULL;
1285
1286     case BFD_RELOC_CTOR:
1287       /* We need to handle BFD_RELOC_CTOR specially.
1288          Select the right relocation (R_MIPS_32 or R_MIPS_64) based on the
1289          size of addresses of the ABI.  */
1290       if ((elf_elfheader (abfd)->e_flags & (E_MIPS_ABI_O64
1291                                             | E_MIPS_ABI_EABI64)) != 0)
1292         return &elf_mips_ctor64_howto;
1293       else
1294         return &howto_table[(int) R_MIPS_32];
1295
1296     case BFD_RELOC_VTABLE_INHERIT:
1297       return &elf_mips_gnu_vtinherit_howto;
1298     case BFD_RELOC_VTABLE_ENTRY:
1299       return &elf_mips_gnu_vtentry_howto;
1300     case BFD_RELOC_32_PCREL:
1301       return &elf_mips_gnu_pcrel32;
1302     }
1303 }
1304
1305 static reloc_howto_type *
1306 bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1307                                  const char *r_name)
1308 {
1309   unsigned int i;
1310
1311   for (i = 0;
1312        i < (sizeof (elf_mips_howto_table_rel)
1313             / sizeof (elf_mips_howto_table_rel[0]));
1314        i++)
1315     if (elf_mips_howto_table_rel[i].name != NULL
1316         && strcasecmp (elf_mips_howto_table_rel[i].name, r_name) == 0)
1317       return &elf_mips_howto_table_rel[i];
1318
1319   for (i = 0;
1320        i < (sizeof (elf_mips16_howto_table_rel)
1321             / sizeof (elf_mips16_howto_table_rel[0]));
1322        i++)
1323     if (elf_mips16_howto_table_rel[i].name != NULL
1324         && strcasecmp (elf_mips16_howto_table_rel[i].name, r_name) == 0)
1325       return &elf_mips16_howto_table_rel[i];
1326
1327   if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
1328     return &elf_mips_gnu_pcrel32;
1329   if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
1330     return &elf_mips_gnu_rel16_s2;
1331   if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
1332     return &elf_mips_gnu_vtinherit_howto;
1333   if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
1334     return &elf_mips_gnu_vtentry_howto;
1335
1336   return NULL;
1337 }
1338
1339 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
1340
1341 static reloc_howto_type *
1342 mips_elf32_rtype_to_howto (unsigned int r_type,
1343                            bfd_boolean rela_p ATTRIBUTE_UNUSED)
1344 {
1345   switch (r_type)
1346     {
1347     case R_MIPS_GNU_VTINHERIT:
1348       return &elf_mips_gnu_vtinherit_howto;
1349     case R_MIPS_GNU_VTENTRY:
1350       return &elf_mips_gnu_vtentry_howto;
1351     case R_MIPS_GNU_REL16_S2:
1352       return &elf_mips_gnu_rel16_s2;
1353     case R_MIPS_PC32:
1354       return &elf_mips_gnu_pcrel32;
1355     default:
1356       if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
1357         return &elf_mips16_howto_table_rel[r_type - R_MIPS16_min];
1358       BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
1359       return &elf_mips_howto_table_rel[r_type];
1360     }
1361 }
1362
1363 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
1364
1365 static void
1366 mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
1367 {
1368   const struct elf_backend_data *bed;
1369   unsigned int r_type;
1370
1371   r_type = ELF32_R_TYPE (dst->r_info);
1372   bed = get_elf_backend_data (abfd);
1373   cache_ptr->howto = bed->elf_backend_mips_rtype_to_howto (r_type, FALSE);
1374
1375   /* The addend for a GPREL16 or LITERAL relocation comes from the GP
1376      value for the object file.  We get the addend now, rather than
1377      when we do the relocation, because the symbol manipulations done
1378      by the linker may cause us to lose track of the input BFD.  */
1379   if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
1380       && (r_type == (unsigned int) R_MIPS_GPREL16
1381           || r_type == (unsigned int) R_MIPS_LITERAL))
1382     cache_ptr->addend = elf_gp (abfd);
1383 }
1384
1385 /* Given a MIPS Elf_Internal_Rela, fill in an arelent structure.  */
1386
1387 static void
1388 mips_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
1389 {
1390   mips_info_to_howto_rel (abfd, cache_ptr, dst);
1391
1392   /* If we ever need to do any extra processing with dst->r_addend
1393      (the field omitted in an Elf_Internal_Rel) we can do it here.  */
1394 }
1395 \f
1396 /* Determine whether a symbol is global for the purposes of splitting
1397    the symbol table into global symbols and local symbols.  At least
1398    on Irix 5, this split must be between section symbols and all other
1399    symbols.  On most ELF targets the split is between static symbols
1400    and externally visible symbols.  */
1401
1402 static bfd_boolean
1403 mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
1404 {
1405   if (SGI_COMPAT (abfd))
1406     return (sym->flags & BSF_SECTION_SYM) == 0;
1407   else
1408     return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
1409             || bfd_is_und_section (bfd_get_section (sym))
1410             || bfd_is_com_section (bfd_get_section (sym)));
1411 }
1412 \f
1413 /* Set the right machine number for a MIPS ELF file.  */
1414
1415 static bfd_boolean
1416 mips_elf32_object_p (bfd *abfd)
1417 {
1418   unsigned long mach;
1419
1420   /* Irix 5 and 6 are broken.  Object file symbol tables are not always
1421      sorted correctly such that local symbols precede global symbols,
1422      and the sh_info field in the symbol table is not always right.  */
1423   if (SGI_COMPAT (abfd))
1424     elf_bad_symtab (abfd) = TRUE;
1425
1426   if (ABI_N32_P (abfd))
1427     return FALSE;
1428
1429   mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
1430   bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
1431
1432   return TRUE;
1433 }
1434 \f
1435 /* MIPS ELF local labels start with '$', not 'L'.  */
1436
1437 static bfd_boolean
1438 mips_elf_is_local_label_name (bfd *abfd, const char *name)
1439 {
1440   if (name[0] == '$')
1441     return TRUE;
1442
1443   /* On Irix 6, the labels go back to starting with '.', so we accept
1444      the generic ELF local label syntax as well.  */
1445   return _bfd_elf_is_local_label_name (abfd, name);
1446 }
1447 \f
1448 /* Support for core dump NOTE sections.  */
1449 static bfd_boolean
1450 elf32_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
1451 {
1452   int offset;
1453   unsigned int size;
1454
1455   switch (note->descsz)
1456     {
1457       default:
1458         return FALSE;
1459
1460       case 256:         /* Linux/MIPS */
1461         /* pr_cursig */
1462         elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
1463
1464         /* pr_pid */
1465         elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
1466
1467         /* pr_reg */
1468         offset = 72;
1469         size = 180;
1470
1471         break;
1472     }
1473
1474   /* Make a ".reg/999" section.  */
1475   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
1476                                           size, note->descpos + offset);
1477 }
1478
1479 static bfd_boolean
1480 elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
1481 {
1482   switch (note->descsz)
1483     {
1484       default:
1485         return FALSE;
1486
1487       case 128:         /* Linux/MIPS elf_prpsinfo */
1488         elf_tdata (abfd)->core_program
1489          = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
1490         elf_tdata (abfd)->core_command
1491          = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
1492     }
1493
1494   /* Note that for some reason, a spurious space is tacked
1495      onto the end of the args in some (at least one anyway)
1496      implementations, so strip it off if it exists.  */
1497
1498   {
1499     char *command = elf_tdata (abfd)->core_command;
1500     int n = strlen (command);
1501
1502     if (0 < n && command[n - 1] == ' ')
1503       command[n - 1] = '\0';
1504   }
1505
1506   return TRUE;
1507 }
1508 \f
1509 /* Depending on the target vector we generate some version of Irix
1510    executables or "normal" MIPS ELF ABI executables.  */
1511 static irix_compat_t
1512 elf32_mips_irix_compat (bfd *abfd)
1513 {
1514   if ((abfd->xvec == &bfd_elf32_bigmips_vec)
1515       || (abfd->xvec == &bfd_elf32_littlemips_vec))
1516     return ict_irix5;
1517   else
1518     return ict_none;
1519 }
1520 \f
1521 /* ECOFF swapping routines.  These are used when dealing with the
1522    .mdebug section, which is in the ECOFF debugging format.  */
1523 static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
1524   /* Symbol table magic number.  */
1525   magicSym,
1526   /* Alignment of debugging information.  E.g., 4.  */
1527   4,
1528   /* Sizes of external symbolic information.  */
1529   sizeof (struct hdr_ext),
1530   sizeof (struct dnr_ext),
1531   sizeof (struct pdr_ext),
1532   sizeof (struct sym_ext),
1533   sizeof (struct opt_ext),
1534   sizeof (struct fdr_ext),
1535   sizeof (struct rfd_ext),
1536   sizeof (struct ext_ext),
1537   /* Functions to swap in external symbolic data.  */
1538   ecoff_swap_hdr_in,
1539   ecoff_swap_dnr_in,
1540   ecoff_swap_pdr_in,
1541   ecoff_swap_sym_in,
1542   ecoff_swap_opt_in,
1543   ecoff_swap_fdr_in,
1544   ecoff_swap_rfd_in,
1545   ecoff_swap_ext_in,
1546   _bfd_ecoff_swap_tir_in,
1547   _bfd_ecoff_swap_rndx_in,
1548   /* Functions to swap out external symbolic data.  */
1549   ecoff_swap_hdr_out,
1550   ecoff_swap_dnr_out,
1551   ecoff_swap_pdr_out,
1552   ecoff_swap_sym_out,
1553   ecoff_swap_opt_out,
1554   ecoff_swap_fdr_out,
1555   ecoff_swap_rfd_out,
1556   ecoff_swap_ext_out,
1557   _bfd_ecoff_swap_tir_out,
1558   _bfd_ecoff_swap_rndx_out,
1559   /* Function to read in symbolic data.  */
1560   _bfd_mips_elf_read_ecoff_info
1561 };
1562 \f
1563 #define ELF_ARCH                        bfd_arch_mips
1564 #define ELF_MACHINE_CODE                EM_MIPS
1565
1566 #define elf_backend_collect             TRUE
1567 #define elf_backend_type_change_ok      TRUE
1568 #define elf_backend_can_gc_sections     TRUE
1569 #define elf_info_to_howto               mips_info_to_howto_rela
1570 #define elf_info_to_howto_rel           mips_info_to_howto_rel
1571 #define elf_backend_sym_is_global       mips_elf_sym_is_global
1572 #define elf_backend_object_p            mips_elf32_object_p
1573 #define elf_backend_symbol_processing   _bfd_mips_elf_symbol_processing
1574 #define elf_backend_section_processing  _bfd_mips_elf_section_processing
1575 #define elf_backend_section_from_shdr   _bfd_mips_elf_section_from_shdr
1576 #define elf_backend_fake_sections       _bfd_mips_elf_fake_sections
1577 #define elf_backend_section_from_bfd_section \
1578                                         _bfd_mips_elf_section_from_bfd_section
1579 #define elf_backend_add_symbol_hook     _bfd_mips_elf_add_symbol_hook
1580 #define elf_backend_link_output_symbol_hook \
1581                                         _bfd_mips_elf_link_output_symbol_hook
1582 #define elf_backend_create_dynamic_sections \
1583                                         _bfd_mips_elf_create_dynamic_sections
1584 #define elf_backend_check_relocs        _bfd_mips_elf_check_relocs
1585 #define elf_backend_merge_symbol_attribute \
1586                                         _bfd_mips_elf_merge_symbol_attribute
1587 #define elf_backend_get_target_dtag     _bfd_mips_elf_get_target_dtag
1588 #define elf_backend_adjust_dynamic_symbol \
1589                                         _bfd_mips_elf_adjust_dynamic_symbol
1590 #define elf_backend_always_size_sections \
1591                                         _bfd_mips_elf_always_size_sections
1592 #define elf_backend_size_dynamic_sections \
1593                                         _bfd_mips_elf_size_dynamic_sections
1594 #define elf_backend_init_index_section  _bfd_elf_init_1_index_section
1595 #define elf_backend_relocate_section    _bfd_mips_elf_relocate_section
1596 #define elf_backend_finish_dynamic_symbol \
1597                                         _bfd_mips_elf_finish_dynamic_symbol
1598 #define elf_backend_finish_dynamic_sections \
1599                                         _bfd_mips_elf_finish_dynamic_sections
1600 #define elf_backend_final_write_processing \
1601                                         _bfd_mips_elf_final_write_processing
1602 #define elf_backend_additional_program_headers \
1603                                         _bfd_mips_elf_additional_program_headers
1604 #define elf_backend_modify_segment_map  _bfd_mips_elf_modify_segment_map
1605 #define elf_backend_gc_mark_hook        _bfd_mips_elf_gc_mark_hook
1606 #define elf_backend_gc_sweep_hook       _bfd_mips_elf_gc_sweep_hook
1607 #define elf_backend_copy_indirect_symbol \
1608                                         _bfd_mips_elf_copy_indirect_symbol
1609 #define elf_backend_grok_prstatus       elf32_mips_grok_prstatus
1610 #define elf_backend_grok_psinfo         elf32_mips_grok_psinfo
1611 #define elf_backend_ecoff_debug_swap    &mips_elf32_ecoff_debug_swap
1612
1613 #define elf_backend_got_header_size     (4 * MIPS_RESERVED_GOTNO)
1614 #define elf_backend_may_use_rel_p       1
1615 #define elf_backend_may_use_rela_p      0
1616 #define elf_backend_default_use_rela_p  0
1617 #define elf_backend_sign_extend_vma     TRUE
1618
1619 #define elf_backend_discard_info        _bfd_mips_elf_discard_info
1620 #define elf_backend_ignore_discarded_relocs \
1621                                         _bfd_mips_elf_ignore_discarded_relocs
1622 #define elf_backend_write_section       _bfd_mips_elf_write_section
1623 #define elf_backend_mips_irix_compat    elf32_mips_irix_compat
1624 #define elf_backend_mips_rtype_to_howto mips_elf32_rtype_to_howto
1625 #define bfd_elf32_bfd_is_local_label_name \
1626                                         mips_elf_is_local_label_name
1627 #define bfd_elf32_find_nearest_line     _bfd_mips_elf_find_nearest_line
1628 #define bfd_elf32_find_inliner_info     _bfd_mips_elf_find_inliner_info
1629 #define bfd_elf32_new_section_hook      _bfd_mips_elf_new_section_hook
1630 #define bfd_elf32_set_section_contents  _bfd_mips_elf_set_section_contents
1631 #define bfd_elf32_bfd_get_relocated_section_contents \
1632                                 _bfd_elf_mips_get_relocated_section_contents
1633 #define bfd_elf32_mkobject              _bfd_mips_elf_mkobject
1634 #define bfd_elf32_bfd_link_hash_table_create \
1635                                         _bfd_mips_elf_link_hash_table_create
1636 #define bfd_elf32_bfd_final_link        _bfd_mips_elf_final_link
1637 #define bfd_elf32_bfd_merge_private_bfd_data \
1638                                         _bfd_mips_elf_merge_private_bfd_data
1639 #define bfd_elf32_bfd_set_private_flags _bfd_mips_elf_set_private_flags
1640 #define bfd_elf32_bfd_print_private_bfd_data \
1641                                         _bfd_mips_elf_print_private_bfd_data
1642
1643 /* Support for SGI-ish mips targets.  */
1644 #define TARGET_LITTLE_SYM               bfd_elf32_littlemips_vec
1645 #define TARGET_LITTLE_NAME              "elf32-littlemips"
1646 #define TARGET_BIG_SYM                  bfd_elf32_bigmips_vec
1647 #define TARGET_BIG_NAME                 "elf32-bigmips"
1648
1649 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
1650    a value of 0x1000, and we are compatible.  */
1651 #define ELF_MAXPAGESIZE                 0x1000
1652 #define ELF_COMMONPAGESIZE              0x1000
1653
1654 #include "elf32-target.h"
1655
1656 /* Support for traditional mips targets.  */
1657 #undef TARGET_LITTLE_SYM
1658 #undef TARGET_LITTLE_NAME
1659 #undef TARGET_BIG_SYM
1660 #undef TARGET_BIG_NAME
1661
1662 #undef ELF_MAXPAGESIZE
1663 #undef ELF_COMMONPAGESIZE
1664
1665 #define TARGET_LITTLE_SYM               bfd_elf32_tradlittlemips_vec
1666 #define TARGET_LITTLE_NAME              "elf32-tradlittlemips"
1667 #define TARGET_BIG_SYM                  bfd_elf32_tradbigmips_vec
1668 #define TARGET_BIG_NAME                 "elf32-tradbigmips"
1669
1670 /* The MIPS ABI says at Page 5-1:
1671    Virtual addresses and file offsets for MIPS segments are congruent
1672    modulo 64 KByte (0x10000) or larger powers of 2.  Because 64 KBytes
1673    is the maximum page size, the files are suitable for paging
1674    regardless of physical page size.  */
1675 #define ELF_MAXPAGESIZE                 0x10000
1676 #define ELF_COMMONPAGESIZE              0x1000
1677 #define elf32_bed                       elf32_tradbed
1678
1679 /* Include the target file again for this target.  */
1680 #include "elf32-target.h"
1681
1682
1683 /* Specific to VxWorks.  */
1684 static reloc_howto_type mips_vxworks_copy_howto_rela =
1685   HOWTO (R_MIPS_COPY,           /* type */
1686          0,                     /* rightshift */
1687          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1688          32,                    /* bitsize */
1689          FALSE,                 /* pc_relative */
1690          0,                     /* bitpos */
1691          complain_overflow_bitfield, /* complain_on_overflow */
1692          bfd_elf_generic_reloc, /* special_function */
1693          "R_MIPS_COPY",         /* name */
1694          FALSE,                 /* partial_inplace */
1695          0x0,                   /* src_mask */
1696          0x0,                   /* dst_mask */
1697          FALSE);                /* pcrel_offset */
1698
1699 /* Specific to VxWorks.  */
1700 static reloc_howto_type mips_vxworks_jump_slot_howto_rela =
1701   HOWTO (R_MIPS_JUMP_SLOT,      /* type */
1702          0,                     /* rightshift */
1703          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1704          32,                    /* bitsize */
1705          FALSE,                 /* pc_relative */
1706          0,                     /* bitpos */
1707          complain_overflow_bitfield, /* complain_on_overflow */
1708          bfd_elf_generic_reloc, /* special_function */
1709          "R_MIPS_JUMP_SLOT",    /* name */
1710          FALSE,                 /* partial_inplace */
1711          0x0,                   /* src_mask */
1712          0x0,                   /* dst_mask */
1713          FALSE);                /* pcrel_offset */
1714
1715 /* Implement elf_backend_bfd_reloc_type_lookup for VxWorks.  */
1716
1717 static reloc_howto_type *
1718 mips_vxworks_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
1719 {
1720   switch (code)
1721     {
1722     case BFD_RELOC_MIPS_COPY:
1723       return &mips_vxworks_copy_howto_rela;
1724     case BFD_RELOC_MIPS_JUMP_SLOT:
1725       return &mips_vxworks_jump_slot_howto_rela;
1726     default:
1727       return bfd_elf32_bfd_reloc_type_lookup (abfd, code);
1728     }
1729 }
1730
1731 static reloc_howto_type *
1732 mips_vxworks_bfd_reloc_name_lookup (bfd *abfd, const char *r_name)
1733 {
1734   if (strcasecmp (mips_vxworks_copy_howto_rela.name, r_name) == 0)
1735     return &mips_vxworks_copy_howto_rela;
1736   if (strcasecmp (mips_vxworks_jump_slot_howto_rela.name, r_name) == 0)
1737     return &mips_vxworks_jump_slot_howto_rela;
1738
1739   return bfd_elf32_bfd_reloc_name_lookup (abfd, r_name);
1740 }
1741
1742 /* Implement elf_backend_mips_rtype_to_lookup for VxWorks.  */
1743
1744 static reloc_howto_type *
1745 mips_vxworks_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
1746 {
1747   switch (r_type)
1748     {
1749     case R_MIPS_COPY:
1750       return &mips_vxworks_copy_howto_rela;
1751     case R_MIPS_JUMP_SLOT:
1752       return &mips_vxworks_jump_slot_howto_rela;
1753     default:
1754       return mips_elf32_rtype_to_howto (r_type, rela_p);
1755     }
1756 }
1757
1758 /* Implement elf_backend_final_write_processing for VxWorks.  */
1759
1760 static void
1761 mips_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
1762 {
1763   _bfd_mips_elf_final_write_processing (abfd, linker);
1764   elf_vxworks_final_write_processing (abfd, linker);
1765 }
1766
1767 #undef TARGET_LITTLE_SYM
1768 #undef TARGET_LITTLE_NAME
1769 #undef TARGET_BIG_SYM
1770 #undef TARGET_BIG_NAME
1771
1772 #undef ELF_MAXPAGESIZE
1773 #undef ELF_COMMONPAGESIZE
1774
1775 #define TARGET_LITTLE_SYM               bfd_elf32_littlemips_vxworks_vec
1776 #define TARGET_LITTLE_NAME              "elf32-littlemips-vxworks"
1777 #define TARGET_BIG_SYM                  bfd_elf32_bigmips_vxworks_vec
1778 #define TARGET_BIG_NAME                 "elf32-bigmips-vxworks"
1779
1780 #undef elf32_bed
1781 #define elf32_bed                       elf32_mips_vxworks_bed
1782
1783 #define ELF_MAXPAGESIZE                 0x1000
1784 #define ELF_COMMONPAGESIZE              0x1000
1785
1786 #undef elf_backend_want_got_plt
1787 #define elf_backend_want_got_plt                1
1788 #undef elf_backend_want_plt_sym
1789 #define elf_backend_want_plt_sym                1
1790 #undef elf_backend_got_symbol_offset
1791 #define elf_backend_got_symbol_offset           0
1792 #undef elf_backend_want_dynbss
1793 #define elf_backend_want_dynbss                 1
1794 #undef elf_backend_may_use_rel_p
1795 #define elf_backend_may_use_rel_p               0
1796 #undef elf_backend_may_use_rela_p
1797 #define elf_backend_may_use_rela_p              1
1798 #undef elf_backend_default_use_rela_p
1799 #define elf_backend_default_use_rela_p          1
1800 #undef elf_backend_got_header_size
1801 #define elf_backend_got_header_size             (4 * 3)
1802 #undef elf_backend_plt_readonly
1803 #define elf_backend_plt_readonly                1
1804
1805 #undef bfd_elf32_bfd_reloc_type_lookup
1806 #define bfd_elf32_bfd_reloc_type_lookup \
1807   mips_vxworks_bfd_reloc_type_lookup
1808 #undef bfd_elf32_bfd_reloc_name_lookup
1809 #define bfd_elf32_bfd_reloc_name_lookup \
1810   mips_vxworks_bfd_reloc_name_lookup
1811 #undef elf_backend_mips_rtype_to_howto
1812 #define elf_backend_mips_rtype_to_howto \
1813   mips_vxworks_rtype_to_howto
1814 #undef elf_backend_adjust_dynamic_symbol
1815 #define elf_backend_adjust_dynamic_symbol \
1816   _bfd_mips_vxworks_adjust_dynamic_symbol
1817 #undef elf_backend_finish_dynamic_symbol
1818 #define elf_backend_finish_dynamic_symbol \
1819   _bfd_mips_vxworks_finish_dynamic_symbol
1820 #undef bfd_elf32_bfd_link_hash_table_create
1821 #define bfd_elf32_bfd_link_hash_table_create \
1822   _bfd_mips_vxworks_link_hash_table_create
1823 #undef elf_backend_add_symbol_hook
1824 #define elf_backend_add_symbol_hook \
1825   elf_vxworks_add_symbol_hook
1826 #undef elf_backend_link_output_symbol_hook
1827 #define elf_backend_link_output_symbol_hook \
1828   elf_vxworks_link_output_symbol_hook
1829 #undef elf_backend_emit_relocs
1830 #define elf_backend_emit_relocs \
1831   elf_vxworks_emit_relocs
1832 #undef elf_backend_final_write_processing
1833 #define elf_backend_final_write_processing \
1834   mips_vxworks_final_write_processing
1835
1836 #undef elf_backend_additional_program_headers
1837 #undef elf_backend_modify_segment_map
1838 #undef elf_backend_symbol_processing
1839 /* NOTE: elf_backend_rela_normal is not defined for MIPS.  */
1840
1841 #include "elf32-target.h"