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