daily update
[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 placeholder for MIPS16 reference to global offset table.  */
775   EMPTY_HOWTO (R_MIPS16_GOT16),
776
777   /* A placeholder for MIPS16 16 bit call through global offset table.  */
778   EMPTY_HOWTO (R_MIPS16_CALL16),
779
780   /* MIPS16 high 16 bits of symbol value.  */
781   HOWTO (R_MIPS16_HI16,         /* type */
782          16,                    /* rightshift */
783          2,                     /* size (0 = byte, 1 = short, 2 = long) */
784          16,                    /* bitsize */
785          FALSE,                 /* pc_relative */
786          0,                     /* bitpos */
787          complain_overflow_dont, /* complain_on_overflow */
788          _bfd_mips_elf_hi16_reloc, /* special_function */
789          "R_MIPS16_HI16",       /* name */
790          TRUE,                  /* partial_inplace */
791          0x0000ffff,            /* src_mask */
792          0x0000ffff,            /* dst_mask */
793          FALSE),                /* pcrel_offset */
794
795   /* MIPS16 low 16 bits of symbol value.  */
796   HOWTO (R_MIPS16_LO16,         /* type */
797          0,                     /* rightshift */
798          2,                     /* size (0 = byte, 1 = short, 2 = long) */
799          16,                    /* bitsize */
800          FALSE,                 /* pc_relative */
801          0,                     /* bitpos */
802          complain_overflow_dont, /* complain_on_overflow */
803          _bfd_mips_elf_lo16_reloc, /* special_function */
804          "R_MIPS16_LO16",       /* name */
805          TRUE,                  /* partial_inplace */
806          0x0000ffff,            /* src_mask */
807          0x0000ffff,            /* dst_mask */
808          FALSE),                /* pcrel_offset */
809 };
810
811 /* 16 bit offset for pc-relative branches.  */
812 static reloc_howto_type elf_mips_gnu_rel16_s2 =
813   HOWTO (R_MIPS_GNU_REL16_S2,   /* type */
814          2,                     /* rightshift */
815          2,                     /* size (0 = byte, 1 = short, 2 = long) */
816          16,                    /* bitsize */
817          TRUE,                  /* pc_relative */
818          0,                     /* bitpos */
819          complain_overflow_signed, /* complain_on_overflow */
820          _bfd_mips_elf_generic_reloc, /* special_function */
821          "R_MIPS_GNU_REL16_S2", /* name */
822          TRUE,                  /* partial_inplace */
823          0xffff,                /* src_mask */
824          0xffff,                /* dst_mask */
825          TRUE);                 /* pcrel_offset */
826
827 /* 32 bit pc-relative.  This was a GNU extension used by embedded-PIC.
828    It was co-opted by mips-linux for exception-handling data.  It is no
829    longer used, but should continue to be supported by the linker for
830    backward compatibility.  (GCC stopped using it in May, 2004.)  */
831 static reloc_howto_type elf_mips_gnu_pcrel32 =
832   HOWTO (R_MIPS_PC32,           /* type */
833          0,                     /* rightshift */
834          2,                     /* size (0 = byte, 1 = short, 2 = long) */
835          32,                    /* bitsize */
836          TRUE,                  /* pc_relative */
837          0,                     /* bitpos */
838          complain_overflow_signed, /* complain_on_overflow */
839          _bfd_mips_elf_generic_reloc, /* special_function */
840          "R_MIPS_PC32",         /* name */
841          TRUE,                  /* partial_inplace */
842          0xffffffff,            /* src_mask */
843          0xffffffff,            /* dst_mask */
844          TRUE);                 /* pcrel_offset */
845
846 /* GNU extension to record C++ vtable hierarchy */
847 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
848   HOWTO (R_MIPS_GNU_VTINHERIT,  /* type */
849          0,                     /* rightshift */
850          2,                     /* size (0 = byte, 1 = short, 2 = long) */
851          0,                     /* bitsize */
852          FALSE,                 /* pc_relative */
853          0,                     /* bitpos */
854          complain_overflow_dont, /* complain_on_overflow */
855          NULL,                  /* special_function */
856          "R_MIPS_GNU_VTINHERIT", /* name */
857          FALSE,                 /* partial_inplace */
858          0,                     /* src_mask */
859          0,                     /* dst_mask */
860          FALSE);                /* pcrel_offset */
861
862 /* GNU extension to record C++ vtable member usage */
863 static reloc_howto_type elf_mips_gnu_vtentry_howto =
864   HOWTO (R_MIPS_GNU_VTENTRY,    /* type */
865          0,                     /* rightshift */
866          2,                     /* size (0 = byte, 1 = short, 2 = long) */
867          0,                     /* bitsize */
868          FALSE,                 /* pc_relative */
869          0,                     /* bitpos */
870          complain_overflow_dont, /* complain_on_overflow */
871          _bfd_elf_rel_vtable_reloc_fn, /* special_function */
872          "R_MIPS_GNU_VTENTRY",  /* name */
873          FALSE,                 /* partial_inplace */
874          0,                     /* src_mask */
875          0,                     /* dst_mask */
876          FALSE);                /* pcrel_offset */
877
878 /* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
879    dangerous relocation.  */
880
881 static bfd_boolean
882 mips_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
883 {
884   unsigned int count;
885   asymbol **sym;
886   unsigned int i;
887
888   /* If we've already figured out what GP will be, just return it.  */
889   *pgp = _bfd_get_gp_value (output_bfd);
890   if (*pgp)
891     return TRUE;
892
893   count = bfd_get_symcount (output_bfd);
894   sym = bfd_get_outsymbols (output_bfd);
895
896   /* The linker script will have created a symbol named `_gp' with the
897      appropriate value.  */
898   if (sym == NULL)
899     i = count;
900   else
901     {
902       for (i = 0; i < count; i++, sym++)
903         {
904           register const char *name;
905
906           name = bfd_asymbol_name (*sym);
907           if (*name == '_' && strcmp (name, "_gp") == 0)
908             {
909               *pgp = bfd_asymbol_value (*sym);
910               _bfd_set_gp_value (output_bfd, *pgp);
911               break;
912             }
913         }
914     }
915
916   if (i >= count)
917     {
918       /* Only get the error once.  */
919       *pgp = 4;
920       _bfd_set_gp_value (output_bfd, *pgp);
921       return FALSE;
922     }
923
924   return TRUE;
925 }
926
927 /* We have to figure out the gp value, so that we can adjust the
928    symbol value correctly.  We look up the symbol _gp in the output
929    BFD.  If we can't find it, we're stuck.  We cache it in the ELF
930    target data.  We don't need to adjust the symbol value for an
931    external symbol if we are producing relocatable output.  */
932
933 static bfd_reloc_status_type
934 mips_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
935                    char **error_message, bfd_vma *pgp)
936 {
937   if (bfd_is_und_section (symbol->section)
938       && ! relocatable)
939     {
940       *pgp = 0;
941       return bfd_reloc_undefined;
942     }
943
944   *pgp = _bfd_get_gp_value (output_bfd);
945   if (*pgp == 0
946       && (! relocatable
947           || (symbol->flags & BSF_SECTION_SYM) != 0))
948     {
949       if (relocatable)
950         {
951           /* Make up a value.  */
952           *pgp = symbol->section->output_section->vma + 0x4000;
953           _bfd_set_gp_value (output_bfd, *pgp);
954         }
955       else if (!mips_elf_assign_gp (output_bfd, pgp))
956         {
957           *error_message =
958             (char *) _("GP relative relocation when _gp not defined");
959           return bfd_reloc_dangerous;
960         }
961     }
962
963   return bfd_reloc_ok;
964 }
965
966 /* Do a R_MIPS_GPREL16 relocation.  This is a 16 bit value which must
967    become the offset from the gp register.  This function also handles
968    R_MIPS_LITERAL relocations, although those can be handled more
969    cleverly because the entries in the .lit8 and .lit4 sections can be
970    merged.  */
971
972 bfd_reloc_status_type
973 _bfd_mips_elf32_gprel16_reloc (bfd *abfd, arelent *reloc_entry,
974                                asymbol *symbol, void *data,
975                                asection *input_section, bfd *output_bfd,
976                                char **error_message)
977 {
978   bfd_boolean relocatable;
979   bfd_reloc_status_type ret;
980   bfd_vma gp;
981
982   /* R_MIPS_LITERAL relocations are defined for local symbols only.  */
983   if (reloc_entry->howto->type == R_MIPS_LITERAL
984       && output_bfd != NULL
985       && (symbol->flags & BSF_SECTION_SYM) == 0
986       && (symbol->flags & BSF_LOCAL) != 0)
987     {
988       *error_message = (char *)
989         _("literal relocation occurs for an external symbol");
990       return bfd_reloc_outofrange;
991     }
992
993   if (output_bfd != NULL)
994     relocatable = TRUE;
995   else
996     {
997       relocatable = FALSE;
998       output_bfd = symbol->section->output_section->owner;
999     }
1000
1001   ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
1002                            &gp);
1003   if (ret != bfd_reloc_ok)
1004     return ret;
1005
1006   return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1007                                         input_section, relocatable,
1008                                         data, gp);
1009 }
1010
1011 /* Do a R_MIPS_GPREL32 relocation.  This is a 32 bit value which must
1012    become the offset from the gp register.  */
1013
1014 static bfd_reloc_status_type
1015 mips_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1016                         void *data, asection *input_section, bfd *output_bfd,
1017                         char **error_message)
1018 {
1019   bfd_boolean relocatable;
1020   bfd_reloc_status_type ret;
1021   bfd_vma gp;
1022
1023   /* R_MIPS_GPREL32 relocations are defined for local symbols only.  */
1024   if (output_bfd != NULL
1025       && (symbol->flags & BSF_SECTION_SYM) == 0
1026       && (symbol->flags & BSF_LOCAL) != 0)
1027     {
1028       *error_message = (char *)
1029         _("32bits gp relative relocation occurs for an external symbol");
1030       return bfd_reloc_outofrange;
1031     }
1032
1033   if (output_bfd != NULL)
1034     relocatable = TRUE;
1035   else
1036     {
1037       relocatable = FALSE;
1038       output_bfd = symbol->section->output_section->owner;
1039     }
1040
1041   ret = mips_elf_final_gp (output_bfd, symbol, relocatable,
1042                            error_message, &gp);
1043   if (ret != bfd_reloc_ok)
1044     return ret;
1045
1046   return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
1047                           relocatable, data, gp);
1048 }
1049
1050 static bfd_reloc_status_type
1051 gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
1052                  asection *input_section, bfd_boolean relocatable,
1053                  void *data, bfd_vma gp)
1054 {
1055   bfd_vma relocation;
1056   bfd_vma val;
1057
1058   if (bfd_is_com_section (symbol->section))
1059     relocation = 0;
1060   else
1061     relocation = symbol->value;
1062
1063   relocation += symbol->section->output_section->vma;
1064   relocation += symbol->section->output_offset;
1065
1066   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
1067     return bfd_reloc_outofrange;
1068
1069   /* Set val to the offset into the section or symbol.  */
1070   val = reloc_entry->addend;
1071
1072   if (reloc_entry->howto->partial_inplace)
1073     val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1074
1075   /* Adjust val for the final section location and GP value.  If we
1076      are producing relocatable output, we don't want to do this for
1077      an external symbol.  */
1078   if (! relocatable
1079       || (symbol->flags & BSF_SECTION_SYM) != 0)
1080     val += relocation - gp;
1081
1082   if (reloc_entry->howto->partial_inplace)
1083     bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
1084   else
1085     reloc_entry->addend = val;
1086
1087   if (relocatable)
1088     reloc_entry->address += input_section->output_offset;
1089
1090   return bfd_reloc_ok;
1091 }
1092
1093 /* Handle a 64 bit reloc in a 32 bit MIPS ELF file.  These are
1094    generated when addresses are 64 bits.  The upper 32 bits are a simple
1095    sign extension.  */
1096
1097 static bfd_reloc_status_type
1098 mips32_64bit_reloc (bfd *abfd, arelent *reloc_entry,
1099                     asymbol *symbol ATTRIBUTE_UNUSED,
1100                     void *data, asection *input_section,
1101                     bfd *output_bfd, char **error_message)
1102 {
1103   bfd_reloc_status_type r;
1104   arelent reloc32;
1105   unsigned long val;
1106   bfd_size_type addr;
1107
1108   /* Do a normal 32 bit relocation on the lower 32 bits.  */
1109   reloc32 = *reloc_entry;
1110   if (bfd_big_endian (abfd))
1111     reloc32.address += 4;
1112   reloc32.howto = &elf_mips_howto_table_rel[R_MIPS_32];
1113   r = bfd_perform_relocation (abfd, &reloc32, data, input_section,
1114                               output_bfd, error_message);
1115
1116   /* Sign extend into the upper 32 bits.  */
1117   val = bfd_get_32 (abfd, (bfd_byte *) data + reloc32.address);
1118   if ((val & 0x80000000) != 0)
1119     val = 0xffffffff;
1120   else
1121     val = 0;
1122   addr = reloc_entry->address;
1123   if (bfd_little_endian (abfd))
1124     addr += 4;
1125   bfd_put_32 (abfd, val, (bfd_byte *) data + addr);
1126
1127   return r;
1128 }
1129
1130 /* Handle a mips16 GP relative reloc.  */
1131
1132 static bfd_reloc_status_type
1133 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1134                     void *data, asection *input_section, bfd *output_bfd,
1135                     char **error_message)
1136 {
1137   bfd_boolean relocatable;
1138   bfd_reloc_status_type ret;
1139   bfd_byte *location;
1140   bfd_vma gp;
1141
1142   /* If we're relocating, and this is an external symbol, we don't want
1143      to change anything.  */
1144   if (output_bfd != NULL
1145       && (symbol->flags & BSF_SECTION_SYM) == 0
1146       && (symbol->flags & BSF_LOCAL) != 0)
1147     {
1148       reloc_entry->address += input_section->output_offset;
1149       return bfd_reloc_ok;
1150     }
1151
1152   if (output_bfd != NULL)
1153     relocatable = TRUE;
1154   else
1155     {
1156       relocatable = FALSE;
1157       output_bfd = symbol->section->output_section->owner;
1158     }
1159
1160   ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
1161                            &gp);
1162   if (ret != bfd_reloc_ok)
1163     return ret;
1164
1165   location = (bfd_byte *) data + reloc_entry->address;
1166   _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
1167                                    location);
1168   ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1169                                        input_section, relocatable,
1170                                        data, gp);
1171   _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
1172                                  location);
1173
1174   return ret;
1175 }
1176
1177 /* A mapping from BFD reloc types to MIPS ELF reloc types.  */
1178
1179 struct elf_reloc_map {
1180   bfd_reloc_code_real_type bfd_val;
1181   enum elf_mips_reloc_type elf_val;
1182 };
1183
1184 static const struct elf_reloc_map mips_reloc_map[] =
1185 {
1186   { BFD_RELOC_NONE, R_MIPS_NONE },
1187   { BFD_RELOC_16, R_MIPS_16 },
1188   { BFD_RELOC_32, R_MIPS_32 },
1189   /* There is no BFD reloc for R_MIPS_REL32.  */
1190   { BFD_RELOC_64, R_MIPS_64 },
1191   { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1192   { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1193   { BFD_RELOC_LO16, R_MIPS_LO16 },
1194   { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
1195   { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1196   { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
1197   { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
1198   { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
1199   { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
1200   { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1201   { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1202   { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
1203   { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1204   { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1205   { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1206   { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
1207   { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
1208   { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
1209   { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
1210   { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
1211   { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
1212   { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
1213   { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
1214   { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
1215   { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
1216   { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
1217   { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
1218   { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
1219   { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
1220   { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
1221 };
1222
1223 static const struct elf_reloc_map mips16_reloc_map[] =
1224 {
1225   { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
1226   { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
1227   { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
1228   { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
1229 };
1230
1231 /* Given a BFD reloc type, return a howto structure.  */
1232
1233 static reloc_howto_type *
1234 bfd_elf32_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
1235 {
1236   unsigned int i;
1237   reloc_howto_type *howto_table = elf_mips_howto_table_rel;
1238   reloc_howto_type *howto16_table = elf_mips16_howto_table_rel;
1239
1240   for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
1241        i++)
1242     {
1243       if (mips_reloc_map[i].bfd_val == code)
1244         return &howto_table[(int) mips_reloc_map[i].elf_val];
1245     }
1246
1247   for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
1248        i++)
1249     {
1250       if (mips16_reloc_map[i].bfd_val == code)
1251         return &howto16_table[(int) mips16_reloc_map[i].elf_val];
1252     }
1253
1254   switch (code)
1255     {
1256     default:
1257       bfd_set_error (bfd_error_bad_value);
1258       return NULL;
1259
1260     case BFD_RELOC_CTOR:
1261       /* We need to handle BFD_RELOC_CTOR specially.
1262          Select the right relocation (R_MIPS_32 or R_MIPS_64) based on the
1263          size of addresses of the ABI.  */
1264       if ((elf_elfheader (abfd)->e_flags & (E_MIPS_ABI_O64
1265                                             | E_MIPS_ABI_EABI64)) != 0)
1266         return &elf_mips_ctor64_howto;
1267       else
1268         return &howto_table[(int) R_MIPS_32];
1269
1270     case BFD_RELOC_VTABLE_INHERIT:
1271       return &elf_mips_gnu_vtinherit_howto;
1272     case BFD_RELOC_VTABLE_ENTRY:
1273       return &elf_mips_gnu_vtentry_howto;
1274     case BFD_RELOC_32_PCREL:
1275       return &elf_mips_gnu_pcrel32;
1276     }
1277 }
1278
1279 static reloc_howto_type *
1280 bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1281                                  const char *r_name)
1282 {
1283   unsigned int i;
1284
1285   for (i = 0;
1286        i < (sizeof (elf_mips_howto_table_rel)
1287             / sizeof (elf_mips_howto_table_rel[0]));
1288        i++)
1289     if (elf_mips_howto_table_rel[i].name != NULL
1290         && strcasecmp (elf_mips_howto_table_rel[i].name, r_name) == 0)
1291       return &elf_mips_howto_table_rel[i];
1292
1293   for (i = 0;
1294        i < (sizeof (elf_mips16_howto_table_rel)
1295             / sizeof (elf_mips16_howto_table_rel[0]));
1296        i++)
1297     if (elf_mips16_howto_table_rel[i].name != NULL
1298         && strcasecmp (elf_mips16_howto_table_rel[i].name, r_name) == 0)
1299       return &elf_mips16_howto_table_rel[i];
1300
1301   if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
1302     return &elf_mips_gnu_pcrel32;
1303   if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
1304     return &elf_mips_gnu_rel16_s2;
1305   if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
1306     return &elf_mips_gnu_vtinherit_howto;
1307   if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
1308     return &elf_mips_gnu_vtentry_howto;
1309
1310   return NULL;
1311 }
1312
1313 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
1314
1315 static reloc_howto_type *
1316 mips_elf32_rtype_to_howto (unsigned int r_type,
1317                            bfd_boolean rela_p ATTRIBUTE_UNUSED)
1318 {
1319   switch (r_type)
1320     {
1321     case R_MIPS_GNU_VTINHERIT:
1322       return &elf_mips_gnu_vtinherit_howto;
1323     case R_MIPS_GNU_VTENTRY:
1324       return &elf_mips_gnu_vtentry_howto;
1325     case R_MIPS_GNU_REL16_S2:
1326       return &elf_mips_gnu_rel16_s2;
1327     case R_MIPS_PC32:
1328       return &elf_mips_gnu_pcrel32;
1329     default:
1330       if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
1331         return &elf_mips16_howto_table_rel[r_type - R_MIPS16_min];
1332       BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
1333       return &elf_mips_howto_table_rel[r_type];
1334     }
1335 }
1336
1337 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
1338
1339 static void
1340 mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
1341 {
1342   const struct elf_backend_data *bed;
1343   unsigned int r_type;
1344
1345   r_type = ELF32_R_TYPE (dst->r_info);
1346   bed = get_elf_backend_data (abfd);
1347   cache_ptr->howto = bed->elf_backend_mips_rtype_to_howto (r_type, FALSE);
1348
1349   /* The addend for a GPREL16 or LITERAL relocation comes from the GP
1350      value for the object file.  We get the addend now, rather than
1351      when we do the relocation, because the symbol manipulations done
1352      by the linker may cause us to lose track of the input BFD.  */
1353   if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
1354       && (r_type == (unsigned int) R_MIPS_GPREL16
1355           || r_type == (unsigned int) R_MIPS_LITERAL))
1356     cache_ptr->addend = elf_gp (abfd);
1357 }
1358
1359 /* Given a MIPS Elf_Internal_Rela, fill in an arelent structure.  */
1360
1361 static void
1362 mips_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
1363 {
1364   mips_info_to_howto_rel (abfd, cache_ptr, dst);
1365
1366   /* If we ever need to do any extra processing with dst->r_addend
1367      (the field omitted in an Elf_Internal_Rel) we can do it here.  */
1368 }
1369 \f
1370 /* Determine whether a symbol is global for the purposes of splitting
1371    the symbol table into global symbols and local symbols.  At least
1372    on Irix 5, this split must be between section symbols and all other
1373    symbols.  On most ELF targets the split is between static symbols
1374    and externally visible symbols.  */
1375
1376 static bfd_boolean
1377 mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
1378 {
1379   if (SGI_COMPAT (abfd))
1380     return (sym->flags & BSF_SECTION_SYM) == 0;
1381   else
1382     return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
1383             || bfd_is_und_section (bfd_get_section (sym))
1384             || bfd_is_com_section (bfd_get_section (sym)));
1385 }
1386 \f
1387 /* Set the right machine number for a MIPS ELF file.  */
1388
1389 static bfd_boolean
1390 mips_elf32_object_p (bfd *abfd)
1391 {
1392   unsigned long mach;
1393
1394   /* Irix 5 and 6 are broken.  Object file symbol tables are not always
1395      sorted correctly such that local symbols precede global symbols,
1396      and the sh_info field in the symbol table is not always right.  */
1397   if (SGI_COMPAT (abfd))
1398     elf_bad_symtab (abfd) = TRUE;
1399
1400   if (ABI_N32_P (abfd))
1401     return FALSE;
1402
1403   mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
1404   bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
1405
1406   return TRUE;
1407 }
1408 \f
1409 /* MIPS ELF local labels start with '$', not 'L'.  */
1410
1411 static bfd_boolean
1412 mips_elf_is_local_label_name (bfd *abfd, const char *name)
1413 {
1414   if (name[0] == '$')
1415     return TRUE;
1416
1417   /* On Irix 6, the labels go back to starting with '.', so we accept
1418      the generic ELF local label syntax as well.  */
1419   return _bfd_elf_is_local_label_name (abfd, name);
1420 }
1421 \f
1422 /* Support for core dump NOTE sections.  */
1423 static bfd_boolean
1424 elf32_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
1425 {
1426   int offset;
1427   unsigned int size;
1428
1429   switch (note->descsz)
1430     {
1431       default:
1432         return FALSE;
1433
1434       case 256:         /* Linux/MIPS */
1435         /* pr_cursig */
1436         elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
1437
1438         /* pr_pid */
1439         elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
1440
1441         /* pr_reg */
1442         offset = 72;
1443         size = 180;
1444
1445         break;
1446     }
1447
1448   /* Make a ".reg/999" section.  */
1449   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
1450                                           size, note->descpos + offset);
1451 }
1452
1453 static bfd_boolean
1454 elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
1455 {
1456   switch (note->descsz)
1457     {
1458       default:
1459         return FALSE;
1460
1461       case 128:         /* Linux/MIPS elf_prpsinfo */
1462         elf_tdata (abfd)->core_program
1463          = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
1464         elf_tdata (abfd)->core_command
1465          = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
1466     }
1467
1468   /* Note that for some reason, a spurious space is tacked
1469      onto the end of the args in some (at least one anyway)
1470      implementations, so strip it off if it exists.  */
1471
1472   {
1473     char *command = elf_tdata (abfd)->core_command;
1474     int n = strlen (command);
1475
1476     if (0 < n && command[n - 1] == ' ')
1477       command[n - 1] = '\0';
1478   }
1479
1480   return TRUE;
1481 }
1482 \f
1483 /* Depending on the target vector we generate some version of Irix
1484    executables or "normal" MIPS ELF ABI executables.  */
1485 static irix_compat_t
1486 elf32_mips_irix_compat (bfd *abfd)
1487 {
1488   if ((abfd->xvec == &bfd_elf32_bigmips_vec)
1489       || (abfd->xvec == &bfd_elf32_littlemips_vec))
1490     return ict_irix5;
1491   else
1492     return ict_none;
1493 }
1494 \f
1495 /* ECOFF swapping routines.  These are used when dealing with the
1496    .mdebug section, which is in the ECOFF debugging format.  */
1497 static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
1498   /* Symbol table magic number.  */
1499   magicSym,
1500   /* Alignment of debugging information.  E.g., 4.  */
1501   4,
1502   /* Sizes of external symbolic information.  */
1503   sizeof (struct hdr_ext),
1504   sizeof (struct dnr_ext),
1505   sizeof (struct pdr_ext),
1506   sizeof (struct sym_ext),
1507   sizeof (struct opt_ext),
1508   sizeof (struct fdr_ext),
1509   sizeof (struct rfd_ext),
1510   sizeof (struct ext_ext),
1511   /* Functions to swap in external symbolic data.  */
1512   ecoff_swap_hdr_in,
1513   ecoff_swap_dnr_in,
1514   ecoff_swap_pdr_in,
1515   ecoff_swap_sym_in,
1516   ecoff_swap_opt_in,
1517   ecoff_swap_fdr_in,
1518   ecoff_swap_rfd_in,
1519   ecoff_swap_ext_in,
1520   _bfd_ecoff_swap_tir_in,
1521   _bfd_ecoff_swap_rndx_in,
1522   /* Functions to swap out external symbolic data.  */
1523   ecoff_swap_hdr_out,
1524   ecoff_swap_dnr_out,
1525   ecoff_swap_pdr_out,
1526   ecoff_swap_sym_out,
1527   ecoff_swap_opt_out,
1528   ecoff_swap_fdr_out,
1529   ecoff_swap_rfd_out,
1530   ecoff_swap_ext_out,
1531   _bfd_ecoff_swap_tir_out,
1532   _bfd_ecoff_swap_rndx_out,
1533   /* Function to read in symbolic data.  */
1534   _bfd_mips_elf_read_ecoff_info
1535 };
1536 \f
1537 #define ELF_ARCH                        bfd_arch_mips
1538 #define ELF_MACHINE_CODE                EM_MIPS
1539
1540 #define elf_backend_collect             TRUE
1541 #define elf_backend_type_change_ok      TRUE
1542 #define elf_backend_can_gc_sections     TRUE
1543 #define elf_info_to_howto               mips_info_to_howto_rela
1544 #define elf_info_to_howto_rel           mips_info_to_howto_rel
1545 #define elf_backend_sym_is_global       mips_elf_sym_is_global
1546 #define elf_backend_object_p            mips_elf32_object_p
1547 #define elf_backend_symbol_processing   _bfd_mips_elf_symbol_processing
1548 #define elf_backend_section_processing  _bfd_mips_elf_section_processing
1549 #define elf_backend_section_from_shdr   _bfd_mips_elf_section_from_shdr
1550 #define elf_backend_fake_sections       _bfd_mips_elf_fake_sections
1551 #define elf_backend_section_from_bfd_section \
1552                                         _bfd_mips_elf_section_from_bfd_section
1553 #define elf_backend_add_symbol_hook     _bfd_mips_elf_add_symbol_hook
1554 #define elf_backend_link_output_symbol_hook \
1555                                         _bfd_mips_elf_link_output_symbol_hook
1556 #define elf_backend_create_dynamic_sections \
1557                                         _bfd_mips_elf_create_dynamic_sections
1558 #define elf_backend_check_relocs        _bfd_mips_elf_check_relocs
1559 #define elf_backend_merge_symbol_attribute \
1560                                         _bfd_mips_elf_merge_symbol_attribute
1561 #define elf_backend_adjust_dynamic_symbol \
1562                                         _bfd_mips_elf_adjust_dynamic_symbol
1563 #define elf_backend_always_size_sections \
1564                                         _bfd_mips_elf_always_size_sections
1565 #define elf_backend_size_dynamic_sections \
1566                                         _bfd_mips_elf_size_dynamic_sections
1567 #define elf_backend_init_index_section  _bfd_elf_init_1_index_section
1568 #define elf_backend_relocate_section    _bfd_mips_elf_relocate_section
1569 #define elf_backend_finish_dynamic_symbol \
1570                                         _bfd_mips_elf_finish_dynamic_symbol
1571 #define elf_backend_finish_dynamic_sections \
1572                                         _bfd_mips_elf_finish_dynamic_sections
1573 #define elf_backend_final_write_processing \
1574                                         _bfd_mips_elf_final_write_processing
1575 #define elf_backend_additional_program_headers \
1576                                         _bfd_mips_elf_additional_program_headers
1577 #define elf_backend_modify_segment_map  _bfd_mips_elf_modify_segment_map
1578 #define elf_backend_gc_mark_hook        _bfd_mips_elf_gc_mark_hook
1579 #define elf_backend_gc_sweep_hook       _bfd_mips_elf_gc_sweep_hook
1580 #define elf_backend_copy_indirect_symbol \
1581                                         _bfd_mips_elf_copy_indirect_symbol
1582 #define elf_backend_hide_symbol         _bfd_mips_elf_hide_symbol
1583 #define elf_backend_grok_prstatus       elf32_mips_grok_prstatus
1584 #define elf_backend_grok_psinfo         elf32_mips_grok_psinfo
1585 #define elf_backend_ecoff_debug_swap    &mips_elf32_ecoff_debug_swap
1586
1587 #define elf_backend_got_header_size     (4 * MIPS_RESERVED_GOTNO)
1588 #define elf_backend_may_use_rel_p       1
1589 #define elf_backend_may_use_rela_p      0
1590 #define elf_backend_default_use_rela_p  0
1591 #define elf_backend_sign_extend_vma     TRUE
1592
1593 #define elf_backend_discard_info        _bfd_mips_elf_discard_info
1594 #define elf_backend_ignore_discarded_relocs \
1595                                         _bfd_mips_elf_ignore_discarded_relocs
1596 #define elf_backend_mips_irix_compat    elf32_mips_irix_compat
1597 #define elf_backend_mips_rtype_to_howto mips_elf32_rtype_to_howto
1598 #define bfd_elf32_bfd_is_local_label_name \
1599                                         mips_elf_is_local_label_name
1600 #define bfd_elf32_find_nearest_line     _bfd_mips_elf_find_nearest_line
1601 #define bfd_elf32_find_inliner_info     _bfd_mips_elf_find_inliner_info
1602 #define bfd_elf32_new_section_hook      _bfd_mips_elf_new_section_hook
1603 #define bfd_elf32_set_section_contents  _bfd_mips_elf_set_section_contents
1604 #define bfd_elf32_bfd_get_relocated_section_contents \
1605                                 _bfd_elf_mips_get_relocated_section_contents
1606 #define bfd_elf32_bfd_link_hash_table_create \
1607                                         _bfd_mips_elf_link_hash_table_create
1608 #define bfd_elf32_bfd_final_link        _bfd_mips_elf_final_link
1609 #define bfd_elf32_bfd_merge_private_bfd_data \
1610                                         _bfd_mips_elf_merge_private_bfd_data
1611 #define bfd_elf32_bfd_set_private_flags _bfd_mips_elf_set_private_flags
1612 #define bfd_elf32_bfd_print_private_bfd_data \
1613                                         _bfd_mips_elf_print_private_bfd_data
1614
1615 /* Support for SGI-ish mips targets.  */
1616 #define TARGET_LITTLE_SYM               bfd_elf32_littlemips_vec
1617 #define TARGET_LITTLE_NAME              "elf32-littlemips"
1618 #define TARGET_BIG_SYM                  bfd_elf32_bigmips_vec
1619 #define TARGET_BIG_NAME                 "elf32-bigmips"
1620
1621 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
1622    a value of 0x1000, and we are compatible.  */
1623 #define ELF_MAXPAGESIZE                 0x1000
1624 #define ELF_COMMONPAGESIZE              0x1000
1625
1626 #include "elf32-target.h"
1627
1628 /* Support for traditional mips targets.  */
1629 #undef TARGET_LITTLE_SYM
1630 #undef TARGET_LITTLE_NAME
1631 #undef TARGET_BIG_SYM
1632 #undef TARGET_BIG_NAME
1633
1634 #undef ELF_MAXPAGESIZE
1635 #undef ELF_COMMONPAGESIZE
1636
1637 #define TARGET_LITTLE_SYM               bfd_elf32_tradlittlemips_vec
1638 #define TARGET_LITTLE_NAME              "elf32-tradlittlemips"
1639 #define TARGET_BIG_SYM                  bfd_elf32_tradbigmips_vec
1640 #define TARGET_BIG_NAME                 "elf32-tradbigmips"
1641
1642 /* The MIPS ABI says at Page 5-1:
1643    Virtual addresses and file offsets for MIPS segments are congruent
1644    modulo 64 KByte (0x10000) or larger powers of 2.  Because 64 KBytes
1645    is the maximum page size, the files are suitable for paging
1646    regardless of physical page size.  */
1647 #define ELF_MAXPAGESIZE                 0x10000
1648 #define ELF_COMMONPAGESIZE              0x1000
1649 #define elf32_bed                       elf32_tradbed
1650
1651 /* Include the target file again for this target.  */
1652 #include "elf32-target.h"
1653
1654
1655 /* Specific to VxWorks.  */
1656 static reloc_howto_type mips_vxworks_copy_howto_rela =
1657   HOWTO (R_MIPS_COPY,           /* type */
1658          0,                     /* rightshift */
1659          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1660          32,                    /* bitsize */
1661          FALSE,                 /* pc_relative */
1662          0,                     /* bitpos */
1663          complain_overflow_bitfield, /* complain_on_overflow */
1664          bfd_elf_generic_reloc, /* special_function */
1665          "R_MIPS_COPY",         /* name */
1666          FALSE,                 /* partial_inplace */
1667          0x0,                   /* src_mask */
1668          0x0,                   /* dst_mask */
1669          FALSE);                /* pcrel_offset */
1670
1671 /* Specific to VxWorks.  */
1672 static reloc_howto_type mips_vxworks_jump_slot_howto_rela =
1673   HOWTO (R_MIPS_JUMP_SLOT,      /* type */
1674          0,                     /* rightshift */
1675          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1676          32,                    /* bitsize */
1677          FALSE,                 /* pc_relative */
1678          0,                     /* bitpos */
1679          complain_overflow_bitfield, /* complain_on_overflow */
1680          bfd_elf_generic_reloc, /* special_function */
1681          "R_MIPS_JUMP_SLOT",    /* name */
1682          FALSE,                 /* partial_inplace */
1683          0x0,                   /* src_mask */
1684          0x0,                   /* dst_mask */
1685          FALSE);                /* pcrel_offset */
1686
1687 /* Implement elf_backend_bfd_reloc_type_lookup for VxWorks.  */
1688
1689 static reloc_howto_type *
1690 mips_vxworks_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
1691 {
1692   switch (code)
1693     {
1694     case BFD_RELOC_MIPS_COPY:
1695       return &mips_vxworks_copy_howto_rela;
1696     case BFD_RELOC_MIPS_JUMP_SLOT:
1697       return &mips_vxworks_jump_slot_howto_rela;
1698     default:
1699       return bfd_elf32_bfd_reloc_type_lookup (abfd, code);
1700     }
1701 }
1702
1703 static reloc_howto_type *
1704 mips_vxworks_bfd_reloc_name_lookup (bfd *abfd, const char *r_name)
1705 {
1706   if (strcasecmp (mips_vxworks_copy_howto_rela.name, r_name) == 0)
1707     return &mips_vxworks_copy_howto_rela;
1708   if (strcasecmp (mips_vxworks_jump_slot_howto_rela.name, r_name) == 0)
1709     return &mips_vxworks_jump_slot_howto_rela;
1710
1711   return bfd_elf32_bfd_reloc_name_lookup (abfd, r_name);
1712 }
1713
1714 /* Implement elf_backend_mips_rtype_to_lookup for VxWorks.  */
1715
1716 static reloc_howto_type *
1717 mips_vxworks_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
1718 {
1719   switch (r_type)
1720     {
1721     case R_MIPS_COPY:
1722       return &mips_vxworks_copy_howto_rela;
1723     case R_MIPS_JUMP_SLOT:
1724       return &mips_vxworks_jump_slot_howto_rela;
1725     default:
1726       return mips_elf32_rtype_to_howto (r_type, rela_p);
1727     }
1728 }
1729
1730 /* Implement elf_backend_final_write_processing for VxWorks.  */
1731
1732 static void
1733 mips_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
1734 {
1735   _bfd_mips_elf_final_write_processing (abfd, linker);
1736   elf_vxworks_final_write_processing (abfd, linker);
1737 }
1738
1739 #undef TARGET_LITTLE_SYM
1740 #undef TARGET_LITTLE_NAME
1741 #undef TARGET_BIG_SYM
1742 #undef TARGET_BIG_NAME
1743
1744 #undef ELF_MAXPAGESIZE
1745 #undef ELF_COMMONPAGESIZE
1746
1747 #define TARGET_LITTLE_SYM               bfd_elf32_littlemips_vxworks_vec
1748 #define TARGET_LITTLE_NAME              "elf32-littlemips-vxworks"
1749 #define TARGET_BIG_SYM                  bfd_elf32_bigmips_vxworks_vec
1750 #define TARGET_BIG_NAME                 "elf32-bigmips-vxworks"
1751
1752 #undef elf32_bed
1753 #define elf32_bed                       elf32_mips_vxworks_bed
1754
1755 #define ELF_MAXPAGESIZE                 0x1000
1756 #define ELF_COMMONPAGESIZE              0x1000
1757
1758 #undef elf_backend_want_got_plt
1759 #define elf_backend_want_got_plt                1
1760 #undef elf_backend_want_plt_sym
1761 #define elf_backend_want_plt_sym                1
1762 #undef elf_backend_got_symbol_offset
1763 #define elf_backend_got_symbol_offset           0
1764 #undef elf_backend_want_dynbss
1765 #define elf_backend_want_dynbss                 1
1766 #undef elf_backend_may_use_rel_p
1767 #define elf_backend_may_use_rel_p               0
1768 #undef elf_backend_may_use_rela_p
1769 #define elf_backend_may_use_rela_p              1
1770 #undef elf_backend_default_use_rela_p
1771 #define elf_backend_default_use_rela_p          1
1772 #undef elf_backend_got_header_size
1773 #define elf_backend_got_header_size             (4 * 3)
1774 #undef elf_backend_plt_readonly
1775 #define elf_backend_plt_readonly                1
1776
1777 #undef bfd_elf32_bfd_reloc_type_lookup
1778 #define bfd_elf32_bfd_reloc_type_lookup \
1779   mips_vxworks_bfd_reloc_type_lookup
1780 #undef bfd_elf32_bfd_reloc_name_lookup
1781 #define bfd_elf32_bfd_reloc_name_lookup \
1782   mips_vxworks_bfd_reloc_name_lookup
1783 #undef elf_backend_mips_rtype_to_howto
1784 #define elf_backend_mips_rtype_to_howto \
1785   mips_vxworks_rtype_to_howto
1786 #undef elf_backend_adjust_dynamic_symbol
1787 #define elf_backend_adjust_dynamic_symbol \
1788   _bfd_mips_vxworks_adjust_dynamic_symbol
1789 #undef elf_backend_finish_dynamic_symbol
1790 #define elf_backend_finish_dynamic_symbol \
1791   _bfd_mips_vxworks_finish_dynamic_symbol
1792 #undef bfd_elf32_bfd_link_hash_table_create
1793 #define bfd_elf32_bfd_link_hash_table_create \
1794   _bfd_mips_vxworks_link_hash_table_create
1795 #undef elf_backend_add_symbol_hook
1796 #define elf_backend_add_symbol_hook \
1797   elf_vxworks_add_symbol_hook
1798 #undef elf_backend_link_output_symbol_hook
1799 #define elf_backend_link_output_symbol_hook \
1800   elf_vxworks_link_output_symbol_hook
1801 #undef elf_backend_emit_relocs
1802 #define elf_backend_emit_relocs \
1803   elf_vxworks_emit_relocs
1804 #undef elf_backend_final_write_processing
1805 #define elf_backend_final_write_processing \
1806   mips_vxworks_final_write_processing
1807
1808 #undef elf_backend_additional_program_headers
1809 #undef elf_backend_modify_segment_map
1810 #undef elf_backend_symbol_processing
1811 /* NOTE: elf_backend_rela_normal is not defined for MIPS.  */
1812
1813 #include "elf32-target.h"