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