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