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