Update year range in copyright notice of binutils files
[external/binutils.git] / bfd / elf64-mips.c
1 /* MIPS-specific support for 64-bit ELF
2    Copyright (C) 1996-2018 Free Software Foundation, Inc.
3    Ian Lance Taylor, Cygnus Support
4    Linker support added by Mark Mitchell, CodeSourcery, LLC.
5    <mark@codesourcery.com>
6
7    This file is part of BFD, the Binary File Descriptor library.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22    MA 02110-1301, USA.  */
23
24
25 /* This file supports the 64-bit MIPS ELF ABI.
26
27    The MIPS 64-bit ELF ABI uses an unusual reloc format.  This file
28    overrides the usual ELF reloc handling, and handles reading and
29    writing the relocations here.  */
30
31 /* TODO: Many things are unsupported, even if there is some code for it
32  .       (which was mostly stolen from elf32-mips.c and slightly adapted).
33  .
34  .   - Relocation handling for REL relocs is wrong in many cases and
35  .     generally untested.
36  .   - Relocation handling for RELA relocs related to GOT support are
37  .     also likely to be wrong.
38  .   - Support for MIPS16 is untested.
39  .   - Combined relocs with RSS_* entries are unsupported.
40  .   - The whole GOT handling for NewABI is missing, some parts of
41  .     the OldABI version is still lying around and should be removed.
42  */
43
44 #include "sysdep.h"
45 #include "bfd.h"
46 #include "libbfd.h"
47 #include "aout/ar.h"
48 #include "bfdlink.h"
49 #include "genlink.h"
50 #include "elf-bfd.h"
51 #include "elfxx-mips.h"
52 #include "elf/mips.h"
53
54 /* Get the ECOFF swapping routines.  The 64-bit ABI is not supposed to
55    use ECOFF.  However, we support it anyhow for an easier changeover.  */
56 #include "coff/sym.h"
57 #include "coff/symconst.h"
58 #include "coff/internal.h"
59 #include "coff/ecoff.h"
60 /* The 64 bit versions of the mdebug data structures are in alpha.h.  */
61 #include "coff/alpha.h"
62 #define ECOFF_SIGNED_64
63 #include "ecoffswap.h"
64
65 static void mips_elf64_swap_reloc_in
66   (bfd *, const Elf64_Mips_External_Rel *, Elf64_Mips_Internal_Rela *);
67 static void mips_elf64_swap_reloca_in
68   (bfd *, const Elf64_Mips_External_Rela *, Elf64_Mips_Internal_Rela *);
69 static void mips_elf64_swap_reloc_out
70   (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rel *);
71 static void mips_elf64_swap_reloca_out
72   (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rela *);
73 static void mips_elf64_be_swap_reloc_in
74   (bfd *, const bfd_byte *, Elf_Internal_Rela *);
75 static void mips_elf64_be_swap_reloc_out
76   (bfd *, const Elf_Internal_Rela *, bfd_byte *);
77 static void mips_elf64_be_swap_reloca_in
78   (bfd *, const bfd_byte *, Elf_Internal_Rela *);
79 static void mips_elf64_be_swap_reloca_out
80   (bfd *, const Elf_Internal_Rela *, bfd_byte *);
81 static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup
82   (bfd *, bfd_reloc_code_real_type);
83 static reloc_howto_type *mips_elf64_rtype_to_howto
84   (unsigned int, bfd_boolean);
85 static void mips_elf64_info_to_howto_rel
86   (bfd *, arelent *, Elf_Internal_Rela *);
87 static void mips_elf64_info_to_howto_rela
88   (bfd *, arelent *, Elf_Internal_Rela *);
89 static long mips_elf64_get_dynamic_reloc_upper_bound
90   (bfd *);
91 static bfd_boolean mips_elf64_slurp_one_reloc_table
92   (bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type, arelent *,
93    asymbol **, bfd_boolean);
94 static bfd_boolean mips_elf64_slurp_reloc_table
95   (bfd *, asection *, asymbol **, bfd_boolean);
96 static void mips_elf64_write_relocs
97   (bfd *, asection *, void *);
98 static void mips_elf64_write_rel
99   (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
100 static void mips_elf64_write_rela
101   (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
102 static bfd_reloc_status_type mips_elf64_gprel16_reloc
103   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
104 static bfd_reloc_status_type mips_elf64_literal_reloc
105   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
106 static bfd_reloc_status_type mips_elf64_gprel32_reloc
107   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
108 static bfd_reloc_status_type mips_elf64_shift6_reloc
109   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
110 static bfd_reloc_status_type mips16_gprel_reloc
111   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
112 static bfd_boolean mips_elf64_assign_gp
113   (bfd *, bfd_vma *);
114 static bfd_reloc_status_type mips_elf64_final_gp
115   (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
116 static bfd_boolean mips_elf64_object_p
117   (bfd *);
118 static irix_compat_t elf64_mips_irix_compat
119   (bfd *);
120 static bfd_boolean elf64_mips_grok_prstatus
121   (bfd *, Elf_Internal_Note *);
122 static bfd_boolean elf64_mips_grok_psinfo
123   (bfd *, Elf_Internal_Note *);
124
125 extern const bfd_target mips_elf64_be_vec;
126 extern const bfd_target mips_elf64_le_vec;
127
128 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
129    from smaller values.  Start with zero, widen, *then* decrement.  */
130 #define MINUS_ONE       (((bfd_vma)0) - 1)
131
132 /* The number of local .got entries we reserve.  */
133 #define MIPS_RESERVED_GOTNO (2)
134 \f
135 /* The relocation table used for SHT_REL sections.  */
136
137 static reloc_howto_type mips_elf64_howto_table_rel[] =
138 {
139   /* No relocation.  */
140   HOWTO (R_MIPS_NONE,           /* type */
141          0,                     /* rightshift */
142          3,                     /* size (0 = byte, 1 = short, 2 = long) */
143          0,                     /* bitsize */
144          FALSE,                 /* pc_relative */
145          0,                     /* bitpos */
146          complain_overflow_dont, /* complain_on_overflow */
147          _bfd_mips_elf_generic_reloc,   /* special_function */
148          "R_MIPS_NONE",         /* name */
149          FALSE,                 /* partial_inplace */
150          0,                     /* src_mask */
151          0,                     /* dst_mask */
152          FALSE),                /* pcrel_offset */
153
154   /* 16 bit relocation.  */
155   HOWTO (R_MIPS_16,             /* type */
156          0,                     /* rightshift */
157          2,                     /* size (0 = byte, 1 = short, 2 = long) */
158          16,                    /* bitsize */
159          FALSE,                 /* pc_relative */
160          0,                     /* bitpos */
161          complain_overflow_signed, /* complain_on_overflow */
162          _bfd_mips_elf_generic_reloc,   /* special_function */
163          "R_MIPS_16",           /* name */
164          TRUE,                  /* partial_inplace */
165          0x0000ffff,            /* src_mask */
166          0x0000ffff,            /* dst_mask */
167          FALSE),                /* pcrel_offset */
168
169   /* 32 bit relocation.  */
170   HOWTO (R_MIPS_32,             /* type */
171          0,                     /* rightshift */
172          2,                     /* size (0 = byte, 1 = short, 2 = long) */
173          32,                    /* bitsize */
174          FALSE,                 /* pc_relative */
175          0,                     /* bitpos */
176          complain_overflow_dont, /* complain_on_overflow */
177          _bfd_mips_elf_generic_reloc,   /* special_function */
178          "R_MIPS_32",           /* name */
179          TRUE,                  /* partial_inplace */
180          0xffffffff,            /* src_mask */
181          0xffffffff,            /* dst_mask */
182          FALSE),                /* pcrel_offset */
183
184   /* 32 bit symbol relative relocation.  */
185   HOWTO (R_MIPS_REL32,          /* type */
186          0,                     /* rightshift */
187          2,                     /* size (0 = byte, 1 = short, 2 = long) */
188          32,                    /* bitsize */
189          FALSE,                 /* pc_relative */
190          0,                     /* bitpos */
191          complain_overflow_dont, /* complain_on_overflow */
192          _bfd_mips_elf_generic_reloc,   /* special_function */
193          "R_MIPS_REL32",        /* name */
194          TRUE,                  /* partial_inplace */
195          0xffffffff,            /* src_mask */
196          0xffffffff,            /* dst_mask */
197          FALSE),                /* pcrel_offset */
198
199   /* 26 bit jump address.  */
200   HOWTO (R_MIPS_26,             /* type */
201          2,                     /* rightshift */
202          2,                     /* size (0 = byte, 1 = short, 2 = long) */
203          26,                    /* bitsize */
204          FALSE,                 /* pc_relative */
205          0,                     /* bitpos */
206          complain_overflow_dont, /* complain_on_overflow */
207                                 /* This needs complex overflow
208                                    detection, because the upper 36
209                                    bits must match the PC + 4.  */
210          _bfd_mips_elf_generic_reloc,   /* special_function */
211          "R_MIPS_26",           /* name */
212          TRUE,                  /* partial_inplace */
213          0x03ffffff,            /* src_mask */
214          0x03ffffff,            /* dst_mask */
215          FALSE),                /* pcrel_offset */
216
217   /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
218      However, the native IRIX6 tools use them, so we try our best. */
219
220   /* High 16 bits of symbol value.  */
221   HOWTO (R_MIPS_HI16,           /* type */
222          16,                    /* rightshift */
223          2,                     /* size (0 = byte, 1 = short, 2 = long) */
224          16,                    /* bitsize */
225          FALSE,                 /* pc_relative */
226          0,                     /* bitpos */
227          complain_overflow_dont, /* complain_on_overflow */
228          _bfd_mips_elf_hi16_reloc, /* special_function */
229          "R_MIPS_HI16",         /* name */
230          TRUE,                  /* partial_inplace */
231          0x0000ffff,            /* src_mask */
232          0x0000ffff,            /* dst_mask */
233          FALSE),                /* pcrel_offset */
234
235   /* Low 16 bits of symbol value.  */
236   HOWTO (R_MIPS_LO16,           /* type */
237          0,                     /* rightshift */
238          2,                     /* size (0 = byte, 1 = short, 2 = long) */
239          16,                    /* bitsize */
240          FALSE,                 /* pc_relative */
241          0,                     /* bitpos */
242          complain_overflow_dont, /* complain_on_overflow */
243          _bfd_mips_elf_lo16_reloc, /* special_function */
244          "R_MIPS_LO16",         /* name */
245          TRUE,                  /* partial_inplace */
246          0x0000ffff,            /* src_mask */
247          0x0000ffff,            /* dst_mask */
248          FALSE),                /* pcrel_offset */
249
250   /* GP relative reference.  */
251   HOWTO (R_MIPS_GPREL16,        /* type */
252          0,                     /* rightshift */
253          2,                     /* size (0 = byte, 1 = short, 2 = long) */
254          16,                    /* bitsize */
255          FALSE,                 /* pc_relative */
256          0,                     /* bitpos */
257          complain_overflow_signed, /* complain_on_overflow */
258          mips_elf64_gprel16_reloc, /* special_function */
259          "R_MIPS_GPREL16",      /* name */
260          TRUE,                  /* partial_inplace */
261          0x0000ffff,            /* src_mask */
262          0x0000ffff,            /* dst_mask */
263          FALSE),                /* pcrel_offset */
264
265   /* Reference to literal section.  */
266   HOWTO (R_MIPS_LITERAL,        /* type */
267          0,                     /* rightshift */
268          2,                     /* size (0 = byte, 1 = short, 2 = long) */
269          16,                    /* bitsize */
270          FALSE,                 /* pc_relative */
271          0,                     /* bitpos */
272          complain_overflow_signed, /* complain_on_overflow */
273          mips_elf64_literal_reloc, /* special_function */
274          "R_MIPS_LITERAL",      /* name */
275          TRUE,                  /* partial_inplace */
276          0x0000ffff,            /* src_mask */
277          0x0000ffff,            /* dst_mask */
278          FALSE),                /* pcrel_offset */
279
280   /* Reference to global offset table.  */
281   HOWTO (R_MIPS_GOT16,          /* type */
282          0,                     /* rightshift */
283          2,                     /* size (0 = byte, 1 = short, 2 = long) */
284          16,                    /* bitsize */
285          FALSE,                 /* pc_relative */
286          0,                     /* bitpos */
287          complain_overflow_signed, /* complain_on_overflow */
288          _bfd_mips_elf_got16_reloc, /* special_function */
289          "R_MIPS_GOT16",        /* name */
290          TRUE,                  /* partial_inplace */
291          0x0000ffff,            /* src_mask */
292          0x0000ffff,            /* dst_mask */
293          FALSE),                /* pcrel_offset */
294
295   /* 16 bit PC relative reference.  Note that the ABI document has a typo
296      and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
297      We do the right thing here.  */
298   HOWTO (R_MIPS_PC16,           /* type */
299          2,                     /* rightshift */
300          2,                     /* size (0 = byte, 1 = short, 2 = long) */
301          16,                    /* bitsize */
302          TRUE,                  /* pc_relative */
303          0,                     /* bitpos */
304          complain_overflow_signed, /* complain_on_overflow */
305          _bfd_mips_elf_generic_reloc,   /* special_function */
306          "R_MIPS_PC16",         /* name */
307          TRUE,                  /* partial_inplace */
308          0x0000ffff,            /* src_mask */
309          0x0000ffff,            /* dst_mask */
310          TRUE),                 /* pcrel_offset */
311
312   /* 16 bit call through global offset table.  */
313   HOWTO (R_MIPS_CALL16,         /* type */
314          0,                     /* rightshift */
315          2,                     /* size (0 = byte, 1 = short, 2 = long) */
316          16,                    /* bitsize */
317          FALSE,                 /* pc_relative */
318          0,                     /* bitpos */
319          complain_overflow_signed, /* complain_on_overflow */
320          _bfd_mips_elf_generic_reloc,   /* special_function */
321          "R_MIPS_CALL16",       /* name */
322          TRUE,                  /* partial_inplace */
323          0x0000ffff,            /* src_mask */
324          0x0000ffff,            /* dst_mask */
325          FALSE),                /* pcrel_offset */
326
327   /* 32 bit GP relative reference.  */
328   HOWTO (R_MIPS_GPREL32,        /* type */
329          0,                     /* rightshift */
330          2,                     /* size (0 = byte, 1 = short, 2 = long) */
331          32,                    /* bitsize */
332          FALSE,                 /* pc_relative */
333          0,                     /* bitpos */
334          complain_overflow_dont, /* complain_on_overflow */
335          mips_elf64_gprel32_reloc, /* special_function */
336          "R_MIPS_GPREL32",      /* name */
337          TRUE,                  /* partial_inplace */
338          0xffffffff,            /* src_mask */
339          0xffffffff,            /* dst_mask */
340          FALSE),                /* pcrel_offset */
341
342   EMPTY_HOWTO (13),
343   EMPTY_HOWTO (14),
344   EMPTY_HOWTO (15),
345
346   /* A 5 bit shift field.  */
347   HOWTO (R_MIPS_SHIFT5,         /* type */
348          0,                     /* rightshift */
349          2,                     /* size (0 = byte, 1 = short, 2 = long) */
350          5,                     /* bitsize */
351          FALSE,                 /* pc_relative */
352          6,                     /* bitpos */
353          complain_overflow_bitfield, /* complain_on_overflow */
354          _bfd_mips_elf_generic_reloc,   /* special_function */
355          "R_MIPS_SHIFT5",       /* name */
356          TRUE,                  /* partial_inplace */
357          0x000007c0,            /* src_mask */
358          0x000007c0,            /* dst_mask */
359          FALSE),                /* pcrel_offset */
360
361   /* A 6 bit shift field.  */
362   HOWTO (R_MIPS_SHIFT6,         /* type */
363          0,                     /* rightshift */
364          2,                     /* size (0 = byte, 1 = short, 2 = long) */
365          6,                     /* bitsize */
366          FALSE,                 /* pc_relative */
367          6,                     /* bitpos */
368          complain_overflow_bitfield, /* complain_on_overflow */
369          mips_elf64_shift6_reloc, /* special_function */
370          "R_MIPS_SHIFT6",       /* name */
371          TRUE,                  /* partial_inplace */
372          0x000007c4,            /* src_mask */
373          0x000007c4,            /* dst_mask */
374          FALSE),                /* pcrel_offset */
375
376   /* 64 bit relocation.  */
377   HOWTO (R_MIPS_64,             /* type */
378          0,                     /* rightshift */
379          4,                     /* size (0 = byte, 1 = short, 2 = long) */
380          64,                    /* bitsize */
381          FALSE,                 /* pc_relative */
382          0,                     /* bitpos */
383          complain_overflow_dont, /* complain_on_overflow */
384          _bfd_mips_elf_generic_reloc,   /* special_function */
385          "R_MIPS_64",           /* name */
386          TRUE,                  /* partial_inplace */
387          MINUS_ONE,             /* src_mask */
388          MINUS_ONE,             /* dst_mask */
389          FALSE),                /* pcrel_offset */
390
391   /* Displacement in the global offset table.  */
392   HOWTO (R_MIPS_GOT_DISP,       /* type */
393          0,                     /* rightshift */
394          2,                     /* size (0 = byte, 1 = short, 2 = long) */
395          16,                    /* bitsize */
396          FALSE,                 /* pc_relative */
397          0,                     /* bitpos */
398          complain_overflow_signed, /* complain_on_overflow */
399          _bfd_mips_elf_generic_reloc,   /* special_function */
400          "R_MIPS_GOT_DISP",     /* name */
401          TRUE,                  /* partial_inplace */
402          0x0000ffff,            /* src_mask */
403          0x0000ffff,            /* dst_mask */
404          FALSE),                /* pcrel_offset */
405
406   /* Displacement to page pointer in the global offset table.  */
407   HOWTO (R_MIPS_GOT_PAGE,       /* type */
408          0,                     /* rightshift */
409          2,                     /* size (0 = byte, 1 = short, 2 = long) */
410          16,                    /* bitsize */
411          FALSE,                 /* pc_relative */
412          0,                     /* bitpos */
413          complain_overflow_signed, /* complain_on_overflow */
414          _bfd_mips_elf_generic_reloc,   /* special_function */
415          "R_MIPS_GOT_PAGE",     /* name */
416          TRUE,                  /* partial_inplace */
417          0x0000ffff,            /* src_mask */
418          0x0000ffff,            /* dst_mask */
419          FALSE),                /* pcrel_offset */
420
421   /* Offset from page pointer in the global offset table.  */
422   HOWTO (R_MIPS_GOT_OFST,       /* type */
423          0,                     /* rightshift */
424          2,                     /* size (0 = byte, 1 = short, 2 = long) */
425          16,                    /* bitsize */
426          FALSE,                 /* pc_relative */
427          0,                     /* bitpos */
428          complain_overflow_signed, /* complain_on_overflow */
429          _bfd_mips_elf_generic_reloc,   /* special_function */
430          "R_MIPS_GOT_OFST",     /* name */
431          TRUE,                  /* partial_inplace */
432          0x0000ffff,            /* src_mask */
433          0x0000ffff,            /* dst_mask */
434          FALSE),                /* pcrel_offset */
435
436   /* High 16 bits of displacement in global offset table.  */
437   HOWTO (R_MIPS_GOT_HI16,       /* type */
438          0,                     /* rightshift */
439          2,                     /* size (0 = byte, 1 = short, 2 = long) */
440          16,                    /* bitsize */
441          FALSE,                 /* pc_relative */
442          0,                     /* bitpos */
443          complain_overflow_dont, /* complain_on_overflow */
444          _bfd_mips_elf_generic_reloc,   /* special_function */
445          "R_MIPS_GOT_HI16",     /* name */
446          TRUE,                  /* partial_inplace */
447          0x0000ffff,            /* src_mask */
448          0x0000ffff,            /* dst_mask */
449          FALSE),                /* pcrel_offset */
450
451   /* Low 16 bits of displacement in global offset table.  */
452   HOWTO (R_MIPS_GOT_LO16,       /* type */
453          0,                     /* rightshift */
454          2,                     /* size (0 = byte, 1 = short, 2 = long) */
455          16,                    /* bitsize */
456          FALSE,                 /* pc_relative */
457          0,                     /* bitpos */
458          complain_overflow_dont, /* complain_on_overflow */
459          _bfd_mips_elf_generic_reloc,   /* special_function */
460          "R_MIPS_GOT_LO16",     /* name */
461          TRUE,                  /* partial_inplace */
462          0x0000ffff,            /* src_mask */
463          0x0000ffff,            /* dst_mask */
464          FALSE),                /* pcrel_offset */
465
466   /* 64 bit subtraction.  */
467   HOWTO (R_MIPS_SUB,            /* type */
468          0,                     /* rightshift */
469          4,                     /* size (0 = byte, 1 = short, 2 = long) */
470          64,                    /* bitsize */
471          FALSE,                 /* pc_relative */
472          0,                     /* bitpos */
473          complain_overflow_dont, /* complain_on_overflow */
474          _bfd_mips_elf_generic_reloc,   /* special_function */
475          "R_MIPS_SUB",          /* name */
476          TRUE,                  /* partial_inplace */
477          MINUS_ONE,             /* src_mask */
478          MINUS_ONE,             /* dst_mask */
479          FALSE),                /* pcrel_offset */
480
481   /* Insert the addend as an instruction.  */
482   /* FIXME: Not handled correctly.  */
483   HOWTO (R_MIPS_INSERT_A,       /* type */
484          0,                     /* rightshift */
485          2,                     /* size (0 = byte, 1 = short, 2 = long) */
486          32,                    /* bitsize */
487          FALSE,                 /* pc_relative */
488          0,                     /* bitpos */
489          complain_overflow_dont, /* complain_on_overflow */
490          _bfd_mips_elf_generic_reloc,   /* special_function */
491          "R_MIPS_INSERT_A",     /* name */
492          TRUE,                  /* partial_inplace */
493          0xffffffff,            /* src_mask */
494          0xffffffff,            /* dst_mask */
495          FALSE),                /* pcrel_offset */
496
497   /* Insert the addend as an instruction, and change all relocations
498      to refer to the old instruction at the address.  */
499   /* FIXME: Not handled correctly.  */
500   HOWTO (R_MIPS_INSERT_B,       /* type */
501          0,                     /* rightshift */
502          2,                     /* size (0 = byte, 1 = short, 2 = long) */
503          32,                    /* bitsize */
504          FALSE,                 /* pc_relative */
505          0,                     /* bitpos */
506          complain_overflow_dont, /* complain_on_overflow */
507          _bfd_mips_elf_generic_reloc,   /* special_function */
508          "R_MIPS_INSERT_B",     /* name */
509          TRUE,                  /* partial_inplace */
510          0xffffffff,            /* src_mask */
511          0xffffffff,            /* dst_mask */
512          FALSE),                /* pcrel_offset */
513
514   /* Delete a 32 bit instruction.  */
515   /* FIXME: Not handled correctly.  */
516   HOWTO (R_MIPS_DELETE,         /* type */
517          0,                     /* rightshift */
518          2,                     /* size (0 = byte, 1 = short, 2 = long) */
519          32,                    /* bitsize */
520          FALSE,                 /* pc_relative */
521          0,                     /* bitpos */
522          complain_overflow_dont, /* complain_on_overflow */
523          _bfd_mips_elf_generic_reloc,   /* special_function */
524          "R_MIPS_DELETE",       /* name */
525          TRUE,                  /* partial_inplace */
526          0xffffffff,            /* src_mask */
527          0xffffffff,            /* dst_mask */
528          FALSE),                /* pcrel_offset */
529
530   /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
531      We don't, because
532        a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
533           R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
534           fallable heuristics.
535        b) No other NewABI toolchain actually emits such relocations.  */
536   EMPTY_HOWTO (R_MIPS_HIGHER),
537   EMPTY_HOWTO (R_MIPS_HIGHEST),
538
539   /* High 16 bits of displacement in global offset table.  */
540   HOWTO (R_MIPS_CALL_HI16,      /* type */
541          0,                     /* rightshift */
542          2,                     /* size (0 = byte, 1 = short, 2 = long) */
543          16,                    /* bitsize */
544          FALSE,                 /* pc_relative */
545          0,                     /* bitpos */
546          complain_overflow_dont, /* complain_on_overflow */
547          _bfd_mips_elf_generic_reloc,   /* special_function */
548          "R_MIPS_CALL_HI16",    /* name */
549          TRUE,                  /* partial_inplace */
550          0x0000ffff,            /* src_mask */
551          0x0000ffff,            /* dst_mask */
552          FALSE),                /* pcrel_offset */
553
554   /* Low 16 bits of displacement in global offset table.  */
555   HOWTO (R_MIPS_CALL_LO16,      /* type */
556          0,                     /* rightshift */
557          2,                     /* size (0 = byte, 1 = short, 2 = long) */
558          16,                    /* bitsize */
559          FALSE,                 /* pc_relative */
560          0,                     /* bitpos */
561          complain_overflow_dont, /* complain_on_overflow */
562          _bfd_mips_elf_generic_reloc,   /* special_function */
563          "R_MIPS_CALL_LO16",    /* name */
564          TRUE,                  /* partial_inplace */
565          0x0000ffff,            /* src_mask */
566          0x0000ffff,            /* dst_mask */
567          FALSE),                /* pcrel_offset */
568
569   /* Section displacement, used by an associated event location section.  */
570   HOWTO (R_MIPS_SCN_DISP,       /* type */
571          0,                     /* rightshift */
572          2,                     /* size (0 = byte, 1 = short, 2 = long) */
573          32,                    /* bitsize */
574          FALSE,                 /* pc_relative */
575          0,                     /* bitpos */
576          complain_overflow_dont, /* complain_on_overflow */
577          _bfd_mips_elf_generic_reloc,   /* special_function */
578          "R_MIPS_SCN_DISP",     /* name */
579          TRUE,                  /* partial_inplace */
580          0xffffffff,            /* src_mask */
581          0xffffffff,            /* dst_mask */
582          FALSE),                /* pcrel_offset */
583
584   HOWTO (R_MIPS_REL16,          /* type */
585          0,                     /* rightshift */
586          1,                     /* size (0 = byte, 1 = short, 2 = long) */
587          16,                    /* bitsize */
588          FALSE,                 /* pc_relative */
589          0,                     /* bitpos */
590          complain_overflow_signed, /* complain_on_overflow */
591          _bfd_mips_elf_generic_reloc,   /* special_function */
592          "R_MIPS_REL16",        /* name */
593          TRUE,                  /* partial_inplace */
594          0xffff,                /* src_mask */
595          0xffff,                /* dst_mask */
596          FALSE),                /* pcrel_offset */
597
598   /* These two are obsolete.  */
599   EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
600   EMPTY_HOWTO (R_MIPS_PJUMP),
601
602   /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
603      It must be used for multigot GOT's (and only there).  */
604   HOWTO (R_MIPS_RELGOT,         /* type */
605          0,                     /* rightshift */
606          2,                     /* size (0 = byte, 1 = short, 2 = long) */
607          32,                    /* bitsize */
608          FALSE,                 /* pc_relative */
609          0,                     /* bitpos */
610          complain_overflow_dont, /* complain_on_overflow */
611          _bfd_mips_elf_generic_reloc,   /* special_function */
612          "R_MIPS_RELGOT",       /* name */
613          TRUE,                  /* partial_inplace */
614          0xffffffff,            /* src_mask */
615          0xffffffff,            /* dst_mask */
616          FALSE),                /* pcrel_offset */
617
618   /* Protected jump conversion.  This is an optimization hint.  No
619      relocation is required for correctness.  */
620   HOWTO (R_MIPS_JALR,           /* type */
621          0,                     /* rightshift */
622          2,                     /* size (0 = byte, 1 = short, 2 = long) */
623          32,                    /* bitsize */
624          FALSE,                 /* pc_relative */
625          0,                     /* bitpos */
626          complain_overflow_dont, /* complain_on_overflow */
627          _bfd_mips_elf_generic_reloc,   /* special_function */
628          "R_MIPS_JALR",         /* name */
629          FALSE,                 /* partial_inplace */
630          0,                     /* src_mask */
631          0x00000000,            /* dst_mask */
632          FALSE),                /* pcrel_offset */
633
634   /* TLS relocations.  */
635   EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
636   EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
637
638   HOWTO (R_MIPS_TLS_DTPMOD64,   /* type */
639          0,                     /* rightshift */
640          4,                     /* size (0 = byte, 1 = short, 2 = long) */
641          64,                    /* bitsize */
642          FALSE,                 /* pc_relative */
643          0,                     /* bitpos */
644          complain_overflow_dont, /* complain_on_overflow */
645          _bfd_mips_elf_generic_reloc, /* special_function */
646          "R_MIPS_TLS_DTPMOD64", /* name */
647          TRUE,                  /* partial_inplace */
648          MINUS_ONE,             /* src_mask */
649          MINUS_ONE,             /* dst_mask */
650          FALSE),                /* pcrel_offset */
651
652   HOWTO (R_MIPS_TLS_DTPREL64,   /* type */
653          0,                     /* rightshift */
654          4,                     /* size (0 = byte, 1 = short, 2 = long) */
655          64,                    /* bitsize */
656          FALSE,                 /* pc_relative */
657          0,                     /* bitpos */
658          complain_overflow_dont, /* complain_on_overflow */
659          _bfd_mips_elf_generic_reloc, /* special_function */
660          "R_MIPS_TLS_DTPREL64", /* name */
661          TRUE,                  /* partial_inplace */
662          MINUS_ONE,             /* src_mask */
663          MINUS_ONE,             /* dst_mask */
664          FALSE),                /* pcrel_offset */
665
666   /* TLS general dynamic variable reference.  */
667   HOWTO (R_MIPS_TLS_GD,         /* type */
668          0,                     /* rightshift */
669          2,                     /* size (0 = byte, 1 = short, 2 = long) */
670          16,                    /* bitsize */
671          FALSE,                 /* pc_relative */
672          0,                     /* bitpos */
673          complain_overflow_signed, /* complain_on_overflow */
674          _bfd_mips_elf_generic_reloc, /* special_function */
675          "R_MIPS_TLS_GD",       /* name */
676          TRUE,                  /* partial_inplace */
677          0x0000ffff,            /* src_mask */
678          0x0000ffff,            /* dst_mask */
679          FALSE),                /* pcrel_offset */
680
681   /* TLS local dynamic variable reference.  */
682   HOWTO (R_MIPS_TLS_LDM,        /* type */
683          0,                     /* rightshift */
684          2,                     /* size (0 = byte, 1 = short, 2 = long) */
685          16,                    /* bitsize */
686          FALSE,                 /* pc_relative */
687          0,                     /* bitpos */
688          complain_overflow_signed, /* complain_on_overflow */
689          _bfd_mips_elf_generic_reloc, /* special_function */
690          "R_MIPS_TLS_LDM",      /* name */
691          TRUE,                  /* partial_inplace */
692          0x0000ffff,            /* src_mask */
693          0x0000ffff,            /* dst_mask */
694          FALSE),                /* pcrel_offset */
695
696   /* TLS local dynamic offset.  */
697   HOWTO (R_MIPS_TLS_DTPREL_HI16,        /* type */
698          0,                     /* rightshift */
699          2,                     /* size (0 = byte, 1 = short, 2 = long) */
700          16,                    /* bitsize */
701          FALSE,                 /* pc_relative */
702          0,                     /* bitpos */
703          complain_overflow_signed, /* complain_on_overflow */
704          _bfd_mips_elf_generic_reloc, /* special_function */
705          "R_MIPS_TLS_DTPREL_HI16",      /* name */
706          TRUE,                  /* partial_inplace */
707          0x0000ffff,            /* src_mask */
708          0x0000ffff,            /* dst_mask */
709          FALSE),                /* pcrel_offset */
710
711   /* TLS local dynamic offset.  */
712   HOWTO (R_MIPS_TLS_DTPREL_LO16,        /* type */
713          0,                     /* rightshift */
714          2,                     /* size (0 = byte, 1 = short, 2 = long) */
715          16,                    /* bitsize */
716          FALSE,                 /* pc_relative */
717          0,                     /* bitpos */
718          complain_overflow_signed, /* complain_on_overflow */
719          _bfd_mips_elf_generic_reloc, /* special_function */
720          "R_MIPS_TLS_DTPREL_LO16",      /* name */
721          TRUE,                  /* partial_inplace */
722          0x0000ffff,            /* src_mask */
723          0x0000ffff,            /* dst_mask */
724          FALSE),                /* pcrel_offset */
725
726   /* TLS thread pointer offset.  */
727   HOWTO (R_MIPS_TLS_GOTTPREL,   /* type */
728          0,                     /* rightshift */
729          2,                     /* size (0 = byte, 1 = short, 2 = long) */
730          16,                    /* bitsize */
731          FALSE,                 /* pc_relative */
732          0,                     /* bitpos */
733          complain_overflow_signed, /* complain_on_overflow */
734          _bfd_mips_elf_generic_reloc, /* special_function */
735          "R_MIPS_TLS_GOTTPREL", /* name */
736          TRUE,                  /* partial_inplace */
737          0x0000ffff,            /* src_mask */
738          0x0000ffff,            /* dst_mask */
739          FALSE),                /* pcrel_offset */
740
741   /* TLS IE dynamic relocations.  */
742   EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
743
744   HOWTO (R_MIPS_TLS_TPREL64,    /* type */
745          0,                     /* rightshift */
746          4,                     /* size (0 = byte, 1 = short, 2 = long) */
747          64,                    /* bitsize */
748          FALSE,                 /* pc_relative */
749          0,                     /* bitpos */
750          complain_overflow_dont, /* complain_on_overflow */
751          _bfd_mips_elf_generic_reloc, /* special_function */
752          "R_MIPS_TLS_TPREL64",  /* name */
753          TRUE,                  /* partial_inplace */
754          MINUS_ONE,             /* src_mask */
755          MINUS_ONE,             /* dst_mask */
756          FALSE),                /* pcrel_offset */
757
758   /* TLS thread pointer offset.  */
759   HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
760          0,                     /* rightshift */
761          2,                     /* size (0 = byte, 1 = short, 2 = long) */
762          16,                    /* bitsize */
763          FALSE,                 /* pc_relative */
764          0,                     /* bitpos */
765          complain_overflow_signed, /* complain_on_overflow */
766          _bfd_mips_elf_generic_reloc, /* special_function */
767          "R_MIPS_TLS_TPREL_HI16", /* name */
768          TRUE,                  /* partial_inplace */
769          0x0000ffff,            /* src_mask */
770          0x0000ffff,            /* dst_mask */
771          FALSE),                /* pcrel_offset */
772
773   /* TLS thread pointer offset.  */
774   HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
775          0,                     /* rightshift */
776          2,                     /* size (0 = byte, 1 = short, 2 = long) */
777          16,                    /* bitsize */
778          FALSE,                 /* pc_relative */
779          0,                     /* bitpos */
780          complain_overflow_signed, /* complain_on_overflow */
781          _bfd_mips_elf_generic_reloc, /* special_function */
782          "R_MIPS_TLS_TPREL_LO16", /* name */
783          TRUE,                  /* partial_inplace */
784          0x0000ffff,            /* src_mask */
785          0x0000ffff,            /* dst_mask */
786          FALSE),                /* pcrel_offset */
787
788   /* 32 bit relocation with no addend.  */
789   HOWTO (R_MIPS_GLOB_DAT,       /* type */
790          0,                     /* rightshift */
791          2,                     /* size (0 = byte, 1 = short, 2 = long) */
792          32,                    /* bitsize */
793          FALSE,                 /* pc_relative */
794          0,                     /* bitpos */
795          complain_overflow_dont, /* complain_on_overflow */
796          _bfd_mips_elf_generic_reloc, /* special_function */
797          "R_MIPS_GLOB_DAT",     /* name */
798          FALSE,                 /* partial_inplace */
799          0x0,                   /* src_mask */
800          0xffffffff,            /* dst_mask */
801          FALSE),                /* pcrel_offset */
802
803   EMPTY_HOWTO (52),
804   EMPTY_HOWTO (53),
805   EMPTY_HOWTO (54),
806   EMPTY_HOWTO (55),
807   EMPTY_HOWTO (56),
808   EMPTY_HOWTO (57),
809   EMPTY_HOWTO (58),
810   EMPTY_HOWTO (59),
811
812   HOWTO (R_MIPS_PC21_S2,        /* type */
813          2,                     /* rightshift */
814          2,                     /* size (0 = byte, 1 = short, 2 = long) */
815          21,                    /* bitsize */
816          TRUE,                  /* pc_relative */
817          0,                     /* bitpos */
818          complain_overflow_signed, /* complain_on_overflow */
819          _bfd_mips_elf_generic_reloc, /* special_function */
820          "R_MIPS_PC21_S2",      /* name */
821          TRUE,                  /* partial_inplace */
822          0x001fffff,            /* src_mask */
823          0x001fffff,            /* dst_mask */
824          TRUE),                 /* pcrel_offset */
825
826   HOWTO (R_MIPS_PC26_S2,        /* type */
827          2,                     /* rightshift */
828          2,                     /* size (0 = byte, 1 = short, 2 = long) */
829          26,                    /* bitsize */
830          TRUE,                  /* pc_relative */
831          0,                     /* bitpos */
832          complain_overflow_signed, /* complain_on_overflow */
833          _bfd_mips_elf_generic_reloc, /* special_function */
834          "R_MIPS_PC26_S2",      /* name */
835          TRUE,                  /* partial_inplace */
836          0x03ffffff,            /* src_mask */
837          0x03ffffff,            /* dst_mask */
838          TRUE),                 /* pcrel_offset */
839
840   HOWTO (R_MIPS_PC18_S3,        /* type */
841          3,                     /* rightshift */
842          2,                     /* size (0 = byte, 1 = short, 2 = long) */
843          18,                    /* bitsize */
844          TRUE,                  /* pc_relative */
845          0,                     /* bitpos */
846          complain_overflow_signed, /* complain_on_overflow */
847          _bfd_mips_elf_generic_reloc,   /* special_function */
848          "R_MIPS_PC18_S3",      /* name */
849          TRUE,                  /* partial_inplace */
850          0x0003ffff,            /* src_mask */
851          0x0003ffff,            /* dst_mask */
852          TRUE),                 /* pcrel_offset */
853
854   HOWTO (R_MIPS_PC19_S2,        /* type */
855          2,                     /* rightshift */
856          2,                     /* size (0 = byte, 1 = short, 2 = long) */
857          19,                    /* bitsize */
858          TRUE,                  /* pc_relative */
859          0,                     /* bitpos */
860          complain_overflow_signed, /* complain_on_overflow */
861          _bfd_mips_elf_generic_reloc,   /* special_function */
862          "R_MIPS_PC19_S2",      /* name */
863          TRUE,                  /* partial_inplace */
864          0x0007ffff,            /* src_mask */
865          0x0007ffff,            /* dst_mask */
866          TRUE),                 /* pcrel_offset */
867
868   HOWTO (R_MIPS_PCHI16,         /* type */
869          16,                    /* rightshift */
870          2,                     /* size (0 = byte, 1 = short, 2 = long) */
871          16,                    /* bitsize */
872          TRUE,                  /* pc_relative */
873          0,                     /* bitpos */
874          complain_overflow_signed, /* complain_on_overflow */
875          _bfd_mips_elf_generic_reloc,   /* special_function */
876          "R_MIPS_PCHI16",       /* name */
877          TRUE,                  /* partial_inplace */
878          0x0000ffff,            /* src_mask */
879          0x0000ffff,            /* dst_mask */
880          TRUE),                 /* pcrel_offset */
881
882   HOWTO (R_MIPS_PCLO16,         /* type */
883          0,                     /* rightshift */
884          2,                     /* size (0 = byte, 1 = short, 2 = long) */
885          16,                    /* bitsize */
886          TRUE,                  /* pc_relative */
887          0,                     /* bitpos */
888          complain_overflow_dont, /* complain_on_overflow */
889          _bfd_mips_elf_generic_reloc,   /* special_function */
890          "R_MIPS_PCLO16",       /* name */
891          TRUE,                  /* partial_inplace */
892          0x0000ffff,            /* src_mask */
893          0x0000ffff,            /* dst_mask */
894          TRUE),                 /* pcrel_offset */
895
896 };
897
898 /* The relocation table used for SHT_RELA sections.  */
899
900 static reloc_howto_type mips_elf64_howto_table_rela[] =
901 {
902   /* No relocation.  */
903   HOWTO (R_MIPS_NONE,           /* type */
904          0,                     /* rightshift */
905          3,                     /* size (0 = byte, 1 = short, 2 = long) */
906          0,                     /* bitsize */
907          FALSE,                 /* pc_relative */
908          0,                     /* bitpos */
909          complain_overflow_dont, /* complain_on_overflow */
910          _bfd_mips_elf_generic_reloc,   /* special_function */
911          "R_MIPS_NONE",         /* name */
912          FALSE,                 /* partial_inplace */
913          0,                     /* src_mask */
914          0,                     /* dst_mask */
915          FALSE),                /* pcrel_offset */
916
917   /* 16 bit relocation.  */
918   HOWTO (R_MIPS_16,             /* type */
919          0,                     /* rightshift */
920          2,                     /* size (0 = byte, 1 = short, 2 = long) */
921          16,                    /* bitsize */
922          FALSE,                 /* pc_relative */
923          0,                     /* bitpos */
924          complain_overflow_signed, /* complain_on_overflow */
925          _bfd_mips_elf_generic_reloc,   /* special_function */
926          "R_MIPS_16",           /* name */
927          FALSE,                 /* partial_inplace */
928          0,                     /* src_mask */
929          0x0000ffff,            /* dst_mask */
930          FALSE),                /* pcrel_offset */
931
932   /* 32 bit relocation.  */
933   HOWTO (R_MIPS_32,             /* type */
934          0,                     /* rightshift */
935          2,                     /* size (0 = byte, 1 = short, 2 = long) */
936          32,                    /* bitsize */
937          FALSE,                 /* pc_relative */
938          0,                     /* bitpos */
939          complain_overflow_dont, /* complain_on_overflow */
940          _bfd_mips_elf_generic_reloc,   /* special_function */
941          "R_MIPS_32",           /* name */
942          FALSE,                 /* partial_inplace */
943          0,                     /* src_mask */
944          0xffffffff,            /* dst_mask */
945          FALSE),                /* pcrel_offset */
946
947   /* 32 bit symbol relative relocation.  */
948   HOWTO (R_MIPS_REL32,          /* type */
949          0,                     /* rightshift */
950          2,                     /* size (0 = byte, 1 = short, 2 = long) */
951          32,                    /* bitsize */
952          FALSE,                 /* pc_relative */
953          0,                     /* bitpos */
954          complain_overflow_dont, /* complain_on_overflow */
955          _bfd_mips_elf_generic_reloc,   /* special_function */
956          "R_MIPS_REL32",        /* name */
957          FALSE,                 /* partial_inplace */
958          0,                     /* src_mask */
959          0xffffffff,            /* dst_mask */
960          FALSE),                /* pcrel_offset */
961
962   /* 26 bit jump address.  */
963   HOWTO (R_MIPS_26,             /* type */
964          2,                     /* rightshift */
965          2,                     /* size (0 = byte, 1 = short, 2 = long) */
966          26,                    /* bitsize */
967          FALSE,                 /* pc_relative */
968          0,                     /* bitpos */
969          complain_overflow_dont, /* complain_on_overflow */
970                                 /* This needs complex overflow
971                                    detection, because the upper 36
972                                    bits must match the PC + 4.  */
973          _bfd_mips_elf_generic_reloc,   /* special_function */
974          "R_MIPS_26",           /* name */
975          FALSE,                 /* partial_inplace */
976          0,                     /* src_mask */
977          0x03ffffff,            /* dst_mask */
978          FALSE),                /* pcrel_offset */
979
980   /* High 16 bits of symbol value.  */
981   HOWTO (R_MIPS_HI16,           /* type */
982          0,                     /* rightshift */
983          2,                     /* size (0 = byte, 1 = short, 2 = long) */
984          16,                    /* bitsize */
985          FALSE,                 /* pc_relative */
986          0,                     /* bitpos */
987          complain_overflow_dont, /* complain_on_overflow */
988          _bfd_mips_elf_generic_reloc,   /* special_function */
989          "R_MIPS_HI16",         /* name */
990          FALSE,                 /* partial_inplace */
991          0,                     /* src_mask */
992          0x0000ffff,            /* dst_mask */
993          FALSE),                /* pcrel_offset */
994
995   /* Low 16 bits of symbol value.  */
996   HOWTO (R_MIPS_LO16,           /* type */
997          0,                     /* rightshift */
998          2,                     /* size (0 = byte, 1 = short, 2 = long) */
999          16,                    /* bitsize */
1000          FALSE,                 /* pc_relative */
1001          0,                     /* bitpos */
1002          complain_overflow_dont, /* complain_on_overflow */
1003          _bfd_mips_elf_generic_reloc,   /* special_function */
1004          "R_MIPS_LO16",         /* name */
1005          FALSE,                 /* partial_inplace */
1006          0,                     /* src_mask */
1007          0x0000ffff,            /* dst_mask */
1008          FALSE),                /* pcrel_offset */
1009
1010   /* GP relative reference.  */
1011   HOWTO (R_MIPS_GPREL16,        /* type */
1012          0,                     /* rightshift */
1013          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1014          16,                    /* bitsize */
1015          FALSE,                 /* pc_relative */
1016          0,                     /* bitpos */
1017          complain_overflow_signed, /* complain_on_overflow */
1018          mips_elf64_gprel16_reloc, /* special_function */
1019          "R_MIPS_GPREL16",      /* name */
1020          FALSE,                 /* partial_inplace */
1021          0,                     /* src_mask */
1022          0x0000ffff,            /* dst_mask */
1023          FALSE),                /* pcrel_offset */
1024
1025   /* Reference to literal section.  */
1026   HOWTO (R_MIPS_LITERAL,        /* type */
1027          0,                     /* rightshift */
1028          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1029          16,                    /* bitsize */
1030          FALSE,                 /* pc_relative */
1031          0,                     /* bitpos */
1032          complain_overflow_signed, /* complain_on_overflow */
1033          mips_elf64_literal_reloc, /* special_function */
1034          "R_MIPS_LITERAL",      /* name */
1035          FALSE,                 /* partial_inplace */
1036          0,                     /* src_mask */
1037          0x0000ffff,            /* dst_mask */
1038          FALSE),                /* pcrel_offset */
1039
1040   /* Reference to global offset table.  */
1041   HOWTO (R_MIPS_GOT16,          /* type */
1042          0,                     /* rightshift */
1043          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1044          16,                    /* bitsize */
1045          FALSE,                 /* pc_relative */
1046          0,                     /* bitpos */
1047          complain_overflow_signed, /* complain_on_overflow */
1048          _bfd_mips_elf_generic_reloc, /* special_function */
1049          "R_MIPS_GOT16",        /* name */
1050          FALSE,                 /* partial_inplace */
1051          0,                     /* src_mask */
1052          0x0000ffff,            /* dst_mask */
1053          FALSE),                /* pcrel_offset */
1054
1055   /* 16 bit PC relative reference.  Note that the ABI document has a typo
1056      and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
1057      We do the right thing here.  */
1058   HOWTO (R_MIPS_PC16,           /* type */
1059          2,                     /* rightshift */
1060          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1061          16,                    /* bitsize */
1062          TRUE,                  /* pc_relative */
1063          0,                     /* bitpos */
1064          complain_overflow_signed, /* complain_on_overflow */
1065          _bfd_mips_elf_generic_reloc,   /* special_function */
1066          "R_MIPS_PC16",         /* name */
1067          FALSE,                 /* partial_inplace */
1068          0,                     /* src_mask */
1069          0x0000ffff,            /* dst_mask */
1070          TRUE),                 /* pcrel_offset */
1071
1072   /* 16 bit call through global offset table.  */
1073   HOWTO (R_MIPS_CALL16,         /* type */
1074          0,                     /* rightshift */
1075          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1076          16,                    /* bitsize */
1077          FALSE,                 /* pc_relative */
1078          0,                     /* bitpos */
1079          complain_overflow_signed, /* complain_on_overflow */
1080          _bfd_mips_elf_generic_reloc,   /* special_function */
1081          "R_MIPS_CALL16",       /* name */
1082          FALSE,                 /* partial_inplace */
1083          0,                     /* src_mask */
1084          0x0000ffff,            /* dst_mask */
1085          FALSE),                /* pcrel_offset */
1086
1087   /* 32 bit GP relative reference.  */
1088   HOWTO (R_MIPS_GPREL32,        /* type */
1089          0,                     /* rightshift */
1090          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1091          32,                    /* bitsize */
1092          FALSE,                 /* pc_relative */
1093          0,                     /* bitpos */
1094          complain_overflow_dont, /* complain_on_overflow */
1095          mips_elf64_gprel32_reloc, /* special_function */
1096          "R_MIPS_GPREL32",      /* name */
1097          FALSE,                 /* partial_inplace */
1098          0,                     /* src_mask */
1099          0xffffffff,            /* dst_mask */
1100          FALSE),                /* pcrel_offset */
1101
1102   EMPTY_HOWTO (13),
1103   EMPTY_HOWTO (14),
1104   EMPTY_HOWTO (15),
1105
1106   /* A 5 bit shift field.  */
1107   HOWTO (R_MIPS_SHIFT5,         /* type */
1108          0,                     /* rightshift */
1109          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1110          5,                     /* bitsize */
1111          FALSE,                 /* pc_relative */
1112          6,                     /* bitpos */
1113          complain_overflow_bitfield, /* complain_on_overflow */
1114          _bfd_mips_elf_generic_reloc,   /* special_function */
1115          "R_MIPS_SHIFT5",       /* name */
1116          FALSE,                 /* partial_inplace */
1117          0,                     /* src_mask */
1118          0x000007c0,            /* dst_mask */
1119          FALSE),                /* pcrel_offset */
1120
1121   /* A 6 bit shift field.  */
1122   HOWTO (R_MIPS_SHIFT6,         /* type */
1123          0,                     /* rightshift */
1124          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1125          6,                     /* bitsize */
1126          FALSE,                 /* pc_relative */
1127          6,                     /* bitpos */
1128          complain_overflow_bitfield, /* complain_on_overflow */
1129          mips_elf64_shift6_reloc, /* special_function */
1130          "R_MIPS_SHIFT6",       /* name */
1131          FALSE,                 /* partial_inplace */
1132          0,                     /* src_mask */
1133          0x000007c4,            /* dst_mask */
1134          FALSE),                /* pcrel_offset */
1135
1136   /* 64 bit relocation.  */
1137   HOWTO (R_MIPS_64,             /* type */
1138          0,                     /* rightshift */
1139          4,                     /* size (0 = byte, 1 = short, 2 = long) */
1140          64,                    /* bitsize */
1141          FALSE,                 /* pc_relative */
1142          0,                     /* bitpos */
1143          complain_overflow_dont, /* complain_on_overflow */
1144          _bfd_mips_elf_generic_reloc,   /* special_function */
1145          "R_MIPS_64",           /* name */
1146          FALSE,                 /* partial_inplace */
1147          0,                     /* src_mask */
1148          MINUS_ONE,             /* dst_mask */
1149          FALSE),                /* pcrel_offset */
1150
1151   /* Displacement in the global offset table.  */
1152   HOWTO (R_MIPS_GOT_DISP,       /* type */
1153          0,                     /* rightshift */
1154          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1155          16,                    /* bitsize */
1156          FALSE,                 /* pc_relative */
1157          0,                     /* bitpos */
1158          complain_overflow_signed, /* complain_on_overflow */
1159          _bfd_mips_elf_generic_reloc,   /* special_function */
1160          "R_MIPS_GOT_DISP",     /* name */
1161          FALSE,                 /* partial_inplace */
1162          0,                     /* src_mask */
1163          0x0000ffff,            /* dst_mask */
1164          FALSE),                /* pcrel_offset */
1165
1166   /* Displacement to page pointer in the global offset table.  */
1167   HOWTO (R_MIPS_GOT_PAGE,       /* type */
1168          0,                     /* rightshift */
1169          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1170          16,                    /* bitsize */
1171          FALSE,                 /* pc_relative */
1172          0,                     /* bitpos */
1173          complain_overflow_signed, /* complain_on_overflow */
1174          _bfd_mips_elf_generic_reloc,   /* special_function */
1175          "R_MIPS_GOT_PAGE",     /* name */
1176          FALSE,                 /* partial_inplace */
1177          0,                     /* src_mask */
1178          0x0000ffff,            /* dst_mask */
1179          FALSE),                /* pcrel_offset */
1180
1181   /* Offset from page pointer in the global offset table.  */
1182   HOWTO (R_MIPS_GOT_OFST,       /* type */
1183          0,                     /* rightshift */
1184          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1185          16,                    /* bitsize */
1186          FALSE,                 /* pc_relative */
1187          0,                     /* bitpos */
1188          complain_overflow_signed, /* complain_on_overflow */
1189          _bfd_mips_elf_generic_reloc,   /* special_function */
1190          "R_MIPS_GOT_OFST",     /* name */
1191          FALSE,                 /* partial_inplace */
1192          0,                     /* src_mask */
1193          0x0000ffff,            /* dst_mask */
1194          FALSE),                /* pcrel_offset */
1195
1196   /* High 16 bits of displacement in global offset table.  */
1197   HOWTO (R_MIPS_GOT_HI16,       /* type */
1198          0,                     /* rightshift */
1199          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1200          16,                    /* bitsize */
1201          FALSE,                 /* pc_relative */
1202          0,                     /* bitpos */
1203          complain_overflow_dont, /* complain_on_overflow */
1204          _bfd_mips_elf_generic_reloc,   /* special_function */
1205          "R_MIPS_GOT_HI16",     /* name */
1206          FALSE,                 /* partial_inplace */
1207          0,                     /* src_mask */
1208          0x0000ffff,            /* dst_mask */
1209          FALSE),                /* pcrel_offset */
1210
1211   /* Low 16 bits of displacement in global offset table.  */
1212   HOWTO (R_MIPS_GOT_LO16,       /* type */
1213          0,                     /* rightshift */
1214          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1215          16,                    /* bitsize */
1216          FALSE,                 /* pc_relative */
1217          0,                     /* bitpos */
1218          complain_overflow_dont, /* complain_on_overflow */
1219          _bfd_mips_elf_generic_reloc,   /* special_function */
1220          "R_MIPS_GOT_LO16",     /* name */
1221          FALSE,                 /* partial_inplace */
1222          0,                     /* src_mask */
1223          0x0000ffff,            /* dst_mask */
1224          FALSE),                /* pcrel_offset */
1225
1226   /* 64 bit subtraction.  */
1227   HOWTO (R_MIPS_SUB,            /* type */
1228          0,                     /* rightshift */
1229          4,                     /* size (0 = byte, 1 = short, 2 = long) */
1230          64,                    /* bitsize */
1231          FALSE,                 /* pc_relative */
1232          0,                     /* bitpos */
1233          complain_overflow_dont, /* complain_on_overflow */
1234          _bfd_mips_elf_generic_reloc,   /* special_function */
1235          "R_MIPS_SUB",          /* name */
1236          FALSE,                 /* partial_inplace */
1237          0,                     /* src_mask */
1238          MINUS_ONE,             /* dst_mask */
1239          FALSE),                /* pcrel_offset */
1240
1241   /* Insert the addend as an instruction.  */
1242   /* FIXME: Not handled correctly.  */
1243   HOWTO (R_MIPS_INSERT_A,       /* type */
1244          0,                     /* rightshift */
1245          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1246          32,                    /* bitsize */
1247          FALSE,                 /* pc_relative */
1248          0,                     /* bitpos */
1249          complain_overflow_dont, /* complain_on_overflow */
1250          _bfd_mips_elf_generic_reloc,   /* special_function */
1251          "R_MIPS_INSERT_A",     /* name */
1252          FALSE,                 /* partial_inplace */
1253          0,                     /* src_mask */
1254          0xffffffff,            /* dst_mask */
1255          FALSE),                /* pcrel_offset */
1256
1257   /* Insert the addend as an instruction, and change all relocations
1258      to refer to the old instruction at the address.  */
1259   /* FIXME: Not handled correctly.  */
1260   HOWTO (R_MIPS_INSERT_B,       /* type */
1261          0,                     /* rightshift */
1262          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1263          32,                    /* bitsize */
1264          FALSE,                 /* pc_relative */
1265          0,                     /* bitpos */
1266          complain_overflow_dont, /* complain_on_overflow */
1267          _bfd_mips_elf_generic_reloc,   /* special_function */
1268          "R_MIPS_INSERT_B",     /* name */
1269          FALSE,                 /* partial_inplace */
1270          0,                     /* src_mask */
1271          0xffffffff,            /* dst_mask */
1272          FALSE),                /* pcrel_offset */
1273
1274   /* Delete a 32 bit instruction.  */
1275   /* FIXME: Not handled correctly.  */
1276   HOWTO (R_MIPS_DELETE,         /* type */
1277          0,                     /* rightshift */
1278          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1279          32,                    /* bitsize */
1280          FALSE,                 /* pc_relative */
1281          0,                     /* bitpos */
1282          complain_overflow_dont, /* complain_on_overflow */
1283          _bfd_mips_elf_generic_reloc,   /* special_function */
1284          "R_MIPS_DELETE",       /* name */
1285          FALSE,                 /* partial_inplace */
1286          0,                     /* src_mask */
1287          0xffffffff,            /* dst_mask */
1288          FALSE),                /* pcrel_offset */
1289
1290   /* Get the higher value of a 64 bit addend.  */
1291   HOWTO (R_MIPS_HIGHER,         /* type */
1292          0,                     /* rightshift */
1293          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1294          16,                    /* bitsize */
1295          FALSE,                 /* pc_relative */
1296          0,                     /* bitpos */
1297          complain_overflow_dont, /* complain_on_overflow */
1298          _bfd_mips_elf_generic_reloc, /* special_function */
1299          "R_MIPS_HIGHER",       /* name */
1300          FALSE,                 /* partial_inplace */
1301          0,                     /* src_mask */
1302          0x0000ffff,            /* dst_mask */
1303          FALSE),                /* pcrel_offset */
1304
1305   /* Get the highest value of a 64 bit addend.  */
1306   HOWTO (R_MIPS_HIGHEST,        /* type */
1307          0,                     /* rightshift */
1308          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1309          16,                    /* bitsize */
1310          FALSE,                 /* pc_relative */
1311          0,                     /* bitpos */
1312          complain_overflow_dont, /* complain_on_overflow */
1313          _bfd_mips_elf_generic_reloc, /* special_function */
1314          "R_MIPS_HIGHEST",      /* name */
1315          FALSE,                 /* partial_inplace */
1316          0,                     /* src_mask */
1317          0x0000ffff,            /* dst_mask */
1318          FALSE),                /* pcrel_offset */
1319
1320   /* High 16 bits of displacement in global offset table.  */
1321   HOWTO (R_MIPS_CALL_HI16,      /* type */
1322          0,                     /* rightshift */
1323          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1324          16,                    /* bitsize */
1325          FALSE,                 /* pc_relative */
1326          0,                     /* bitpos */
1327          complain_overflow_dont, /* complain_on_overflow */
1328          _bfd_mips_elf_generic_reloc,   /* special_function */
1329          "R_MIPS_CALL_HI16",    /* name */
1330          FALSE,                 /* partial_inplace */
1331          0,                     /* src_mask */
1332          0x0000ffff,            /* dst_mask */
1333          FALSE),                /* pcrel_offset */
1334
1335   /* Low 16 bits of displacement in global offset table.  */
1336   HOWTO (R_MIPS_CALL_LO16,      /* type */
1337          0,                     /* rightshift */
1338          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1339          16,                    /* bitsize */
1340          FALSE,                 /* pc_relative */
1341          0,                     /* bitpos */
1342          complain_overflow_dont, /* complain_on_overflow */
1343          _bfd_mips_elf_generic_reloc,   /* special_function */
1344          "R_MIPS_CALL_LO16",    /* name */
1345          FALSE,                 /* partial_inplace */
1346          0,                     /* src_mask */
1347          0x0000ffff,            /* dst_mask */
1348          FALSE),                /* pcrel_offset */
1349
1350   /* Section displacement, used by an associated event location section.  */
1351   HOWTO (R_MIPS_SCN_DISP,       /* type */
1352          0,                     /* rightshift */
1353          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1354          32,                    /* bitsize */
1355          FALSE,                 /* pc_relative */
1356          0,                     /* bitpos */
1357          complain_overflow_dont, /* complain_on_overflow */
1358          _bfd_mips_elf_generic_reloc,   /* special_function */
1359          "R_MIPS_SCN_DISP",     /* name */
1360          FALSE,                 /* partial_inplace */
1361          0,                     /* src_mask */
1362          0xffffffff,            /* dst_mask */
1363          FALSE),                /* pcrel_offset */
1364
1365   HOWTO (R_MIPS_REL16,          /* type */
1366          0,                     /* rightshift */
1367          1,                     /* size (0 = byte, 1 = short, 2 = long) */
1368          16,                    /* bitsize */
1369          FALSE,                 /* pc_relative */
1370          0,                     /* bitpos */
1371          complain_overflow_signed, /* complain_on_overflow */
1372          _bfd_mips_elf_generic_reloc,   /* special_function */
1373          "R_MIPS_REL16",        /* name */
1374          FALSE,                 /* partial_inplace */
1375          0,                     /* src_mask */
1376          0xffff,                /* dst_mask */
1377          FALSE),                /* pcrel_offset */
1378
1379   /* These two are obsolete.  */
1380   EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1381   EMPTY_HOWTO (R_MIPS_PJUMP),
1382
1383   /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1384      It must be used for multigot GOT's (and only there).  */
1385   HOWTO (R_MIPS_RELGOT,         /* type */
1386          0,                     /* rightshift */
1387          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1388          32,                    /* bitsize */
1389          FALSE,                 /* pc_relative */
1390          0,                     /* bitpos */
1391          complain_overflow_dont, /* complain_on_overflow */
1392          _bfd_mips_elf_generic_reloc,   /* special_function */
1393          "R_MIPS_RELGOT",       /* name */
1394          FALSE,                 /* partial_inplace */
1395          0,                     /* src_mask */
1396          0xffffffff,            /* dst_mask */
1397          FALSE),                /* pcrel_offset */
1398
1399   /* Protected jump conversion.  This is an optimization hint.  No
1400      relocation is required for correctness.  */
1401   HOWTO (R_MIPS_JALR,           /* type */
1402          0,                     /* rightshift */
1403          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1404          32,                    /* bitsize */
1405          FALSE,                 /* pc_relative */
1406          0,                     /* bitpos */
1407          complain_overflow_dont, /* complain_on_overflow */
1408          _bfd_mips_elf_generic_reloc,   /* special_function */
1409          "R_MIPS_JALR",         /* name */
1410          FALSE,                 /* partial_inplace */
1411          0,                     /* src_mask */
1412          0x00000000,            /* dst_mask */
1413          FALSE),                /* pcrel_offset */
1414
1415   /* TLS relocations.  */
1416   EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
1417   EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
1418
1419   HOWTO (R_MIPS_TLS_DTPMOD64,   /* type */
1420          0,                     /* rightshift */
1421          4,                     /* size (0 = byte, 1 = short, 2 = long) */
1422          64,                    /* bitsize */
1423          FALSE,                 /* pc_relative */
1424          0,                     /* bitpos */
1425          complain_overflow_dont, /* complain_on_overflow */
1426          _bfd_mips_elf_generic_reloc, /* special_function */
1427          "R_MIPS_TLS_DTPMOD64", /* name */
1428          FALSE,                 /* partial_inplace */
1429          0,                     /* src_mask */
1430          MINUS_ONE,             /* dst_mask */
1431          FALSE),                /* pcrel_offset */
1432
1433   HOWTO (R_MIPS_TLS_DTPREL64,   /* type */
1434          0,                     /* rightshift */
1435          4,                     /* size (0 = byte, 1 = short, 2 = long) */
1436          64,                    /* bitsize */
1437          FALSE,                 /* pc_relative */
1438          0,                     /* bitpos */
1439          complain_overflow_dont, /* complain_on_overflow */
1440          _bfd_mips_elf_generic_reloc, /* special_function */
1441          "R_MIPS_TLS_DTPREL64", /* name */
1442          FALSE,                 /* partial_inplace */
1443          0,                     /* src_mask */
1444          MINUS_ONE,             /* dst_mask */
1445          FALSE),                /* pcrel_offset */
1446
1447   /* TLS general dynamic variable reference.  */
1448   HOWTO (R_MIPS_TLS_GD,         /* type */
1449          0,                     /* rightshift */
1450          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1451          16,                    /* bitsize */
1452          FALSE,                 /* pc_relative */
1453          0,                     /* bitpos */
1454          complain_overflow_signed, /* complain_on_overflow */
1455          _bfd_mips_elf_generic_reloc, /* special_function */
1456          "R_MIPS_TLS_GD",       /* name */
1457          FALSE,                 /* partial_inplace */
1458          0,                     /* src_mask */
1459          0x0000ffff,            /* dst_mask */
1460          FALSE),                /* pcrel_offset */
1461
1462   /* TLS local dynamic variable reference.  */
1463   HOWTO (R_MIPS_TLS_LDM,        /* type */
1464          0,                     /* rightshift */
1465          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1466          16,                    /* bitsize */
1467          FALSE,                 /* pc_relative */
1468          0,                     /* bitpos */
1469          complain_overflow_signed, /* complain_on_overflow */
1470          _bfd_mips_elf_generic_reloc, /* special_function */
1471          "R_MIPS_TLS_LDM",      /* name */
1472          FALSE,                 /* partial_inplace */
1473          0,                     /* src_mask */
1474          0x0000ffff,            /* dst_mask */
1475          FALSE),                /* pcrel_offset */
1476
1477   /* TLS local dynamic offset.  */
1478   HOWTO (R_MIPS_TLS_DTPREL_HI16,        /* type */
1479          0,                     /* rightshift */
1480          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1481          16,                    /* bitsize */
1482          FALSE,                 /* pc_relative */
1483          0,                     /* bitpos */
1484          complain_overflow_signed, /* complain_on_overflow */
1485          _bfd_mips_elf_generic_reloc, /* special_function */
1486          "R_MIPS_TLS_DTPREL_HI16",      /* name */
1487          FALSE,                 /* partial_inplace */
1488          0,                     /* src_mask */
1489          0x0000ffff,            /* dst_mask */
1490          FALSE),                /* pcrel_offset */
1491
1492   /* TLS local dynamic offset.  */
1493   HOWTO (R_MIPS_TLS_DTPREL_LO16,        /* type */
1494          0,                     /* rightshift */
1495          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1496          16,                    /* bitsize */
1497          FALSE,                 /* pc_relative */
1498          0,                     /* bitpos */
1499          complain_overflow_signed, /* complain_on_overflow */
1500          _bfd_mips_elf_generic_reloc, /* special_function */
1501          "R_MIPS_TLS_DTPREL_LO16",      /* name */
1502          FALSE,                 /* partial_inplace */
1503          0,                     /* src_mask */
1504          0x0000ffff,            /* dst_mask */
1505          FALSE),                /* pcrel_offset */
1506
1507   /* TLS thread pointer offset.  */
1508   HOWTO (R_MIPS_TLS_GOTTPREL,   /* type */
1509          0,                     /* rightshift */
1510          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1511          16,                    /* bitsize */
1512          FALSE,                 /* pc_relative */
1513          0,                     /* bitpos */
1514          complain_overflow_signed, /* complain_on_overflow */
1515          _bfd_mips_elf_generic_reloc, /* special_function */
1516          "R_MIPS_TLS_GOTTPREL", /* name */
1517          FALSE,                 /* partial_inplace */
1518          0,                     /* src_mask */
1519          0x0000ffff,            /* dst_mask */
1520          FALSE),                /* pcrel_offset */
1521
1522   /* TLS IE dynamic relocations.  */
1523   EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
1524
1525   HOWTO (R_MIPS_TLS_TPREL64,    /* type */
1526          0,                     /* rightshift */
1527          4,                     /* size (0 = byte, 1 = short, 2 = long) */
1528          64,                    /* bitsize */
1529          FALSE,                 /* pc_relative */
1530          0,                     /* bitpos */
1531          complain_overflow_dont, /* complain_on_overflow */
1532          _bfd_mips_elf_generic_reloc, /* special_function */
1533          "R_MIPS_TLS_TPREL64",  /* name */
1534          FALSE,                 /* partial_inplace */
1535          0,                     /* src_mask */
1536          MINUS_ONE,             /* dst_mask */
1537          FALSE),                /* pcrel_offset */
1538
1539   /* TLS thread pointer offset.  */
1540   HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
1541          0,                     /* rightshift */
1542          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1543          16,                    /* bitsize */
1544          FALSE,                 /* pc_relative */
1545          0,                     /* bitpos */
1546          complain_overflow_signed, /* complain_on_overflow */
1547          _bfd_mips_elf_generic_reloc, /* special_function */
1548          "R_MIPS_TLS_TPREL_HI16", /* name */
1549          FALSE,                 /* partial_inplace */
1550          0,                     /* src_mask */
1551          0x0000ffff,            /* dst_mask */
1552          FALSE),                /* pcrel_offset */
1553
1554   /* TLS thread pointer offset.  */
1555   HOWTO (R_MIPS_TLS_TPREL_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_signed, /* complain_on_overflow */
1562          _bfd_mips_elf_generic_reloc, /* special_function */
1563          "R_MIPS_TLS_TPREL_LO16", /* name */
1564          FALSE,                 /* partial_inplace */
1565          0,                     /* src_mask */
1566          0x0000ffff,            /* dst_mask */
1567          FALSE),                /* pcrel_offset */
1568
1569   /* 32 bit relocation with no addend.  */
1570   HOWTO (R_MIPS_GLOB_DAT,       /* type */
1571          0,                     /* rightshift */
1572          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1573          32,                    /* bitsize */
1574          FALSE,                 /* pc_relative */
1575          0,                     /* bitpos */
1576          complain_overflow_dont, /* complain_on_overflow */
1577          _bfd_mips_elf_generic_reloc, /* special_function */
1578          "R_MIPS_GLOB_DAT",     /* name */
1579          FALSE,                 /* partial_inplace */
1580          0x0,                   /* src_mask */
1581          0xffffffff,            /* dst_mask */
1582          FALSE),                /* pcrel_offset */
1583
1584   EMPTY_HOWTO (52),
1585   EMPTY_HOWTO (53),
1586   EMPTY_HOWTO (54),
1587   EMPTY_HOWTO (55),
1588   EMPTY_HOWTO (56),
1589   EMPTY_HOWTO (57),
1590   EMPTY_HOWTO (58),
1591   EMPTY_HOWTO (59),
1592
1593   HOWTO (R_MIPS_PC21_S2,        /* type */
1594          2,                     /* rightshift */
1595          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1596          21,                    /* bitsize */
1597          TRUE,                  /* pc_relative */
1598          0,                     /* bitpos */
1599          complain_overflow_signed, /* complain_on_overflow */
1600          _bfd_mips_elf_generic_reloc, /* special_function */
1601          "R_MIPS_PC21_S2",      /* name */
1602          FALSE,                 /* partial_inplace */
1603          0,                     /* src_mask */
1604          0x001fffff,            /* dst_mask */
1605          TRUE),                 /* pcrel_offset */
1606
1607   HOWTO (R_MIPS_PC26_S2,        /* type */
1608          2,                     /* rightshift */
1609          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1610          26,                    /* bitsize */
1611          TRUE,                  /* pc_relative */
1612          0,                     /* bitpos */
1613          complain_overflow_signed, /* complain_on_overflow */
1614          _bfd_mips_elf_generic_reloc, /* special_function */
1615          "R_MIPS_PC26_S2",      /* name */
1616          FALSE,                 /* partial_inplace */
1617          0,                     /* src_mask */
1618          0x03ffffff,            /* dst_mask */
1619          TRUE),                 /* pcrel_offset */
1620
1621   HOWTO (R_MIPS_PC18_S3,        /* type */
1622          3,                     /* rightshift */
1623          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1624          18,                    /* bitsize */
1625          TRUE,                  /* pc_relative */
1626          0,                     /* bitpos */
1627          complain_overflow_signed, /* complain_on_overflow */
1628          _bfd_mips_elf_generic_reloc,   /* special_function */
1629          "R_MIPS_PC18_S3",      /* name */
1630          FALSE,                 /* partial_inplace */
1631          0,                     /* src_mask */
1632          0x0003ffff,            /* dst_mask */
1633          TRUE),                 /* pcrel_offset */
1634
1635   HOWTO (R_MIPS_PC19_S2,        /* type */
1636          2,                     /* rightshift */
1637          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1638          19,                    /* bitsize */
1639          TRUE,                  /* pc_relative */
1640          0,                     /* bitpos */
1641          complain_overflow_signed, /* complain_on_overflow */
1642          _bfd_mips_elf_generic_reloc,   /* special_function */
1643          "R_MIPS_PC19_S2",      /* name */
1644          FALSE,                 /* partial_inplace */
1645          0,                     /* src_mask */
1646          0x0007ffff,            /* dst_mask */
1647          TRUE),                 /* pcrel_offset */
1648
1649   HOWTO (R_MIPS_PCHI16,         /* type */
1650          16,                    /* rightshift */
1651          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1652          16,                    /* bitsize */
1653          TRUE,                  /* pc_relative */
1654          0,                     /* bitpos */
1655          complain_overflow_signed, /* complain_on_overflow */
1656          _bfd_mips_elf_generic_reloc,   /* special_function */
1657          "R_MIPS_PCHI16",       /* name */
1658          FALSE,                 /* partial_inplace */
1659          0,                     /* src_mask */
1660          0x0000ffff,            /* dst_mask */
1661          TRUE),                 /* pcrel_offset */
1662
1663   HOWTO (R_MIPS_PCLO16,         /* type */
1664          0,                     /* rightshift */
1665          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1666          16,                    /* bitsize */
1667          TRUE,                  /* pc_relative */
1668          0,                     /* bitpos */
1669          complain_overflow_dont, /* complain_on_overflow */
1670          _bfd_mips_elf_generic_reloc,   /* special_function */
1671          "R_MIPS_PCLO16",       /* name */
1672          FALSE,                 /* partial_inplace */
1673          0,                     /* src_mask */
1674          0x0000ffff,            /* dst_mask */
1675          TRUE),                 /* pcrel_offset */
1676
1677 };
1678
1679 static reloc_howto_type mips16_elf64_howto_table_rel[] =
1680 {
1681   /* The reloc used for the mips16 jump instruction.  */
1682   HOWTO (R_MIPS16_26,           /* type */
1683          2,                     /* rightshift */
1684          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1685          26,                    /* bitsize */
1686          FALSE,                 /* pc_relative */
1687          0,                     /* bitpos */
1688          complain_overflow_dont, /* complain_on_overflow */
1689                                 /* This needs complex overflow
1690                                    detection, because the upper four
1691                                    bits must match the PC.  */
1692          _bfd_mips_elf_generic_reloc, /* special_function */
1693          "R_MIPS16_26",         /* name */
1694          TRUE,                  /* partial_inplace */
1695          0x3ffffff,             /* src_mask */
1696          0x3ffffff,             /* dst_mask */
1697          FALSE),                /* pcrel_offset */
1698
1699   /* The reloc used for the mips16 gprel instruction.  */
1700   HOWTO (R_MIPS16_GPREL,        /* type */
1701          0,                     /* rightshift */
1702          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1703          16,                    /* bitsize */
1704          FALSE,                 /* pc_relative */
1705          0,                     /* bitpos */
1706          complain_overflow_signed, /* complain_on_overflow */
1707          mips16_gprel_reloc,    /* special_function */
1708          "R_MIPS16_GPREL",      /* name */
1709          TRUE,                  /* partial_inplace */
1710          0x0000ffff,            /* src_mask */
1711          0x0000ffff,            /* dst_mask */
1712          FALSE),                /* pcrel_offset */
1713
1714   /* A MIPS16 reference to the global offset table.  */
1715   HOWTO (R_MIPS16_GOT16,        /* type */
1716          0,                     /* rightshift */
1717          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1718          16,                    /* bitsize */
1719          FALSE,                 /* pc_relative */
1720          0,                     /* bitpos */
1721          complain_overflow_dont, /* complain_on_overflow */
1722          _bfd_mips_elf_got16_reloc, /* special_function */
1723          "R_MIPS16_GOT16",      /* name */
1724          TRUE,                  /* partial_inplace */
1725          0x0000ffff,            /* src_mask */
1726          0x0000ffff,            /* dst_mask */
1727          FALSE),                /* pcrel_offset */
1728
1729   /* A MIPS16 call through the global offset table.  */
1730   HOWTO (R_MIPS16_CALL16,       /* type */
1731          0,                     /* rightshift */
1732          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1733          16,                    /* bitsize */
1734          FALSE,                 /* pc_relative */
1735          0,                     /* bitpos */
1736          complain_overflow_dont, /* complain_on_overflow */
1737          _bfd_mips_elf_generic_reloc, /* special_function */
1738          "R_MIPS16_CALL16",     /* name */
1739          TRUE,                  /* partial_inplace */
1740          0x0000ffff,            /* src_mask */
1741          0x0000ffff,            /* dst_mask */
1742          FALSE),                /* pcrel_offset */
1743
1744   /* MIPS16 high 16 bits of symbol value.  */
1745   HOWTO (R_MIPS16_HI16,         /* type */
1746          16,                    /* rightshift */
1747          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1748          16,                    /* bitsize */
1749          FALSE,                 /* pc_relative */
1750          0,                     /* bitpos */
1751          complain_overflow_dont, /* complain_on_overflow */
1752          _bfd_mips_elf_hi16_reloc, /* special_function */
1753          "R_MIPS16_HI16",       /* name */
1754          TRUE,                  /* partial_inplace */
1755          0x0000ffff,            /* src_mask */
1756          0x0000ffff,            /* dst_mask */
1757          FALSE),                /* pcrel_offset */
1758
1759   /* MIPS16 low 16 bits of symbol value.  */
1760   HOWTO (R_MIPS16_LO16,         /* type */
1761          0,                     /* rightshift */
1762          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1763          16,                    /* bitsize */
1764          FALSE,                 /* pc_relative */
1765          0,                     /* bitpos */
1766          complain_overflow_dont, /* complain_on_overflow */
1767          _bfd_mips_elf_lo16_reloc, /* special_function */
1768          "R_MIPS16_LO16",       /* name */
1769          TRUE,                  /* partial_inplace */
1770          0x0000ffff,            /* src_mask */
1771          0x0000ffff,            /* dst_mask */
1772          FALSE),                /* pcrel_offset */
1773
1774   /* MIPS16 TLS general dynamic variable reference.  */
1775   HOWTO (R_MIPS16_TLS_GD,       /* type */
1776          0,                     /* rightshift */
1777          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1778          16,                    /* bitsize */
1779          FALSE,                 /* pc_relative */
1780          0,                     /* bitpos */
1781          complain_overflow_signed, /* complain_on_overflow */
1782          _bfd_mips_elf_generic_reloc, /* special_function */
1783          "R_MIPS16_TLS_GD",     /* name */
1784          TRUE,                  /* partial_inplace */
1785          0x0000ffff,            /* src_mask */
1786          0x0000ffff,            /* dst_mask */
1787          FALSE),                /* pcrel_offset */
1788
1789   /* MIPS16 TLS local dynamic variable reference.  */
1790   HOWTO (R_MIPS16_TLS_LDM,      /* type */
1791          0,                     /* rightshift */
1792          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1793          16,                    /* bitsize */
1794          FALSE,                 /* pc_relative */
1795          0,                     /* bitpos */
1796          complain_overflow_signed, /* complain_on_overflow */
1797          _bfd_mips_elf_generic_reloc, /* special_function */
1798          "R_MIPS16_TLS_LDM",    /* name */
1799          TRUE,                  /* partial_inplace */
1800          0x0000ffff,            /* src_mask */
1801          0x0000ffff,            /* dst_mask */
1802          FALSE),                /* pcrel_offset */
1803
1804   /* MIPS16 TLS local dynamic offset.  */
1805   HOWTO (R_MIPS16_TLS_DTPREL_HI16,      /* type */
1806          0,                     /* rightshift */
1807          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1808          16,                    /* bitsize */
1809          FALSE,                 /* pc_relative */
1810          0,                     /* bitpos */
1811          complain_overflow_signed, /* complain_on_overflow */
1812          _bfd_mips_elf_generic_reloc, /* special_function */
1813          "R_MIPS16_TLS_DTPREL_HI16",    /* name */
1814          TRUE,                  /* partial_inplace */
1815          0x0000ffff,            /* src_mask */
1816          0x0000ffff,            /* dst_mask */
1817          FALSE),                /* pcrel_offset */
1818
1819   /* MIPS16 TLS local dynamic offset.  */
1820   HOWTO (R_MIPS16_TLS_DTPREL_LO16,      /* type */
1821          0,                     /* rightshift */
1822          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1823          16,                    /* bitsize */
1824          FALSE,                 /* pc_relative */
1825          0,                     /* bitpos */
1826          complain_overflow_signed, /* complain_on_overflow */
1827          _bfd_mips_elf_generic_reloc, /* special_function */
1828          "R_MIPS16_TLS_DTPREL_LO16",    /* name */
1829          TRUE,                  /* partial_inplace */
1830          0x0000ffff,            /* src_mask */
1831          0x0000ffff,            /* dst_mask */
1832          FALSE),                /* pcrel_offset */
1833
1834   /* MIPS16 TLS thread pointer offset.  */
1835   HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */
1836          0,                     /* rightshift */
1837          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1838          16,                    /* bitsize */
1839          FALSE,                 /* pc_relative */
1840          0,                     /* bitpos */
1841          complain_overflow_signed, /* complain_on_overflow */
1842          _bfd_mips_elf_generic_reloc, /* special_function */
1843          "R_MIPS16_TLS_GOTTPREL",       /* name */
1844          TRUE,                  /* partial_inplace */
1845          0x0000ffff,            /* src_mask */
1846          0x0000ffff,            /* dst_mask */
1847          FALSE),                /* pcrel_offset */
1848
1849   /* MIPS16 TLS thread pointer offset.  */
1850   HOWTO (R_MIPS16_TLS_TPREL_HI16,       /* type */
1851          0,                     /* rightshift */
1852          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1853          16,                    /* bitsize */
1854          FALSE,                 /* pc_relative */
1855          0,                     /* bitpos */
1856          complain_overflow_signed, /* complain_on_overflow */
1857          _bfd_mips_elf_generic_reloc, /* special_function */
1858          "R_MIPS16_TLS_TPREL_HI16", /* name */
1859          TRUE,                  /* partial_inplace */
1860          0x0000ffff,            /* src_mask */
1861          0x0000ffff,            /* dst_mask */
1862          FALSE),                /* pcrel_offset */
1863
1864   /* MIPS16 TLS thread pointer offset.  */
1865   HOWTO (R_MIPS16_TLS_TPREL_LO16,       /* type */
1866          0,                     /* rightshift */
1867          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1868          16,                    /* bitsize */
1869          FALSE,                 /* pc_relative */
1870          0,                     /* bitpos */
1871          complain_overflow_signed, /* complain_on_overflow */
1872          _bfd_mips_elf_generic_reloc, /* special_function */
1873          "R_MIPS16_TLS_TPREL_LO16", /* name */
1874          TRUE,                  /* partial_inplace */
1875          0x0000ffff,            /* src_mask */
1876          0x0000ffff,            /* dst_mask */
1877          FALSE),                /* pcrel_offset */
1878
1879   /* MIPS16 16-bit PC-relative branch offset.  */
1880   HOWTO (R_MIPS16_PC16_S1,      /* type */
1881          1,                     /* rightshift */
1882          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1883          16,                    /* bitsize */
1884          TRUE,                  /* pc_relative */
1885          0,                     /* bitpos */
1886          complain_overflow_signed, /* complain_on_overflow */
1887          _bfd_mips_elf_generic_reloc, /* special_function */
1888          "R_MIPS16_PC16_S1",    /* name */
1889          TRUE,                  /* partial_inplace */
1890          0x0000ffff,            /* src_mask */
1891          0x0000ffff,            /* dst_mask */
1892          TRUE),                 /* pcrel_offset */
1893 };
1894
1895 static reloc_howto_type mips16_elf64_howto_table_rela[] =
1896 {
1897   /* The reloc used for the mips16 jump instruction.  */
1898   HOWTO (R_MIPS16_26,           /* type */
1899          2,                     /* rightshift */
1900          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1901          26,                    /* bitsize */
1902          FALSE,                 /* pc_relative */
1903          0,                     /* bitpos */
1904          complain_overflow_dont, /* complain_on_overflow */
1905                                 /* This needs complex overflow
1906                                    detection, because the upper four
1907                                    bits must match the PC.  */
1908          _bfd_mips_elf_generic_reloc, /* special_function */
1909          "R_MIPS16_26",         /* name */
1910          FALSE,                 /* partial_inplace */
1911          0,                     /* src_mask */
1912          0x3ffffff,             /* dst_mask */
1913          FALSE),                /* pcrel_offset */
1914
1915   /* The reloc used for the mips16 gprel instruction.  */
1916   HOWTO (R_MIPS16_GPREL,        /* type */
1917          0,                     /* rightshift */
1918          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1919          16,                    /* bitsize */
1920          FALSE,                 /* pc_relative */
1921          0,                     /* bitpos */
1922          complain_overflow_signed, /* complain_on_overflow */
1923          mips16_gprel_reloc,    /* special_function */
1924          "R_MIPS16_GPREL",      /* name */
1925          FALSE,                 /* partial_inplace */
1926          0,                     /* src_mask */
1927          0x0000ffff,            /* dst_mask */
1928          FALSE),                /* pcrel_offset */
1929
1930   /* A MIPS16 reference to the global offset table.  */
1931   HOWTO (R_MIPS16_GOT16,        /* type */
1932          0,                     /* rightshift */
1933          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1934          16,                    /* bitsize */
1935          FALSE,                 /* pc_relative */
1936          0,                     /* bitpos */
1937          complain_overflow_dont, /* complain_on_overflow */
1938          _bfd_mips_elf_got16_reloc, /* special_function */
1939          "R_MIPS16_GOT16",      /* name */
1940          FALSE,                 /* partial_inplace */
1941          0,                     /* src_mask */
1942          0x0000ffff,            /* dst_mask */
1943          FALSE),                /* pcrel_offset */
1944
1945   /* A MIPS16 call through the global offset table.  */
1946   HOWTO (R_MIPS16_CALL16,       /* type */
1947          0,                     /* rightshift */
1948          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1949          16,                    /* bitsize */
1950          FALSE,                 /* pc_relative */
1951          0,                     /* bitpos */
1952          complain_overflow_dont, /* complain_on_overflow */
1953          _bfd_mips_elf_generic_reloc, /* special_function */
1954          "R_MIPS16_CALL16",     /* name */
1955          FALSE,                 /* partial_inplace */
1956          0,                     /* src_mask */
1957          0x0000ffff,            /* dst_mask */
1958          FALSE),                /* pcrel_offset */
1959
1960   /* MIPS16 high 16 bits of symbol value.  */
1961   HOWTO (R_MIPS16_HI16,         /* type */
1962          16,                    /* rightshift */
1963          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1964          16,                    /* bitsize */
1965          FALSE,                 /* pc_relative */
1966          0,                     /* bitpos */
1967          complain_overflow_dont, /* complain_on_overflow */
1968          _bfd_mips_elf_hi16_reloc, /* special_function */
1969          "R_MIPS16_HI16",       /* name */
1970          FALSE,                 /* partial_inplace */
1971          0,                     /* src_mask */
1972          0x0000ffff,            /* dst_mask */
1973          FALSE),                /* pcrel_offset */
1974
1975   /* MIPS16 low 16 bits of symbol value.  */
1976   HOWTO (R_MIPS16_LO16,         /* type */
1977          0,                     /* rightshift */
1978          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1979          16,                    /* bitsize */
1980          FALSE,                 /* pc_relative */
1981          0,                     /* bitpos */
1982          complain_overflow_dont, /* complain_on_overflow */
1983          _bfd_mips_elf_lo16_reloc, /* special_function */
1984          "R_MIPS16_LO16",       /* name */
1985          FALSE,                 /* partial_inplace */
1986          0,                     /* src_mask */
1987          0x0000ffff,            /* dst_mask */
1988          FALSE),                /* pcrel_offset */
1989
1990   /* MIPS16 TLS general dynamic variable reference.  */
1991   HOWTO (R_MIPS16_TLS_GD,       /* type */
1992          0,                     /* rightshift */
1993          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1994          16,                    /* bitsize */
1995          FALSE,                 /* pc_relative */
1996          0,                     /* bitpos */
1997          complain_overflow_signed, /* complain_on_overflow */
1998          _bfd_mips_elf_generic_reloc, /* special_function */
1999          "R_MIPS16_TLS_GD",     /* name */
2000          FALSE,                 /* partial_inplace */
2001          0,                     /* src_mask */
2002          0x0000ffff,            /* dst_mask */
2003          FALSE),                /* pcrel_offset */
2004
2005   /* MIPS16 TLS local dynamic variable reference.  */
2006   HOWTO (R_MIPS16_TLS_LDM,      /* type */
2007          0,                     /* rightshift */
2008          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2009          16,                    /* bitsize */
2010          FALSE,                 /* pc_relative */
2011          0,                     /* bitpos */
2012          complain_overflow_signed, /* complain_on_overflow */
2013          _bfd_mips_elf_generic_reloc, /* special_function */
2014          "R_MIPS16_TLS_LDM",    /* name */
2015          FALSE,                 /* partial_inplace */
2016          0,                     /* src_mask */
2017          0x0000ffff,            /* dst_mask */
2018          FALSE),                /* pcrel_offset */
2019
2020   /* MIPS16 TLS local dynamic offset.  */
2021   HOWTO (R_MIPS16_TLS_DTPREL_HI16,      /* type */
2022          0,                     /* rightshift */
2023          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2024          16,                    /* bitsize */
2025          FALSE,                 /* pc_relative */
2026          0,                     /* bitpos */
2027          complain_overflow_signed, /* complain_on_overflow */
2028          _bfd_mips_elf_generic_reloc, /* special_function */
2029          "R_MIPS16_TLS_DTPREL_HI16",    /* name */
2030          FALSE,                 /* partial_inplace */
2031          0,                     /* src_mask */
2032          0x0000ffff,            /* dst_mask */
2033          FALSE),                /* pcrel_offset */
2034
2035   /* MIPS16 TLS local dynamic offset.  */
2036   HOWTO (R_MIPS16_TLS_DTPREL_LO16,      /* type */
2037          0,                     /* rightshift */
2038          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2039          16,                    /* bitsize */
2040          FALSE,                 /* pc_relative */
2041          0,                     /* bitpos */
2042          complain_overflow_signed, /* complain_on_overflow */
2043          _bfd_mips_elf_generic_reloc, /* special_function */
2044          "R_MIPS16_TLS_DTPREL_LO16",    /* name */
2045          FALSE,                 /* partial_inplace */
2046          0,                     /* src_mask */
2047          0x0000ffff,            /* dst_mask */
2048          FALSE),                /* pcrel_offset */
2049
2050   /* MIPS16 TLS thread pointer offset.  */
2051   HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */
2052          0,                     /* rightshift */
2053          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2054          16,                    /* bitsize */
2055          FALSE,                 /* pc_relative */
2056          0,                     /* bitpos */
2057          complain_overflow_signed, /* complain_on_overflow */
2058          _bfd_mips_elf_generic_reloc, /* special_function */
2059          "R_MIPS16_TLS_GOTTPREL",       /* name */
2060          FALSE,                 /* partial_inplace */
2061          0,                     /* src_mask */
2062          0x0000ffff,            /* dst_mask */
2063          FALSE),                /* pcrel_offset */
2064
2065   /* MIPS16 TLS thread pointer offset.  */
2066   HOWTO (R_MIPS16_TLS_TPREL_HI16,       /* type */
2067          0,                     /* rightshift */
2068          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2069          16,                    /* bitsize */
2070          FALSE,                 /* pc_relative */
2071          0,                     /* bitpos */
2072          complain_overflow_signed, /* complain_on_overflow */
2073          _bfd_mips_elf_generic_reloc, /* special_function */
2074          "R_MIPS16_TLS_TPREL_HI16", /* name */
2075          FALSE,                 /* partial_inplace */
2076          0,                     /* src_mask */
2077          0x0000ffff,            /* dst_mask */
2078          FALSE),                /* pcrel_offset */
2079
2080   /* MIPS16 TLS thread pointer offset.  */
2081   HOWTO (R_MIPS16_TLS_TPREL_LO16,       /* type */
2082          0,                     /* rightshift */
2083          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2084          16,                    /* bitsize */
2085          FALSE,                 /* pc_relative */
2086          0,                     /* bitpos */
2087          complain_overflow_signed, /* complain_on_overflow */
2088          _bfd_mips_elf_generic_reloc, /* special_function */
2089          "R_MIPS16_TLS_TPREL_LO16", /* name */
2090          FALSE,                 /* partial_inplace */
2091          0,                     /* src_mask */
2092          0x0000ffff,            /* dst_mask */
2093          FALSE),                /* pcrel_offset */
2094
2095   /* MIPS16 16-bit PC-relative branch offset.  */
2096   HOWTO (R_MIPS16_PC16_S1,      /* type */
2097          1,                     /* rightshift */
2098          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2099          16,                    /* bitsize */
2100          TRUE,                  /* pc_relative */
2101          0,                     /* bitpos */
2102          complain_overflow_signed, /* complain_on_overflow */
2103          _bfd_mips_elf_generic_reloc, /* special_function */
2104          "R_MIPS16_PC16_S1",    /* name */
2105          FALSE,                 /* partial_inplace */
2106          0,                     /* src_mask */
2107          0x0000ffff,            /* dst_mask */
2108          TRUE),                 /* pcrel_offset */
2109 };
2110
2111 static reloc_howto_type micromips_elf64_howto_table_rel[] =
2112 {
2113   EMPTY_HOWTO (130),
2114   EMPTY_HOWTO (131),
2115   EMPTY_HOWTO (132),
2116
2117   /* 26 bit jump address.  */
2118   HOWTO (R_MICROMIPS_26_S1,     /* type */
2119          1,                     /* rightshift */
2120          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2121          26,                    /* bitsize */
2122          FALSE,                 /* pc_relative */
2123          0,                     /* bitpos */
2124          complain_overflow_dont, /* complain_on_overflow */
2125                                 /* This needs complex overflow
2126                                    detection, because the upper four
2127                                    bits must match the PC.  */
2128          _bfd_mips_elf_generic_reloc, /* special_function */
2129          "R_MICROMIPS_26_S1",   /* name */
2130          TRUE,                  /* partial_inplace */
2131          0x3ffffff,             /* src_mask */
2132          0x3ffffff,             /* dst_mask */
2133          FALSE),                /* pcrel_offset */
2134
2135   /* High 16 bits of symbol value.  */
2136   HOWTO (R_MICROMIPS_HI16,      /* type */
2137          16,                    /* rightshift */
2138          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2139          16,                    /* bitsize */
2140          FALSE,                 /* pc_relative */
2141          0,                     /* bitpos */
2142          complain_overflow_dont, /* complain_on_overflow */
2143          _bfd_mips_elf_hi16_reloc, /* special_function */
2144          "R_MICROMIPS_HI16",    /* name */
2145          TRUE,                  /* partial_inplace */
2146          0x0000ffff,            /* src_mask */
2147          0x0000ffff,            /* dst_mask */
2148          FALSE),                /* pcrel_offset */
2149
2150   /* Low 16 bits of symbol value.  */
2151   HOWTO (R_MICROMIPS_LO16,      /* type */
2152          0,                     /* rightshift */
2153          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2154          16,                    /* bitsize */
2155          FALSE,                 /* pc_relative */
2156          0,                     /* bitpos */
2157          complain_overflow_dont, /* complain_on_overflow */
2158          _bfd_mips_elf_lo16_reloc, /* special_function */
2159          "R_MICROMIPS_LO16",    /* name */
2160          TRUE,                  /* partial_inplace */
2161          0x0000ffff,            /* src_mask */
2162          0x0000ffff,            /* dst_mask */
2163          FALSE),                /* pcrel_offset */
2164
2165   /* GP relative reference.  */
2166   HOWTO (R_MICROMIPS_GPREL16,   /* type */
2167          0,                     /* rightshift */
2168          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2169          16,                    /* bitsize */
2170          FALSE,                 /* pc_relative */
2171          0,                     /* bitpos */
2172          complain_overflow_signed, /* complain_on_overflow */
2173          _bfd_mips_elf32_gprel16_reloc, /* special_function */
2174          "R_MICROMIPS_GPREL16", /* name */
2175          TRUE,                  /* partial_inplace */
2176          0x0000ffff,            /* src_mask */
2177          0x0000ffff,            /* dst_mask */
2178          FALSE),                /* pcrel_offset */
2179
2180   /* Reference to literal section.  */
2181   HOWTO (R_MICROMIPS_LITERAL,   /* type */
2182          0,                     /* rightshift */
2183          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2184          16,                    /* bitsize */
2185          FALSE,                 /* pc_relative */
2186          0,                     /* bitpos */
2187          complain_overflow_signed, /* complain_on_overflow */
2188          _bfd_mips_elf32_gprel16_reloc, /* special_function */
2189          "R_MICROMIPS_LITERAL", /* name */
2190          TRUE,                  /* partial_inplace */
2191          0x0000ffff,            /* src_mask */
2192          0x0000ffff,            /* dst_mask */
2193          FALSE),                /* pcrel_offset */
2194
2195   /* Reference to global offset table.  */
2196   HOWTO (R_MICROMIPS_GOT16,     /* type */
2197          0,                     /* rightshift */
2198          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2199          16,                    /* bitsize */
2200          FALSE,                 /* pc_relative */
2201          0,                     /* bitpos */
2202          complain_overflow_signed, /* complain_on_overflow */
2203          _bfd_mips_elf_got16_reloc, /* special_function */
2204          "R_MICROMIPS_GOT16",   /* name */
2205          TRUE,                  /* partial_inplace */
2206          0x0000ffff,            /* src_mask */
2207          0x0000ffff,            /* dst_mask */
2208          FALSE),                /* pcrel_offset */
2209
2210   /* This is for microMIPS branches.  */
2211   HOWTO (R_MICROMIPS_PC7_S1,    /* type */
2212          1,                     /* rightshift */
2213          1,                     /* size (0 = byte, 1 = short, 2 = long) */
2214          7,                     /* bitsize */
2215          TRUE,                  /* pc_relative */
2216          0,                     /* bitpos */
2217          complain_overflow_signed, /* complain_on_overflow */
2218          _bfd_mips_elf_generic_reloc, /* special_function */
2219          "R_MICROMIPS_PC7_S1",  /* name */
2220          TRUE,                  /* partial_inplace */
2221          0x0000007f,            /* src_mask */
2222          0x0000007f,            /* dst_mask */
2223          TRUE),                 /* pcrel_offset */
2224
2225   HOWTO (R_MICROMIPS_PC10_S1,   /* type */
2226          1,                     /* rightshift */
2227          1,                     /* size (0 = byte, 1 = short, 2 = long) */
2228          10,                    /* bitsize */
2229          TRUE,                  /* pc_relative */
2230          0,                     /* bitpos */
2231          complain_overflow_signed, /* complain_on_overflow */
2232          _bfd_mips_elf_generic_reloc, /* special_function */
2233          "R_MICROMIPS_PC10_S1", /* name */
2234          TRUE,                  /* partial_inplace */
2235          0x000003ff,            /* src_mask */
2236          0x000003ff,            /* dst_mask */
2237          TRUE),                 /* pcrel_offset */
2238
2239   HOWTO (R_MICROMIPS_PC16_S1,   /* type */
2240          1,                     /* rightshift */
2241          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2242          16,                    /* bitsize */
2243          TRUE,                  /* pc_relative */
2244          0,                     /* bitpos */
2245          complain_overflow_signed, /* complain_on_overflow */
2246          _bfd_mips_elf_generic_reloc, /* special_function */
2247          "R_MICROMIPS_PC16_S1", /* name */
2248          TRUE,                  /* partial_inplace */
2249          0x0000ffff,            /* src_mask */
2250          0x0000ffff,            /* dst_mask */
2251          TRUE),                 /* pcrel_offset */
2252
2253   /* 16 bit call through global offset table.  */
2254   HOWTO (R_MICROMIPS_CALL16,    /* type */
2255          0,                     /* rightshift */
2256          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2257          16,                    /* bitsize */
2258          FALSE,                 /* pc_relative */
2259          0,                     /* bitpos */
2260          complain_overflow_signed, /* complain_on_overflow */
2261          _bfd_mips_elf_generic_reloc, /* special_function */
2262          "R_MICROMIPS_CALL16",  /* name */
2263          TRUE,                  /* partial_inplace */
2264          0x0000ffff,            /* src_mask */
2265          0x0000ffff,            /* dst_mask */
2266          FALSE),                /* pcrel_offset */
2267
2268   EMPTY_HOWTO (143),
2269   EMPTY_HOWTO (144),
2270
2271   /* Displacement in the global offset table.  */
2272   HOWTO (R_MICROMIPS_GOT_DISP,  /* type */
2273          0,                     /* rightshift */
2274          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2275          16,                    /* bitsize */
2276          FALSE,                 /* pc_relative */
2277          0,                     /* bitpos */
2278          complain_overflow_signed, /* complain_on_overflow */
2279          _bfd_mips_elf_generic_reloc, /* special_function */
2280          "R_MICROMIPS_GOT_DISP",/* name */
2281          TRUE,                  /* partial_inplace */
2282          0x0000ffff,            /* src_mask */
2283          0x0000ffff,            /* dst_mask */
2284          FALSE),                /* pcrel_offset */
2285
2286   /* Displacement to page pointer in the global offset table.  */
2287   HOWTO (R_MICROMIPS_GOT_PAGE,  /* type */
2288          0,                     /* rightshift */
2289          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2290          16,                    /* bitsize */
2291          FALSE,                 /* pc_relative */
2292          0,                     /* bitpos */
2293          complain_overflow_signed, /* complain_on_overflow */
2294          _bfd_mips_elf_generic_reloc, /* special_function */
2295          "R_MICROMIPS_GOT_PAGE",/* name */
2296          TRUE,                  /* partial_inplace */
2297          0x0000ffff,            /* src_mask */
2298          0x0000ffff,            /* dst_mask */
2299          FALSE),                /* pcrel_offset */
2300
2301   /* Offset from page pointer in the global offset table.  */
2302   HOWTO (R_MICROMIPS_GOT_OFST,  /* type */
2303          0,                     /* rightshift */
2304          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2305          16,                    /* bitsize */
2306          FALSE,                 /* pc_relative */
2307          0,                     /* bitpos */
2308          complain_overflow_signed, /* complain_on_overflow */
2309          _bfd_mips_elf_generic_reloc, /* special_function */
2310          "R_MICROMIPS_GOT_OFST",/* name */
2311          TRUE,                  /* partial_inplace */
2312          0x0000ffff,            /* src_mask */
2313          0x0000ffff,            /* dst_mask */
2314          FALSE),                /* pcrel_offset */
2315
2316   /* High 16 bits of displacement in global offset table.  */
2317   HOWTO (R_MICROMIPS_GOT_HI16,  /* type */
2318          0,                     /* rightshift */
2319          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2320          16,                    /* bitsize */
2321          FALSE,                 /* pc_relative */
2322          0,                     /* bitpos */
2323          complain_overflow_dont, /* complain_on_overflow */
2324          _bfd_mips_elf_generic_reloc, /* special_function */
2325          "R_MICROMIPS_GOT_HI16",/* name */
2326          TRUE,                  /* partial_inplace */
2327          0x0000ffff,            /* src_mask */
2328          0x0000ffff,            /* dst_mask */
2329          FALSE),                /* pcrel_offset */
2330
2331   /* Low 16 bits of displacement in global offset table.  */
2332   HOWTO (R_MICROMIPS_GOT_LO16,  /* type */
2333          0,                     /* rightshift */
2334          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2335          16,                    /* bitsize */
2336          FALSE,                 /* pc_relative */
2337          0,                     /* bitpos */
2338          complain_overflow_dont, /* complain_on_overflow */
2339          _bfd_mips_elf_generic_reloc, /* special_function */
2340          "R_MICROMIPS_GOT_LO16",/* name */
2341          TRUE,                  /* partial_inplace */
2342          0x0000ffff,            /* src_mask */
2343          0x0000ffff,            /* dst_mask */
2344          FALSE),                /* pcrel_offset */
2345
2346   /* 64 bit subtraction.  Used in the N32 ABI.  */
2347   HOWTO (R_MICROMIPS_SUB,       /* type */
2348          0,                     /* rightshift */
2349          4,                     /* size (0 = byte, 1 = short, 2 = long) */
2350          64,                    /* bitsize */
2351          FALSE,                 /* pc_relative */
2352          0,                     /* bitpos */
2353          complain_overflow_dont, /* complain_on_overflow */
2354          _bfd_mips_elf_generic_reloc, /* special_function */
2355          "R_MICROMIPS_SUB",     /* name */
2356          TRUE,                  /* partial_inplace */
2357          MINUS_ONE,             /* src_mask */
2358          MINUS_ONE,             /* dst_mask */
2359          FALSE),                /* pcrel_offset */
2360
2361   /* We don't support these for REL relocations, because it means building
2362      the addend from a R_MICROMIPS_HIGHEST/R_MICROMIPS_HIGHER/
2363      R_MICROMIPS_HI16/R_MICROMIPS_LO16 sequence with varying ordering,
2364      using fallable heuristics.  */
2365   EMPTY_HOWTO (R_MICROMIPS_HIGHER),
2366   EMPTY_HOWTO (R_MICROMIPS_HIGHEST),
2367
2368   /* High 16 bits of displacement in global offset table.  */
2369   HOWTO (R_MICROMIPS_CALL_HI16, /* type */
2370          0,                     /* rightshift */
2371          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2372          16,                    /* bitsize */
2373          FALSE,                 /* pc_relative */
2374          0,                     /* bitpos */
2375          complain_overflow_dont, /* complain_on_overflow */
2376          _bfd_mips_elf_generic_reloc, /* special_function */
2377          "R_MICROMIPS_CALL_HI16",/* name */
2378          TRUE,                  /* partial_inplace */
2379          0x0000ffff,            /* src_mask */
2380          0x0000ffff,            /* dst_mask */
2381          FALSE),                /* pcrel_offset */
2382
2383   /* Low 16 bits of displacement in global offset table.  */
2384   HOWTO (R_MICROMIPS_CALL_LO16, /* type */
2385          0,                     /* rightshift */
2386          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2387          16,                    /* bitsize */
2388          FALSE,                 /* pc_relative */
2389          0,                     /* bitpos */
2390          complain_overflow_dont, /* complain_on_overflow */
2391          _bfd_mips_elf_generic_reloc, /* special_function */
2392          "R_MICROMIPS_CALL_LO16",/* name */
2393          TRUE,                  /* partial_inplace */
2394          0x0000ffff,            /* src_mask */
2395          0x0000ffff,            /* dst_mask */
2396          FALSE),                /* pcrel_offset */
2397
2398   /* Section displacement.  */
2399   HOWTO (R_MICROMIPS_SCN_DISP,  /* type */
2400          0,                     /* rightshift */
2401          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2402          32,                    /* bitsize */
2403          FALSE,                 /* pc_relative */
2404          0,                     /* bitpos */
2405          complain_overflow_dont, /* complain_on_overflow */
2406          _bfd_mips_elf_generic_reloc, /* special_function */
2407          "R_MICROMIPS_SCN_DISP", /* name */
2408          TRUE,                  /* partial_inplace */
2409          0xffffffff,            /* src_mask */
2410          0xffffffff,            /* dst_mask */
2411          FALSE),                /* pcrel_offset */
2412
2413   /* Protected jump conversion.  This is an optimization hint.  No
2414      relocation is required for correctness.  */
2415   HOWTO (R_MICROMIPS_JALR,      /* type */
2416          0,                     /* rightshift */
2417          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2418          32,                    /* bitsize */
2419          FALSE,                 /* pc_relative */
2420          0,                     /* bitpos */
2421          complain_overflow_dont, /* complain_on_overflow */
2422          _bfd_mips_elf_generic_reloc, /* special_function */
2423          "R_MICROMIPS_JALR",    /* name */
2424          FALSE,                 /* partial_inplace */
2425          0,                     /* src_mask */
2426          0x00000000,            /* dst_mask */
2427          FALSE),                /* pcrel_offset */
2428 };
2429
2430 static reloc_howto_type micromips_elf64_howto_table_rela[] =
2431 {
2432   EMPTY_HOWTO (130),
2433   EMPTY_HOWTO (131),
2434   EMPTY_HOWTO (132),
2435
2436   /* 26 bit jump address.  */
2437   HOWTO (R_MICROMIPS_26_S1,     /* type */
2438          1,                     /* rightshift */
2439          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2440          26,                    /* bitsize */
2441          FALSE,                 /* pc_relative */
2442          0,                     /* bitpos */
2443          complain_overflow_dont, /* complain_on_overflow */
2444                                 /* This needs complex overflow
2445                                    detection, because the upper four
2446                                    bits must match the PC.  */
2447          _bfd_mips_elf_generic_reloc, /* special_function */
2448          "R_MICROMIPS_26_S1",   /* name */
2449          FALSE,                 /* partial_inplace */
2450          0,                     /* src_mask */
2451          0x3ffffff,             /* dst_mask */
2452          FALSE),                /* pcrel_offset */
2453
2454   /* High 16 bits of symbol value.  */
2455   HOWTO (R_MICROMIPS_HI16,      /* type */
2456          16,                    /* rightshift */
2457          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2458          16,                    /* bitsize */
2459          FALSE,                 /* pc_relative */
2460          0,                     /* bitpos */
2461          complain_overflow_dont, /* complain_on_overflow */
2462          _bfd_mips_elf_hi16_reloc, /* special_function */
2463          "R_MICROMIPS_HI16",    /* name */
2464          FALSE,                 /* partial_inplace */
2465          0,                     /* src_mask */
2466          0x0000ffff,            /* dst_mask */
2467          FALSE),                /* pcrel_offset */
2468
2469   /* Low 16 bits of symbol value.  */
2470   HOWTO (R_MICROMIPS_LO16,      /* type */
2471          0,                     /* rightshift */
2472          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2473          16,                    /* bitsize */
2474          FALSE,                 /* pc_relative */
2475          0,                     /* bitpos */
2476          complain_overflow_dont, /* complain_on_overflow */
2477          _bfd_mips_elf_lo16_reloc, /* special_function */
2478          "R_MICROMIPS_LO16",    /* name */
2479          FALSE,                 /* partial_inplace */
2480          0,                     /* src_mask */
2481          0x0000ffff,            /* dst_mask */
2482          FALSE),                /* pcrel_offset */
2483
2484   /* GP relative reference.  */
2485   HOWTO (R_MICROMIPS_GPREL16,   /* type */
2486          0,                     /* rightshift */
2487          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2488          16,                    /* bitsize */
2489          FALSE,                 /* pc_relative */
2490          0,                     /* bitpos */
2491          complain_overflow_signed, /* complain_on_overflow */
2492          _bfd_mips_elf32_gprel16_reloc, /* special_function */
2493          "R_MICROMIPS_GPREL16", /* name */
2494          FALSE,                 /* partial_inplace */
2495          0,                     /* src_mask */
2496          0x0000ffff,            /* dst_mask */
2497          FALSE),                /* pcrel_offset */
2498
2499   /* Reference to literal section.  */
2500   HOWTO (R_MICROMIPS_LITERAL,   /* type */
2501          0,                     /* rightshift */
2502          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2503          16,                    /* bitsize */
2504          FALSE,                 /* pc_relative */
2505          0,                     /* bitpos */
2506          complain_overflow_signed, /* complain_on_overflow */
2507          _bfd_mips_elf32_gprel16_reloc, /* special_function */
2508          "R_MICROMIPS_LITERAL", /* name */
2509          FALSE,                 /* partial_inplace */
2510          0,                     /* src_mask */
2511          0x0000ffff,            /* dst_mask */
2512          FALSE),                /* pcrel_offset */
2513
2514   /* Reference to global offset table.  */
2515   HOWTO (R_MICROMIPS_GOT16,     /* type */
2516          0,                     /* rightshift */
2517          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2518          16,                    /* bitsize */
2519          FALSE,                 /* pc_relative */
2520          0,                     /* bitpos */
2521          complain_overflow_signed, /* complain_on_overflow */
2522          _bfd_mips_elf_got16_reloc, /* special_function */
2523          "R_MICROMIPS_GOT16",   /* name */
2524          FALSE,                 /* partial_inplace */
2525          0,                     /* src_mask */
2526          0x0000ffff,            /* dst_mask */
2527          FALSE),                /* pcrel_offset */
2528
2529   /* This is for microMIPS branches.  */
2530   HOWTO (R_MICROMIPS_PC7_S1,    /* type */
2531          1,                     /* rightshift */
2532          1,                     /* size (0 = byte, 1 = short, 2 = long) */
2533          7,                     /* bitsize */
2534          TRUE,                  /* pc_relative */
2535          0,                     /* bitpos */
2536          complain_overflow_signed, /* complain_on_overflow */
2537          _bfd_mips_elf_generic_reloc, /* special_function */
2538          "R_MICROMIPS_PC7_S1",  /* name */
2539          FALSE,                 /* partial_inplace */
2540          0,                     /* src_mask */
2541          0x0000007f,            /* dst_mask */
2542          TRUE),                 /* pcrel_offset */
2543
2544   HOWTO (R_MICROMIPS_PC10_S1,   /* type */
2545          1,                     /* rightshift */
2546          1,                     /* size (0 = byte, 1 = short, 2 = long) */
2547          10,                    /* bitsize */
2548          TRUE,                  /* pc_relative */
2549          0,                     /* bitpos */
2550          complain_overflow_signed, /* complain_on_overflow */
2551          _bfd_mips_elf_generic_reloc, /* special_function */
2552          "R_MICROMIPS_PC10_S1", /* name */
2553          FALSE,                 /* partial_inplace */
2554          0,                     /* src_mask */
2555          0x000003ff,            /* dst_mask */
2556          TRUE),                 /* pcrel_offset */
2557
2558   HOWTO (R_MICROMIPS_PC16_S1,   /* type */
2559          1,                     /* rightshift */
2560          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2561          16,                    /* bitsize */
2562          TRUE,                  /* pc_relative */
2563          0,                     /* bitpos */
2564          complain_overflow_signed, /* complain_on_overflow */
2565          _bfd_mips_elf_generic_reloc, /* special_function */
2566          "R_MICROMIPS_PC16_S1", /* name */
2567          FALSE,                 /* partial_inplace */
2568          0,                     /* src_mask */
2569          0x0000ffff,            /* dst_mask */
2570          TRUE),                 /* pcrel_offset */
2571
2572   /* 16 bit call through global offset table.  */
2573   HOWTO (R_MICROMIPS_CALL16,    /* type */
2574          0,                     /* rightshift */
2575          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2576          16,                    /* bitsize */
2577          FALSE,                 /* pc_relative */
2578          0,                     /* bitpos */
2579          complain_overflow_signed, /* complain_on_overflow */
2580          _bfd_mips_elf_generic_reloc, /* special_function */
2581          "R_MICROMIPS_CALL16",  /* name */
2582          FALSE,                 /* partial_inplace */
2583          0,                     /* src_mask */
2584          0x0000ffff,            /* dst_mask */
2585          FALSE),                /* pcrel_offset */
2586
2587   EMPTY_HOWTO (143),
2588   EMPTY_HOWTO (144),
2589
2590   /* Displacement in the global offset table.  */
2591   HOWTO (R_MICROMIPS_GOT_DISP,  /* type */
2592          0,                     /* rightshift */
2593          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2594          16,                    /* bitsize */
2595          FALSE,                 /* pc_relative */
2596          0,                     /* bitpos */
2597          complain_overflow_signed, /* complain_on_overflow */
2598          _bfd_mips_elf_generic_reloc, /* special_function */
2599          "R_MICROMIPS_GOT_DISP",/* name */
2600          FALSE,                 /* partial_inplace */
2601          0,                     /* src_mask */
2602          0x0000ffff,            /* dst_mask */
2603          FALSE),                /* pcrel_offset */
2604
2605   /* Displacement to page pointer in the global offset table.  */
2606   HOWTO (R_MICROMIPS_GOT_PAGE,  /* type */
2607          0,                     /* rightshift */
2608          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2609          16,                    /* bitsize */
2610          FALSE,                 /* pc_relative */
2611          0,                     /* bitpos */
2612          complain_overflow_signed, /* complain_on_overflow */
2613          _bfd_mips_elf_generic_reloc, /* special_function */
2614          "R_MICROMIPS_GOT_PAGE",/* name */
2615          FALSE,                 /* partial_inplace */
2616          0,                     /* src_mask */
2617          0x0000ffff,            /* dst_mask */
2618          FALSE),                /* pcrel_offset */
2619
2620   /* Offset from page pointer in the global offset table.  */
2621   HOWTO (R_MICROMIPS_GOT_OFST,  /* type */
2622          0,                     /* rightshift */
2623          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2624          16,                    /* bitsize */
2625          FALSE,                 /* pc_relative */
2626          0,                     /* bitpos */
2627          complain_overflow_signed, /* complain_on_overflow */
2628          _bfd_mips_elf_generic_reloc, /* special_function */
2629          "R_MICROMIPS_GOT_OFST",/* name */
2630          FALSE,                 /* partial_inplace */
2631          0,                     /* src_mask */
2632          0x0000ffff,            /* dst_mask */
2633          FALSE),                /* pcrel_offset */
2634
2635   /* High 16 bits of displacement in global offset table.  */
2636   HOWTO (R_MICROMIPS_GOT_HI16,  /* type */
2637          0,                     /* rightshift */
2638          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2639          16,                    /* bitsize */
2640          FALSE,                 /* pc_relative */
2641          0,                     /* bitpos */
2642          complain_overflow_dont, /* complain_on_overflow */
2643          _bfd_mips_elf_generic_reloc, /* special_function */
2644          "R_MICROMIPS_GOT_HI16",/* name */
2645          FALSE,                 /* partial_inplace */
2646          0,                     /* src_mask */
2647          0x0000ffff,            /* dst_mask */
2648          FALSE),                /* pcrel_offset */
2649
2650   /* Low 16 bits of displacement in global offset table.  */
2651   HOWTO (R_MICROMIPS_GOT_LO16,  /* type */
2652          0,                     /* rightshift */
2653          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2654          16,                    /* bitsize */
2655          FALSE,                 /* pc_relative */
2656          0,                     /* bitpos */
2657          complain_overflow_dont, /* complain_on_overflow */
2658          _bfd_mips_elf_generic_reloc, /* special_function */
2659          "R_MICROMIPS_GOT_LO16",/* name */
2660          FALSE,                 /* partial_inplace */
2661          0,                     /* src_mask */
2662          0x0000ffff,            /* dst_mask */
2663          FALSE),                /* pcrel_offset */
2664
2665   /* 64 bit subtraction.  Used in the N32 ABI.  */
2666   HOWTO (R_MICROMIPS_SUB,       /* type */
2667          0,                     /* rightshift */
2668          4,                     /* size (0 = byte, 1 = short, 2 = long) */
2669          64,                    /* bitsize */
2670          FALSE,                 /* pc_relative */
2671          0,                     /* bitpos */
2672          complain_overflow_dont, /* complain_on_overflow */
2673          _bfd_mips_elf_generic_reloc, /* special_function */
2674          "R_MICROMIPS_SUB",     /* name */
2675          FALSE,                 /* partial_inplace */
2676          0,                     /* src_mask */
2677          MINUS_ONE,             /* dst_mask */
2678          FALSE),                /* pcrel_offset */
2679
2680   /* Get the higher value of a 64 bit addend.  */
2681   HOWTO (R_MICROMIPS_HIGHER,    /* type */
2682          0,                     /* rightshift */
2683          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2684          16,                    /* bitsize */
2685          FALSE,                 /* pc_relative */
2686          0,                     /* bitpos */
2687          complain_overflow_dont, /* complain_on_overflow */
2688          _bfd_mips_elf_generic_reloc, /* special_function */
2689          "R_MICROMIPS_HIGHER",  /* name */
2690          FALSE,                 /* partial_inplace */
2691          0,                     /* src_mask */
2692          0x0000ffff,            /* dst_mask */
2693          FALSE),                /* pcrel_offset */
2694
2695   /* Get the highest value of a 64 bit addend.  */
2696   HOWTO (R_MICROMIPS_HIGHEST,   /* type */
2697          0,                     /* rightshift */
2698          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2699          16,                    /* bitsize */
2700          FALSE,                 /* pc_relative */
2701          0,                     /* bitpos */
2702          complain_overflow_dont, /* complain_on_overflow */
2703          _bfd_mips_elf_generic_reloc, /* special_function */
2704          "R_MICROMIPS_HIGHEST", /* name */
2705          FALSE,                 /* partial_inplace */
2706          0,                     /* src_mask */
2707          0x0000ffff,            /* dst_mask */
2708          FALSE),                /* pcrel_offset */
2709
2710   /* High 16 bits of displacement in global offset table.  */
2711   HOWTO (R_MICROMIPS_CALL_HI16, /* type */
2712          0,                     /* rightshift */
2713          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2714          16,                    /* bitsize */
2715          FALSE,                 /* pc_relative */
2716          0,                     /* bitpos */
2717          complain_overflow_dont, /* complain_on_overflow */
2718          _bfd_mips_elf_generic_reloc, /* special_function */
2719          "R_MICROMIPS_CALL_HI16",/* name */
2720          FALSE,                 /* partial_inplace */
2721          0,                     /* src_mask */
2722          0x0000ffff,            /* dst_mask */
2723          FALSE),                /* pcrel_offset */
2724
2725   /* Low 16 bits of displacement in global offset table.  */
2726   HOWTO (R_MICROMIPS_CALL_LO16, /* type */
2727          0,                     /* rightshift */
2728          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2729          16,                    /* bitsize */
2730          FALSE,                 /* pc_relative */
2731          0,                     /* bitpos */
2732          complain_overflow_dont, /* complain_on_overflow */
2733          _bfd_mips_elf_generic_reloc, /* special_function */
2734          "R_MICROMIPS_CALL_LO16",/* name */
2735          FALSE,                 /* partial_inplace */
2736          0,                     /* src_mask */
2737          0x0000ffff,            /* dst_mask */
2738          FALSE),                /* pcrel_offset */
2739
2740   /* Section displacement.  */
2741   HOWTO (R_MICROMIPS_SCN_DISP,  /* type */
2742          0,                     /* rightshift */
2743          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2744          32,                    /* bitsize */
2745          FALSE,                 /* pc_relative */
2746          0,                     /* bitpos */
2747          complain_overflow_dont, /* complain_on_overflow */
2748          _bfd_mips_elf_generic_reloc, /* special_function */
2749          "R_MICROMIPS_SCN_DISP", /* name */
2750          FALSE,                 /* partial_inplace */
2751          0,                     /* src_mask */
2752          0xffffffff,            /* dst_mask */
2753          FALSE),                /* pcrel_offset */
2754
2755   /* Protected jump conversion.  This is an optimization hint.  No
2756      relocation is required for correctness.  */
2757   HOWTO (R_MICROMIPS_JALR,      /* type */
2758          0,                     /* rightshift */
2759          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2760          32,                    /* bitsize */
2761          FALSE,                 /* pc_relative */
2762          0,                     /* bitpos */
2763          complain_overflow_dont, /* complain_on_overflow */
2764          _bfd_mips_elf_generic_reloc, /* special_function */
2765          "R_MICROMIPS_JALR",    /* name */
2766          FALSE,                 /* partial_inplace */
2767          0,                     /* src_mask */
2768          0x00000000,            /* dst_mask */
2769          FALSE),                /* pcrel_offset */
2770 };
2771
2772 /* GNU extension to record C++ vtable hierarchy */
2773 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
2774   HOWTO (R_MIPS_GNU_VTINHERIT,  /* type */
2775          0,                     /* rightshift */
2776          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2777          0,                     /* bitsize */
2778          FALSE,                 /* pc_relative */
2779          0,                     /* bitpos */
2780          complain_overflow_dont, /* complain_on_overflow */
2781          NULL,                  /* special_function */
2782          "R_MIPS_GNU_VTINHERIT", /* name */
2783          FALSE,                 /* partial_inplace */
2784          0,                     /* src_mask */
2785          0,                     /* dst_mask */
2786          FALSE);                /* pcrel_offset */
2787
2788 /* GNU extension to record C++ vtable member usage */
2789 static reloc_howto_type elf_mips_gnu_vtentry_howto =
2790   HOWTO (R_MIPS_GNU_VTENTRY,    /* type */
2791          0,                     /* rightshift */
2792          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2793          0,                     /* bitsize */
2794          FALSE,                 /* pc_relative */
2795          0,                     /* bitpos */
2796          complain_overflow_dont, /* complain_on_overflow */
2797          _bfd_elf_rel_vtable_reloc_fn, /* special_function */
2798          "R_MIPS_GNU_VTENTRY",  /* name */
2799          FALSE,                 /* partial_inplace */
2800          0,                     /* src_mask */
2801          0,                     /* dst_mask */
2802          FALSE);                /* pcrel_offset */
2803 \f
2804 /* 16 bit offset for pc-relative branches.  */
2805 static reloc_howto_type elf_mips_gnu_rel16_s2 =
2806   HOWTO (R_MIPS_GNU_REL16_S2,   /* type */
2807          2,                     /* rightshift */
2808          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2809          16,                    /* bitsize */
2810          TRUE,                  /* pc_relative */
2811          0,                     /* bitpos */
2812          complain_overflow_signed, /* complain_on_overflow */
2813          _bfd_mips_elf_generic_reloc,   /* special_function */
2814          "R_MIPS_GNU_REL16_S2", /* name */
2815          TRUE,                  /* partial_inplace */
2816          0x0000ffff,            /* src_mask */
2817          0x0000ffff,            /* dst_mask */
2818          TRUE);                 /* pcrel_offset */
2819
2820 /* 16 bit offset for pc-relative branches.  */
2821 static reloc_howto_type elf_mips_gnu_rela16_s2 =
2822   HOWTO (R_MIPS_GNU_REL16_S2,   /* type */
2823          2,                     /* rightshift */
2824          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2825          16,                    /* bitsize */
2826          TRUE,                  /* pc_relative */
2827          0,                     /* bitpos */
2828          complain_overflow_signed, /* complain_on_overflow */
2829          _bfd_mips_elf_generic_reloc,   /* special_function */
2830          "R_MIPS_GNU_REL16_S2", /* name */
2831          FALSE,                 /* partial_inplace */
2832          0,                     /* src_mask */
2833          0x0000ffff,            /* dst_mask */
2834          TRUE);                 /* pcrel_offset */
2835
2836 /* 32 bit pc-relative.  Used for compact EH tables.  */
2837 static reloc_howto_type elf_mips_gnu_pcrel32 =
2838   HOWTO (R_MIPS_PC32,           /* type */
2839          0,                     /* rightshift */
2840          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2841          32,                    /* bitsize */
2842          TRUE,                  /* pc_relative */
2843          0,                     /* bitpos */
2844          complain_overflow_signed, /* complain_on_overflow */
2845          _bfd_mips_elf_generic_reloc, /* special_function */
2846          "R_MIPS_PC32",         /* name */
2847          TRUE,                  /* partial_inplace */
2848          0xffffffff,            /* src_mask */
2849          0xffffffff,            /* dst_mask */
2850          TRUE);                 /* pcrel_offset */
2851
2852 \f
2853 /* Originally a VxWorks extension, but now used for other systems too.  */
2854 static reloc_howto_type elf_mips_copy_howto =
2855   HOWTO (R_MIPS_COPY,           /* type */
2856          0,                     /* rightshift */
2857          0,                     /* this one is variable size */
2858          0,                     /* bitsize */
2859          FALSE,                 /* pc_relative */
2860          0,                     /* bitpos */
2861          complain_overflow_bitfield, /* complain_on_overflow */
2862          _bfd_mips_elf_generic_reloc, /* special_function */
2863          "R_MIPS_COPY",         /* name */
2864          FALSE,                 /* partial_inplace */
2865          0x0,                   /* src_mask */
2866          0x0,                   /* dst_mask */
2867          FALSE);                /* pcrel_offset */
2868
2869 /* Originally a VxWorks extension, but now used for other systems too.  */
2870 static reloc_howto_type elf_mips_jump_slot_howto =
2871   HOWTO (R_MIPS_JUMP_SLOT,      /* type */
2872          0,                     /* rightshift */
2873          4,                     /* size (0 = byte, 1 = short, 2 = long) */
2874          64,                    /* bitsize */
2875          FALSE,                 /* pc_relative */
2876          0,                     /* bitpos */
2877          complain_overflow_bitfield, /* complain_on_overflow */
2878          _bfd_mips_elf_generic_reloc, /* special_function */
2879          "R_MIPS_JUMP_SLOT",    /* name */
2880          FALSE,                 /* partial_inplace */
2881          0x0,                   /* src_mask */
2882          0x0,                   /* dst_mask */
2883          FALSE);                /* pcrel_offset */
2884
2885 /* Used in EH tables.  */
2886 static reloc_howto_type elf_mips_eh_howto =
2887   HOWTO (R_MIPS_EH,             /* type */
2888          0,                     /* rightshift */
2889          2,                     /* size (0 = byte, 1 = short, 2 = long) */
2890          32,                    /* bitsize */
2891          FALSE,                 /* pc_relative */
2892          0,                     /* bitpos */
2893          complain_overflow_signed, /* complain_on_overflow */
2894          _bfd_mips_elf_generic_reloc, /* special_function */
2895          "R_MIPS_EH",           /* name */
2896          TRUE,                  /* partial_inplace */
2897          0xffffffff,            /* src_mask */
2898          0xffffffff,            /* dst_mask */
2899          FALSE);                /* pcrel_offset */
2900
2901 \f
2902 /* Swap in a MIPS 64-bit Rel reloc.  */
2903
2904 static void
2905 mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src,
2906                           Elf64_Mips_Internal_Rela *dst)
2907 {
2908   dst->r_offset = H_GET_64 (abfd, src->r_offset);
2909   dst->r_sym = H_GET_32 (abfd, src->r_sym);
2910   dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
2911   dst->r_type3 = H_GET_8 (abfd, src->r_type3);
2912   dst->r_type2 = H_GET_8 (abfd, src->r_type2);
2913   dst->r_type = H_GET_8 (abfd, src->r_type);
2914   dst->r_addend = 0;
2915 }
2916
2917 /* Swap in a MIPS 64-bit Rela reloc.  */
2918
2919 static void
2920 mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src,
2921                            Elf64_Mips_Internal_Rela *dst)
2922 {
2923   dst->r_offset = H_GET_64 (abfd, src->r_offset);
2924   dst->r_sym = H_GET_32 (abfd, src->r_sym);
2925   dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
2926   dst->r_type3 = H_GET_8 (abfd, src->r_type3);
2927   dst->r_type2 = H_GET_8 (abfd, src->r_type2);
2928   dst->r_type = H_GET_8 (abfd, src->r_type);
2929   dst->r_addend = H_GET_S64 (abfd, src->r_addend);
2930 }
2931
2932 /* Swap out a MIPS 64-bit Rel reloc.  */
2933
2934 static void
2935 mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
2936                            Elf64_Mips_External_Rel *dst)
2937 {
2938   H_PUT_64 (abfd, src->r_offset, dst->r_offset);
2939   H_PUT_32 (abfd, src->r_sym, dst->r_sym);
2940   H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
2941   H_PUT_8 (abfd, src->r_type3, dst->r_type3);
2942   H_PUT_8 (abfd, src->r_type2, dst->r_type2);
2943   H_PUT_8 (abfd, src->r_type, dst->r_type);
2944 }
2945
2946 /* Swap out a MIPS 64-bit Rela reloc.  */
2947
2948 static void
2949 mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
2950                             Elf64_Mips_External_Rela *dst)
2951 {
2952   H_PUT_64 (abfd, src->r_offset, dst->r_offset);
2953   H_PUT_32 (abfd, src->r_sym, dst->r_sym);
2954   H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
2955   H_PUT_8 (abfd, src->r_type3, dst->r_type3);
2956   H_PUT_8 (abfd, src->r_type2, dst->r_type2);
2957   H_PUT_8 (abfd, src->r_type, dst->r_type);
2958   H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
2959 }
2960
2961 /* Swap in a MIPS 64-bit Rel reloc.  */
2962
2963 static void
2964 mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src,
2965                              Elf_Internal_Rela *dst)
2966 {
2967   Elf64_Mips_Internal_Rela mirel;
2968
2969   mips_elf64_swap_reloc_in (abfd,
2970                             (const Elf64_Mips_External_Rel *) src,
2971                             &mirel);
2972
2973   dst[0].r_offset = mirel.r_offset;
2974   dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
2975   dst[0].r_addend = 0;
2976   dst[1].r_offset = mirel.r_offset;
2977   dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
2978   dst[1].r_addend = 0;
2979   dst[2].r_offset = mirel.r_offset;
2980   dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
2981   dst[2].r_addend = 0;
2982 }
2983
2984 /* Swap in a MIPS 64-bit Rela reloc.  */
2985
2986 static void
2987 mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src,
2988                               Elf_Internal_Rela *dst)
2989 {
2990   Elf64_Mips_Internal_Rela mirela;
2991
2992   mips_elf64_swap_reloca_in (abfd,
2993                              (const Elf64_Mips_External_Rela *) src,
2994                              &mirela);
2995
2996   dst[0].r_offset = mirela.r_offset;
2997   dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
2998   dst[0].r_addend = mirela.r_addend;
2999   dst[1].r_offset = mirela.r_offset;
3000   dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
3001   dst[1].r_addend = 0;
3002   dst[2].r_offset = mirela.r_offset;
3003   dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
3004   dst[2].r_addend = 0;
3005 }
3006
3007 /* Swap out a MIPS 64-bit Rel reloc.  */
3008
3009 static void
3010 mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src,
3011                               bfd_byte *dst)
3012 {
3013   Elf64_Mips_Internal_Rela mirel;
3014
3015   mirel.r_offset = src[0].r_offset;
3016   BFD_ASSERT(src[0].r_offset == src[1].r_offset);
3017   BFD_ASSERT(src[0].r_offset == src[2].r_offset);
3018
3019   mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
3020   mirel.r_sym = ELF64_R_SYM (src[0].r_info);
3021   mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
3022   mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
3023   mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
3024
3025   mips_elf64_swap_reloc_out (abfd, &mirel,
3026                              (Elf64_Mips_External_Rel *) dst);
3027 }
3028
3029 /* Swap out a MIPS 64-bit Rela reloc.  */
3030
3031 static void
3032 mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src,
3033                                bfd_byte *dst)
3034 {
3035   Elf64_Mips_Internal_Rela mirela;
3036
3037   mirela.r_offset = src[0].r_offset;
3038   BFD_ASSERT(src[0].r_offset == src[1].r_offset);
3039   BFD_ASSERT(src[0].r_offset == src[2].r_offset);
3040
3041   mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
3042   mirela.r_sym = ELF64_R_SYM (src[0].r_info);
3043   mirela.r_addend = src[0].r_addend;
3044   BFD_ASSERT(src[1].r_addend == 0);
3045   BFD_ASSERT(src[2].r_addend == 0);
3046
3047   mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
3048   mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
3049   mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
3050
3051   mips_elf64_swap_reloca_out (abfd, &mirela,
3052                               (Elf64_Mips_External_Rela *) dst);
3053 }
3054 \f
3055 /* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
3056    dangerous relocation.  */
3057
3058 static bfd_boolean
3059 mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp)
3060 {
3061   unsigned int count;
3062   asymbol **sym;
3063   unsigned int i;
3064
3065   /* If we've already figured out what GP will be, just return it.  */
3066   *pgp = _bfd_get_gp_value (output_bfd);
3067   if (*pgp)
3068     return TRUE;
3069
3070   count = bfd_get_symcount (output_bfd);
3071   sym = bfd_get_outsymbols (output_bfd);
3072
3073   /* The linker script will have created a symbol named `_gp' with the
3074      appropriate value.  */
3075   if (sym == NULL)
3076     i = count;
3077   else
3078     {
3079       for (i = 0; i < count; i++, sym++)
3080         {
3081           register const char *name;
3082
3083           name = bfd_asymbol_name (*sym);
3084           if (*name == '_' && strcmp (name, "_gp") == 0)
3085             {
3086               *pgp = bfd_asymbol_value (*sym);
3087               _bfd_set_gp_value (output_bfd, *pgp);
3088               break;
3089             }
3090         }
3091     }
3092
3093   if (i >= count)
3094     {
3095       /* Only get the error once.  */
3096       *pgp = 4;
3097       _bfd_set_gp_value (output_bfd, *pgp);
3098       return FALSE;
3099     }
3100
3101   return TRUE;
3102 }
3103
3104 /* We have to figure out the gp value, so that we can adjust the
3105    symbol value correctly.  We look up the symbol _gp in the output
3106    BFD.  If we can't find it, we're stuck.  We cache it in the ELF
3107    target data.  We don't need to adjust the symbol value for an
3108    external symbol if we are producing relocatable output.  */
3109
3110 static bfd_reloc_status_type
3111 mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
3112                      char **error_message, bfd_vma *pgp)
3113 {
3114   if (bfd_is_und_section (symbol->section)
3115       && ! relocatable)
3116     {
3117       *pgp = 0;
3118       return bfd_reloc_undefined;
3119     }
3120
3121   *pgp = _bfd_get_gp_value (output_bfd);
3122   if (*pgp == 0
3123       && (! relocatable
3124           || (symbol->flags & BSF_SECTION_SYM) != 0))
3125     {
3126       if (relocatable)
3127         {
3128           /* Make up a value.  */
3129           *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
3130           _bfd_set_gp_value (output_bfd, *pgp);
3131         }
3132       else if (!mips_elf64_assign_gp (output_bfd, pgp))
3133         {
3134           *error_message =
3135             (char *) _("GP relative relocation when _gp not defined");
3136           return bfd_reloc_dangerous;
3137         }
3138     }
3139
3140   return bfd_reloc_ok;
3141 }
3142
3143 /* Do a R_MIPS_GPREL16 relocation.  This is a 16 bit value which must
3144    become the offset from the gp register.  */
3145
3146 static bfd_reloc_status_type
3147 mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3148                           void *data, asection *input_section, bfd *output_bfd,
3149                           char **error_message)
3150 {
3151   bfd_boolean relocatable;
3152   bfd_reloc_status_type ret;
3153   bfd_vma gp;
3154
3155   /* If we're relocating, and this is an external symbol, we don't want
3156      to change anything.  */
3157   if (output_bfd != NULL
3158       && (symbol->flags & BSF_SECTION_SYM) == 0
3159       && (symbol->flags & BSF_LOCAL) != 0)
3160     {
3161       reloc_entry->address += input_section->output_offset;
3162       return bfd_reloc_ok;
3163     }
3164
3165   if (output_bfd != NULL)
3166     relocatable = TRUE;
3167   else
3168     {
3169       relocatable = FALSE;
3170       output_bfd = symbol->section->output_section->owner;
3171     }
3172
3173   ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
3174                              &gp);
3175   if (ret != bfd_reloc_ok)
3176     return ret;
3177
3178   return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
3179                                         input_section, relocatable,
3180                                         data, gp);
3181 }
3182
3183 /* Do a R_MIPS_LITERAL relocation.  */
3184
3185 static bfd_reloc_status_type
3186 mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3187                           void *data, asection *input_section, bfd *output_bfd,
3188                           char **error_message)
3189 {
3190   bfd_boolean relocatable;
3191   bfd_reloc_status_type ret;
3192   bfd_vma gp;
3193
3194   /* R_MIPS_LITERAL relocations are defined for local symbols only.  */
3195   if (output_bfd != NULL
3196       && (symbol->flags & BSF_SECTION_SYM) == 0
3197       && (symbol->flags & BSF_LOCAL) != 0)
3198     {
3199       *error_message = (char *)
3200         _("literal relocation occurs for an external symbol");
3201       return bfd_reloc_outofrange;
3202     }
3203
3204   /* FIXME: The entries in the .lit8 and .lit4 sections should be merged.  */
3205   if (output_bfd != NULL)
3206     relocatable = TRUE;
3207   else
3208     {
3209       relocatable = FALSE;
3210       output_bfd = symbol->section->output_section->owner;
3211     }
3212
3213   ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
3214                              &gp);
3215   if (ret != bfd_reloc_ok)
3216     return ret;
3217
3218   return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
3219                                         input_section, relocatable,
3220                                         data, gp);
3221 }
3222
3223 /* Do a R_MIPS_GPREL32 relocation.  This is a 32 bit value which must
3224    become the offset from the gp register.  */
3225
3226 static bfd_reloc_status_type
3227 mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3228                           void *data, asection *input_section, bfd *output_bfd,
3229                           char **error_message)
3230 {
3231   bfd_boolean relocatable;
3232   bfd_reloc_status_type ret;
3233   bfd_vma gp;
3234   bfd_vma relocation;
3235   bfd_vma val;
3236
3237   /* R_MIPS_GPREL32 relocations are defined for local symbols only.  */
3238   if (output_bfd != NULL
3239       && (symbol->flags & BSF_SECTION_SYM) == 0
3240       && (symbol->flags & BSF_LOCAL) != 0)
3241     {
3242       *error_message = (char *)
3243         _("32bits gp relative relocation occurs for an external symbol");
3244       return bfd_reloc_outofrange;
3245     }
3246
3247   if (output_bfd != NULL)
3248     relocatable = TRUE;
3249   else
3250     {
3251       relocatable = FALSE;
3252       output_bfd = symbol->section->output_section->owner;
3253     }
3254
3255   ret = mips_elf64_final_gp (output_bfd, symbol, relocatable,
3256                              error_message, &gp);
3257   if (ret != bfd_reloc_ok)
3258     return ret;
3259
3260   if (bfd_is_com_section (symbol->section))
3261     relocation = 0;
3262   else
3263     relocation = symbol->value;
3264
3265   relocation += symbol->section->output_section->vma;
3266   relocation += symbol->section->output_offset;
3267
3268   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
3269     return bfd_reloc_outofrange;
3270
3271   /* Set val to the offset into the section or symbol.  */
3272   val = reloc_entry->addend;
3273
3274   if (reloc_entry->howto->partial_inplace)
3275     val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
3276
3277   /* Adjust val for the final section location and GP value.  If we
3278      are producing relocatable output, we don't want to do this for
3279      an external symbol.  */
3280   if (! relocatable
3281       || (symbol->flags & BSF_SECTION_SYM) != 0)
3282     val += relocation - gp;
3283
3284   if (reloc_entry->howto->partial_inplace)
3285     bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
3286   else
3287     reloc_entry->addend = val;
3288
3289   if (relocatable)
3290     reloc_entry->address += input_section->output_offset;
3291
3292   return bfd_reloc_ok;
3293 }
3294
3295 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
3296    the rest is at bits 6-10. The bitpos already got right by the howto.  */
3297
3298 static bfd_reloc_status_type
3299 mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3300                          void *data, asection *input_section, bfd *output_bfd,
3301                          char **error_message)
3302 {
3303   if (reloc_entry->howto->partial_inplace)
3304     {
3305       reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
3306                              | (reloc_entry->addend & 0x00000800) >> 9);
3307     }
3308
3309   return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
3310                                       input_section, output_bfd,
3311                                       error_message);
3312 }
3313
3314 /* Handle a mips16 GP relative reloc.  */
3315
3316 static bfd_reloc_status_type
3317 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3318                     void *data, asection *input_section, bfd *output_bfd,
3319                     char **error_message)
3320 {
3321   bfd_boolean relocatable;
3322   bfd_reloc_status_type ret;
3323   bfd_byte *location;
3324   bfd_vma gp;
3325
3326   /* If we're relocating, and this is an external symbol, we don't want
3327      to change anything.  */
3328   if (output_bfd != NULL
3329       && (symbol->flags & BSF_SECTION_SYM) == 0
3330       && (symbol->flags & BSF_LOCAL) != 0)
3331     {
3332       reloc_entry->address += input_section->output_offset;
3333       return bfd_reloc_ok;
3334     }
3335
3336   if (output_bfd != NULL)
3337     relocatable = TRUE;
3338   else
3339     {
3340       relocatable = FALSE;
3341       output_bfd = symbol->section->output_section->owner;
3342     }
3343
3344   ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
3345                              &gp);
3346   if (ret != bfd_reloc_ok)
3347     return ret;
3348
3349   location = (bfd_byte *) data + reloc_entry->address;
3350   _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
3351                                  location);
3352   ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
3353                                        input_section, relocatable,
3354                                        data, gp);
3355   _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
3356                                location);
3357
3358   return ret;
3359 }
3360 \f
3361 /* A mapping from BFD reloc types to MIPS ELF reloc types.  */
3362
3363 struct elf_reloc_map {
3364   bfd_reloc_code_real_type bfd_val;
3365   enum elf_mips_reloc_type elf_val;
3366 };
3367
3368 static const struct elf_reloc_map mips_reloc_map[] =
3369 {
3370   { BFD_RELOC_NONE, R_MIPS_NONE },
3371   { BFD_RELOC_16, R_MIPS_16 },
3372   { BFD_RELOC_32, R_MIPS_32 },
3373   /* There is no BFD reloc for R_MIPS_REL32.  */
3374   { BFD_RELOC_64, R_MIPS_64 },
3375   { BFD_RELOC_CTOR, R_MIPS_64 },
3376   { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
3377   { BFD_RELOC_HI16_S, R_MIPS_HI16 },
3378   { BFD_RELOC_LO16, R_MIPS_LO16 },
3379   { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
3380   { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
3381   { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
3382   { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
3383   { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
3384   { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
3385   { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
3386   { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
3387   { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
3388   { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
3389   { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
3390   { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
3391   { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
3392   { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
3393   { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
3394   { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
3395   { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
3396   { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
3397   { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
3398   { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
3399   { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
3400   { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
3401   { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
3402   /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated.  */
3403   { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
3404   { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
3405   { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
3406   { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
3407   { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
3408   { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
3409   { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
3410   { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
3411   { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
3412   { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
3413   { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
3414   { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
3415   { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
3416   { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
3417   { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 },
3418   { BFD_RELOC_MIPS_21_PCREL_S2, R_MIPS_PC21_S2 },
3419   { BFD_RELOC_MIPS_26_PCREL_S2, R_MIPS_PC26_S2 },
3420   { BFD_RELOC_MIPS_18_PCREL_S3, R_MIPS_PC18_S3 },
3421   { BFD_RELOC_MIPS_19_PCREL_S2, R_MIPS_PC19_S2 },
3422   { BFD_RELOC_HI16_S_PCREL, R_MIPS_PCHI16 },
3423   { BFD_RELOC_LO16_PCREL, R_MIPS_PCLO16 }
3424 };
3425
3426 static const struct elf_reloc_map mips16_reloc_map[] =
3427 {
3428   { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
3429   { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
3430   { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
3431   { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
3432   { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
3433   { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
3434   { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
3435   { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
3436   { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
3437     R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
3438   { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
3439     R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
3440   { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
3441   { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
3442   { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min },
3443   { BFD_RELOC_MIPS16_16_PCREL_S1, R_MIPS16_PC16_S1 - R_MIPS16_min }
3444 };
3445
3446 static const struct elf_reloc_map micromips_reloc_map[] =
3447 {
3448   { BFD_RELOC_MICROMIPS_JMP, R_MICROMIPS_26_S1 - R_MICROMIPS_min },
3449   { BFD_RELOC_MICROMIPS_HI16_S, R_MICROMIPS_HI16 - R_MICROMIPS_min },
3450   { BFD_RELOC_MICROMIPS_LO16, R_MICROMIPS_LO16 - R_MICROMIPS_min },
3451   { BFD_RELOC_MICROMIPS_GPREL16, R_MICROMIPS_GPREL16 - R_MICROMIPS_min },
3452   { BFD_RELOC_MICROMIPS_LITERAL, R_MICROMIPS_LITERAL - R_MICROMIPS_min },
3453   { BFD_RELOC_MICROMIPS_GOT16, R_MICROMIPS_GOT16 - R_MICROMIPS_min },
3454   { BFD_RELOC_MICROMIPS_7_PCREL_S1, R_MICROMIPS_PC7_S1 - R_MICROMIPS_min },
3455   { BFD_RELOC_MICROMIPS_10_PCREL_S1, R_MICROMIPS_PC10_S1 - R_MICROMIPS_min },
3456   { BFD_RELOC_MICROMIPS_16_PCREL_S1, R_MICROMIPS_PC16_S1 - R_MICROMIPS_min },
3457   { BFD_RELOC_MICROMIPS_CALL16, R_MICROMIPS_CALL16 - R_MICROMIPS_min },
3458   { BFD_RELOC_MICROMIPS_GOT_DISP, R_MICROMIPS_GOT_DISP - R_MICROMIPS_min },
3459   { BFD_RELOC_MICROMIPS_GOT_PAGE, R_MICROMIPS_GOT_PAGE - R_MICROMIPS_min },
3460   { BFD_RELOC_MICROMIPS_GOT_OFST, R_MICROMIPS_GOT_OFST - R_MICROMIPS_min },
3461   { BFD_RELOC_MICROMIPS_GOT_HI16, R_MICROMIPS_GOT_HI16 - R_MICROMIPS_min },
3462   { BFD_RELOC_MICROMIPS_GOT_LO16, R_MICROMIPS_GOT_LO16 - R_MICROMIPS_min },
3463   { BFD_RELOC_MICROMIPS_SUB, R_MICROMIPS_SUB - R_MICROMIPS_min },
3464   { BFD_RELOC_MICROMIPS_HIGHER, R_MICROMIPS_HIGHER - R_MICROMIPS_min },
3465   { BFD_RELOC_MICROMIPS_HIGHEST, R_MICROMIPS_HIGHEST - R_MICROMIPS_min },
3466   { BFD_RELOC_MICROMIPS_CALL_HI16, R_MICROMIPS_CALL_HI16 - R_MICROMIPS_min },
3467   { BFD_RELOC_MICROMIPS_CALL_LO16, R_MICROMIPS_CALL_LO16 - R_MICROMIPS_min },
3468   { BFD_RELOC_MICROMIPS_SCN_DISP, R_MICROMIPS_SCN_DISP - R_MICROMIPS_min },
3469   { BFD_RELOC_MICROMIPS_JALR, R_MICROMIPS_JALR - R_MICROMIPS_min },
3470 };
3471 /* Given a BFD reloc type, return a howto structure.  */
3472
3473 static reloc_howto_type *
3474 bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3475                                  bfd_reloc_code_real_type code)
3476 {
3477   unsigned int i;
3478   /* FIXME: We default to RELA here instead of choosing the right
3479      relocation variant.  */
3480   reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
3481   reloc_howto_type *howto16_table = mips16_elf64_howto_table_rela;
3482   reloc_howto_type *howto_micromips_table = micromips_elf64_howto_table_rela;
3483
3484   for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
3485        i++)
3486     {
3487       if (mips_reloc_map[i].bfd_val == code)
3488         return &howto_table[(int) mips_reloc_map[i].elf_val];
3489     }
3490
3491   for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
3492        i++)
3493     {
3494       if (mips16_reloc_map[i].bfd_val == code)
3495         return &howto16_table[(int) mips16_reloc_map[i].elf_val];
3496     }
3497
3498   for (i = 0; i < sizeof (micromips_reloc_map) / sizeof (struct elf_reloc_map);
3499        i++)
3500     {
3501       if (micromips_reloc_map[i].bfd_val == code)
3502         return &howto_micromips_table[(int) micromips_reloc_map[i].elf_val];
3503     }
3504
3505   switch (code)
3506     {
3507     case BFD_RELOC_VTABLE_INHERIT:
3508       return &elf_mips_gnu_vtinherit_howto;
3509     case BFD_RELOC_VTABLE_ENTRY:
3510       return &elf_mips_gnu_vtentry_howto;
3511     case BFD_RELOC_32_PCREL:
3512       return &elf_mips_gnu_pcrel32;
3513     case BFD_RELOC_MIPS_EH:
3514       return &elf_mips_eh_howto;
3515     case BFD_RELOC_MIPS_COPY:
3516       return &elf_mips_copy_howto;
3517     case BFD_RELOC_MIPS_JUMP_SLOT:
3518       return &elf_mips_jump_slot_howto;
3519     default:
3520       bfd_set_error (bfd_error_bad_value);
3521       return NULL;
3522     }
3523 }
3524
3525 static reloc_howto_type *
3526 bfd_elf64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3527                                  const char *r_name)
3528 {
3529   unsigned int i;
3530
3531   for (i = 0;
3532        i < (sizeof (mips_elf64_howto_table_rela)
3533             / sizeof (mips_elf64_howto_table_rela[0])); i++)
3534     if (mips_elf64_howto_table_rela[i].name != NULL
3535         && strcasecmp (mips_elf64_howto_table_rela[i].name, r_name) == 0)
3536       return &mips_elf64_howto_table_rela[i];
3537
3538   for (i = 0;
3539        i < (sizeof (mips16_elf64_howto_table_rela)
3540             / sizeof (mips16_elf64_howto_table_rela[0]));
3541        i++)
3542     if (mips16_elf64_howto_table_rela[i].name != NULL
3543         && strcasecmp (mips16_elf64_howto_table_rela[i].name, r_name) == 0)
3544       return &mips16_elf64_howto_table_rela[i];
3545
3546   for (i = 0;
3547        i < (sizeof (micromips_elf64_howto_table_rela)
3548             / sizeof (micromips_elf64_howto_table_rela[0]));
3549        i++)
3550     if (micromips_elf64_howto_table_rela[i].name != NULL
3551         && strcasecmp (micromips_elf64_howto_table_rela[i].name, r_name) == 0)
3552       return &micromips_elf64_howto_table_rela[i];
3553
3554   if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
3555     return &elf_mips_gnu_vtinherit_howto;
3556   if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
3557     return &elf_mips_gnu_vtentry_howto;
3558   if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
3559     return &elf_mips_gnu_rel16_s2;
3560   if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
3561     return &elf_mips_gnu_rela16_s2;
3562   if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
3563     return &elf_mips_gnu_pcrel32;
3564   if (strcasecmp (elf_mips_eh_howto.name, r_name) == 0)
3565     return &elf_mips_eh_howto;
3566   if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
3567     return &elf_mips_copy_howto;
3568   if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
3569     return &elf_mips_jump_slot_howto;
3570
3571   return NULL;
3572 }
3573
3574 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
3575
3576 static reloc_howto_type *
3577 mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
3578 {
3579   switch (r_type)
3580     {
3581     case R_MIPS_GNU_VTINHERIT:
3582       return &elf_mips_gnu_vtinherit_howto;
3583     case R_MIPS_GNU_VTENTRY:
3584       return &elf_mips_gnu_vtentry_howto;
3585     case R_MIPS_GNU_REL16_S2:
3586       if (rela_p)
3587         return &elf_mips_gnu_rela16_s2;
3588       else
3589         return &elf_mips_gnu_rel16_s2;
3590     case R_MIPS_PC32:
3591       return &elf_mips_gnu_pcrel32;
3592     case R_MIPS_EH:
3593       return &elf_mips_eh_howto;
3594     case R_MIPS_COPY:
3595       return &elf_mips_copy_howto;
3596     case R_MIPS_JUMP_SLOT:
3597       return &elf_mips_jump_slot_howto;
3598     default:
3599       if (r_type >= R_MICROMIPS_min && r_type < R_MICROMIPS_max)
3600         {
3601           if (rela_p)
3602             return &micromips_elf64_howto_table_rela[r_type - R_MICROMIPS_min];
3603           else
3604             return &micromips_elf64_howto_table_rel[r_type - R_MICROMIPS_min];
3605         }
3606       if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
3607         {
3608           if (rela_p)
3609             return &mips16_elf64_howto_table_rela[r_type - R_MIPS16_min];
3610           else
3611             return &mips16_elf64_howto_table_rel[r_type - R_MIPS16_min];
3612         }
3613       if (r_type >= R_MIPS_max)
3614         {
3615           _bfd_error_handler (_("unrecognised MIPS reloc number: %d"), r_type);
3616           bfd_set_error (bfd_error_bad_value);
3617           r_type = R_MIPS_NONE;
3618         }
3619       if (rela_p)
3620         return &mips_elf64_howto_table_rela[r_type];
3621       else
3622         return &mips_elf64_howto_table_rel[r_type];
3623       break;
3624     }
3625 }
3626
3627 /* Prevent relocation handling by bfd for MIPS ELF64.  */
3628
3629 static void
3630 mips_elf64_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
3631                               arelent *cache_ptr ATTRIBUTE_UNUSED,
3632                               Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
3633 {
3634   BFD_ASSERT (0);
3635 }
3636
3637 static void
3638 mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
3639                                arelent *cache_ptr ATTRIBUTE_UNUSED,
3640                                Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
3641 {
3642   BFD_ASSERT (0);
3643 }
3644
3645 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
3646    to three relocs, we must tell the user to allocate more space.  */
3647
3648 static long
3649 mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd)
3650 {
3651   return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
3652 }
3653
3654 /* Read the relocations from one reloc section.  This is mostly copied
3655    from elfcode.h, except for the changes to expand one external
3656    relocation to 3 internal ones.  To reduce processing effort we
3657    could discard those R_MIPS_NONE relocations that occupy the second
3658    and the third entry of a triplet, as `mips_elf64_write_rel' and
3659    `mips_elf64_write_rela' recreate them in output automagically,
3660    however that would also remove them from `objdump -r' output,
3661    breaking a long-established tradition and likely confusing people.  */
3662
3663 static bfd_boolean
3664 mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
3665                                   Elf_Internal_Shdr *rel_hdr,
3666                                   bfd_size_type reloc_count,
3667                                   arelent *relents, asymbol **symbols,
3668                                   bfd_boolean dynamic)
3669 {
3670   void *allocated;
3671   bfd_byte *native_relocs;
3672   arelent *relent;
3673   bfd_vma i;
3674   int entsize;
3675   bfd_boolean rela_p;
3676
3677   allocated = bfd_malloc (rel_hdr->sh_size);
3678   if (allocated == NULL)
3679     return FALSE;
3680
3681   if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
3682       || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
3683           != rel_hdr->sh_size))
3684     goto error_return;
3685
3686   native_relocs = allocated;
3687
3688   entsize = rel_hdr->sh_entsize;
3689   BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
3690               || entsize == sizeof (Elf64_Mips_External_Rela));
3691
3692   if (entsize == sizeof (Elf64_Mips_External_Rel))
3693     rela_p = FALSE;
3694   else
3695     rela_p = TRUE;
3696
3697   for (i = 0, relent = relents;
3698        i < reloc_count;
3699        i++, native_relocs += entsize)
3700     {
3701       Elf64_Mips_Internal_Rela rela;
3702       bfd_boolean used_sym, used_ssym;
3703       int ir;
3704
3705       if (entsize == sizeof (Elf64_Mips_External_Rela))
3706         mips_elf64_swap_reloca_in (abfd,
3707                                    (Elf64_Mips_External_Rela *) native_relocs,
3708                                    &rela);
3709       else
3710         mips_elf64_swap_reloc_in (abfd,
3711                                   (Elf64_Mips_External_Rel *) native_relocs,
3712                                   &rela);
3713
3714       /* Each entry represents exactly three actual relocations.  */
3715
3716       used_sym = FALSE;
3717       used_ssym = FALSE;
3718       for (ir = 0; ir < 3; ir++)
3719         {
3720           enum elf_mips_reloc_type type;
3721
3722           switch (ir)
3723             {
3724             default:
3725               abort ();
3726             case 0:
3727               type = (enum elf_mips_reloc_type) rela.r_type;
3728               break;
3729             case 1:
3730               type = (enum elf_mips_reloc_type) rela.r_type2;
3731               break;
3732             case 2:
3733               type = (enum elf_mips_reloc_type) rela.r_type3;
3734               break;
3735             }
3736
3737           /* Some types require symbols, whereas some do not.  */
3738           switch (type)
3739             {
3740             case R_MIPS_NONE:
3741             case R_MIPS_LITERAL:
3742             case R_MIPS_INSERT_A:
3743             case R_MIPS_INSERT_B:
3744             case R_MIPS_DELETE:
3745               relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3746               break;
3747
3748             default:
3749               if (! used_sym)
3750                 {
3751                   if (rela.r_sym == STN_UNDEF)
3752                     relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3753                   else
3754                     {
3755                       asymbol **ps, *s;
3756
3757                       ps = symbols + rela.r_sym - 1;
3758                       s = *ps;
3759                       if ((s->flags & BSF_SECTION_SYM) == 0)
3760                         relent->sym_ptr_ptr = ps;
3761                       else
3762                         relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
3763                     }
3764
3765                   used_sym = TRUE;
3766                 }
3767               else if (! used_ssym)
3768                 {
3769                   switch (rela.r_ssym)
3770                     {
3771                     case RSS_UNDEF:
3772                       relent->sym_ptr_ptr =
3773                         bfd_abs_section_ptr->symbol_ptr_ptr;
3774                       break;
3775
3776                     case RSS_GP:
3777                     case RSS_GP0:
3778                     case RSS_LOC:
3779                       /* FIXME: I think these need to be handled using
3780                          special howto structures.  */
3781                       BFD_ASSERT (0);
3782                       break;
3783
3784                     default:
3785                       BFD_ASSERT (0);
3786                       break;
3787                     }
3788
3789                   used_ssym = TRUE;
3790                 }
3791               else
3792                 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3793
3794               break;
3795             }
3796
3797           /* The address of an ELF reloc is section relative for an
3798              object file, and absolute for an executable file or
3799              shared library.  The address of a BFD reloc is always
3800              section relative.  */
3801           if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
3802             relent->address = rela.r_offset;
3803           else
3804             relent->address = rela.r_offset - asect->vma;
3805
3806           relent->addend = rela.r_addend;
3807
3808           relent->howto = mips_elf64_rtype_to_howto (type, rela_p);
3809
3810           ++relent;
3811         }
3812     }
3813
3814   if (allocated != NULL)
3815     free (allocated);
3816
3817   return TRUE;
3818
3819  error_return:
3820   if (allocated != NULL)
3821     free (allocated);
3822   return FALSE;
3823 }
3824
3825 /* Read the relocations.  On Irix 6, there can be two reloc sections
3826    associated with a single data section.  This is copied from
3827    elfcode.h as well, with changes as small as accounting for 3
3828    internal relocs per external reloc.  */
3829
3830 static bfd_boolean
3831 mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
3832                               asymbol **symbols, bfd_boolean dynamic)
3833 {
3834   struct bfd_elf_section_data * const d = elf_section_data (asect);
3835   Elf_Internal_Shdr *rel_hdr;
3836   Elf_Internal_Shdr *rel_hdr2;
3837   bfd_size_type reloc_count;
3838   bfd_size_type reloc_count2;
3839   arelent *relents;
3840   bfd_size_type amt;
3841
3842   if (asect->relocation != NULL)
3843     return TRUE;
3844
3845   if (! dynamic)
3846     {
3847       if ((asect->flags & SEC_RELOC) == 0
3848           || asect->reloc_count == 0)
3849         return TRUE;
3850
3851       rel_hdr = d->rel.hdr;
3852       reloc_count = rel_hdr ? NUM_SHDR_ENTRIES (rel_hdr) : 0;
3853       rel_hdr2 = d->rela.hdr;
3854       reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
3855
3856       BFD_ASSERT (asect->reloc_count == 3 * (reloc_count + reloc_count2));
3857       BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
3858                   || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
3859
3860     }
3861   else
3862     {
3863       /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
3864          case because relocations against this section may use the
3865          dynamic symbol table, and in that case bfd_section_from_shdr
3866          in elf.c does not update the RELOC_COUNT.  */
3867       if (asect->size == 0)
3868         return TRUE;
3869
3870       rel_hdr = &d->this_hdr;
3871       reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
3872       rel_hdr2 = NULL;
3873       reloc_count2 = 0;
3874     }
3875
3876   /* Allocate space for 3 arelent structures for each Rel structure.  */
3877   amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
3878   relents = bfd_alloc (abfd, amt);
3879   if (relents == NULL)
3880     return FALSE;
3881
3882   if (rel_hdr != NULL
3883       && ! mips_elf64_slurp_one_reloc_table (abfd, asect,
3884                                              rel_hdr, reloc_count,
3885                                              relents,
3886                                              symbols, dynamic))
3887     return FALSE;
3888   if (rel_hdr2 != NULL
3889       && ! mips_elf64_slurp_one_reloc_table (abfd, asect,
3890                                              rel_hdr2, reloc_count2,
3891                                              relents + reloc_count * 3,
3892                                              symbols, dynamic))
3893     return FALSE;
3894
3895   asect->relocation = relents;
3896   return TRUE;
3897 }
3898
3899 /* Write out the relocations.  */
3900
3901 static void
3902 mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
3903 {
3904   bfd_boolean *failedp = data;
3905   int count;
3906   Elf_Internal_Shdr *rel_hdr;
3907   unsigned int idx;
3908
3909   /* If we have already failed, don't do anything.  */
3910   if (*failedp)
3911     return;
3912
3913   if ((sec->flags & SEC_RELOC) == 0)
3914     return;
3915
3916   /* The linker backend writes the relocs out itself, and sets the
3917      reloc_count field to zero to inhibit writing them here.  Also,
3918      sometimes the SEC_RELOC flag gets set even when there aren't any
3919      relocs.  */
3920   if (sec->reloc_count == 0)
3921     return;
3922
3923   /* We can combine up to three relocs that refer to the same address
3924      if the latter relocs have no associated symbol.  */
3925   count = 0;
3926   for (idx = 0; idx < sec->reloc_count; idx++)
3927     {
3928       bfd_vma addr;
3929       unsigned int i;
3930
3931       ++count;
3932
3933       addr = sec->orelocation[idx]->address;
3934       for (i = 0; i < 2; i++)
3935         {
3936           arelent *r;
3937
3938           if (idx + 1 >= sec->reloc_count)
3939             break;
3940           r = sec->orelocation[idx + 1];
3941           if (r->address != addr
3942               || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
3943               || (*r->sym_ptr_ptr)->value != 0)
3944             break;
3945
3946           /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
3947
3948           ++idx;
3949         }
3950     }
3951
3952   rel_hdr = _bfd_elf_single_rel_hdr (sec);
3953
3954   /* Do the actual relocation.  */
3955
3956   if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
3957     mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
3958   else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
3959     mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
3960   else
3961     BFD_ASSERT (0);
3962 }
3963
3964 static void
3965 mips_elf64_write_rel (bfd *abfd, asection *sec,
3966                       Elf_Internal_Shdr *rel_hdr,
3967                       int *count, void *data)
3968 {
3969   bfd_boolean *failedp = data;
3970   Elf64_Mips_External_Rel *ext_rel;
3971   unsigned int idx;
3972   asymbol *last_sym = 0;
3973   int last_sym_idx = 0;
3974
3975   rel_hdr->sh_size = rel_hdr->sh_entsize * *count;
3976   rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size);
3977   if (rel_hdr->contents == NULL)
3978     {
3979       *failedp = TRUE;
3980       return;
3981     }
3982
3983   ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
3984   for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
3985     {
3986       arelent *ptr;
3987       Elf64_Mips_Internal_Rela int_rel;
3988       asymbol *sym;
3989       int n;
3990       unsigned int i;
3991
3992       ptr = sec->orelocation[idx];
3993
3994       /* The address of an ELF reloc is section relative for an object
3995          file, and absolute for an executable file or shared library.
3996          The address of a BFD reloc is always section relative.  */
3997       if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
3998         int_rel.r_offset = ptr->address;
3999       else
4000         int_rel.r_offset = ptr->address + sec->vma;
4001
4002       sym = *ptr->sym_ptr_ptr;
4003       if (sym == last_sym)
4004         n = last_sym_idx;
4005       else if (bfd_is_abs_section (sym->section) && sym->value == 0)
4006         n = STN_UNDEF;
4007       else
4008         {
4009           last_sym = sym;
4010           n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
4011           if (n < 0)
4012             {
4013               *failedp = TRUE;
4014               return;
4015             }
4016           last_sym_idx = n;
4017         }
4018
4019       int_rel.r_sym = n;
4020       int_rel.r_ssym = RSS_UNDEF;
4021
4022       if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
4023           && ! _bfd_elf_validate_reloc (abfd, ptr))
4024         {
4025           *failedp = TRUE;
4026           return;
4027         }
4028
4029       int_rel.r_type = ptr->howto->type;
4030       int_rel.r_type2 = (int) R_MIPS_NONE;
4031       int_rel.r_type3 = (int) R_MIPS_NONE;
4032
4033       for (i = 0; i < 2; i++)
4034         {
4035           arelent *r;
4036
4037           if (idx + 1 >= sec->reloc_count)
4038             break;
4039           r = sec->orelocation[idx + 1];
4040           if (r->address != ptr->address
4041               || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
4042               || (*r->sym_ptr_ptr)->value != 0)
4043             break;
4044
4045           /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
4046
4047           if (i == 0)
4048             int_rel.r_type2 = r->howto->type;
4049           else
4050             int_rel.r_type3 = r->howto->type;
4051
4052           ++idx;
4053         }
4054
4055       mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
4056     }
4057
4058   BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
4059               == *count);
4060 }
4061
4062 static void
4063 mips_elf64_write_rela (bfd *abfd, asection *sec,
4064                        Elf_Internal_Shdr *rela_hdr,
4065                        int *count, void *data)
4066 {
4067   bfd_boolean *failedp = data;
4068   Elf64_Mips_External_Rela *ext_rela;
4069   unsigned int idx;
4070   asymbol *last_sym = 0;
4071   int last_sym_idx = 0;
4072
4073   rela_hdr->sh_size = rela_hdr->sh_entsize * *count;
4074   rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
4075   if (rela_hdr->contents == NULL)
4076     {
4077       *failedp = TRUE;
4078       return;
4079     }
4080
4081   ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
4082   for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
4083     {
4084       arelent *ptr;
4085       Elf64_Mips_Internal_Rela int_rela;
4086       asymbol *sym;
4087       int n;
4088       unsigned int i;
4089
4090       ptr = sec->orelocation[idx];
4091
4092       /* The address of an ELF reloc is section relative for an object
4093          file, and absolute for an executable file or shared library.
4094          The address of a BFD reloc is always section relative.  */
4095       if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
4096         int_rela.r_offset = ptr->address;
4097       else
4098         int_rela.r_offset = ptr->address + sec->vma;
4099
4100       sym = *ptr->sym_ptr_ptr;
4101       if (sym == last_sym)
4102         n = last_sym_idx;
4103       else if (bfd_is_abs_section (sym->section) && sym->value == 0)
4104         n = STN_UNDEF;
4105       else
4106         {
4107           last_sym = sym;
4108           n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
4109           if (n < 0)
4110             {
4111               *failedp = TRUE;
4112               return;
4113             }
4114           last_sym_idx = n;
4115         }
4116
4117       int_rela.r_sym = n;
4118       int_rela.r_addend = ptr->addend;
4119       int_rela.r_ssym = RSS_UNDEF;
4120
4121       if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
4122           && ! _bfd_elf_validate_reloc (abfd, ptr))
4123         {
4124           *failedp = TRUE;
4125           return;
4126         }
4127
4128       int_rela.r_type = ptr->howto->type;
4129       int_rela.r_type2 = (int) R_MIPS_NONE;
4130       int_rela.r_type3 = (int) R_MIPS_NONE;
4131
4132       for (i = 0; i < 2; i++)
4133         {
4134           arelent *r;
4135
4136           if (idx + 1 >= sec->reloc_count)
4137             break;
4138           r = sec->orelocation[idx + 1];
4139           if (r->address != ptr->address
4140               || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
4141               || (*r->sym_ptr_ptr)->value != 0)
4142             break;
4143
4144           /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
4145
4146           if (i == 0)
4147             int_rela.r_type2 = r->howto->type;
4148           else
4149             int_rela.r_type3 = r->howto->type;
4150
4151           ++idx;
4152         }
4153
4154       mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
4155     }
4156
4157   BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
4158               == *count);
4159 }
4160 \f
4161 /* Set the right machine number for a MIPS ELF file.  */
4162
4163 static bfd_boolean
4164 mips_elf64_object_p (bfd *abfd)
4165 {
4166   unsigned long mach;
4167
4168   /* Irix 6 is broken.  Object file symbol tables are not always
4169      sorted correctly such that local symbols precede global symbols,
4170      and the sh_info field in the symbol table is not always right.  */
4171   if (elf64_mips_irix_compat (abfd) != ict_none)
4172     elf_bad_symtab (abfd) = TRUE;
4173
4174   mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
4175   bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
4176   return TRUE;
4177 }
4178
4179 /* Depending on the target vector we generate some version of Irix
4180    executables or "normal" MIPS ELF ABI executables.  */
4181 static irix_compat_t
4182 elf64_mips_irix_compat (bfd *abfd)
4183 {
4184   if ((abfd->xvec == &mips_elf64_be_vec)
4185       || (abfd->xvec == &mips_elf64_le_vec))
4186     return ict_irix6;
4187   else
4188     return ict_none;
4189 }
4190 \f
4191 /* Support for core dump NOTE sections.  */
4192 static bfd_boolean
4193 elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
4194 {
4195   int offset;
4196   unsigned int size;
4197
4198   switch (note->descsz)
4199     {
4200       default:
4201         return FALSE;
4202
4203       case 480:         /* Linux/MIPS - N64 kernel */
4204         /* pr_cursig */
4205         elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
4206
4207         /* pr_pid */
4208         elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 32);
4209
4210         /* pr_reg */
4211         offset = 112;
4212         size = 360;
4213
4214         break;
4215     }
4216
4217   /* Make a ".reg/999" section.  */
4218   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
4219                                           size, note->descpos + offset);
4220 }
4221
4222 static bfd_boolean
4223 elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
4224 {
4225   switch (note->descsz)
4226     {
4227       default:
4228         return FALSE;
4229
4230       case 136:         /* Linux/MIPS - N64 kernel elf_prpsinfo */
4231         elf_tdata (abfd)->core->pid
4232          = bfd_get_32 (abfd, note->descdata + 24);
4233         elf_tdata (abfd)->core->program
4234          = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
4235         elf_tdata (abfd)->core->command
4236          = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
4237     }
4238
4239   /* Note that for some reason, a spurious space is tacked
4240      onto the end of the args in some (at least one anyway)
4241      implementations, so strip it off if it exists.  */
4242
4243   {
4244     char *command = elf_tdata (abfd)->core->command;
4245     int n = strlen (command);
4246
4247     if (0 < n && command[n - 1] == ' ')
4248       command[n - 1] = '\0';
4249   }
4250
4251   return TRUE;
4252 }
4253
4254 /* Write Linux core PRSTATUS note into core file.  */
4255
4256 static char *
4257 elf64_mips_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
4258                              ...)
4259 {
4260   switch (note_type)
4261     {
4262     default:
4263       return NULL;
4264
4265     case NT_PRPSINFO:
4266       BFD_FAIL ();
4267       return NULL;
4268
4269     case NT_PRSTATUS:
4270       {
4271         char data[480];
4272         va_list ap;
4273         long pid;
4274         int cursig;
4275         const void *greg;
4276
4277         va_start (ap, note_type);
4278         memset (data, 0, 112);
4279         pid = va_arg (ap, long);
4280         bfd_put_32 (abfd, pid, data + 32);
4281         cursig = va_arg (ap, int);
4282         bfd_put_16 (abfd, cursig, data + 12);
4283         greg = va_arg (ap, const void *);
4284         memcpy (data + 112, greg, 360);
4285         memset (data + 472, 0, 8);
4286         va_end (ap);
4287         return elfcore_write_note (abfd, buf, bufsiz,
4288                                    "CORE", note_type, data, sizeof (data));
4289       }
4290     }
4291 }
4292 \f
4293 /* ECOFF swapping routines.  These are used when dealing with the
4294    .mdebug section, which is in the ECOFF debugging format.  */
4295 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
4296 {
4297   /* Symbol table magic number.  */
4298   magicSym2,
4299   /* Alignment of debugging information.  E.g., 4.  */
4300   8,
4301   /* Sizes of external symbolic information.  */
4302   sizeof (struct hdr_ext),
4303   sizeof (struct dnr_ext),
4304   sizeof (struct pdr_ext),
4305   sizeof (struct sym_ext),
4306   sizeof (struct opt_ext),
4307   sizeof (struct fdr_ext),
4308   sizeof (struct rfd_ext),
4309   sizeof (struct ext_ext),
4310   /* Functions to swap in external symbolic data.  */
4311   ecoff_swap_hdr_in,
4312   ecoff_swap_dnr_in,
4313   ecoff_swap_pdr_in,
4314   ecoff_swap_sym_in,
4315   ecoff_swap_opt_in,
4316   ecoff_swap_fdr_in,
4317   ecoff_swap_rfd_in,
4318   ecoff_swap_ext_in,
4319   _bfd_ecoff_swap_tir_in,
4320   _bfd_ecoff_swap_rndx_in,
4321   /* Functions to swap out external symbolic data.  */
4322   ecoff_swap_hdr_out,
4323   ecoff_swap_dnr_out,
4324   ecoff_swap_pdr_out,
4325   ecoff_swap_sym_out,
4326   ecoff_swap_opt_out,
4327   ecoff_swap_fdr_out,
4328   ecoff_swap_rfd_out,
4329   ecoff_swap_ext_out,
4330   _bfd_ecoff_swap_tir_out,
4331   _bfd_ecoff_swap_rndx_out,
4332   /* Function to read in symbolic data.  */
4333   _bfd_mips_elf_read_ecoff_info
4334 };
4335 \f
4336 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
4337    standard ELF.  This structure is used to redirect the relocation
4338    handling routines.  */
4339
4340 const struct elf_size_info mips_elf64_size_info =
4341 {
4342   sizeof (Elf64_External_Ehdr),
4343   sizeof (Elf64_External_Phdr),
4344   sizeof (Elf64_External_Shdr),
4345   sizeof (Elf64_Mips_External_Rel),
4346   sizeof (Elf64_Mips_External_Rela),
4347   sizeof (Elf64_External_Sym),
4348   sizeof (Elf64_External_Dyn),
4349   sizeof (Elf_External_Note),
4350   4,            /* hash-table entry size */
4351   3,            /* internal relocations per external relocations */
4352   64,           /* arch_size */
4353   3,            /* log_file_align */
4354   ELFCLASS64,
4355   EV_CURRENT,
4356   bfd_elf64_write_out_phdrs,
4357   bfd_elf64_write_shdrs_and_ehdr,
4358   bfd_elf64_checksum_contents,
4359   mips_elf64_write_relocs,
4360   bfd_elf64_swap_symbol_in,
4361   bfd_elf64_swap_symbol_out,
4362   mips_elf64_slurp_reloc_table,
4363   bfd_elf64_slurp_symbol_table,
4364   bfd_elf64_swap_dyn_in,
4365   bfd_elf64_swap_dyn_out,
4366   mips_elf64_be_swap_reloc_in,
4367   mips_elf64_be_swap_reloc_out,
4368   mips_elf64_be_swap_reloca_in,
4369   mips_elf64_be_swap_reloca_out
4370 };
4371
4372 #define ELF_ARCH                        bfd_arch_mips
4373 #define ELF_TARGET_ID                   MIPS_ELF_DATA
4374 #define ELF_MACHINE_CODE                EM_MIPS
4375
4376 #define elf_backend_collect             TRUE
4377 #define elf_backend_type_change_ok      TRUE
4378 #define elf_backend_can_gc_sections     TRUE
4379 #define elf_backend_gc_mark_extra_sections \
4380                                         _bfd_mips_elf_gc_mark_extra_sections
4381 #define elf_info_to_howto               mips_elf64_info_to_howto_rela
4382 #define elf_info_to_howto_rel           mips_elf64_info_to_howto_rel
4383 #define elf_backend_object_p            mips_elf64_object_p
4384 #define elf_backend_symbol_processing   _bfd_mips_elf_symbol_processing
4385 #define elf_backend_section_processing  _bfd_mips_elf_section_processing
4386 #define elf_backend_section_from_shdr   _bfd_mips_elf_section_from_shdr
4387 #define elf_backend_fake_sections       _bfd_mips_elf_fake_sections
4388 #define elf_backend_section_from_bfd_section \
4389                                 _bfd_mips_elf_section_from_bfd_section
4390 #define elf_backend_add_symbol_hook     _bfd_mips_elf_add_symbol_hook
4391 #define elf_backend_link_output_symbol_hook \
4392                                 _bfd_mips_elf_link_output_symbol_hook
4393 #define elf_backend_create_dynamic_sections \
4394                                 _bfd_mips_elf_create_dynamic_sections
4395 #define elf_backend_check_relocs        _bfd_mips_elf_check_relocs
4396 #define elf_backend_merge_symbol_attribute \
4397                                 _bfd_mips_elf_merge_symbol_attribute
4398 #define elf_backend_get_target_dtag     _bfd_mips_elf_get_target_dtag
4399 #define elf_backend_adjust_dynamic_symbol \
4400                                 _bfd_mips_elf_adjust_dynamic_symbol
4401 #define elf_backend_always_size_sections \
4402                                 _bfd_mips_elf_always_size_sections
4403 #define elf_backend_size_dynamic_sections \
4404                                 _bfd_mips_elf_size_dynamic_sections
4405 #define elf_backend_init_index_section  _bfd_elf_init_1_index_section
4406 #define elf_backend_relocate_section    _bfd_mips_elf_relocate_section
4407 #define elf_backend_finish_dynamic_symbol \
4408                                 _bfd_mips_elf_finish_dynamic_symbol
4409 #define elf_backend_finish_dynamic_sections \
4410                                 _bfd_mips_elf_finish_dynamic_sections
4411 #define elf_backend_final_write_processing \
4412                                 _bfd_mips_elf_final_write_processing
4413 #define elf_backend_additional_program_headers \
4414                                 _bfd_mips_elf_additional_program_headers
4415 #define elf_backend_modify_segment_map  _bfd_mips_elf_modify_segment_map
4416 #define elf_backend_gc_mark_hook        _bfd_mips_elf_gc_mark_hook
4417 #define elf_backend_copy_indirect_symbol \
4418                                         _bfd_mips_elf_copy_indirect_symbol
4419 #define elf_backend_ignore_discarded_relocs \
4420                                         _bfd_mips_elf_ignore_discarded_relocs
4421 #define elf_backend_mips_irix_compat    elf64_mips_irix_compat
4422 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
4423 #define elf_backend_ecoff_debug_swap    &mips_elf64_ecoff_debug_swap
4424 #define elf_backend_size_info           mips_elf64_size_info
4425
4426 #define elf_backend_grok_prstatus       elf64_mips_grok_prstatus
4427 #define elf_backend_grok_psinfo         elf64_mips_grok_psinfo
4428
4429 #define elf_backend_got_header_size     (8 * MIPS_RESERVED_GOTNO)
4430 #define elf_backend_want_dynrelro       1
4431
4432 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
4433    work better/work only in RELA, so we default to this.  */
4434 #define elf_backend_may_use_rel_p       1
4435 #define elf_backend_may_use_rela_p      1
4436 #define elf_backend_default_use_rela_p  1
4437 #define elf_backend_rela_plts_and_copies_p 0
4438 #define elf_backend_plt_readonly        1
4439 #define elf_backend_plt_sym_val         _bfd_mips_elf_plt_sym_val
4440
4441 #define elf_backend_sign_extend_vma     TRUE
4442
4443 #define elf_backend_write_section       _bfd_mips_elf_write_section
4444 #define elf_backend_sort_relocs_p       _bfd_mips_elf_sort_relocs_p
4445
4446 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
4447    MIPS-specific function only applies to IRIX5, which had no 64-bit
4448    ABI.  */
4449 #define bfd_elf64_bfd_is_target_special_symbol \
4450                                         _bfd_mips_elf_is_target_special_symbol
4451 #define bfd_elf64_find_nearest_line     _bfd_mips_elf_find_nearest_line
4452 #define bfd_elf64_find_inliner_info     _bfd_mips_elf_find_inliner_info
4453 #define bfd_elf64_new_section_hook      _bfd_mips_elf_new_section_hook
4454 #define bfd_elf64_set_section_contents  _bfd_mips_elf_set_section_contents
4455 #define bfd_elf64_bfd_get_relocated_section_contents \
4456                                 _bfd_elf_mips_get_relocated_section_contents
4457 #define bfd_elf64_bfd_link_hash_table_create \
4458                                 _bfd_mips_elf_link_hash_table_create
4459 #define bfd_elf64_bfd_final_link        _bfd_mips_elf_final_link
4460 #define bfd_elf64_bfd_merge_private_bfd_data \
4461                                 _bfd_mips_elf_merge_private_bfd_data
4462 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
4463 #define bfd_elf64_bfd_print_private_bfd_data \
4464                                 _bfd_mips_elf_print_private_bfd_data
4465
4466 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
4467 #define bfd_elf64_mkobject              _bfd_mips_elf_mkobject
4468
4469 /* The SGI style (n)64 NewABI.  */
4470 #define TARGET_LITTLE_SYM               mips_elf64_le_vec
4471 #define TARGET_LITTLE_NAME              "elf64-littlemips"
4472 #define TARGET_BIG_SYM                  mips_elf64_be_vec
4473 #define TARGET_BIG_NAME                 "elf64-bigmips"
4474
4475 #define ELF_MAXPAGESIZE                 0x10000
4476 #define ELF_COMMONPAGESIZE              0x1000
4477
4478 #include "elf64-target.h"
4479
4480 /* The SYSV-style 'traditional' (n)64 NewABI.  */
4481 #undef TARGET_LITTLE_SYM
4482 #undef TARGET_LITTLE_NAME
4483 #undef TARGET_BIG_SYM
4484 #undef TARGET_BIG_NAME
4485
4486 #undef ELF_MAXPAGESIZE
4487 #undef ELF_COMMONPAGESIZE
4488
4489 #define TARGET_LITTLE_SYM               mips_elf64_trad_le_vec
4490 #define TARGET_LITTLE_NAME              "elf64-tradlittlemips"
4491 #define TARGET_BIG_SYM                  mips_elf64_trad_be_vec
4492 #define TARGET_BIG_NAME                 "elf64-tradbigmips"
4493
4494 #define ELF_MAXPAGESIZE                 0x10000
4495 #define ELF_COMMONPAGESIZE              0x1000
4496 #define elf64_bed                       elf64_tradbed
4497
4498 #undef elf_backend_write_core_note
4499 #define elf_backend_write_core_note     elf64_mips_write_core_note
4500
4501 /* Include the target file again for this target.  */
4502 #include "elf64-target.h"
4503
4504
4505 /* FreeBSD support.  */
4506
4507 #undef TARGET_LITTLE_SYM
4508 #undef TARGET_LITTLE_NAME
4509 #undef TARGET_BIG_SYM
4510 #undef TARGET_BIG_NAME
4511
4512 #define TARGET_LITTLE_SYM               mips_elf64_tradfbsd_le_vec
4513 #define TARGET_LITTLE_NAME              "elf64-tradlittlemips-freebsd"
4514 #define TARGET_BIG_SYM                  mips_elf64_tradfbsd_be_vec
4515 #define TARGET_BIG_NAME                 "elf64-tradbigmips-freebsd"
4516
4517 #undef  ELF_OSABI
4518 #define ELF_OSABI                       ELFOSABI_FREEBSD
4519
4520 #undef  elf64_bed
4521 #define elf64_bed                               elf64_fbsd_tradbed
4522
4523 #undef elf64_mips_write_core_note
4524
4525 #include "elf64-target.h"