aa33cf7d6cc29361c29fd7b74c2d4956ce637155
[external/binutils.git] / bfd / elf64-mips.c
1 /* MIPS-specific support for 64-bit ELF
2    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3    Free Software Foundation, Inc.
4    Ian Lance Taylor, Cygnus Support
5    Linker support added by Mark Mitchell, CodeSourcery, LLC.
6    <mark@codesourcery.com>
7
8 This file is part of BFD, the Binary File Descriptor library.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
23
24 /* This file supports the 64-bit MIPS ELF ABI.
25
26    The MIPS 64-bit ELF ABI uses an unusual reloc format.  This file
27    overrides the usual ELF reloc handling, and handles reading and
28    writing the relocations here.  */
29
30 /* TODO: Many things are unsupported, even if there is some code for it
31  .       (which was mostly stolen from elf32-mips.c and slightly adapted).
32  .
33  .   - Relocation handling for REL relocs is wrong in many cases and
34  .     generally untested.
35  .   - Relocation handling for RELA relocs related to GOT support are
36  .     also likely to be wrong.
37  .   - Support for MIPS16 is untested.
38  .   - Combined relocs with RSS_* entries are unsupported.
39  .   - The whole GOT handling for NewABI is missing, some parts of
40  .     the OldABI version is still lying around and should be removed.
41  */
42
43 #include "bfd.h"
44 #include "sysdep.h"
45 #include "libbfd.h"
46 #include "aout/ar.h"
47 #include "bfdlink.h"
48 #include "genlink.h"
49 #include "elf-bfd.h"
50 #include "elfxx-mips.h"
51 #include "elf/mips.h"
52
53 /* Get the ECOFF swapping routines.  The 64-bit ABI is not supposed to
54    use ECOFF.  However, we support it anyhow for an easier changeover.  */
55 #include "coff/sym.h"
56 #include "coff/symconst.h"
57 #include "coff/internal.h"
58 #include "coff/ecoff.h"
59 /* The 64 bit versions of the mdebug data structures are in alpha.h.  */
60 #include "coff/alpha.h"
61 #define ECOFF_SIGNED_64
62 #include "ecoffswap.h"
63
64 static void mips_elf64_swap_reloc_in
65   (bfd *, const Elf64_Mips_External_Rel *, Elf64_Mips_Internal_Rela *);
66 static void mips_elf64_swap_reloca_in
67   (bfd *, const Elf64_Mips_External_Rela *, Elf64_Mips_Internal_Rela *);
68 static void mips_elf64_swap_reloc_out
69   (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rel *);
70 static void mips_elf64_swap_reloca_out
71   (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rela *);
72 static void mips_elf64_be_swap_reloc_in
73   (bfd *, const bfd_byte *, Elf_Internal_Rela *);
74 static void mips_elf64_be_swap_reloc_out
75   (bfd *, const Elf_Internal_Rela *, bfd_byte *);
76 static void mips_elf64_be_swap_reloca_in
77   (bfd *, const bfd_byte *, Elf_Internal_Rela *);
78 static void mips_elf64_be_swap_reloca_out
79   (bfd *, const Elf_Internal_Rela *, bfd_byte *);
80 static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup
81   (bfd *, bfd_reloc_code_real_type);
82 static reloc_howto_type *mips_elf64_rtype_to_howto
83   (unsigned int, bfd_boolean);
84 static void mips_elf64_info_to_howto_rel
85   (bfd *, arelent *, Elf_Internal_Rela *);
86 static void mips_elf64_info_to_howto_rela
87   (bfd *, arelent *, Elf_Internal_Rela *);
88 static long mips_elf64_get_reloc_upper_bound
89   (bfd *, asection *);
90 static long mips_elf64_canonicalize_reloc
91   (bfd *, asection *, arelent **, asymbol **);
92 static long mips_elf64_get_dynamic_reloc_upper_bound
93   (bfd *);
94 static long mips_elf64_canonicalize_dynamic_reloc
95   (bfd *, arelent **, asymbol **);
96 static bfd_boolean mips_elf64_slurp_one_reloc_table
97   (bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type, arelent *,
98    asymbol **, bfd_boolean);
99 static bfd_boolean mips_elf64_slurp_reloc_table
100   (bfd *, asection *, asymbol **, bfd_boolean);
101 static void mips_elf64_write_relocs
102   (bfd *, asection *, void *);
103 static void mips_elf64_write_rel
104   (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
105 static void mips_elf64_write_rela
106   (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
107 static bfd_reloc_status_type mips_elf64_gprel16_reloc
108   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
109 static bfd_reloc_status_type mips_elf64_literal_reloc
110   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
111 static bfd_reloc_status_type mips_elf64_gprel32_reloc
112   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
113 static bfd_reloc_status_type mips_elf64_shift6_reloc
114   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
115 static bfd_reloc_status_type mips16_gprel_reloc
116   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
117 static bfd_boolean mips_elf64_assign_gp
118   (bfd *, bfd_vma *);
119 static bfd_reloc_status_type mips_elf64_final_gp
120   (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
121 static bfd_boolean mips_elf64_object_p
122   (bfd *);
123 static irix_compat_t elf64_mips_irix_compat
124   (bfd *);
125 static bfd_boolean elf64_mips_grok_prstatus
126   (bfd *, Elf_Internal_Note *);
127 static bfd_boolean elf64_mips_grok_psinfo
128   (bfd *, Elf_Internal_Note *);
129
130 extern const bfd_target bfd_elf64_bigmips_vec;
131 extern const bfd_target bfd_elf64_littlemips_vec;
132
133 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
134    from smaller values.  Start with zero, widen, *then* decrement.  */
135 #define MINUS_ONE       (((bfd_vma)0) - 1)
136
137 /* The number of local .got entries we reserve.  */
138 #define MIPS_RESERVED_GOTNO (2)
139 \f
140 /* The relocation table used for SHT_REL sections.  */
141
142 static reloc_howto_type mips_elf64_howto_table_rel[] =
143 {
144   /* No relocation.  */
145   HOWTO (R_MIPS_NONE,           /* type */
146          0,                     /* rightshift */
147          0,                     /* size (0 = byte, 1 = short, 2 = long) */
148          0,                     /* bitsize */
149          FALSE,                 /* pc_relative */
150          0,                     /* bitpos */
151          complain_overflow_dont, /* complain_on_overflow */
152          _bfd_mips_elf_generic_reloc,   /* special_function */
153          "R_MIPS_NONE",         /* name */
154          FALSE,                 /* partial_inplace */
155          0,                     /* src_mask */
156          0,                     /* dst_mask */
157          FALSE),                /* pcrel_offset */
158
159   /* 16 bit relocation.  */
160   HOWTO (R_MIPS_16,             /* type */
161          0,                     /* rightshift */
162          2,                     /* size (0 = byte, 1 = short, 2 = long) */
163          16,                    /* bitsize */
164          FALSE,                 /* pc_relative */
165          0,                     /* bitpos */
166          complain_overflow_signed, /* complain_on_overflow */
167          _bfd_mips_elf_generic_reloc,   /* special_function */
168          "R_MIPS_16",           /* name */
169          TRUE,                  /* partial_inplace */
170          0x0000ffff,            /* src_mask */
171          0x0000ffff,            /* dst_mask */
172          FALSE),                /* pcrel_offset */
173
174   /* 32 bit relocation.  */
175   HOWTO (R_MIPS_32,             /* type */
176          0,                     /* rightshift */
177          2,                     /* size (0 = byte, 1 = short, 2 = long) */
178          32,                    /* bitsize */
179          FALSE,                 /* pc_relative */
180          0,                     /* bitpos */
181          complain_overflow_dont, /* complain_on_overflow */
182          _bfd_mips_elf_generic_reloc,   /* special_function */
183          "R_MIPS_32",           /* name */
184          TRUE,                  /* partial_inplace */
185          0xffffffff,            /* src_mask */
186          0xffffffff,            /* dst_mask */
187          FALSE),                /* pcrel_offset */
188
189   /* 32 bit symbol relative relocation.  */
190   HOWTO (R_MIPS_REL32,          /* type */
191          0,                     /* rightshift */
192          2,                     /* size (0 = byte, 1 = short, 2 = long) */
193          32,                    /* bitsize */
194          FALSE,                 /* pc_relative */
195          0,                     /* bitpos */
196          complain_overflow_dont, /* complain_on_overflow */
197          _bfd_mips_elf_generic_reloc,   /* special_function */
198          "R_MIPS_REL32",        /* name */
199          TRUE,                  /* partial_inplace */
200          0xffffffff,            /* src_mask */
201          0xffffffff,            /* dst_mask */
202          FALSE),                /* pcrel_offset */
203
204   /* 26 bit jump address.  */
205   HOWTO (R_MIPS_26,             /* type */
206          2,                     /* rightshift */
207          2,                     /* size (0 = byte, 1 = short, 2 = long) */
208          26,                    /* bitsize */
209          FALSE,                 /* pc_relative */
210          0,                     /* bitpos */
211          complain_overflow_dont, /* complain_on_overflow */
212                                 /* This needs complex overflow
213                                    detection, because the upper 36
214                                    bits must match the PC + 4.  */
215          _bfd_mips_elf_generic_reloc,   /* special_function */
216          "R_MIPS_26",           /* name */
217          TRUE,                  /* partial_inplace */
218          0x03ffffff,            /* src_mask */
219          0x03ffffff,            /* dst_mask */
220          FALSE),                /* pcrel_offset */
221
222   /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
223      However, the native IRIX6 tools use them, so we try our best. */
224
225   /* High 16 bits of symbol value.  */
226   HOWTO (R_MIPS_HI16,           /* type */
227          16,                    /* rightshift */
228          2,                     /* size (0 = byte, 1 = short, 2 = long) */
229          16,                    /* bitsize */
230          FALSE,                 /* pc_relative */
231          0,                     /* bitpos */
232          complain_overflow_dont, /* complain_on_overflow */
233          _bfd_mips_elf_hi16_reloc, /* special_function */
234          "R_MIPS_HI16",         /* name */
235          TRUE,                  /* partial_inplace */
236          0x0000ffff,            /* src_mask */
237          0x0000ffff,            /* dst_mask */
238          FALSE),                /* pcrel_offset */
239
240   /* Low 16 bits of symbol value.  */
241   HOWTO (R_MIPS_LO16,           /* type */
242          0,                     /* rightshift */
243          2,                     /* size (0 = byte, 1 = short, 2 = long) */
244          16,                    /* bitsize */
245          FALSE,                 /* pc_relative */
246          0,                     /* bitpos */
247          complain_overflow_dont, /* complain_on_overflow */
248          _bfd_mips_elf_lo16_reloc, /* special_function */
249          "R_MIPS_LO16",         /* name */
250          TRUE,                  /* partial_inplace */
251          0x0000ffff,            /* src_mask */
252          0x0000ffff,            /* dst_mask */
253          FALSE),                /* pcrel_offset */
254
255   /* GP relative reference.  */
256   HOWTO (R_MIPS_GPREL16,        /* type */
257          0,                     /* rightshift */
258          2,                     /* size (0 = byte, 1 = short, 2 = long) */
259          16,                    /* bitsize */
260          FALSE,                 /* pc_relative */
261          0,                     /* bitpos */
262          complain_overflow_signed, /* complain_on_overflow */
263          mips_elf64_gprel16_reloc, /* special_function */
264          "R_MIPS_GPREL16",      /* name */
265          TRUE,                  /* partial_inplace */
266          0x0000ffff,            /* src_mask */
267          0x0000ffff,            /* dst_mask */
268          FALSE),                /* pcrel_offset */
269
270   /* Reference to literal section.  */
271   HOWTO (R_MIPS_LITERAL,        /* type */
272          0,                     /* rightshift */
273          2,                     /* size (0 = byte, 1 = short, 2 = long) */
274          16,                    /* bitsize */
275          FALSE,                 /* pc_relative */
276          0,                     /* bitpos */
277          complain_overflow_signed, /* complain_on_overflow */
278          mips_elf64_literal_reloc, /* special_function */
279          "R_MIPS_LITERAL",      /* name */
280          TRUE,                  /* partial_inplace */
281          0x0000ffff,            /* src_mask */
282          0x0000ffff,            /* dst_mask */
283          FALSE),                /* pcrel_offset */
284
285   /* Reference to global offset table.  */
286   HOWTO (R_MIPS_GOT16,          /* type */
287          0,                     /* rightshift */
288          2,                     /* size (0 = byte, 1 = short, 2 = long) */
289          16,                    /* bitsize */
290          FALSE,                 /* pc_relative */
291          0,                     /* bitpos */
292          complain_overflow_signed, /* complain_on_overflow */
293          _bfd_mips_elf_got16_reloc, /* special_function */
294          "R_MIPS_GOT16",        /* name */
295          TRUE,                  /* partial_inplace */
296          0x0000ffff,            /* src_mask */
297          0x0000ffff,            /* dst_mask */
298          FALSE),                /* pcrel_offset */
299
300   /* 16 bit PC relative reference.  Note that the ABI document has a typo
301      and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
302      We do the right thing here.  */
303   HOWTO (R_MIPS_PC16,           /* type */
304          2,                     /* rightshift */
305          2,                     /* size (0 = byte, 1 = short, 2 = long) */
306          16,                    /* bitsize */
307          TRUE,                  /* pc_relative */
308          0,                     /* bitpos */
309          complain_overflow_signed, /* complain_on_overflow */
310          _bfd_mips_elf_generic_reloc,   /* special_function */
311          "R_MIPS_PC16",         /* name */
312          TRUE,                  /* partial_inplace */
313          0x0000ffff,            /* src_mask */
314          0x0000ffff,            /* dst_mask */
315          TRUE),                 /* pcrel_offset */
316
317   /* 16 bit call through global offset table.  */
318   HOWTO (R_MIPS_CALL16,         /* type */
319          0,                     /* rightshift */
320          2,                     /* size (0 = byte, 1 = short, 2 = long) */
321          16,                    /* bitsize */
322          FALSE,                 /* pc_relative */
323          0,                     /* bitpos */
324          complain_overflow_signed, /* complain_on_overflow */
325          _bfd_mips_elf_generic_reloc,   /* special_function */
326          "R_MIPS_CALL16",       /* name */
327          TRUE,                  /* partial_inplace */
328          0x0000ffff,            /* src_mask */
329          0x0000ffff,            /* dst_mask */
330          FALSE),                /* pcrel_offset */
331
332   /* 32 bit GP relative reference.  */
333   HOWTO (R_MIPS_GPREL32,        /* type */
334          0,                     /* rightshift */
335          2,                     /* size (0 = byte, 1 = short, 2 = long) */
336          32,                    /* bitsize */
337          FALSE,                 /* pc_relative */
338          0,                     /* bitpos */
339          complain_overflow_dont, /* complain_on_overflow */
340          mips_elf64_gprel32_reloc, /* special_function */
341          "R_MIPS_GPREL32",      /* name */
342          TRUE,                  /* partial_inplace */
343          0xffffffff,            /* src_mask */
344          0xffffffff,            /* dst_mask */
345          FALSE),                /* pcrel_offset */
346
347   EMPTY_HOWTO (13),
348   EMPTY_HOWTO (14),
349   EMPTY_HOWTO (15),
350
351   /* A 5 bit shift field.  */
352   HOWTO (R_MIPS_SHIFT5,         /* type */
353          0,                     /* rightshift */
354          2,                     /* size (0 = byte, 1 = short, 2 = long) */
355          5,                     /* bitsize */
356          FALSE,                 /* pc_relative */
357          6,                     /* bitpos */
358          complain_overflow_bitfield, /* complain_on_overflow */
359          _bfd_mips_elf_generic_reloc,   /* special_function */
360          "R_MIPS_SHIFT5",       /* name */
361          TRUE,                  /* partial_inplace */
362          0x000007c0,            /* src_mask */
363          0x000007c0,            /* dst_mask */
364          FALSE),                /* pcrel_offset */
365
366   /* A 6 bit shift field.  */
367   HOWTO (R_MIPS_SHIFT6,         /* type */
368          0,                     /* rightshift */
369          2,                     /* size (0 = byte, 1 = short, 2 = long) */
370          6,                     /* bitsize */
371          FALSE,                 /* pc_relative */
372          6,                     /* bitpos */
373          complain_overflow_bitfield, /* complain_on_overflow */
374          mips_elf64_shift6_reloc, /* special_function */
375          "R_MIPS_SHIFT6",       /* name */
376          TRUE,                  /* partial_inplace */
377          0x000007c4,            /* src_mask */
378          0x000007c4,            /* dst_mask */
379          FALSE),                /* pcrel_offset */
380
381   /* 64 bit relocation.  */
382   HOWTO (R_MIPS_64,             /* type */
383          0,                     /* rightshift */
384          4,                     /* size (0 = byte, 1 = short, 2 = long) */
385          64,                    /* bitsize */
386          FALSE,                 /* pc_relative */
387          0,                     /* bitpos */
388          complain_overflow_dont, /* complain_on_overflow */
389          _bfd_mips_elf_generic_reloc,   /* special_function */
390          "R_MIPS_64",           /* name */
391          TRUE,                  /* partial_inplace */
392          MINUS_ONE,             /* src_mask */
393          MINUS_ONE,             /* dst_mask */
394          FALSE),                /* pcrel_offset */
395
396   /* Displacement in the global offset table.  */
397   HOWTO (R_MIPS_GOT_DISP,       /* type */
398          0,                     /* rightshift */
399          2,                     /* size (0 = byte, 1 = short, 2 = long) */
400          16,                    /* bitsize */
401          FALSE,                 /* pc_relative */
402          0,                     /* bitpos */
403          complain_overflow_signed, /* complain_on_overflow */
404          _bfd_mips_elf_generic_reloc,   /* special_function */
405          "R_MIPS_GOT_DISP",     /* name */
406          TRUE,                  /* partial_inplace */
407          0x0000ffff,            /* src_mask */
408          0x0000ffff,            /* dst_mask */
409          FALSE),                /* pcrel_offset */
410
411   /* Displacement to page pointer in the global offset table.  */
412   HOWTO (R_MIPS_GOT_PAGE,       /* type */
413          0,                     /* rightshift */
414          2,                     /* size (0 = byte, 1 = short, 2 = long) */
415          16,                    /* bitsize */
416          FALSE,                 /* pc_relative */
417          0,                     /* bitpos */
418          complain_overflow_signed, /* complain_on_overflow */
419          _bfd_mips_elf_generic_reloc,   /* special_function */
420          "R_MIPS_GOT_PAGE",     /* name */
421          TRUE,                  /* partial_inplace */
422          0x0000ffff,            /* src_mask */
423          0x0000ffff,            /* dst_mask */
424          FALSE),                /* pcrel_offset */
425
426   /* Offset from page pointer in the global offset table.  */
427   HOWTO (R_MIPS_GOT_OFST,       /* type */
428          0,                     /* rightshift */
429          2,                     /* size (0 = byte, 1 = short, 2 = long) */
430          16,                    /* bitsize */
431          FALSE,                 /* pc_relative */
432          0,                     /* bitpos */
433          complain_overflow_signed, /* complain_on_overflow */
434          _bfd_mips_elf_generic_reloc,   /* special_function */
435          "R_MIPS_GOT_OFST",     /* name */
436          TRUE,                  /* partial_inplace */
437          0x0000ffff,            /* src_mask */
438          0x0000ffff,            /* dst_mask */
439          FALSE),                /* pcrel_offset */
440
441   /* High 16 bits of displacement in global offset table.  */
442   HOWTO (R_MIPS_GOT_HI16,       /* type */
443          0,                     /* rightshift */
444          2,                     /* size (0 = byte, 1 = short, 2 = long) */
445          16,                    /* bitsize */
446          FALSE,                 /* pc_relative */
447          0,                     /* bitpos */
448          complain_overflow_dont, /* complain_on_overflow */
449          _bfd_mips_elf_generic_reloc,   /* special_function */
450          "R_MIPS_GOT_HI16",     /* name */
451          TRUE,                  /* partial_inplace */
452          0x0000ffff,            /* src_mask */
453          0x0000ffff,            /* dst_mask */
454          FALSE),                /* pcrel_offset */
455
456   /* Low 16 bits of displacement in global offset table.  */
457   HOWTO (R_MIPS_GOT_LO16,       /* 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_GOT_LO16",     /* name */
466          TRUE,                  /* partial_inplace */
467          0x0000ffff,            /* src_mask */
468          0x0000ffff,            /* dst_mask */
469          FALSE),                /* pcrel_offset */
470
471   /* 64 bit subtraction.  */
472   HOWTO (R_MIPS_SUB,            /* type */
473          0,                     /* rightshift */
474          4,                     /* size (0 = byte, 1 = short, 2 = long) */
475          64,                    /* 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_SUB",          /* name */
481          TRUE,                  /* partial_inplace */
482          MINUS_ONE,             /* src_mask */
483          MINUS_ONE,             /* dst_mask */
484          FALSE),                /* pcrel_offset */
485
486   /* Insert the addend as an instruction.  */
487   /* FIXME: Not handled correctly.  */
488   HOWTO (R_MIPS_INSERT_A,       /* type */
489          0,                     /* rightshift */
490          2,                     /* size (0 = byte, 1 = short, 2 = long) */
491          32,                    /* bitsize */
492          FALSE,                 /* pc_relative */
493          0,                     /* bitpos */
494          complain_overflow_dont, /* complain_on_overflow */
495          _bfd_mips_elf_generic_reloc,   /* special_function */
496          "R_MIPS_INSERT_A",     /* name */
497          TRUE,                  /* partial_inplace */
498          0xffffffff,            /* src_mask */
499          0xffffffff,            /* dst_mask */
500          FALSE),                /* pcrel_offset */
501
502   /* Insert the addend as an instruction, and change all relocations
503      to refer to the old instruction at the address.  */
504   /* FIXME: Not handled correctly.  */
505   HOWTO (R_MIPS_INSERT_B,       /* type */
506          0,                     /* rightshift */
507          2,                     /* size (0 = byte, 1 = short, 2 = long) */
508          32,                    /* bitsize */
509          FALSE,                 /* pc_relative */
510          0,                     /* bitpos */
511          complain_overflow_dont, /* complain_on_overflow */
512          _bfd_mips_elf_generic_reloc,   /* special_function */
513          "R_MIPS_INSERT_B",     /* name */
514          TRUE,                  /* partial_inplace */
515          0xffffffff,            /* src_mask */
516          0xffffffff,            /* dst_mask */
517          FALSE),                /* pcrel_offset */
518
519   /* Delete a 32 bit instruction.  */
520   /* FIXME: Not handled correctly.  */
521   HOWTO (R_MIPS_DELETE,         /* type */
522          0,                     /* rightshift */
523          2,                     /* size (0 = byte, 1 = short, 2 = long) */
524          32,                    /* bitsize */
525          FALSE,                 /* pc_relative */
526          0,                     /* bitpos */
527          complain_overflow_dont, /* complain_on_overflow */
528          _bfd_mips_elf_generic_reloc,   /* special_function */
529          "R_MIPS_DELETE",       /* name */
530          TRUE,                  /* partial_inplace */
531          0xffffffff,            /* src_mask */
532          0xffffffff,            /* dst_mask */
533          FALSE),                /* pcrel_offset */
534
535   /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
536      We don't, because
537        a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
538           R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
539           fallable heuristics.
540        b) No other NewABI toolchain actually emits such relocations.  */
541   EMPTY_HOWTO (R_MIPS_HIGHER),
542   EMPTY_HOWTO (R_MIPS_HIGHEST),
543
544   /* High 16 bits of displacement in global offset table.  */
545   HOWTO (R_MIPS_CALL_HI16,      /* type */
546          0,                     /* rightshift */
547          2,                     /* size (0 = byte, 1 = short, 2 = long) */
548          16,                    /* bitsize */
549          FALSE,                 /* pc_relative */
550          0,                     /* bitpos */
551          complain_overflow_dont, /* complain_on_overflow */
552          _bfd_mips_elf_generic_reloc,   /* special_function */
553          "R_MIPS_CALL_HI16",    /* name */
554          TRUE,                  /* partial_inplace */
555          0x0000ffff,            /* src_mask */
556          0x0000ffff,            /* dst_mask */
557          FALSE),                /* pcrel_offset */
558
559   /* Low 16 bits of displacement in global offset table.  */
560   HOWTO (R_MIPS_CALL_LO16,      /* type */
561          0,                     /* rightshift */
562          2,                     /* size (0 = byte, 1 = short, 2 = long) */
563          16,                    /* bitsize */
564          FALSE,                 /* pc_relative */
565          0,                     /* bitpos */
566          complain_overflow_dont, /* complain_on_overflow */
567          _bfd_mips_elf_generic_reloc,   /* special_function */
568          "R_MIPS_CALL_LO16",    /* name */
569          TRUE,                  /* partial_inplace */
570          0x0000ffff,            /* src_mask */
571          0x0000ffff,            /* dst_mask */
572          FALSE),                /* pcrel_offset */
573
574   /* Section displacement, used by an associated event location section.  */
575   HOWTO (R_MIPS_SCN_DISP,       /* type */
576          0,                     /* rightshift */
577          2,                     /* size (0 = byte, 1 = short, 2 = long) */
578          32,                    /* bitsize */
579          FALSE,                 /* pc_relative */
580          0,                     /* bitpos */
581          complain_overflow_dont, /* complain_on_overflow */
582          _bfd_mips_elf_generic_reloc,   /* special_function */
583          "R_MIPS_SCN_DISP",     /* name */
584          TRUE,                  /* partial_inplace */
585          0xffffffff,            /* src_mask */
586          0xffffffff,            /* dst_mask */
587          FALSE),                /* pcrel_offset */
588
589   HOWTO (R_MIPS_REL16,          /* type */
590          0,                     /* rightshift */
591          1,                     /* size (0 = byte, 1 = short, 2 = long) */
592          16,                    /* bitsize */
593          FALSE,                 /* pc_relative */
594          0,                     /* bitpos */
595          complain_overflow_signed, /* complain_on_overflow */
596          _bfd_mips_elf_generic_reloc,   /* special_function */
597          "R_MIPS_REL16",        /* name */
598          TRUE,                  /* partial_inplace */
599          0xffff,                /* src_mask */
600          0xffff,                /* dst_mask */
601          FALSE),                /* pcrel_offset */
602
603   /* These two are obsolete.  */
604   EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
605   EMPTY_HOWTO (R_MIPS_PJUMP),
606
607   /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
608      It must be used for multigot GOT's (and only there).  */
609   HOWTO (R_MIPS_RELGOT,         /* type */
610          0,                     /* rightshift */
611          2,                     /* size (0 = byte, 1 = short, 2 = long) */
612          32,                    /* bitsize */
613          FALSE,                 /* pc_relative */
614          0,                     /* bitpos */
615          complain_overflow_dont, /* complain_on_overflow */
616          _bfd_mips_elf_generic_reloc,   /* special_function */
617          "R_MIPS_RELGOT",       /* name */
618          TRUE,                  /* partial_inplace */
619          0xffffffff,            /* src_mask */
620          0xffffffff,            /* dst_mask */
621          FALSE),                /* pcrel_offset */
622
623   /* Protected jump conversion.  This is an optimization hint.  No
624      relocation is required for correctness.  */
625   HOWTO (R_MIPS_JALR,           /* type */
626          0,                     /* rightshift */
627          2,                     /* size (0 = byte, 1 = short, 2 = long) */
628          32,                    /* bitsize */
629          FALSE,                 /* pc_relative */
630          0,                     /* bitpos */
631          complain_overflow_dont, /* complain_on_overflow */
632          _bfd_mips_elf_generic_reloc,   /* special_function */
633          "R_MIPS_JALR",         /* name */
634          FALSE,                 /* partial_inplace */
635          0,                     /* src_mask */
636          0x00000000,            /* dst_mask */
637          FALSE),                /* pcrel_offset */
638
639   /* TLS relocations.  */
640   EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
641   EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
642
643   HOWTO (R_MIPS_TLS_DTPMOD64,   /* type */
644          0,                     /* rightshift */
645          4,                     /* size (0 = byte, 1 = short, 2 = long) */
646          64,                    /* bitsize */
647          FALSE,                 /* pc_relative */
648          0,                     /* bitpos */
649          complain_overflow_dont, /* complain_on_overflow */
650          _bfd_mips_elf_generic_reloc, /* special_function */
651          "R_MIPS_TLS_DTPMOD64", /* name */
652          TRUE,                  /* partial_inplace */
653          MINUS_ONE,             /* src_mask */
654          MINUS_ONE,             /* dst_mask */
655          FALSE),                /* pcrel_offset */
656
657   HOWTO (R_MIPS_TLS_DTPREL64,   /* type */
658          0,                     /* rightshift */
659          4,                     /* size (0 = byte, 1 = short, 2 = long) */
660          64,                    /* bitsize */
661          FALSE,                 /* pc_relative */
662          0,                     /* bitpos */
663          complain_overflow_dont, /* complain_on_overflow */
664          _bfd_mips_elf_generic_reloc, /* special_function */
665          "R_MIPS_TLS_DTPREL64", /* name */
666          TRUE,                  /* partial_inplace */
667          MINUS_ONE,             /* src_mask */
668          MINUS_ONE,             /* dst_mask */
669          FALSE),                /* pcrel_offset */
670
671   /* TLS general dynamic variable reference.  */
672   HOWTO (R_MIPS_TLS_GD,         /* type */
673          0,                     /* rightshift */
674          2,                     /* size (0 = byte, 1 = short, 2 = long) */
675          16,                    /* bitsize */
676          FALSE,                 /* pc_relative */
677          0,                     /* bitpos */
678          complain_overflow_signed, /* complain_on_overflow */
679          _bfd_mips_elf_generic_reloc, /* special_function */
680          "R_MIPS_TLS_GD",       /* name */
681          TRUE,                  /* partial_inplace */
682          0x0000ffff,            /* src_mask */
683          0x0000ffff,            /* dst_mask */
684          FALSE),                /* pcrel_offset */
685
686   /* TLS local dynamic variable reference.  */
687   HOWTO (R_MIPS_TLS_LDM,        /* type */
688          0,                     /* rightshift */
689          2,                     /* size (0 = byte, 1 = short, 2 = long) */
690          16,                    /* bitsize */
691          FALSE,                 /* pc_relative */
692          0,                     /* bitpos */
693          complain_overflow_signed, /* complain_on_overflow */
694          _bfd_mips_elf_generic_reloc, /* special_function */
695          "R_MIPS_TLS_LDM",      /* name */
696          TRUE,                  /* partial_inplace */
697          0x0000ffff,            /* src_mask */
698          0x0000ffff,            /* dst_mask */
699          FALSE),                /* pcrel_offset */
700
701   /* TLS local dynamic offset.  */
702   HOWTO (R_MIPS_TLS_DTPREL_HI16,        /* type */
703          0,                     /* rightshift */
704          2,                     /* size (0 = byte, 1 = short, 2 = long) */
705          16,                    /* bitsize */
706          FALSE,                 /* pc_relative */
707          0,                     /* bitpos */
708          complain_overflow_signed, /* complain_on_overflow */
709          _bfd_mips_elf_generic_reloc, /* special_function */
710          "R_MIPS_TLS_DTPREL_HI16",      /* name */
711          TRUE,                  /* partial_inplace */
712          0x0000ffff,            /* src_mask */
713          0x0000ffff,            /* dst_mask */
714          FALSE),                /* pcrel_offset */
715
716   /* TLS local dynamic offset.  */
717   HOWTO (R_MIPS_TLS_DTPREL_LO16,        /* type */
718          0,                     /* rightshift */
719          2,                     /* size (0 = byte, 1 = short, 2 = long) */
720          16,                    /* bitsize */
721          FALSE,                 /* pc_relative */
722          0,                     /* bitpos */
723          complain_overflow_signed, /* complain_on_overflow */
724          _bfd_mips_elf_generic_reloc, /* special_function */
725          "R_MIPS_TLS_DTPREL_LO16",      /* name */
726          TRUE,                  /* partial_inplace */
727          0x0000ffff,            /* src_mask */
728          0x0000ffff,            /* dst_mask */
729          FALSE),                /* pcrel_offset */
730
731   /* TLS thread pointer offset.  */
732   HOWTO (R_MIPS_TLS_GOTTPREL,   /* type */
733          0,                     /* rightshift */
734          2,                     /* size (0 = byte, 1 = short, 2 = long) */
735          16,                    /* bitsize */
736          FALSE,                 /* pc_relative */
737          0,                     /* bitpos */
738          complain_overflow_signed, /* complain_on_overflow */
739          _bfd_mips_elf_generic_reloc, /* special_function */
740          "R_MIPS_TLS_GOTTPREL", /* name */
741          TRUE,                  /* partial_inplace */
742          0x0000ffff,            /* src_mask */
743          0x0000ffff,            /* dst_mask */
744          FALSE),                /* pcrel_offset */
745
746   /* TLS IE dynamic relocations.  */
747   EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
748
749   HOWTO (R_MIPS_TLS_TPREL64,    /* type */
750          0,                     /* rightshift */
751          4,                     /* size (0 = byte, 1 = short, 2 = long) */
752          64,                    /* bitsize */
753          FALSE,                 /* pc_relative */
754          0,                     /* bitpos */
755          complain_overflow_dont, /* complain_on_overflow */
756          _bfd_mips_elf_generic_reloc, /* special_function */
757          "R_MIPS_TLS_TPREL64",  /* name */
758          TRUE,                  /* partial_inplace */
759          MINUS_ONE,             /* src_mask */
760          MINUS_ONE,             /* dst_mask */
761          FALSE),                /* pcrel_offset */
762
763   /* TLS thread pointer offset.  */
764   HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
765          0,                     /* rightshift */
766          2,                     /* size (0 = byte, 1 = short, 2 = long) */
767          16,                    /* bitsize */
768          FALSE,                 /* pc_relative */
769          0,                     /* bitpos */
770          complain_overflow_signed, /* complain_on_overflow */
771          _bfd_mips_elf_generic_reloc, /* special_function */
772          "R_MIPS_TLS_TPREL_HI16", /* name */
773          TRUE,                  /* partial_inplace */
774          0x0000ffff,            /* src_mask */
775          0x0000ffff,            /* dst_mask */
776          FALSE),                /* pcrel_offset */
777
778   /* TLS thread pointer offset.  */
779   HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
780          0,                     /* rightshift */
781          2,                     /* size (0 = byte, 1 = short, 2 = long) */
782          16,                    /* bitsize */
783          FALSE,                 /* pc_relative */
784          0,                     /* bitpos */
785          complain_overflow_signed, /* complain_on_overflow */
786          _bfd_mips_elf_generic_reloc, /* special_function */
787          "R_MIPS_TLS_TPREL_LO16", /* name */
788          TRUE,                  /* partial_inplace */
789          0x0000ffff,            /* src_mask */
790          0x0000ffff,            /* dst_mask */
791          FALSE),                /* pcrel_offset */
792 };
793
794 /* The relocation table used for SHT_RELA sections.  */
795
796 static reloc_howto_type mips_elf64_howto_table_rela[] =
797 {
798   /* No relocation.  */
799   HOWTO (R_MIPS_NONE,           /* type */
800          0,                     /* rightshift */
801          0,                     /* size (0 = byte, 1 = short, 2 = long) */
802          0,                     /* bitsize */
803          FALSE,                 /* pc_relative */
804          0,                     /* bitpos */
805          complain_overflow_dont, /* complain_on_overflow */
806          _bfd_mips_elf_generic_reloc,   /* special_function */
807          "R_MIPS_NONE",         /* name */
808          FALSE,                 /* partial_inplace */
809          0,                     /* src_mask */
810          0,                     /* dst_mask */
811          FALSE),                /* pcrel_offset */
812
813   /* 16 bit relocation.  */
814   HOWTO (R_MIPS_16,             /* type */
815          0,                     /* rightshift */
816          2,                     /* size (0 = byte, 1 = short, 2 = long) */
817          16,                    /* bitsize */
818          FALSE,                 /* pc_relative */
819          0,                     /* bitpos */
820          complain_overflow_signed, /* complain_on_overflow */
821          _bfd_mips_elf_generic_reloc,   /* special_function */
822          "R_MIPS_16",           /* name */
823          FALSE,                 /* partial_inplace */
824          0,                     /* src_mask */
825          0x0000ffff,            /* dst_mask */
826          FALSE),                /* pcrel_offset */
827
828   /* 32 bit relocation.  */
829   HOWTO (R_MIPS_32,             /* type */
830          0,                     /* rightshift */
831          2,                     /* size (0 = byte, 1 = short, 2 = long) */
832          32,                    /* bitsize */
833          FALSE,                 /* pc_relative */
834          0,                     /* bitpos */
835          complain_overflow_dont, /* complain_on_overflow */
836          _bfd_mips_elf_generic_reloc,   /* special_function */
837          "R_MIPS_32",           /* name */
838          FALSE,                 /* partial_inplace */
839          0,                     /* src_mask */
840          0xffffffff,            /* dst_mask */
841          FALSE),                /* pcrel_offset */
842
843   /* 32 bit symbol relative relocation.  */
844   HOWTO (R_MIPS_REL32,          /* type */
845          0,                     /* rightshift */
846          2,                     /* size (0 = byte, 1 = short, 2 = long) */
847          32,                    /* bitsize */
848          FALSE,                 /* pc_relative */
849          0,                     /* bitpos */
850          complain_overflow_dont, /* complain_on_overflow */
851          _bfd_mips_elf_generic_reloc,   /* special_function */
852          "R_MIPS_REL32",        /* name */
853          FALSE,                 /* partial_inplace */
854          0,                     /* src_mask */
855          0xffffffff,            /* dst_mask */
856          FALSE),                /* pcrel_offset */
857
858   /* 26 bit jump address.  */
859   HOWTO (R_MIPS_26,             /* type */
860          2,                     /* rightshift */
861          2,                     /* size (0 = byte, 1 = short, 2 = long) */
862          26,                    /* bitsize */
863          FALSE,                 /* pc_relative */
864          0,                     /* bitpos */
865          complain_overflow_dont, /* complain_on_overflow */
866                                 /* This needs complex overflow
867                                    detection, because the upper 36
868                                    bits must match the PC + 4.  */
869          _bfd_mips_elf_generic_reloc,   /* special_function */
870          "R_MIPS_26",           /* name */
871          FALSE,                 /* partial_inplace */
872          0,                     /* src_mask */
873          0x03ffffff,            /* dst_mask */
874          FALSE),                /* pcrel_offset */
875
876   /* High 16 bits of symbol value.  */
877   HOWTO (R_MIPS_HI16,           /* type */
878          0,                     /* rightshift */
879          2,                     /* size (0 = byte, 1 = short, 2 = long) */
880          16,                    /* bitsize */
881          FALSE,                 /* pc_relative */
882          0,                     /* bitpos */
883          complain_overflow_dont, /* complain_on_overflow */
884          _bfd_mips_elf_generic_reloc,   /* special_function */
885          "R_MIPS_HI16",         /* name */
886          FALSE,                 /* partial_inplace */
887          0,                     /* src_mask */
888          0x0000ffff,            /* dst_mask */
889          FALSE),                /* pcrel_offset */
890
891   /* Low 16 bits of symbol value.  */
892   HOWTO (R_MIPS_LO16,           /* type */
893          0,                     /* rightshift */
894          2,                     /* size (0 = byte, 1 = short, 2 = long) */
895          16,                    /* bitsize */
896          FALSE,                 /* pc_relative */
897          0,                     /* bitpos */
898          complain_overflow_dont, /* complain_on_overflow */
899          _bfd_mips_elf_generic_reloc,   /* special_function */
900          "R_MIPS_LO16",         /* name */
901          FALSE,                 /* partial_inplace */
902          0,                     /* src_mask */
903          0x0000ffff,            /* dst_mask */
904          FALSE),                /* pcrel_offset */
905
906   /* GP relative reference.  */
907   HOWTO (R_MIPS_GPREL16,        /* type */
908          0,                     /* rightshift */
909          2,                     /* size (0 = byte, 1 = short, 2 = long) */
910          16,                    /* bitsize */
911          FALSE,                 /* pc_relative */
912          0,                     /* bitpos */
913          complain_overflow_signed, /* complain_on_overflow */
914          mips_elf64_gprel16_reloc, /* special_function */
915          "R_MIPS_GPREL16",      /* name */
916          FALSE,                 /* partial_inplace */
917          0,                     /* src_mask */
918          0x0000ffff,            /* dst_mask */
919          FALSE),                /* pcrel_offset */
920
921   /* Reference to literal section.  */
922   HOWTO (R_MIPS_LITERAL,        /* type */
923          0,                     /* rightshift */
924          2,                     /* size (0 = byte, 1 = short, 2 = long) */
925          16,                    /* bitsize */
926          FALSE,                 /* pc_relative */
927          0,                     /* bitpos */
928          complain_overflow_signed, /* complain_on_overflow */
929          mips_elf64_literal_reloc, /* special_function */
930          "R_MIPS_LITERAL",      /* name */
931          FALSE,                 /* partial_inplace */
932          0,                     /* src_mask */
933          0x0000ffff,            /* dst_mask */
934          FALSE),                /* pcrel_offset */
935
936   /* Reference to global offset table.  */
937   HOWTO (R_MIPS_GOT16,          /* type */
938          0,                     /* rightshift */
939          2,                     /* size (0 = byte, 1 = short, 2 = long) */
940          16,                    /* bitsize */
941          FALSE,                 /* pc_relative */
942          0,                     /* bitpos */
943          complain_overflow_signed, /* complain_on_overflow */
944          _bfd_mips_elf_generic_reloc, /* special_function */
945          "R_MIPS_GOT16",        /* name */
946          FALSE,                 /* partial_inplace */
947          0,                     /* src_mask */
948          0x0000ffff,            /* dst_mask */
949          FALSE),                /* pcrel_offset */
950
951   /* 16 bit PC relative reference.  Note that the ABI document has a typo
952      and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
953      We do the right thing here.  */
954   HOWTO (R_MIPS_PC16,           /* type */
955          2,                     /* rightshift */
956          2,                     /* size (0 = byte, 1 = short, 2 = long) */
957          16,                    /* bitsize */
958          TRUE,                  /* pc_relative */
959          0,                     /* bitpos */
960          complain_overflow_signed, /* complain_on_overflow */
961          _bfd_mips_elf_generic_reloc,   /* special_function */
962          "R_MIPS_PC16",         /* name */
963          FALSE,                 /* partial_inplace */
964          0,                     /* src_mask */
965          0x0000ffff,            /* dst_mask */
966          TRUE),                 /* pcrel_offset */
967
968   /* 16 bit call through global offset table.  */
969   HOWTO (R_MIPS_CALL16,         /* type */
970          0,                     /* rightshift */
971          2,                     /* size (0 = byte, 1 = short, 2 = long) */
972          16,                    /* bitsize */
973          FALSE,                 /* pc_relative */
974          0,                     /* bitpos */
975          complain_overflow_signed, /* complain_on_overflow */
976          _bfd_mips_elf_generic_reloc,   /* special_function */
977          "R_MIPS_CALL16",       /* name */
978          FALSE,                 /* partial_inplace */
979          0,                     /* src_mask */
980          0x0000ffff,            /* dst_mask */
981          FALSE),                /* pcrel_offset */
982
983   /* 32 bit GP relative reference.  */
984   HOWTO (R_MIPS_GPREL32,        /* type */
985          0,                     /* rightshift */
986          2,                     /* size (0 = byte, 1 = short, 2 = long) */
987          32,                    /* bitsize */
988          FALSE,                 /* pc_relative */
989          0,                     /* bitpos */
990          complain_overflow_dont, /* complain_on_overflow */
991          mips_elf64_gprel32_reloc, /* special_function */
992          "R_MIPS_GPREL32",      /* name */
993          FALSE,                 /* partial_inplace */
994          0,                     /* src_mask */
995          0xffffffff,            /* dst_mask */
996          FALSE),                /* pcrel_offset */
997
998   EMPTY_HOWTO (13),
999   EMPTY_HOWTO (14),
1000   EMPTY_HOWTO (15),
1001
1002   /* A 5 bit shift field.  */
1003   HOWTO (R_MIPS_SHIFT5,         /* type */
1004          0,                     /* rightshift */
1005          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1006          5,                     /* bitsize */
1007          FALSE,                 /* pc_relative */
1008          6,                     /* bitpos */
1009          complain_overflow_bitfield, /* complain_on_overflow */
1010          _bfd_mips_elf_generic_reloc,   /* special_function */
1011          "R_MIPS_SHIFT5",       /* name */
1012          FALSE,                 /* partial_inplace */
1013          0,                     /* src_mask */
1014          0x000007c0,            /* dst_mask */
1015          FALSE),                /* pcrel_offset */
1016
1017   /* A 6 bit shift field.  */
1018   HOWTO (R_MIPS_SHIFT6,         /* type */
1019          0,                     /* rightshift */
1020          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1021          6,                     /* bitsize */
1022          FALSE,                 /* pc_relative */
1023          6,                     /* bitpos */
1024          complain_overflow_bitfield, /* complain_on_overflow */
1025          mips_elf64_shift6_reloc, /* special_function */
1026          "R_MIPS_SHIFT6",       /* name */
1027          FALSE,                 /* partial_inplace */
1028          0,                     /* src_mask */
1029          0x000007c4,            /* dst_mask */
1030          FALSE),                /* pcrel_offset */
1031
1032   /* 64 bit relocation.  */
1033   HOWTO (R_MIPS_64,             /* type */
1034          0,                     /* rightshift */
1035          4,                     /* size (0 = byte, 1 = short, 2 = long) */
1036          64,                    /* bitsize */
1037          FALSE,                 /* pc_relative */
1038          0,                     /* bitpos */
1039          complain_overflow_dont, /* complain_on_overflow */
1040          _bfd_mips_elf_generic_reloc,   /* special_function */
1041          "R_MIPS_64",           /* name */
1042          FALSE,                 /* partial_inplace */
1043          0,                     /* src_mask */
1044          MINUS_ONE,             /* dst_mask */
1045          FALSE),                /* pcrel_offset */
1046
1047   /* Displacement in the global offset table.  */
1048   HOWTO (R_MIPS_GOT_DISP,       /* type */
1049          0,                     /* rightshift */
1050          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1051          16,                    /* bitsize */
1052          FALSE,                 /* pc_relative */
1053          0,                     /* bitpos */
1054          complain_overflow_signed, /* complain_on_overflow */
1055          _bfd_mips_elf_generic_reloc,   /* special_function */
1056          "R_MIPS_GOT_DISP",     /* name */
1057          FALSE,                 /* partial_inplace */
1058          0,                     /* src_mask */
1059          0x0000ffff,            /* dst_mask */
1060          FALSE),                /* pcrel_offset */
1061
1062   /* Displacement to page pointer in the global offset table.  */
1063   HOWTO (R_MIPS_GOT_PAGE,       /* type */
1064          0,                     /* rightshift */
1065          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1066          16,                    /* bitsize */
1067          FALSE,                 /* pc_relative */
1068          0,                     /* bitpos */
1069          complain_overflow_signed, /* complain_on_overflow */
1070          _bfd_mips_elf_generic_reloc,   /* special_function */
1071          "R_MIPS_GOT_PAGE",     /* name */
1072          FALSE,                 /* partial_inplace */
1073          0,                     /* src_mask */
1074          0x0000ffff,            /* dst_mask */
1075          FALSE),                /* pcrel_offset */
1076
1077   /* Offset from page pointer in the global offset table.  */
1078   HOWTO (R_MIPS_GOT_OFST,       /* type */
1079          0,                     /* rightshift */
1080          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1081          16,                    /* bitsize */
1082          FALSE,                 /* pc_relative */
1083          0,                     /* bitpos */
1084          complain_overflow_signed, /* complain_on_overflow */
1085          _bfd_mips_elf_generic_reloc,   /* special_function */
1086          "R_MIPS_GOT_OFST",     /* name */
1087          FALSE,                 /* partial_inplace */
1088          0,                     /* src_mask */
1089          0x0000ffff,            /* dst_mask */
1090          FALSE),                /* pcrel_offset */
1091
1092   /* High 16 bits of displacement in global offset table.  */
1093   HOWTO (R_MIPS_GOT_HI16,       /* type */
1094          0,                     /* rightshift */
1095          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1096          16,                    /* bitsize */
1097          FALSE,                 /* pc_relative */
1098          0,                     /* bitpos */
1099          complain_overflow_dont, /* complain_on_overflow */
1100          _bfd_mips_elf_generic_reloc,   /* special_function */
1101          "R_MIPS_GOT_HI16",     /* name */
1102          FALSE,                 /* partial_inplace */
1103          0,                     /* src_mask */
1104          0x0000ffff,            /* dst_mask */
1105          FALSE),                /* pcrel_offset */
1106
1107   /* Low 16 bits of displacement in global offset table.  */
1108   HOWTO (R_MIPS_GOT_LO16,       /* type */
1109          0,                     /* rightshift */
1110          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1111          16,                    /* bitsize */
1112          FALSE,                 /* pc_relative */
1113          0,                     /* bitpos */
1114          complain_overflow_dont, /* complain_on_overflow */
1115          _bfd_mips_elf_generic_reloc,   /* special_function */
1116          "R_MIPS_GOT_LO16",     /* name */
1117          FALSE,                 /* partial_inplace */
1118          0,                     /* src_mask */
1119          0x0000ffff,            /* dst_mask */
1120          FALSE),                /* pcrel_offset */
1121
1122   /* 64 bit subtraction.  */
1123   HOWTO (R_MIPS_SUB,            /* type */
1124          0,                     /* rightshift */
1125          4,                     /* size (0 = byte, 1 = short, 2 = long) */
1126          64,                    /* bitsize */
1127          FALSE,                 /* pc_relative */
1128          0,                     /* bitpos */
1129          complain_overflow_dont, /* complain_on_overflow */
1130          _bfd_mips_elf_generic_reloc,   /* special_function */
1131          "R_MIPS_SUB",          /* name */
1132          FALSE,                 /* partial_inplace */
1133          0,                     /* src_mask */
1134          MINUS_ONE,             /* dst_mask */
1135          FALSE),                /* pcrel_offset */
1136
1137   /* Insert the addend as an instruction.  */
1138   /* FIXME: Not handled correctly.  */
1139   HOWTO (R_MIPS_INSERT_A,       /* type */
1140          0,                     /* rightshift */
1141          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1142          32,                    /* bitsize */
1143          FALSE,                 /* pc_relative */
1144          0,                     /* bitpos */
1145          complain_overflow_dont, /* complain_on_overflow */
1146          _bfd_mips_elf_generic_reloc,   /* special_function */
1147          "R_MIPS_INSERT_A",     /* name */
1148          FALSE,                 /* partial_inplace */
1149          0,                     /* src_mask */
1150          0xffffffff,            /* dst_mask */
1151          FALSE),                /* pcrel_offset */
1152
1153   /* Insert the addend as an instruction, and change all relocations
1154      to refer to the old instruction at the address.  */
1155   /* FIXME: Not handled correctly.  */
1156   HOWTO (R_MIPS_INSERT_B,       /* type */
1157          0,                     /* rightshift */
1158          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1159          32,                    /* bitsize */
1160          FALSE,                 /* pc_relative */
1161          0,                     /* bitpos */
1162          complain_overflow_dont, /* complain_on_overflow */
1163          _bfd_mips_elf_generic_reloc,   /* special_function */
1164          "R_MIPS_INSERT_B",     /* name */
1165          FALSE,                 /* partial_inplace */
1166          0,                     /* src_mask */
1167          0xffffffff,            /* dst_mask */
1168          FALSE),                /* pcrel_offset */
1169
1170   /* Delete a 32 bit instruction.  */
1171   /* FIXME: Not handled correctly.  */
1172   HOWTO (R_MIPS_DELETE,         /* type */
1173          0,                     /* rightshift */
1174          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1175          32,                    /* bitsize */
1176          FALSE,                 /* pc_relative */
1177          0,                     /* bitpos */
1178          complain_overflow_dont, /* complain_on_overflow */
1179          _bfd_mips_elf_generic_reloc,   /* special_function */
1180          "R_MIPS_DELETE",       /* name */
1181          FALSE,                 /* partial_inplace */
1182          0,                     /* src_mask */
1183          0xffffffff,            /* dst_mask */
1184          FALSE),                /* pcrel_offset */
1185
1186   /* Get the higher value of a 64 bit addend.  */
1187   HOWTO (R_MIPS_HIGHER,         /* type */
1188          0,                     /* rightshift */
1189          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1190          16,                    /* bitsize */
1191          FALSE,                 /* pc_relative */
1192          0,                     /* bitpos */
1193          complain_overflow_dont, /* complain_on_overflow */
1194          _bfd_mips_elf_generic_reloc, /* special_function */
1195          "R_MIPS_HIGHER",       /* name */
1196          FALSE,                 /* partial_inplace */
1197          0,                     /* src_mask */
1198          0x0000ffff,            /* dst_mask */
1199          FALSE),                /* pcrel_offset */
1200
1201   /* Get the highest value of a 64 bit addend.  */
1202   HOWTO (R_MIPS_HIGHEST,        /* type */
1203          0,                     /* rightshift */
1204          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1205          16,                    /* bitsize */
1206          FALSE,                 /* pc_relative */
1207          0,                     /* bitpos */
1208          complain_overflow_dont, /* complain_on_overflow */
1209          _bfd_mips_elf_generic_reloc, /* special_function */
1210          "R_MIPS_HIGHEST",      /* name */
1211          FALSE,                 /* partial_inplace */
1212          0,                     /* src_mask */
1213          0x0000ffff,            /* dst_mask */
1214          FALSE),                /* pcrel_offset */
1215
1216   /* High 16 bits of displacement in global offset table.  */
1217   HOWTO (R_MIPS_CALL_HI16,      /* type */
1218          0,                     /* rightshift */
1219          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1220          16,                    /* bitsize */
1221          FALSE,                 /* pc_relative */
1222          0,                     /* bitpos */
1223          complain_overflow_dont, /* complain_on_overflow */
1224          _bfd_mips_elf_generic_reloc,   /* special_function */
1225          "R_MIPS_CALL_HI16",    /* name */
1226          FALSE,                 /* partial_inplace */
1227          0,                     /* src_mask */
1228          0x0000ffff,            /* dst_mask */
1229          FALSE),                /* pcrel_offset */
1230
1231   /* Low 16 bits of displacement in global offset table.  */
1232   HOWTO (R_MIPS_CALL_LO16,      /* type */
1233          0,                     /* rightshift */
1234          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1235          16,                    /* bitsize */
1236          FALSE,                 /* pc_relative */
1237          0,                     /* bitpos */
1238          complain_overflow_dont, /* complain_on_overflow */
1239          _bfd_mips_elf_generic_reloc,   /* special_function */
1240          "R_MIPS_CALL_LO16",    /* name */
1241          FALSE,                 /* partial_inplace */
1242          0,                     /* src_mask */
1243          0x0000ffff,            /* dst_mask */
1244          FALSE),                /* pcrel_offset */
1245
1246   /* Section displacement, used by an associated event location section.  */
1247   HOWTO (R_MIPS_SCN_DISP,       /* type */
1248          0,                     /* rightshift */
1249          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1250          32,                    /* bitsize */
1251          FALSE,                 /* pc_relative */
1252          0,                     /* bitpos */
1253          complain_overflow_dont, /* complain_on_overflow */
1254          _bfd_mips_elf_generic_reloc,   /* special_function */
1255          "R_MIPS_SCN_DISP",     /* name */
1256          FALSE,                 /* partial_inplace */
1257          0,                     /* src_mask */
1258          0xffffffff,            /* dst_mask */
1259          FALSE),                /* pcrel_offset */
1260
1261   HOWTO (R_MIPS_REL16,          /* type */
1262          0,                     /* rightshift */
1263          1,                     /* size (0 = byte, 1 = short, 2 = long) */
1264          16,                    /* bitsize */
1265          FALSE,                 /* pc_relative */
1266          0,                     /* bitpos */
1267          complain_overflow_signed, /* complain_on_overflow */
1268          _bfd_mips_elf_generic_reloc,   /* special_function */
1269          "R_MIPS_REL16",        /* name */
1270          FALSE,                 /* partial_inplace */
1271          0,                     /* src_mask */
1272          0xffff,                /* dst_mask */
1273          FALSE),                /* pcrel_offset */
1274
1275   /* These two are obsolete.  */
1276   EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1277   EMPTY_HOWTO (R_MIPS_PJUMP),
1278
1279   /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1280      It must be used for multigot GOT's (and only there).  */
1281   HOWTO (R_MIPS_RELGOT,         /* type */
1282          0,                     /* rightshift */
1283          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1284          32,                    /* bitsize */
1285          FALSE,                 /* pc_relative */
1286          0,                     /* bitpos */
1287          complain_overflow_dont, /* complain_on_overflow */
1288          _bfd_mips_elf_generic_reloc,   /* special_function */
1289          "R_MIPS_RELGOT",       /* name */
1290          FALSE,                 /* partial_inplace */
1291          0,                     /* src_mask */
1292          0xffffffff,            /* dst_mask */
1293          FALSE),                /* pcrel_offset */
1294
1295   /* Protected jump conversion.  This is an optimization hint.  No
1296      relocation is required for correctness.  */
1297   HOWTO (R_MIPS_JALR,           /* type */
1298          0,                     /* rightshift */
1299          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1300          32,                    /* bitsize */
1301          FALSE,                 /* pc_relative */
1302          0,                     /* bitpos */
1303          complain_overflow_dont, /* complain_on_overflow */
1304          _bfd_mips_elf_generic_reloc,   /* special_function */
1305          "R_MIPS_JALR",         /* name */
1306          FALSE,                 /* partial_inplace */
1307          0,                     /* src_mask */
1308          0x00000000,            /* dst_mask */
1309          FALSE),                /* pcrel_offset */
1310
1311   /* TLS relocations.  */
1312   EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
1313   EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
1314   EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
1315   EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
1316
1317   /* TLS general dynamic variable reference.  */
1318   HOWTO (R_MIPS_TLS_GD,         /* type */
1319          0,                     /* rightshift */
1320          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1321          16,                    /* bitsize */
1322          FALSE,                 /* pc_relative */
1323          0,                     /* bitpos */
1324          complain_overflow_signed, /* complain_on_overflow */
1325          _bfd_mips_elf_generic_reloc, /* special_function */
1326          "R_MIPS_TLS_GD",       /* name */
1327          TRUE,                  /* partial_inplace */
1328          0x0000ffff,            /* src_mask */
1329          0x0000ffff,            /* dst_mask */
1330          FALSE),                /* pcrel_offset */
1331
1332   /* TLS local dynamic variable reference.  */
1333   HOWTO (R_MIPS_TLS_LDM,        /* type */
1334          0,                     /* rightshift */
1335          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1336          16,                    /* bitsize */
1337          FALSE,                 /* pc_relative */
1338          0,                     /* bitpos */
1339          complain_overflow_signed, /* complain_on_overflow */
1340          _bfd_mips_elf_generic_reloc, /* special_function */
1341          "R_MIPS_TLS_LDM",      /* name */
1342          TRUE,                  /* partial_inplace */
1343          0x0000ffff,            /* src_mask */
1344          0x0000ffff,            /* dst_mask */
1345          FALSE),                /* pcrel_offset */
1346
1347   /* TLS local dynamic offset.  */
1348   HOWTO (R_MIPS_TLS_DTPREL_HI16,        /* type */
1349          0,                     /* rightshift */
1350          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1351          16,                    /* bitsize */
1352          FALSE,                 /* pc_relative */
1353          0,                     /* bitpos */
1354          complain_overflow_signed, /* complain_on_overflow */
1355          _bfd_mips_elf_generic_reloc, /* special_function */
1356          "R_MIPS_TLS_DTPREL_HI16",      /* name */
1357          TRUE,                  /* partial_inplace */
1358          0x0000ffff,            /* src_mask */
1359          0x0000ffff,            /* dst_mask */
1360          FALSE),                /* pcrel_offset */
1361
1362   /* TLS local dynamic offset.  */
1363   HOWTO (R_MIPS_TLS_DTPREL_LO16,        /* type */
1364          0,                     /* rightshift */
1365          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1366          16,                    /* bitsize */
1367          FALSE,                 /* pc_relative */
1368          0,                     /* bitpos */
1369          complain_overflow_signed, /* complain_on_overflow */
1370          _bfd_mips_elf_generic_reloc, /* special_function */
1371          "R_MIPS_TLS_DTPREL_LO16",      /* name */
1372          TRUE,                  /* partial_inplace */
1373          0x0000ffff,            /* src_mask */
1374          0x0000ffff,            /* dst_mask */
1375          FALSE),                /* pcrel_offset */
1376
1377   /* TLS thread pointer offset.  */
1378   HOWTO (R_MIPS_TLS_GOTTPREL,   /* type */
1379          0,                     /* rightshift */
1380          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1381          16,                    /* bitsize */
1382          FALSE,                 /* pc_relative */
1383          0,                     /* bitpos */
1384          complain_overflow_signed, /* complain_on_overflow */
1385          _bfd_mips_elf_generic_reloc, /* special_function */
1386          "R_MIPS_TLS_GOTTPREL", /* name */
1387          TRUE,                  /* partial_inplace */
1388          0x0000ffff,            /* src_mask */
1389          0x0000ffff,            /* dst_mask */
1390          FALSE),                /* pcrel_offset */
1391
1392   EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
1393   EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
1394
1395   /* TLS thread pointer offset.  */
1396   HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
1397          0,                     /* rightshift */
1398          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1399          16,                    /* bitsize */
1400          FALSE,                 /* pc_relative */
1401          0,                     /* bitpos */
1402          complain_overflow_signed, /* complain_on_overflow */
1403          _bfd_mips_elf_generic_reloc, /* special_function */
1404          "R_MIPS_TLS_TPREL_HI16", /* name */
1405          TRUE,                  /* partial_inplace */
1406          0x0000ffff,            /* src_mask */
1407          0x0000ffff,            /* dst_mask */
1408          FALSE),                /* pcrel_offset */
1409
1410   /* TLS thread pointer offset.  */
1411   HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
1412          0,                     /* rightshift */
1413          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1414          16,                    /* bitsize */
1415          FALSE,                 /* pc_relative */
1416          0,                     /* bitpos */
1417          complain_overflow_signed, /* complain_on_overflow */
1418          _bfd_mips_elf_generic_reloc, /* special_function */
1419          "R_MIPS_TLS_TPREL_LO16", /* name */
1420          TRUE,                  /* partial_inplace */
1421          0x0000ffff,            /* src_mask */
1422          0x0000ffff,            /* dst_mask */
1423          FALSE),                /* pcrel_offset */
1424 };
1425
1426 static reloc_howto_type mips16_elf64_howto_table_rel[] =
1427 {
1428   /* The reloc used for the mips16 jump instruction.  */
1429   HOWTO (R_MIPS16_26,           /* type */
1430          2,                     /* rightshift */
1431          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1432          26,                    /* bitsize */
1433          FALSE,                 /* pc_relative */
1434          0,                     /* bitpos */
1435          complain_overflow_dont, /* complain_on_overflow */
1436                                 /* This needs complex overflow
1437                                    detection, because the upper four
1438                                    bits must match the PC.  */
1439          _bfd_mips_elf_generic_reloc, /* special_function */
1440          "R_MIPS16_26",         /* name */
1441          TRUE,                  /* partial_inplace */
1442          0x3ffffff,             /* src_mask */
1443          0x3ffffff,             /* dst_mask */
1444          FALSE),                /* pcrel_offset */
1445
1446   /* The reloc used for the mips16 gprel instruction.  */
1447   HOWTO (R_MIPS16_GPREL,        /* type */
1448          0,                     /* rightshift */
1449          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1450          16,                    /* bitsize */
1451          FALSE,                 /* pc_relative */
1452          0,                     /* bitpos */
1453          complain_overflow_signed, /* complain_on_overflow */
1454          mips16_gprel_reloc,    /* special_function */
1455          "R_MIPS16_GPREL",      /* name */
1456          TRUE,                  /* partial_inplace */
1457          0x0000ffff,            /* src_mask */
1458          0x0000ffff,            /* dst_mask */
1459          FALSE),                /* pcrel_offset */
1460
1461   /* A placeholder for MIPS16 reference to global offset table.  */
1462   EMPTY_HOWTO (R_MIPS16_GOT16),
1463
1464   /* A placeholder for MIPS16 16 bit call through global offset table.  */
1465   EMPTY_HOWTO (R_MIPS16_CALL16),
1466
1467   /* MIPS16 high 16 bits of symbol value.  */
1468   HOWTO (R_MIPS16_HI16,         /* type */
1469          16,                    /* rightshift */
1470          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1471          16,                    /* bitsize */
1472          FALSE,                 /* pc_relative */
1473          0,                     /* bitpos */
1474          complain_overflow_dont, /* complain_on_overflow */
1475          _bfd_mips_elf_hi16_reloc, /* special_function */
1476          "R_MIPS16_HI16",       /* name */
1477          TRUE,                  /* partial_inplace */
1478          0x0000ffff,            /* src_mask */
1479          0x0000ffff,            /* dst_mask */
1480          FALSE),                /* pcrel_offset */
1481
1482   /* MIPS16 low 16 bits of symbol value.  */
1483   HOWTO (R_MIPS16_LO16,         /* type */
1484          0,                     /* rightshift */
1485          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1486          16,                    /* bitsize */
1487          FALSE,                 /* pc_relative */
1488          0,                     /* bitpos */
1489          complain_overflow_dont, /* complain_on_overflow */
1490          _bfd_mips_elf_lo16_reloc, /* special_function */
1491          "R_MIPS16_LO16",       /* name */
1492          TRUE,                  /* partial_inplace */
1493          0x0000ffff,            /* src_mask */
1494          0x0000ffff,            /* dst_mask */
1495          FALSE),                /* pcrel_offset */
1496 };
1497
1498 static reloc_howto_type mips16_elf64_howto_table_rela[] =
1499 {
1500   /* The reloc used for the mips16 jump instruction.  */
1501   HOWTO (R_MIPS16_26,           /* type */
1502          2,                     /* rightshift */
1503          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1504          26,                    /* bitsize */
1505          FALSE,                 /* pc_relative */
1506          0,                     /* bitpos */
1507          complain_overflow_dont, /* complain_on_overflow */
1508                                 /* This needs complex overflow
1509                                    detection, because the upper four
1510                                    bits must match the PC.  */
1511          _bfd_mips_elf_generic_reloc, /* special_function */
1512          "R_MIPS16_26",         /* name */
1513          FALSE,                 /* partial_inplace */
1514          0x3ffffff,             /* src_mask */
1515          0x3ffffff,             /* dst_mask */
1516          FALSE),                /* pcrel_offset */
1517
1518   /* The reloc used for the mips16 gprel instruction.  */
1519   HOWTO (R_MIPS16_GPREL,        /* type */
1520          0,                     /* rightshift */
1521          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1522          16,                    /* bitsize */
1523          FALSE,                 /* pc_relative */
1524          0,                     /* bitpos */
1525          complain_overflow_signed, /* complain_on_overflow */
1526          mips16_gprel_reloc,    /* special_function */
1527          "R_MIPS16_GPREL",      /* name */
1528          FALSE,                 /* partial_inplace */
1529          0x0000ffff,            /* src_mask */
1530          0x0000ffff,            /* dst_mask */
1531          FALSE),                /* pcrel_offset */
1532
1533   /* A placeholder for MIPS16 reference to global offset table.  */
1534   EMPTY_HOWTO (R_MIPS16_GOT16),
1535
1536   /* A placeholder for MIPS16 16 bit call through global offset table.  */
1537   EMPTY_HOWTO (R_MIPS16_CALL16),
1538
1539   /* MIPS16 high 16 bits of symbol value.  */
1540   HOWTO (R_MIPS16_HI16,         /* type */
1541          16,                    /* rightshift */
1542          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1543          16,                    /* bitsize */
1544          FALSE,                 /* pc_relative */
1545          0,                     /* bitpos */
1546          complain_overflow_dont, /* complain_on_overflow */
1547          _bfd_mips_elf_hi16_reloc, /* special_function */
1548          "R_MIPS16_HI16",       /* name */
1549          FALSE,                 /* partial_inplace */
1550          0x0000ffff,            /* src_mask */
1551          0x0000ffff,            /* dst_mask */
1552          FALSE),                /* pcrel_offset */
1553
1554   /* MIPS16 low 16 bits of symbol value.  */
1555   HOWTO (R_MIPS16_LO16,         /* type */
1556          0,                     /* rightshift */
1557          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1558          16,                    /* bitsize */
1559          FALSE,                 /* pc_relative */
1560          0,                     /* bitpos */
1561          complain_overflow_dont, /* complain_on_overflow */
1562          _bfd_mips_elf_lo16_reloc, /* special_function */
1563          "R_MIPS16_LO16",       /* name */
1564          FALSE,                 /* partial_inplace */
1565          0x0000ffff,            /* src_mask */
1566          0x0000ffff,            /* dst_mask */
1567          FALSE),                /* pcrel_offset */
1568 };
1569
1570 /* GNU extension to record C++ vtable hierarchy */
1571 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
1572   HOWTO (R_MIPS_GNU_VTINHERIT,  /* type */
1573          0,                     /* rightshift */
1574          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1575          0,                     /* bitsize */
1576          FALSE,                 /* pc_relative */
1577          0,                     /* bitpos */
1578          complain_overflow_dont, /* complain_on_overflow */
1579          NULL,                  /* special_function */
1580          "R_MIPS_GNU_VTINHERIT", /* name */
1581          FALSE,                 /* partial_inplace */
1582          0,                     /* src_mask */
1583          0,                     /* dst_mask */
1584          FALSE);                /* pcrel_offset */
1585
1586 /* GNU extension to record C++ vtable member usage */
1587 static reloc_howto_type elf_mips_gnu_vtentry_howto =
1588   HOWTO (R_MIPS_GNU_VTENTRY,    /* type */
1589          0,                     /* rightshift */
1590          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1591          0,                     /* bitsize */
1592          FALSE,                 /* pc_relative */
1593          0,                     /* bitpos */
1594          complain_overflow_dont, /* complain_on_overflow */
1595          _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1596          "R_MIPS_GNU_VTENTRY",  /* name */
1597          FALSE,                 /* partial_inplace */
1598          0,                     /* src_mask */
1599          0,                     /* dst_mask */
1600          FALSE);                /* pcrel_offset */
1601 \f
1602 /* 16 bit offset for pc-relative branches.  */
1603 static reloc_howto_type elf_mips_gnu_rel16_s2 =
1604   HOWTO (R_MIPS_GNU_REL16_S2,   /* type */
1605          2,                     /* rightshift */
1606          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1607          16,                    /* bitsize */
1608          TRUE,                  /* pc_relative */
1609          0,                     /* bitpos */
1610          complain_overflow_signed, /* complain_on_overflow */
1611          _bfd_mips_elf_generic_reloc,   /* special_function */
1612          "R_MIPS_GNU_REL16_S2", /* name */
1613          TRUE,                  /* partial_inplace */
1614          0x0000ffff,            /* src_mask */
1615          0x0000ffff,            /* dst_mask */
1616          TRUE);                 /* pcrel_offset */
1617
1618 /* 16 bit offset for pc-relative branches.  */
1619 static reloc_howto_type elf_mips_gnu_rela16_s2 =
1620   HOWTO (R_MIPS_GNU_REL16_S2,   /* type */
1621          2,                     /* rightshift */
1622          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1623          16,                    /* bitsize */
1624          TRUE,                  /* pc_relative */
1625          0,                     /* bitpos */
1626          complain_overflow_signed, /* complain_on_overflow */
1627          _bfd_mips_elf_generic_reloc,   /* special_function */
1628          "R_MIPS_GNU_REL16_S2", /* name */
1629          FALSE,                 /* partial_inplace */
1630          0,                     /* src_mask */
1631          0x0000ffff,            /* dst_mask */
1632          TRUE);                 /* pcrel_offset */
1633 \f
1634 /* Swap in a MIPS 64-bit Rel reloc.  */
1635
1636 static void
1637 mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src,
1638                           Elf64_Mips_Internal_Rela *dst)
1639 {
1640   dst->r_offset = H_GET_64 (abfd, src->r_offset);
1641   dst->r_sym = H_GET_32 (abfd, src->r_sym);
1642   dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1643   dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1644   dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1645   dst->r_type = H_GET_8 (abfd, src->r_type);
1646   dst->r_addend = 0;
1647 }
1648
1649 /* Swap in a MIPS 64-bit Rela reloc.  */
1650
1651 static void
1652 mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src,
1653                            Elf64_Mips_Internal_Rela *dst)
1654 {
1655   dst->r_offset = H_GET_64 (abfd, src->r_offset);
1656   dst->r_sym = H_GET_32 (abfd, src->r_sym);
1657   dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1658   dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1659   dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1660   dst->r_type = H_GET_8 (abfd, src->r_type);
1661   dst->r_addend = H_GET_S64 (abfd, src->r_addend);
1662 }
1663
1664 /* Swap out a MIPS 64-bit Rel reloc.  */
1665
1666 static void
1667 mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
1668                            Elf64_Mips_External_Rel *dst)
1669 {
1670   H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1671   H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1672   H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1673   H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1674   H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1675   H_PUT_8 (abfd, src->r_type, dst->r_type);
1676 }
1677
1678 /* Swap out a MIPS 64-bit Rela reloc.  */
1679
1680 static void
1681 mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
1682                             Elf64_Mips_External_Rela *dst)
1683 {
1684   H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1685   H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1686   H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1687   H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1688   H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1689   H_PUT_8 (abfd, src->r_type, dst->r_type);
1690   H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
1691 }
1692
1693 /* Swap in a MIPS 64-bit Rel reloc.  */
1694
1695 static void
1696 mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src,
1697                              Elf_Internal_Rela *dst)
1698 {
1699   Elf64_Mips_Internal_Rela mirel;
1700
1701   mips_elf64_swap_reloc_in (abfd,
1702                             (const Elf64_Mips_External_Rel *) src,
1703                             &mirel);
1704
1705   dst[0].r_offset = mirel.r_offset;
1706   dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
1707   dst[0].r_addend = 0;
1708   dst[1].r_offset = mirel.r_offset;
1709   dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
1710   dst[1].r_addend = 0;
1711   dst[2].r_offset = mirel.r_offset;
1712   dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
1713   dst[2].r_addend = 0;
1714 }
1715
1716 /* Swap in a MIPS 64-bit Rela reloc.  */
1717
1718 static void
1719 mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src,
1720                               Elf_Internal_Rela *dst)
1721 {
1722   Elf64_Mips_Internal_Rela mirela;
1723
1724   mips_elf64_swap_reloca_in (abfd,
1725                              (const Elf64_Mips_External_Rela *) src,
1726                              &mirela);
1727
1728   dst[0].r_offset = mirela.r_offset;
1729   dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
1730   dst[0].r_addend = mirela.r_addend;
1731   dst[1].r_offset = mirela.r_offset;
1732   dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
1733   dst[1].r_addend = 0;
1734   dst[2].r_offset = mirela.r_offset;
1735   dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
1736   dst[2].r_addend = 0;
1737 }
1738
1739 /* Swap out a MIPS 64-bit Rel reloc.  */
1740
1741 static void
1742 mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src,
1743                               bfd_byte *dst)
1744 {
1745   Elf64_Mips_Internal_Rela mirel;
1746
1747   mirel.r_offset = src[0].r_offset;
1748   BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1749
1750   mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1751   mirel.r_sym = ELF64_R_SYM (src[0].r_info);
1752   mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1753   mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1754   mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1755
1756   mips_elf64_swap_reloc_out (abfd, &mirel,
1757                              (Elf64_Mips_External_Rel *) dst);
1758 }
1759
1760 /* Swap out a MIPS 64-bit Rela reloc.  */
1761
1762 static void
1763 mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src,
1764                                bfd_byte *dst)
1765 {
1766   Elf64_Mips_Internal_Rela mirela;
1767
1768   mirela.r_offset = src[0].r_offset;
1769   BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1770   BFD_ASSERT(src[0].r_offset == src[2].r_offset);
1771
1772   mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1773   mirela.r_sym = ELF64_R_SYM (src[0].r_info);
1774   mirela.r_addend = src[0].r_addend;
1775   BFD_ASSERT(src[1].r_addend == 0);
1776   BFD_ASSERT(src[2].r_addend == 0);
1777
1778   mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1779   mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1780   mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1781
1782   mips_elf64_swap_reloca_out (abfd, &mirela,
1783                               (Elf64_Mips_External_Rela *) dst);
1784 }
1785 \f
1786 /* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
1787    dangerous relocation.  */
1788
1789 static bfd_boolean
1790 mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp)
1791 {
1792   unsigned int count;
1793   asymbol **sym;
1794   unsigned int i;
1795
1796   /* If we've already figured out what GP will be, just return it.  */
1797   *pgp = _bfd_get_gp_value (output_bfd);
1798   if (*pgp)
1799     return TRUE;
1800
1801   count = bfd_get_symcount (output_bfd);
1802   sym = bfd_get_outsymbols (output_bfd);
1803
1804   /* The linker script will have created a symbol named `_gp' with the
1805      appropriate value.  */
1806   if (sym == NULL)
1807     i = count;
1808   else
1809     {
1810       for (i = 0; i < count; i++, sym++)
1811         {
1812           register const char *name;
1813
1814           name = bfd_asymbol_name (*sym);
1815           if (*name == '_' && strcmp (name, "_gp") == 0)
1816             {
1817               *pgp = bfd_asymbol_value (*sym);
1818               _bfd_set_gp_value (output_bfd, *pgp);
1819               break;
1820             }
1821         }
1822     }
1823
1824   if (i >= count)
1825     {
1826       /* Only get the error once.  */
1827       *pgp = 4;
1828       _bfd_set_gp_value (output_bfd, *pgp);
1829       return FALSE;
1830     }
1831
1832   return TRUE;
1833 }
1834
1835 /* We have to figure out the gp value, so that we can adjust the
1836    symbol value correctly.  We look up the symbol _gp in the output
1837    BFD.  If we can't find it, we're stuck.  We cache it in the ELF
1838    target data.  We don't need to adjust the symbol value for an
1839    external symbol if we are producing relocatable output.  */
1840
1841 static bfd_reloc_status_type
1842 mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
1843                      char **error_message, bfd_vma *pgp)
1844 {
1845   if (bfd_is_und_section (symbol->section)
1846       && ! relocatable)
1847     {
1848       *pgp = 0;
1849       return bfd_reloc_undefined;
1850     }
1851
1852   *pgp = _bfd_get_gp_value (output_bfd);
1853   if (*pgp == 0
1854       && (! relocatable
1855           || (symbol->flags & BSF_SECTION_SYM) != 0))
1856     {
1857       if (relocatable)
1858         {
1859           /* Make up a value.  */
1860           *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
1861           _bfd_set_gp_value (output_bfd, *pgp);
1862         }
1863       else if (!mips_elf64_assign_gp (output_bfd, pgp))
1864         {
1865           *error_message =
1866             (char *) _("GP relative relocation when _gp not defined");
1867           return bfd_reloc_dangerous;
1868         }
1869     }
1870
1871   return bfd_reloc_ok;
1872 }
1873
1874 /* Do a R_MIPS_GPREL16 relocation.  This is a 16 bit value which must
1875    become the offset from the gp register.  */
1876
1877 static bfd_reloc_status_type
1878 mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1879                           void *data, asection *input_section, bfd *output_bfd,
1880                           char **error_message)
1881 {
1882   bfd_boolean relocatable;
1883   bfd_reloc_status_type ret;
1884   bfd_vma gp;
1885
1886   /* If we're relocating, and this is an external symbol, we don't want
1887      to change anything.  */
1888   if (output_bfd != NULL
1889       && (symbol->flags & BSF_SECTION_SYM) == 0
1890       && (symbol->flags & BSF_LOCAL) != 0)
1891     {
1892       reloc_entry->address += input_section->output_offset;
1893       return bfd_reloc_ok;
1894     }
1895
1896   if (output_bfd != NULL)
1897     relocatable = TRUE;
1898   else
1899     {
1900       relocatable = FALSE;
1901       output_bfd = symbol->section->output_section->owner;
1902     }
1903
1904   ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
1905                              &gp);
1906   if (ret != bfd_reloc_ok)
1907     return ret;
1908
1909   return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1910                                         input_section, relocatable,
1911                                         data, gp);
1912 }
1913
1914 /* Do a R_MIPS_LITERAL relocation.  */
1915
1916 static bfd_reloc_status_type
1917 mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1918                           void *data, asection *input_section, bfd *output_bfd,
1919                           char **error_message)
1920 {
1921   bfd_boolean relocatable;
1922   bfd_reloc_status_type ret;
1923   bfd_vma gp;
1924
1925   /* R_MIPS_LITERAL relocations are defined for local symbols only.  */
1926   if (output_bfd != NULL
1927       && (symbol->flags & BSF_SECTION_SYM) == 0
1928       && (symbol->flags & BSF_LOCAL) != 0)
1929     {
1930       *error_message = (char *)
1931         _("literal relocation occurs for an external symbol");
1932       return bfd_reloc_outofrange;
1933     }
1934
1935   /* FIXME: The entries in the .lit8 and .lit4 sections should be merged.  */
1936   if (output_bfd != NULL)
1937     relocatable = TRUE;
1938   else
1939     {
1940       relocatable = FALSE;
1941       output_bfd = symbol->section->output_section->owner;
1942     }
1943
1944   ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
1945                              &gp);
1946   if (ret != bfd_reloc_ok)
1947     return ret;
1948
1949   return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1950                                         input_section, relocatable,
1951                                         data, gp);
1952 }
1953
1954 /* Do a R_MIPS_GPREL32 relocation.  This is a 32 bit value which must
1955    become the offset from the gp register.  */
1956
1957 static bfd_reloc_status_type
1958 mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1959                           void *data, asection *input_section, bfd *output_bfd,
1960                           char **error_message)
1961 {
1962   bfd_boolean relocatable;
1963   bfd_reloc_status_type ret;
1964   bfd_vma gp;
1965   bfd_vma relocation;
1966   bfd_vma val;
1967
1968   /* R_MIPS_GPREL32 relocations are defined for local symbols only.  */
1969   if (output_bfd != NULL
1970       && (symbol->flags & BSF_SECTION_SYM) == 0
1971       && (symbol->flags & BSF_LOCAL) != 0)
1972     {
1973       *error_message = (char *)
1974         _("32bits gp relative relocation occurs for an external symbol");
1975       return bfd_reloc_outofrange;
1976     }
1977
1978   if (output_bfd != NULL)
1979     relocatable = TRUE;
1980   else
1981     {
1982       relocatable = FALSE;
1983       output_bfd = symbol->section->output_section->owner;
1984     }
1985
1986   ret = mips_elf64_final_gp (output_bfd, symbol, relocatable,
1987                              error_message, &gp);
1988   if (ret != bfd_reloc_ok)
1989     return ret;
1990
1991   if (bfd_is_com_section (symbol->section))
1992     relocation = 0;
1993   else
1994     relocation = symbol->value;
1995
1996   relocation += symbol->section->output_section->vma;
1997   relocation += symbol->section->output_offset;
1998
1999   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
2000     return bfd_reloc_outofrange;
2001
2002   /* Set val to the offset into the section or symbol.  */
2003   val = reloc_entry->addend;
2004
2005   if (reloc_entry->howto->partial_inplace)
2006     val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
2007
2008   /* Adjust val for the final section location and GP value.  If we
2009      are producing relocatable output, we don't want to do this for
2010      an external symbol.  */
2011   if (! relocatable
2012       || (symbol->flags & BSF_SECTION_SYM) != 0)
2013     val += relocation - gp;
2014
2015   if (reloc_entry->howto->partial_inplace)
2016     bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
2017   else
2018     reloc_entry->addend = val;
2019
2020   if (relocatable)
2021     reloc_entry->address += input_section->output_offset;
2022
2023   return bfd_reloc_ok;
2024 }
2025
2026 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
2027    the rest is at bits 6-10. The bitpos already got right by the howto.  */
2028
2029 static bfd_reloc_status_type
2030 mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2031                          void *data, asection *input_section, bfd *output_bfd,
2032                          char **error_message)
2033 {
2034   if (reloc_entry->howto->partial_inplace)
2035     {
2036       reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
2037                              | (reloc_entry->addend & 0x00000800) >> 9);
2038     }
2039
2040   return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
2041                                       input_section, output_bfd,
2042                                       error_message);
2043 }
2044
2045 /* Handle a mips16 GP relative reloc.  */
2046
2047 static bfd_reloc_status_type
2048 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2049                     void *data, asection *input_section, bfd *output_bfd,
2050                     char **error_message)
2051 {
2052   bfd_boolean relocatable;
2053   bfd_reloc_status_type ret;
2054   bfd_byte *location;
2055   bfd_vma gp;
2056
2057   /* If we're relocating, and this is an external symbol, we don't want
2058      to change anything.  */
2059   if (output_bfd != NULL
2060       && (symbol->flags & BSF_SECTION_SYM) == 0
2061       && (symbol->flags & BSF_LOCAL) != 0)
2062     {
2063       reloc_entry->address += input_section->output_offset;
2064       return bfd_reloc_ok;
2065     }
2066
2067   if (output_bfd != NULL)
2068     relocatable = TRUE;
2069   else
2070     {
2071       relocatable = FALSE;
2072       output_bfd = symbol->section->output_section->owner;
2073     }
2074
2075   ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
2076                              &gp);
2077   if (ret != bfd_reloc_ok)
2078     return ret;
2079
2080   location = (bfd_byte *) data + reloc_entry->address;
2081   _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
2082                                    location);
2083   ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2084                                        input_section, relocatable,
2085                                        data, gp);
2086   _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
2087                                  location);
2088
2089   return ret;
2090 }
2091 \f
2092 /* A mapping from BFD reloc types to MIPS ELF reloc types.  */
2093
2094 struct elf_reloc_map {
2095   bfd_reloc_code_real_type bfd_val;
2096   enum elf_mips_reloc_type elf_val;
2097 };
2098
2099 static const struct elf_reloc_map mips_reloc_map[] =
2100 {
2101   { BFD_RELOC_NONE, R_MIPS_NONE },
2102   { BFD_RELOC_16, R_MIPS_16 },
2103   { BFD_RELOC_32, R_MIPS_32 },
2104   /* There is no BFD reloc for R_MIPS_REL32.  */
2105   { BFD_RELOC_64, R_MIPS_64 },
2106   { BFD_RELOC_CTOR, R_MIPS_64 },
2107   { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
2108   { BFD_RELOC_HI16_S, R_MIPS_HI16 },
2109   { BFD_RELOC_LO16, R_MIPS_LO16 },
2110   { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
2111   { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
2112   { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
2113   { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
2114   { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
2115   { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
2116   { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
2117   { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
2118   { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
2119   { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
2120   { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
2121   { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
2122   { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
2123   { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
2124   { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
2125   { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
2126   { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
2127   { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
2128   { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
2129   { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
2130   { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
2131   { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
2132   { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
2133   /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated.  */
2134   { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
2135   { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
2136   { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
2137   { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
2138   { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
2139   { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
2140   { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
2141   { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
2142   { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
2143   { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
2144   { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
2145   { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
2146   { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
2147   { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
2148   { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
2149 };
2150
2151 static const struct elf_reloc_map mips16_reloc_map[] =
2152 {
2153   { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
2154   { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
2155   { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
2156   { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
2157 };
2158
2159 /* Given a BFD reloc type, return a howto structure.  */
2160
2161 static reloc_howto_type *
2162 bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
2163                                  bfd_reloc_code_real_type code)
2164 {
2165   unsigned int i;
2166   /* FIXME: We default to RELA here instead of choosing the right
2167      relocation variant.  */
2168   reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
2169   reloc_howto_type *howto16_table = mips16_elf64_howto_table_rela;
2170
2171   for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
2172        i++)
2173     {
2174       if (mips_reloc_map[i].bfd_val == code)
2175         return &howto_table[(int) mips_reloc_map[i].elf_val];
2176     }
2177
2178   for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
2179        i++)
2180     {
2181       if (mips16_reloc_map[i].bfd_val == code)
2182         return &howto16_table[(int) mips16_reloc_map[i].elf_val];
2183     }
2184
2185   switch (code)
2186     {
2187     case BFD_RELOC_VTABLE_INHERIT:
2188       return &elf_mips_gnu_vtinherit_howto;
2189     case BFD_RELOC_VTABLE_ENTRY:
2190       return &elf_mips_gnu_vtentry_howto;
2191     default:
2192       bfd_set_error (bfd_error_bad_value);
2193       return NULL;
2194     }
2195 }
2196
2197 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
2198
2199 static reloc_howto_type *
2200 mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
2201 {
2202   switch (r_type)
2203     {
2204     case R_MIPS_GNU_VTINHERIT:
2205       return &elf_mips_gnu_vtinherit_howto;
2206     case R_MIPS_GNU_VTENTRY:
2207       return &elf_mips_gnu_vtentry_howto;
2208     case R_MIPS_GNU_REL16_S2:
2209       if (rela_p)
2210         return &elf_mips_gnu_rela16_s2;
2211       else
2212         return &elf_mips_gnu_rel16_s2;
2213     default:
2214       if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
2215         {
2216           if (rela_p)
2217             return &mips16_elf64_howto_table_rela[r_type - R_MIPS16_min];
2218           else
2219             return &mips16_elf64_howto_table_rel[r_type - R_MIPS16_min];
2220         }
2221       BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
2222       if (rela_p)
2223         return &mips_elf64_howto_table_rela[r_type];
2224       else
2225         return &mips_elf64_howto_table_rel[r_type];
2226       break;
2227     }
2228 }
2229
2230 /* Prevent relocation handling by bfd for MIPS ELF64.  */
2231
2232 static void
2233 mips_elf64_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
2234                               arelent *cache_ptr ATTRIBUTE_UNUSED,
2235                               Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
2236 {
2237   BFD_ASSERT (0);
2238 }
2239
2240 static void
2241 mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
2242                                arelent *cache_ptr ATTRIBUTE_UNUSED,
2243                                Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
2244 {
2245   BFD_ASSERT (0);
2246 }
2247
2248 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
2249    to three relocs, we must tell the user to allocate more space.  */
2250
2251 static long
2252 mips_elf64_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
2253 {
2254   return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
2255 }
2256
2257 static long
2258 mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd)
2259 {
2260   return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
2261 }
2262
2263 /* We must also copy more relocations than the corresponding functions
2264    in elf.c would, so the two following functions are slightly
2265    modified from elf.c, that multiply the external relocation count by
2266    3 to obtain the internal relocation count.  */
2267
2268 static long
2269 mips_elf64_canonicalize_reloc (bfd *abfd, sec_ptr section,
2270                                arelent **relptr, asymbol **symbols)
2271 {
2272   arelent *tblptr;
2273   unsigned int i;
2274   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
2275
2276   if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
2277     return -1;
2278
2279   tblptr = section->relocation;
2280   for (i = 0; i < section->reloc_count * 3; i++)
2281     *relptr++ = tblptr++;
2282
2283   *relptr = NULL;
2284
2285   return section->reloc_count * 3;
2286 }
2287
2288 static long
2289 mips_elf64_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
2290                                        asymbol **syms)
2291 {
2292   bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
2293   asection *s;
2294   long ret;
2295
2296   if (elf_dynsymtab (abfd) == 0)
2297     {
2298       bfd_set_error (bfd_error_invalid_operation);
2299       return -1;
2300     }
2301
2302   slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
2303   ret = 0;
2304   for (s = abfd->sections; s != NULL; s = s->next)
2305     {
2306       if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
2307           && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
2308               || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
2309         {
2310           arelent *p;
2311           long count, i;
2312
2313           if (! (*slurp_relocs) (abfd, s, syms, TRUE))
2314             return -1;
2315           count = s->size / elf_section_data (s)->this_hdr.sh_entsize * 3;
2316           p = s->relocation;
2317           for (i = 0; i < count; i++)
2318             *storage++ = p++;
2319           ret += count;
2320         }
2321     }
2322
2323   *storage = NULL;
2324
2325   return ret;
2326 }
2327
2328 /* Read the relocations from one reloc section.  This is mostly copied
2329    from elfcode.h, except for the changes to expand one external
2330    relocation to 3 internal ones.  We must unfortunately set
2331    reloc_count to the number of external relocations, because a lot of
2332    generic code seems to depend on this.  */
2333
2334 static bfd_boolean
2335 mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
2336                                   Elf_Internal_Shdr *rel_hdr,
2337                                   bfd_size_type reloc_count,
2338                                   arelent *relents, asymbol **symbols,
2339                                   bfd_boolean dynamic)
2340 {
2341   void *allocated;
2342   bfd_byte *native_relocs;
2343   arelent *relent;
2344   bfd_vma i;
2345   int entsize;
2346   bfd_boolean rela_p;
2347
2348   allocated = bfd_malloc (rel_hdr->sh_size);
2349   if (allocated == NULL)
2350     return FALSE;
2351
2352   if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
2353       || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
2354           != rel_hdr->sh_size))
2355     goto error_return;
2356
2357   native_relocs = allocated;
2358
2359   entsize = rel_hdr->sh_entsize;
2360   BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
2361               || entsize == sizeof (Elf64_Mips_External_Rela));
2362
2363   if (entsize == sizeof (Elf64_Mips_External_Rel))
2364     rela_p = FALSE;
2365   else
2366     rela_p = TRUE;
2367
2368   for (i = 0, relent = relents;
2369        i < reloc_count;
2370        i++, native_relocs += entsize)
2371     {
2372       Elf64_Mips_Internal_Rela rela;
2373       bfd_boolean used_sym, used_ssym;
2374       int ir;
2375
2376       if (entsize == sizeof (Elf64_Mips_External_Rela))
2377         mips_elf64_swap_reloca_in (abfd,
2378                                    (Elf64_Mips_External_Rela *) native_relocs,
2379                                    &rela);
2380       else
2381         mips_elf64_swap_reloc_in (abfd,
2382                                   (Elf64_Mips_External_Rel *) native_relocs,
2383                                   &rela);
2384
2385       /* Each entry represents exactly three actual relocations.  */
2386
2387       used_sym = FALSE;
2388       used_ssym = FALSE;
2389       for (ir = 0; ir < 3; ir++)
2390         {
2391           enum elf_mips_reloc_type type;
2392
2393           switch (ir)
2394             {
2395             default:
2396               abort ();
2397             case 0:
2398               type = (enum elf_mips_reloc_type) rela.r_type;
2399               break;
2400             case 1:
2401               type = (enum elf_mips_reloc_type) rela.r_type2;
2402               break;
2403             case 2:
2404               type = (enum elf_mips_reloc_type) rela.r_type3;
2405               break;
2406             }
2407
2408           /* Some types require symbols, whereas some do not.  */
2409           switch (type)
2410             {
2411             case R_MIPS_NONE:
2412             case R_MIPS_LITERAL:
2413             case R_MIPS_INSERT_A:
2414             case R_MIPS_INSERT_B:
2415             case R_MIPS_DELETE:
2416               relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2417               break;
2418
2419             default:
2420               if (! used_sym)
2421                 {
2422                   if (rela.r_sym == 0)
2423                     relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2424                   else
2425                     {
2426                       asymbol **ps, *s;
2427
2428                       ps = symbols + rela.r_sym - 1;
2429                       s = *ps;
2430                       if ((s->flags & BSF_SECTION_SYM) == 0)
2431                         relent->sym_ptr_ptr = ps;
2432                       else
2433                         relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
2434                     }
2435
2436                   used_sym = TRUE;
2437                 }
2438               else if (! used_ssym)
2439                 {
2440                   switch (rela.r_ssym)
2441                     {
2442                     case RSS_UNDEF:
2443                       relent->sym_ptr_ptr =
2444                         bfd_abs_section_ptr->symbol_ptr_ptr;
2445                       break;
2446
2447                     case RSS_GP:
2448                     case RSS_GP0:
2449                     case RSS_LOC:
2450                       /* FIXME: I think these need to be handled using
2451                          special howto structures.  */
2452                       BFD_ASSERT (0);
2453                       break;
2454
2455                     default:
2456                       BFD_ASSERT (0);
2457                       break;
2458                     }
2459
2460                   used_ssym = TRUE;
2461                 }
2462               else
2463                 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2464
2465               break;
2466             }
2467
2468           /* The address of an ELF reloc is section relative for an
2469              object file, and absolute for an executable file or
2470              shared library.  The address of a BFD reloc is always
2471              section relative.  */
2472           if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
2473             relent->address = rela.r_offset;
2474           else
2475             relent->address = rela.r_offset - asect->vma;
2476
2477           relent->addend = rela.r_addend;
2478
2479           relent->howto = mips_elf64_rtype_to_howto (type, rela_p);
2480
2481           ++relent;
2482         }
2483     }
2484
2485   asect->reloc_count += (relent - relents) / 3;
2486
2487   if (allocated != NULL)
2488     free (allocated);
2489
2490   return TRUE;
2491
2492  error_return:
2493   if (allocated != NULL)
2494     free (allocated);
2495   return FALSE;
2496 }
2497
2498 /* Read the relocations.  On Irix 6, there can be two reloc sections
2499    associated with a single data section.  This is copied from
2500    elfcode.h as well, with changes as small as accounting for 3
2501    internal relocs per external reloc and resetting reloc_count to
2502    zero before processing the relocs of a section.  */
2503
2504 static bfd_boolean
2505 mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
2506                               asymbol **symbols, bfd_boolean dynamic)
2507 {
2508   struct bfd_elf_section_data * const d = elf_section_data (asect);
2509   Elf_Internal_Shdr *rel_hdr;
2510   Elf_Internal_Shdr *rel_hdr2;
2511   bfd_size_type reloc_count;
2512   bfd_size_type reloc_count2;
2513   arelent *relents;
2514   bfd_size_type amt;
2515
2516   if (asect->relocation != NULL)
2517     return TRUE;
2518
2519   if (! dynamic)
2520     {
2521       if ((asect->flags & SEC_RELOC) == 0
2522           || asect->reloc_count == 0)
2523         return TRUE;
2524
2525       rel_hdr = &d->rel_hdr;
2526       reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2527       rel_hdr2 = d->rel_hdr2;
2528       reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
2529
2530       BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
2531       BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
2532                   || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
2533
2534     }
2535   else
2536     {
2537       /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
2538          case because relocations against this section may use the
2539          dynamic symbol table, and in that case bfd_section_from_shdr
2540          in elf.c does not update the RELOC_COUNT.  */
2541       if (asect->size == 0)
2542         return TRUE;
2543
2544       rel_hdr = &d->this_hdr;
2545       reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2546       rel_hdr2 = NULL;
2547       reloc_count2 = 0;
2548     }
2549
2550   /* Allocate space for 3 arelent structures for each Rel structure.  */
2551   amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
2552   relents = bfd_alloc (abfd, amt);
2553   if (relents == NULL)
2554     return FALSE;
2555
2556   /* The slurp_one_reloc_table routine increments reloc_count.  */
2557   asect->reloc_count = 0;
2558
2559   if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2560                                           rel_hdr, reloc_count,
2561                                           relents,
2562                                           symbols, dynamic))
2563     return FALSE;
2564   if (d->rel_hdr2 != NULL)
2565     {
2566       if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2567                                               rel_hdr2, reloc_count2,
2568                                               relents + reloc_count * 3,
2569                                               symbols, dynamic))
2570         return FALSE;
2571     }
2572
2573   asect->relocation = relents;
2574   return TRUE;
2575 }
2576
2577 /* Write out the relocations.  */
2578
2579 static void
2580 mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
2581 {
2582   bfd_boolean *failedp = data;
2583   int count;
2584   Elf_Internal_Shdr *rel_hdr;
2585   unsigned int idx;
2586
2587   /* If we have already failed, don't do anything.  */
2588   if (*failedp)
2589     return;
2590
2591   if ((sec->flags & SEC_RELOC) == 0)
2592     return;
2593
2594   /* The linker backend writes the relocs out itself, and sets the
2595      reloc_count field to zero to inhibit writing them here.  Also,
2596      sometimes the SEC_RELOC flag gets set even when there aren't any
2597      relocs.  */
2598   if (sec->reloc_count == 0)
2599     return;
2600
2601   /* We can combine up to three relocs that refer to the same address
2602      if the latter relocs have no associated symbol.  */
2603   count = 0;
2604   for (idx = 0; idx < sec->reloc_count; idx++)
2605     {
2606       bfd_vma addr;
2607       unsigned int i;
2608
2609       ++count;
2610
2611       addr = sec->orelocation[idx]->address;
2612       for (i = 0; i < 2; i++)
2613         {
2614           arelent *r;
2615
2616           if (idx + 1 >= sec->reloc_count)
2617             break;
2618           r = sec->orelocation[idx + 1];
2619           if (r->address != addr
2620               || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2621               || (*r->sym_ptr_ptr)->value != 0)
2622             break;
2623
2624           /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
2625
2626           ++idx;
2627         }
2628     }
2629
2630   rel_hdr = &elf_section_data (sec)->rel_hdr;
2631
2632   /* Do the actual relocation.  */
2633
2634   if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
2635     mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
2636   else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
2637     mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
2638   else
2639     BFD_ASSERT (0);
2640 }
2641
2642 static void
2643 mips_elf64_write_rel (bfd *abfd, asection *sec,
2644                       Elf_Internal_Shdr *rel_hdr,
2645                       int *count, void *data)
2646 {
2647   bfd_boolean *failedp = data;
2648   Elf64_Mips_External_Rel *ext_rel;
2649   unsigned int idx;
2650   asymbol *last_sym = 0;
2651   int last_sym_idx = 0;
2652
2653   rel_hdr->sh_size = rel_hdr->sh_entsize * *count;
2654   rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size);
2655   if (rel_hdr->contents == NULL)
2656     {
2657       *failedp = TRUE;
2658       return;
2659     }
2660
2661   ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
2662   for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
2663     {
2664       arelent *ptr;
2665       Elf64_Mips_Internal_Rela int_rel;
2666       asymbol *sym;
2667       int n;
2668       unsigned int i;
2669
2670       ptr = sec->orelocation[idx];
2671
2672       /* The address of an ELF reloc is section relative for an object
2673          file, and absolute for an executable file or shared library.
2674          The address of a BFD reloc is always section relative.  */
2675       if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2676         int_rel.r_offset = ptr->address;
2677       else
2678         int_rel.r_offset = ptr->address + sec->vma;
2679
2680       sym = *ptr->sym_ptr_ptr;
2681       if (sym == last_sym)
2682         n = last_sym_idx;
2683       else if (bfd_is_abs_section (sym->section) && sym->value == 0)
2684         n = STN_UNDEF;
2685       else
2686         {
2687           last_sym = sym;
2688           n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2689           if (n < 0)
2690             {
2691               *failedp = TRUE;
2692               return;
2693             }
2694           last_sym_idx = n;
2695         }
2696
2697       int_rel.r_sym = n;
2698       int_rel.r_ssym = RSS_UNDEF;
2699
2700       if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2701           && ! _bfd_elf_validate_reloc (abfd, ptr))
2702         {
2703           *failedp = TRUE;
2704           return;
2705         }
2706
2707       int_rel.r_type = ptr->howto->type;
2708       int_rel.r_type2 = (int) R_MIPS_NONE;
2709       int_rel.r_type3 = (int) R_MIPS_NONE;
2710
2711       for (i = 0; i < 2; i++)
2712         {
2713           arelent *r;
2714
2715           if (idx + 1 >= sec->reloc_count)
2716             break;
2717           r = sec->orelocation[idx + 1];
2718           if (r->address != ptr->address
2719               || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2720               || (*r->sym_ptr_ptr)->value != 0)
2721             break;
2722
2723           /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
2724
2725           if (i == 0)
2726             int_rel.r_type2 = r->howto->type;
2727           else
2728             int_rel.r_type3 = r->howto->type;
2729
2730           ++idx;
2731         }
2732
2733       mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
2734     }
2735
2736   BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
2737               == *count);
2738 }
2739
2740 static void
2741 mips_elf64_write_rela (bfd *abfd, asection *sec,
2742                        Elf_Internal_Shdr *rela_hdr,
2743                        int *count, void *data)
2744 {
2745   bfd_boolean *failedp = data;
2746   Elf64_Mips_External_Rela *ext_rela;
2747   unsigned int idx;
2748   asymbol *last_sym = 0;
2749   int last_sym_idx = 0;
2750
2751   rela_hdr->sh_size = rela_hdr->sh_entsize * *count;
2752   rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
2753   if (rela_hdr->contents == NULL)
2754     {
2755       *failedp = TRUE;
2756       return;
2757     }
2758
2759   ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
2760   for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
2761     {
2762       arelent *ptr;
2763       Elf64_Mips_Internal_Rela int_rela;
2764       asymbol *sym;
2765       int n;
2766       unsigned int i;
2767
2768       ptr = sec->orelocation[idx];
2769
2770       /* The address of an ELF reloc is section relative for an object
2771          file, and absolute for an executable file or shared library.
2772          The address of a BFD reloc is always section relative.  */
2773       if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2774         int_rela.r_offset = ptr->address;
2775       else
2776         int_rela.r_offset = ptr->address + sec->vma;
2777
2778       sym = *ptr->sym_ptr_ptr;
2779       if (sym == last_sym)
2780         n = last_sym_idx;
2781       else if (bfd_is_abs_section (sym->section) && sym->value == 0)
2782         n = STN_UNDEF;
2783       else
2784         {
2785           last_sym = sym;
2786           n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2787           if (n < 0)
2788             {
2789               *failedp = TRUE;
2790               return;
2791             }
2792           last_sym_idx = n;
2793         }
2794
2795       int_rela.r_sym = n;
2796       int_rela.r_addend = ptr->addend;
2797       int_rela.r_ssym = RSS_UNDEF;
2798
2799       if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2800           && ! _bfd_elf_validate_reloc (abfd, ptr))
2801         {
2802           *failedp = TRUE;
2803           return;
2804         }
2805
2806       int_rela.r_type = ptr->howto->type;
2807       int_rela.r_type2 = (int) R_MIPS_NONE;
2808       int_rela.r_type3 = (int) R_MIPS_NONE;
2809
2810       for (i = 0; i < 2; i++)
2811         {
2812           arelent *r;
2813
2814           if (idx + 1 >= sec->reloc_count)
2815             break;
2816           r = sec->orelocation[idx + 1];
2817           if (r->address != ptr->address
2818               || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2819               || (*r->sym_ptr_ptr)->value != 0)
2820             break;
2821
2822           /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
2823
2824           if (i == 0)
2825             int_rela.r_type2 = r->howto->type;
2826           else
2827             int_rela.r_type3 = r->howto->type;
2828
2829           ++idx;
2830         }
2831
2832       mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
2833     }
2834
2835   BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
2836               == *count);
2837 }
2838 \f
2839 /* Set the right machine number for a MIPS ELF file.  */
2840
2841 static bfd_boolean
2842 mips_elf64_object_p (bfd *abfd)
2843 {
2844   unsigned long mach;
2845
2846   /* Irix 6 is broken.  Object file symbol tables are not always
2847      sorted correctly such that local symbols precede global symbols,
2848      and the sh_info field in the symbol table is not always right.  */
2849   if (elf64_mips_irix_compat (abfd) != ict_none)
2850     elf_bad_symtab (abfd) = TRUE;
2851
2852   mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
2853   bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
2854   return TRUE;
2855 }
2856
2857 /* Depending on the target vector we generate some version of Irix
2858    executables or "normal" MIPS ELF ABI executables.  */
2859 static irix_compat_t
2860 elf64_mips_irix_compat (bfd *abfd)
2861 {
2862   if ((abfd->xvec == &bfd_elf64_bigmips_vec)
2863       || (abfd->xvec == &bfd_elf64_littlemips_vec))
2864     return ict_irix6;
2865   else
2866     return ict_none;
2867 }
2868 \f
2869 /* Support for core dump NOTE sections.  */
2870 static bfd_boolean
2871 elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
2872 {
2873   int offset;
2874   unsigned int size;
2875
2876   switch (note->descsz)
2877     {
2878       default:
2879         return FALSE;
2880
2881       case 480:         /* Linux/MIPS - N64 kernel */
2882         /* pr_cursig */
2883         elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
2884
2885         /* pr_pid */
2886         elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 32);
2887
2888         /* pr_reg */
2889         offset = 112;
2890         size = 360;
2891
2892         break;
2893     }
2894
2895   /* Make a ".reg/999" section.  */
2896   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
2897                                           size, note->descpos + offset);
2898 }
2899
2900 static bfd_boolean
2901 elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
2902 {
2903   switch (note->descsz)
2904     {
2905       default:
2906         return FALSE;
2907
2908       case 136:         /* Linux/MIPS - N64 kernel elf_prpsinfo */
2909         elf_tdata (abfd)->core_program
2910          = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
2911         elf_tdata (abfd)->core_command
2912          = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
2913     }
2914
2915   /* Note that for some reason, a spurious space is tacked
2916      onto the end of the args in some (at least one anyway)
2917      implementations, so strip it off if it exists.  */
2918
2919   {
2920     char *command = elf_tdata (abfd)->core_command;
2921     int n = strlen (command);
2922
2923     if (0 < n && command[n - 1] == ' ')
2924       command[n - 1] = '\0';
2925   }
2926
2927   return TRUE;
2928 }
2929 \f
2930 /* ECOFF swapping routines.  These are used when dealing with the
2931    .mdebug section, which is in the ECOFF debugging format.  */
2932 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
2933 {
2934   /* Symbol table magic number.  */
2935   magicSym2,
2936   /* Alignment of debugging information.  E.g., 4.  */
2937   8,
2938   /* Sizes of external symbolic information.  */
2939   sizeof (struct hdr_ext),
2940   sizeof (struct dnr_ext),
2941   sizeof (struct pdr_ext),
2942   sizeof (struct sym_ext),
2943   sizeof (struct opt_ext),
2944   sizeof (struct fdr_ext),
2945   sizeof (struct rfd_ext),
2946   sizeof (struct ext_ext),
2947   /* Functions to swap in external symbolic data.  */
2948   ecoff_swap_hdr_in,
2949   ecoff_swap_dnr_in,
2950   ecoff_swap_pdr_in,
2951   ecoff_swap_sym_in,
2952   ecoff_swap_opt_in,
2953   ecoff_swap_fdr_in,
2954   ecoff_swap_rfd_in,
2955   ecoff_swap_ext_in,
2956   _bfd_ecoff_swap_tir_in,
2957   _bfd_ecoff_swap_rndx_in,
2958   /* Functions to swap out external symbolic data.  */
2959   ecoff_swap_hdr_out,
2960   ecoff_swap_dnr_out,
2961   ecoff_swap_pdr_out,
2962   ecoff_swap_sym_out,
2963   ecoff_swap_opt_out,
2964   ecoff_swap_fdr_out,
2965   ecoff_swap_rfd_out,
2966   ecoff_swap_ext_out,
2967   _bfd_ecoff_swap_tir_out,
2968   _bfd_ecoff_swap_rndx_out,
2969   /* Function to read in symbolic data.  */
2970   _bfd_mips_elf_read_ecoff_info
2971 };
2972 \f
2973 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
2974    standard ELF.  This structure is used to redirect the relocation
2975    handling routines.  */
2976
2977 const struct elf_size_info mips_elf64_size_info =
2978 {
2979   sizeof (Elf64_External_Ehdr),
2980   sizeof (Elf64_External_Phdr),
2981   sizeof (Elf64_External_Shdr),
2982   sizeof (Elf64_Mips_External_Rel),
2983   sizeof (Elf64_Mips_External_Rela),
2984   sizeof (Elf64_External_Sym),
2985   sizeof (Elf64_External_Dyn),
2986   sizeof (Elf_External_Note),
2987   4,            /* hash-table entry size */
2988   3,            /* internal relocations per external relocations */
2989   64,           /* arch_size */
2990   3,            /* log_file_align */
2991   ELFCLASS64,
2992   EV_CURRENT,
2993   bfd_elf64_write_out_phdrs,
2994   bfd_elf64_write_shdrs_and_ehdr,
2995   mips_elf64_write_relocs,
2996   bfd_elf64_swap_symbol_in,
2997   bfd_elf64_swap_symbol_out,
2998   mips_elf64_slurp_reloc_table,
2999   bfd_elf64_slurp_symbol_table,
3000   bfd_elf64_swap_dyn_in,
3001   bfd_elf64_swap_dyn_out,
3002   mips_elf64_be_swap_reloc_in,
3003   mips_elf64_be_swap_reloc_out,
3004   mips_elf64_be_swap_reloca_in,
3005   mips_elf64_be_swap_reloca_out
3006 };
3007
3008 #define ELF_ARCH                        bfd_arch_mips
3009 #define ELF_MACHINE_CODE                EM_MIPS
3010
3011 #define elf_backend_collect             TRUE
3012 #define elf_backend_type_change_ok      TRUE
3013 #define elf_backend_can_gc_sections     TRUE
3014 #define elf_info_to_howto               mips_elf64_info_to_howto_rela
3015 #define elf_info_to_howto_rel           mips_elf64_info_to_howto_rel
3016 #define elf_backend_object_p            mips_elf64_object_p
3017 #define elf_backend_symbol_processing   _bfd_mips_elf_symbol_processing
3018 #define elf_backend_section_processing  _bfd_mips_elf_section_processing
3019 #define elf_backend_section_from_shdr   _bfd_mips_elf_section_from_shdr
3020 #define elf_backend_fake_sections       _bfd_mips_elf_fake_sections
3021 #define elf_backend_section_from_bfd_section \
3022                                 _bfd_mips_elf_section_from_bfd_section
3023 #define elf_backend_add_symbol_hook     _bfd_mips_elf_add_symbol_hook
3024 #define elf_backend_link_output_symbol_hook \
3025                                 _bfd_mips_elf_link_output_symbol_hook
3026 #define elf_backend_create_dynamic_sections \
3027                                 _bfd_mips_elf_create_dynamic_sections
3028 #define elf_backend_check_relocs        _bfd_mips_elf_check_relocs
3029 #define elf_backend_adjust_dynamic_symbol \
3030                                 _bfd_mips_elf_adjust_dynamic_symbol
3031 #define elf_backend_always_size_sections \
3032                                 _bfd_mips_elf_always_size_sections
3033 #define elf_backend_size_dynamic_sections \
3034                                 _bfd_mips_elf_size_dynamic_sections
3035 #define elf_backend_relocate_section    _bfd_mips_elf_relocate_section
3036 #define elf_backend_finish_dynamic_symbol \
3037                                 _bfd_mips_elf_finish_dynamic_symbol
3038 #define elf_backend_finish_dynamic_sections \
3039                                 _bfd_mips_elf_finish_dynamic_sections
3040 #define elf_backend_final_write_processing \
3041                                 _bfd_mips_elf_final_write_processing
3042 #define elf_backend_additional_program_headers \
3043                                 _bfd_mips_elf_additional_program_headers
3044 #define elf_backend_modify_segment_map  _bfd_mips_elf_modify_segment_map
3045 #define elf_backend_gc_mark_hook        _bfd_mips_elf_gc_mark_hook
3046 #define elf_backend_gc_sweep_hook       _bfd_mips_elf_gc_sweep_hook
3047 #define elf_backend_copy_indirect_symbol \
3048                                         _bfd_mips_elf_copy_indirect_symbol
3049 #define elf_backend_hide_symbol         _bfd_mips_elf_hide_symbol
3050 #define elf_backend_ignore_discarded_relocs \
3051                                         _bfd_mips_elf_ignore_discarded_relocs
3052 #define elf_backend_mips_irix_compat    elf64_mips_irix_compat
3053 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
3054 #define elf_backend_ecoff_debug_swap    &mips_elf64_ecoff_debug_swap
3055 #define elf_backend_size_info           mips_elf64_size_info
3056
3057 #define elf_backend_grok_prstatus       elf64_mips_grok_prstatus
3058 #define elf_backend_grok_psinfo         elf64_mips_grok_psinfo
3059
3060 #define elf_backend_got_header_size     (4 * MIPS_RESERVED_GOTNO)
3061
3062 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
3063    work better/work only in RELA, so we default to this.  */
3064 #define elf_backend_may_use_rel_p       1
3065 #define elf_backend_may_use_rela_p      1
3066 #define elf_backend_default_use_rela_p  1
3067
3068 #define elf_backend_write_section       _bfd_mips_elf_write_section
3069
3070 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
3071    MIPS-specific function only applies to IRIX5, which had no 64-bit
3072    ABI.  */
3073 #define bfd_elf64_find_nearest_line     _bfd_mips_elf_find_nearest_line
3074 #define bfd_elf64_find_inliner_info     _bfd_mips_elf_find_inliner_info
3075 #define bfd_elf64_new_section_hook      _bfd_mips_elf_new_section_hook
3076 #define bfd_elf64_set_section_contents  _bfd_mips_elf_set_section_contents
3077 #define bfd_elf64_bfd_get_relocated_section_contents \
3078                                 _bfd_elf_mips_get_relocated_section_contents
3079 #define bfd_elf64_bfd_link_hash_table_create \
3080                                 _bfd_mips_elf_link_hash_table_create
3081 #define bfd_elf64_bfd_final_link        _bfd_mips_elf_final_link
3082 #define bfd_elf64_bfd_merge_private_bfd_data \
3083                                 _bfd_mips_elf_merge_private_bfd_data
3084 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
3085 #define bfd_elf64_bfd_print_private_bfd_data \
3086                                 _bfd_mips_elf_print_private_bfd_data
3087
3088 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
3089 #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
3090 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
3091 #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
3092 #define bfd_elf64_bfd_relax_section     _bfd_mips_relax_section
3093
3094 /* MIPS ELF64 archive functions.  */
3095 #define bfd_elf64_archive_functions
3096 extern bfd_boolean bfd_elf64_archive_slurp_armap
3097   (bfd *);
3098 extern bfd_boolean bfd_elf64_archive_write_armap
3099   (bfd *, unsigned int, struct orl *, unsigned int, int);
3100 #define bfd_elf64_archive_slurp_extended_name_table \
3101                         _bfd_archive_coff_slurp_extended_name_table
3102 #define bfd_elf64_archive_construct_extended_name_table \
3103                         _bfd_archive_coff_construct_extended_name_table
3104 #define bfd_elf64_archive_truncate_arname \
3105                         _bfd_archive_coff_truncate_arname
3106 #define bfd_elf64_archive_read_ar_hdr   _bfd_archive_coff_read_ar_hdr
3107 #define bfd_elf64_archive_openr_next_archived_file \
3108                         _bfd_archive_coff_openr_next_archived_file
3109 #define bfd_elf64_archive_get_elt_at_index \
3110                         _bfd_archive_coff_get_elt_at_index
3111 #define bfd_elf64_archive_generic_stat_arch_elt \
3112                         _bfd_archive_coff_generic_stat_arch_elt
3113 #define bfd_elf64_archive_update_armap_timestamp \
3114                         _bfd_archive_coff_update_armap_timestamp
3115
3116 /* The SGI style (n)64 NewABI.  */
3117 #define TARGET_LITTLE_SYM               bfd_elf64_littlemips_vec
3118 #define TARGET_LITTLE_NAME              "elf64-littlemips"
3119 #define TARGET_BIG_SYM                  bfd_elf64_bigmips_vec
3120 #define TARGET_BIG_NAME                 "elf64-bigmips"
3121
3122 #define ELF_MAXPAGESIZE                 0x10000
3123 #define ELF_COMMONPAGESIZE              0x1000
3124
3125 #include "elf64-target.h"
3126
3127 /* The SYSV-style 'traditional' (n)64 NewABI.  */
3128 #undef TARGET_LITTLE_SYM
3129 #undef TARGET_LITTLE_NAME
3130 #undef TARGET_BIG_SYM
3131 #undef TARGET_BIG_NAME
3132
3133 #undef ELF_MAXPAGESIZE
3134 #undef ELF_COMMONPAGESIZE
3135
3136 #define TARGET_LITTLE_SYM               bfd_elf64_tradlittlemips_vec
3137 #define TARGET_LITTLE_NAME              "elf64-tradlittlemips"
3138 #define TARGET_BIG_SYM                  bfd_elf64_tradbigmips_vec
3139 #define TARGET_BIG_NAME                 "elf64-tradbigmips"
3140
3141 #define ELF_MAXPAGESIZE                 0x10000
3142 #define ELF_COMMONPAGESIZE              0x1000
3143 #define elf64_bed                       elf64_tradbed
3144
3145 /* Include the target file again for this target.  */
3146 #include "elf64-target.h"