* elf64-mips.c (elf_mips_gnu_rel16_s2): Add internally used
[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       && (! reloc_entry->howto->partial_inplace
1451           || reloc_entry->addend == 0))
1452     {
1453       reloc_entry->address += input_section->output_offset;
1454       return bfd_reloc_ok;
1455     }
1456
1457   if (((reloc_entry->addend & 0xffff) + 0x8000) & ~0xffff)
1458     reloc_entry->addend += 0x8000;
1459
1460   return bfd_reloc_continue;
1461 }
1462
1463 /* Do a R_MIPS_GOT16 reloc.  This is a reloc against the global offset
1464    table used for PIC code.  If the symbol is an external symbol, the
1465    instruction is modified to contain the offset of the appropriate
1466    entry in the global offset table.  If the symbol is a section
1467    symbol, the next reloc is a R_MIPS_LO16 reloc.  The two 16 bit
1468    addends are combined to form the real addend against the section
1469    symbol; the GOT16 is modified to contain the offset of an entry in
1470    the global offset table, and the LO16 is modified to offset it
1471    appropriately.  Thus an offset larger than 16 bits requires a
1472    modified value in the global offset table.
1473
1474    This implementation suffices for the assembler, but the linker does
1475    not yet know how to create global offset tables.  */
1476
1477 static bfd_reloc_status_type
1478 mips_elf64_got16_reloc (abfd, reloc_entry, symbol, data, input_section,
1479                         output_bfd, error_message)
1480      bfd *abfd;
1481      arelent *reloc_entry;
1482      asymbol *symbol;
1483      PTR data;
1484      asection *input_section;
1485      bfd *output_bfd;
1486      char **error_message;
1487 {
1488   /* If we're relocating, and this is a local symbol, we can handle it
1489      just like an R_MIPS_HI16.  */
1490   if (output_bfd != (bfd *) NULL
1491       && (symbol->flags & BSF_SECTION_SYM) != 0)
1492     return mips_elf64_hi16_reloc (abfd, reloc_entry, symbol, data,
1493                                   input_section, output_bfd, error_message);
1494
1495
1496   /* Otherwise we try to handle it as R_MIPS_GOT_DISP.  */
1497   return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
1498                                 input_section, output_bfd, error_message);
1499 }
1500
1501 /* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
1502    dangerous relocation.  */
1503
1504 static bfd_boolean
1505 mips_elf64_assign_gp (output_bfd, pgp)
1506      bfd *output_bfd;
1507      bfd_vma *pgp;
1508 {
1509   unsigned int count;
1510   asymbol **sym;
1511   unsigned int i;
1512
1513   /* If we've already figured out what GP will be, just return it.  */
1514   *pgp = _bfd_get_gp_value (output_bfd);
1515   if (*pgp)
1516     return TRUE;
1517
1518   count = bfd_get_symcount (output_bfd);
1519   sym = bfd_get_outsymbols (output_bfd);
1520
1521   /* The linker script will have created a symbol named `_gp' with the
1522      appropriate value.  */
1523   if (sym == (asymbol **) NULL)
1524     i = count;
1525   else
1526     {
1527       for (i = 0; i < count; i++, sym++)
1528         {
1529           register const char *name;
1530
1531           name = bfd_asymbol_name (*sym);
1532           if (*name == '_' && strcmp (name, "_gp") == 0)
1533             {
1534               *pgp = bfd_asymbol_value (*sym);
1535               _bfd_set_gp_value (output_bfd, *pgp);
1536               break;
1537             }
1538         }
1539     }
1540
1541   if (i >= count)
1542     {
1543       /* Only get the error once.  */
1544       *pgp = 4;
1545       _bfd_set_gp_value (output_bfd, *pgp);
1546       return FALSE;
1547     }
1548
1549   return TRUE;
1550 }
1551
1552 /* We have to figure out the gp value, so that we can adjust the
1553    symbol value correctly.  We look up the symbol _gp in the output
1554    BFD.  If we can't find it, we're stuck.  We cache it in the ELF
1555    target data.  We don't need to adjust the symbol value for an
1556    external symbol if we are producing relocateable output.  */
1557
1558 static bfd_reloc_status_type
1559 mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message, pgp)
1560      bfd *output_bfd;
1561      asymbol *symbol;
1562      bfd_boolean relocateable;
1563      char **error_message;
1564      bfd_vma *pgp;
1565 {
1566   if (bfd_is_und_section (symbol->section)
1567       && ! relocateable)
1568     {
1569       *pgp = 0;
1570       return bfd_reloc_undefined;
1571     }
1572
1573   *pgp = _bfd_get_gp_value (output_bfd);
1574   if (*pgp == 0
1575       && (! relocateable
1576           || (symbol->flags & BSF_SECTION_SYM) != 0))
1577     {
1578       if (relocateable)
1579         {
1580           /* Make up a value.  */
1581           *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
1582           _bfd_set_gp_value (output_bfd, *pgp);
1583         }
1584       else if (!mips_elf64_assign_gp (output_bfd, pgp))
1585         {
1586           *error_message =
1587             (char *) _("GP relative relocation when _gp not defined");
1588           return bfd_reloc_dangerous;
1589         }
1590     }
1591
1592   return bfd_reloc_ok;
1593 }
1594
1595 /* Do a R_MIPS_GPREL16 relocation.  This is a 16 bit value which must
1596    become the offset from the gp register.  */
1597
1598 static bfd_reloc_status_type
1599 mips_elf64_gprel16_reloc (abfd, reloc_entry, symbol, data, input_section,
1600                           output_bfd, error_message)
1601      bfd *abfd;
1602      arelent *reloc_entry;
1603      asymbol *symbol;
1604      PTR data;
1605      asection *input_section;
1606      bfd *output_bfd;
1607      char **error_message;
1608 {
1609   bfd_boolean relocateable;
1610   bfd_reloc_status_type ret;
1611   bfd_vma gp;
1612
1613   /* If we're relocating, and this is an external symbol with no
1614      addend, we don't want to change anything.  We will only have an
1615      addend if this is a newly created reloc, not read from an ELF
1616      file.  */
1617   if (output_bfd != (bfd *) NULL
1618       && (symbol->flags & BSF_SECTION_SYM) == 0
1619       && (! reloc_entry->howto->partial_inplace
1620           || reloc_entry->addend == 0))
1621     {
1622       reloc_entry->address += input_section->output_offset;
1623       return bfd_reloc_ok;
1624     }
1625
1626   if (output_bfd != (bfd *) NULL)
1627     relocateable = TRUE;
1628   else
1629     {
1630       relocateable = FALSE;
1631       output_bfd = symbol->section->output_section->owner;
1632     }
1633
1634   ret = mips_elf64_final_gp (output_bfd, symbol, relocateable, 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, relocateable,
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 relocateable;
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       && (! reloc_entry->howto->partial_inplace
1666           || reloc_entry->addend == 0))
1667     {
1668       reloc_entry->address += input_section->output_offset;
1669       return bfd_reloc_ok;
1670     }
1671
1672   /* FIXME: The entries in the .lit8 and .lit4 sections should be merged.  */
1673   if (output_bfd != (bfd *) NULL)
1674     relocateable = TRUE;
1675   else
1676     {
1677       relocateable = FALSE;
1678       output_bfd = symbol->section->output_section->owner;
1679     }
1680
1681   ret = mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message,
1682                              &gp);
1683   if (ret != bfd_reloc_ok)
1684     return ret;
1685
1686   return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1687                                         input_section, relocateable,
1688                                         data, gp);
1689 }
1690
1691 /* Do a R_MIPS_GPREL32 relocation.  This is a 32 bit value which must
1692    become the offset from the gp register.  */
1693
1694 static bfd_reloc_status_type
1695 mips_elf64_gprel32_reloc (abfd, reloc_entry, symbol, data, input_section,
1696                           output_bfd, error_message)
1697      bfd *abfd;
1698      arelent *reloc_entry;
1699      asymbol *symbol;
1700      PTR data;
1701      asection *input_section;
1702      bfd *output_bfd;
1703      char **error_message;
1704 {
1705   bfd_boolean relocateable;
1706   bfd_reloc_status_type ret;
1707   bfd_vma gp;
1708   bfd_vma relocation;
1709   unsigned long val;
1710
1711   /* If we're relocating, and this is an external symbol with no
1712      addend, we don't want to change anything.  We will only have an
1713      addend if this is a newly created reloc, not read from an ELF
1714      file.  */
1715   if (output_bfd != (bfd *) NULL
1716       && (symbol->flags & BSF_SECTION_SYM) == 0
1717       && reloc_entry->addend == 0)
1718     {
1719       *error_message = (char *)
1720         _("32bits gp relative relocation occurs for an external symbol");
1721       return bfd_reloc_outofrange;
1722     }
1723
1724   if (output_bfd != (bfd *) NULL)
1725     {
1726       relocateable = TRUE;
1727       gp = _bfd_get_gp_value (output_bfd);
1728     }
1729   else
1730     {
1731       relocateable = FALSE;
1732       output_bfd = symbol->section->output_section->owner;
1733
1734       ret = mips_elf64_final_gp (output_bfd, symbol, relocateable,
1735                                  error_message, &gp);
1736       if (ret != bfd_reloc_ok)
1737         return ret;
1738     }
1739
1740   if (bfd_is_com_section (symbol->section))
1741     relocation = 0;
1742   else
1743     relocation = symbol->value;
1744
1745   relocation += symbol->section->output_section->vma;
1746   relocation += symbol->section->output_offset;
1747
1748   if (reloc_entry->address > input_section->_cooked_size)
1749     return bfd_reloc_outofrange;
1750
1751   if (reloc_entry->howto->src_mask == 0)
1752     {
1753       /* This case arises with the 64-bit MIPS ELF ABI.  */
1754       val = 0;
1755     }
1756   else
1757     val = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1758
1759   /* Set val to the offset into the section or symbol.  */
1760   val += reloc_entry->addend;
1761
1762   /* Adjust val for the final section location and GP value.  If we
1763      are producing relocateable output, we don't want to do this for
1764      an external symbol.  */
1765   if (! relocateable
1766       || (symbol->flags & BSF_SECTION_SYM) != 0)
1767     val += relocation - gp;
1768
1769   bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
1770
1771   if (relocateable)
1772     reloc_entry->address += input_section->output_offset;
1773
1774   return bfd_reloc_ok;
1775 }
1776
1777 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
1778    the rest is at bits 6-10. The bitpos already got right by the howto.  */
1779
1780 static bfd_reloc_status_type
1781 mips_elf64_shift6_reloc (abfd, reloc_entry, symbol, data, input_section,
1782                          output_bfd, error_message)
1783      bfd *abfd ATTRIBUTE_UNUSED;
1784      arelent *reloc_entry;
1785      asymbol *symbol;
1786      PTR data ATTRIBUTE_UNUSED;
1787      asection *input_section;
1788      bfd *output_bfd;
1789      char **error_message ATTRIBUTE_UNUSED;
1790 {
1791   /* If we're relocating, and this is an external symbol, we don't
1792      want to change anything.  */
1793   if (output_bfd != (bfd *) NULL
1794       && (symbol->flags & BSF_SECTION_SYM) == 0
1795       && (! reloc_entry->howto->partial_inplace
1796           || reloc_entry->addend == 0))
1797     {
1798       reloc_entry->address += input_section->output_offset;
1799       return bfd_reloc_ok;
1800     }
1801
1802   reloc_entry->addend = (reloc_entry->addend & 0x00007c0)
1803                         | (reloc_entry->addend & 0x00000800) >> 9;
1804
1805   return bfd_reloc_continue;
1806 }
1807
1808 /* Handle a mips16 jump.  */
1809
1810 static bfd_reloc_status_type
1811 mips16_jump_reloc (abfd, reloc_entry, symbol, data, input_section,
1812                    output_bfd, error_message)
1813      bfd *abfd ATTRIBUTE_UNUSED;
1814      arelent *reloc_entry;
1815      asymbol *symbol;
1816      PTR data ATTRIBUTE_UNUSED;
1817      asection *input_section;
1818      bfd *output_bfd;
1819      char **error_message ATTRIBUTE_UNUSED;
1820 {
1821   if (output_bfd != (bfd *) NULL
1822       && (symbol->flags & BSF_SECTION_SYM) == 0
1823       && (! reloc_entry->howto->partial_inplace
1824           || reloc_entry->addend == 0))
1825     {
1826       reloc_entry->address += input_section->output_offset;
1827       return bfd_reloc_ok;
1828     }
1829
1830   /* FIXME.  */
1831   {
1832     static bfd_boolean warned;
1833
1834     if (! warned)
1835       (*_bfd_error_handler)
1836         (_("Linking mips16 objects into %s format is not supported"),
1837          bfd_get_target (input_section->output_section->owner));
1838     warned = TRUE;
1839   }
1840
1841   return bfd_reloc_undefined;
1842 }
1843
1844 /* Handle a mips16 GP relative reloc.  */
1845
1846 static bfd_reloc_status_type
1847 mips16_gprel_reloc (abfd, reloc_entry, symbol, data, input_section,
1848                     output_bfd, error_message)
1849      bfd *abfd;
1850      arelent *reloc_entry;
1851      asymbol *symbol;
1852      PTR data;
1853      asection *input_section;
1854      bfd *output_bfd;
1855      char **error_message;
1856 {
1857   bfd_boolean relocateable;
1858   bfd_reloc_status_type ret;
1859   bfd_vma gp;
1860   unsigned short extend, insn;
1861   unsigned long final;
1862
1863   /* If we're relocating, and this is an external symbol with no
1864      addend, we don't want to change anything.  We will only have an
1865      addend if this is a newly created reloc, not read from an ELF
1866      file.  */
1867   if (output_bfd != NULL
1868       && (symbol->flags & BSF_SECTION_SYM) == 0
1869       && reloc_entry->addend == 0)
1870     {
1871       reloc_entry->address += input_section->output_offset;
1872       return bfd_reloc_ok;
1873     }
1874
1875   if (output_bfd != NULL)
1876     relocateable = TRUE;
1877   else
1878     {
1879       relocateable = FALSE;
1880       output_bfd = symbol->section->output_section->owner;
1881     }
1882
1883   ret = mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message,
1884                              &gp);
1885   if (ret != bfd_reloc_ok)
1886     return ret;
1887
1888   if (reloc_entry->address > input_section->_cooked_size)
1889     return bfd_reloc_outofrange;
1890
1891   /* Pick up the mips16 extend instruction and the real instruction.  */
1892   extend = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address);
1893   insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address + 2);
1894
1895   /* Stuff the current addend back as a 32 bit value, do the usual
1896      relocation, and then clean up.  */
1897   bfd_put_32 (abfd,
1898               (bfd_vma) (((extend & 0x1f) << 11)
1899                          | (extend & 0x7e0)
1900                          | (insn & 0x1f)),
1901               (bfd_byte *) data + reloc_entry->address);
1902
1903   ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1904                                        input_section, relocateable, data, gp);
1905
1906   final = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1907   bfd_put_16 (abfd,
1908               (bfd_vma) ((extend & 0xf800)
1909                          | ((final >> 11) & 0x1f)
1910                          | (final & 0x7e0)),
1911               (bfd_byte *) data + reloc_entry->address);
1912   bfd_put_16 (abfd,
1913               (bfd_vma) ((insn & 0xffe0)
1914                          | (final & 0x1f)),
1915               (bfd_byte *) data + reloc_entry->address + 2);
1916
1917   return ret;
1918 }
1919 \f
1920 /* A mapping from BFD reloc types to MIPS ELF reloc types.  */
1921
1922 struct elf_reloc_map {
1923   bfd_reloc_code_real_type bfd_val;
1924   enum elf_mips_reloc_type elf_val;
1925 };
1926
1927 static const struct elf_reloc_map mips_reloc_map[] =
1928 {
1929   { BFD_RELOC_NONE, R_MIPS_NONE },
1930   { BFD_RELOC_16, R_MIPS_16 },
1931   { BFD_RELOC_32, R_MIPS_32 },
1932   /* There is no BFD reloc for R_MIPS_REL32.  */
1933   { BFD_RELOC_64, R_MIPS_64 },
1934   { BFD_RELOC_CTOR, R_MIPS_64 },
1935   { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
1936   { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1937   { BFD_RELOC_LO16, R_MIPS_LO16 },
1938   { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
1939   { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
1940   { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1941   { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1942   { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
1943   { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
1944   { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
1945   { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
1946   { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
1947   { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1948   { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
1949   { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1950   { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1951   { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1952   { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
1953   { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
1954   { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
1955   { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
1956   { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
1957   { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
1958   { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1959   { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
1960   { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
1961   /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated.  */
1962   { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
1963   { BFD_RELOC_MIPS_JALR, R_MIPS_JALR }
1964 };
1965
1966 /* Given a BFD reloc type, return a howto structure.  */
1967
1968 static reloc_howto_type *
1969 bfd_elf64_bfd_reloc_type_lookup (abfd, code)
1970      bfd *abfd ATTRIBUTE_UNUSED;
1971      bfd_reloc_code_real_type code;
1972 {
1973   unsigned int i;
1974   /* FIXME: We default to RELA here instead of choosing the right
1975      relocation variant.  */
1976   reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
1977
1978   for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
1979        i++)
1980     {
1981       if (mips_reloc_map[i].bfd_val == code)
1982         return &howto_table[(int) mips_reloc_map[i].elf_val];
1983     }
1984
1985   switch (code)
1986     {
1987     case BFD_RELOC_MIPS16_JMP:
1988       return &elf_mips16_jump_howto;
1989     case BFD_RELOC_MIPS16_GPREL:
1990       return &elf_mips16_gprel_howto;
1991     case BFD_RELOC_VTABLE_INHERIT:
1992       return &elf_mips_gnu_vtinherit_howto;
1993     case BFD_RELOC_VTABLE_ENTRY:
1994       return &elf_mips_gnu_vtentry_howto;
1995     case BFD_RELOC_16_PCREL_S2:
1996       return &elf_mips_gnu_rela16_s2;
1997     default:
1998       bfd_set_error (bfd_error_bad_value);
1999       return NULL;
2000     }
2001 }
2002
2003 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
2004
2005 static reloc_howto_type *
2006 mips_elf64_rtype_to_howto (r_type, rela_p)
2007      unsigned int r_type;
2008      bfd_boolean rela_p;
2009 {
2010   switch (r_type)
2011     {
2012     case R_MIPS16_26:
2013       return &elf_mips16_jump_howto;
2014     case R_MIPS16_GPREL:
2015       return &elf_mips16_gprel_howto;
2016     case R_MIPS_GNU_VTINHERIT:
2017       return &elf_mips_gnu_vtinherit_howto;
2018     case R_MIPS_GNU_VTENTRY:
2019       return &elf_mips_gnu_vtentry_howto;
2020     case R_MIPS_GNU_REL16_S2:
2021       if (rela_p)
2022         return &elf_mips_gnu_rela16_s2;
2023       else
2024         return &elf_mips_gnu_rel16_s2;
2025     default:
2026       BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
2027       if (rela_p)
2028         return &mips_elf64_howto_table_rela[r_type];
2029       else
2030         return &mips_elf64_howto_table_rel[r_type];
2031       break;
2032     }
2033 }
2034
2035 /* Prevent relocation handling by bfd for MIPS ELF64.  */
2036
2037 static void
2038 mips_elf64_info_to_howto_rel (abfd, cache_ptr, dst)
2039      bfd *abfd ATTRIBUTE_UNUSED;
2040      arelent *cache_ptr ATTRIBUTE_UNUSED;
2041      Elf_Internal_Rela *dst ATTRIBUTE_UNUSED;
2042 {
2043   BFD_ASSERT (0);
2044 }
2045
2046 static void
2047 mips_elf64_info_to_howto_rela (abfd, cache_ptr, dst)
2048      bfd *abfd ATTRIBUTE_UNUSED;
2049      arelent *cache_ptr ATTRIBUTE_UNUSED;
2050      Elf_Internal_Rela *dst ATTRIBUTE_UNUSED;
2051 {
2052   BFD_ASSERT (0);
2053 }
2054
2055 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
2056    to three relocs, we must tell the user to allocate more space.  */
2057
2058 static long
2059 mips_elf64_get_reloc_upper_bound (abfd, sec)
2060      bfd *abfd ATTRIBUTE_UNUSED;
2061      asection *sec;
2062 {
2063   return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
2064 }
2065
2066 static long
2067 mips_elf64_get_dynamic_reloc_upper_bound (abfd)
2068      bfd *abfd;
2069 {
2070   return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
2071 }
2072
2073 /* We must also copy more relocations than the corresponding functions
2074    in elf.c would, so the two following functions are slightly
2075    modified from elf.c, that multiply the external relocation count by
2076    3 to obtain the internal relocation count.  */
2077
2078 static long
2079 mips_elf64_canonicalize_reloc (abfd, section, relptr, symbols)
2080      bfd *abfd;
2081      sec_ptr section;
2082      arelent **relptr;
2083      asymbol **symbols;
2084 {
2085   arelent *tblptr;
2086   unsigned int i;
2087   struct elf_backend_data *bed = get_elf_backend_data (abfd);
2088
2089   if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
2090     return -1;
2091
2092   tblptr = section->relocation;
2093   for (i = 0; i < section->reloc_count * 3; i++)
2094     *relptr++ = tblptr++;
2095
2096   *relptr = NULL;
2097
2098   return section->reloc_count * 3;
2099 }
2100
2101 static long
2102 mips_elf64_canonicalize_dynamic_reloc (abfd, storage, syms)
2103      bfd *abfd;
2104      arelent **storage;
2105      asymbol **syms;
2106 {
2107   bfd_boolean (*slurp_relocs)
2108     PARAMS ((bfd *, asection *, asymbol **, bfd_boolean));
2109   asection *s;
2110   long ret;
2111
2112   if (elf_dynsymtab (abfd) == 0)
2113     {
2114       bfd_set_error (bfd_error_invalid_operation);
2115       return -1;
2116     }
2117
2118   slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
2119   ret = 0;
2120   for (s = abfd->sections; s != NULL; s = s->next)
2121     {
2122       if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
2123           && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
2124               || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
2125         {
2126           arelent *p;
2127           long count, i;
2128
2129           if (! (*slurp_relocs) (abfd, s, syms, TRUE))
2130             return -1;
2131           count = s->_raw_size / elf_section_data (s)->this_hdr.sh_entsize * 3;
2132           p = s->relocation;
2133           for (i = 0; i < count; i++)
2134             *storage++ = p++;
2135           ret += count;
2136         }
2137     }
2138
2139   *storage = NULL;
2140
2141   return ret;
2142 }
2143
2144 /* Read the relocations from one reloc section.  This is mostly copied
2145    from elfcode.h, except for the changes to expand one external
2146    relocation to 3 internal ones.  We must unfortunately set
2147    reloc_count to the number of external relocations, because a lot of
2148    generic code seems to depend on this.  */
2149
2150 static bfd_boolean
2151 mips_elf64_slurp_one_reloc_table (abfd, asect, rel_hdr, reloc_count,
2152                                   relents, symbols, dynamic)
2153      bfd *abfd;
2154      asection *asect;
2155      Elf_Internal_Shdr *rel_hdr;
2156      bfd_size_type reloc_count;
2157      arelent *relents;
2158      asymbol **symbols;
2159      bfd_boolean dynamic;
2160 {
2161   PTR allocated = NULL;
2162   bfd_byte *native_relocs;
2163   arelent *relent;
2164   bfd_vma i;
2165   int entsize;
2166   reloc_howto_type *howto_table;
2167
2168   allocated = (PTR) bfd_malloc (rel_hdr->sh_size);
2169   if (allocated == NULL)
2170     return FALSE;
2171
2172   if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
2173       || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
2174           != rel_hdr->sh_size))
2175     goto error_return;
2176
2177   native_relocs = (bfd_byte *) allocated;
2178
2179   entsize = rel_hdr->sh_entsize;
2180   BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
2181               || entsize == sizeof (Elf64_Mips_External_Rela));
2182
2183   if (entsize == sizeof (Elf64_Mips_External_Rel))
2184     howto_table = mips_elf64_howto_table_rel;
2185   else
2186     howto_table = mips_elf64_howto_table_rela;
2187
2188   for (i = 0, relent = relents;
2189        i < reloc_count;
2190        i++, native_relocs += entsize)
2191     {
2192       Elf64_Mips_Internal_Rela rela;
2193       bfd_boolean used_sym, used_ssym;
2194       int ir;
2195
2196       if (entsize == sizeof (Elf64_Mips_External_Rela))
2197         mips_elf64_swap_reloca_in (abfd,
2198                                    (Elf64_Mips_External_Rela *) native_relocs,
2199                                    &rela);
2200       else
2201         mips_elf64_swap_reloc_in (abfd,
2202                                   (Elf64_Mips_External_Rel *) native_relocs,
2203                                   &rela);
2204
2205       /* Each entry represents exactly three actual relocations.  */
2206
2207       used_sym = FALSE;
2208       used_ssym = FALSE;
2209       for (ir = 0; ir < 3; ir++)
2210         {
2211           enum elf_mips_reloc_type type;
2212
2213           switch (ir)
2214             {
2215             default:
2216               abort ();
2217             case 0:
2218               type = (enum elf_mips_reloc_type) rela.r_type;
2219               break;
2220             case 1:
2221               type = (enum elf_mips_reloc_type) rela.r_type2;
2222               break;
2223             case 2:
2224               type = (enum elf_mips_reloc_type) rela.r_type3;
2225               break;
2226             }
2227
2228           /* Some types require symbols, whereas some do not.  */
2229           switch (type)
2230             {
2231             case R_MIPS_NONE:
2232             case R_MIPS_LITERAL:
2233             case R_MIPS_INSERT_A:
2234             case R_MIPS_INSERT_B:
2235             case R_MIPS_DELETE:
2236               relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2237               break;
2238
2239             default:
2240               if (! used_sym)
2241                 {
2242                   if (rela.r_sym == 0)
2243                     relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2244                   else
2245                     {
2246                       asymbol **ps, *s;
2247
2248                       ps = symbols + rela.r_sym - 1;
2249                       s = *ps;
2250                       if ((s->flags & BSF_SECTION_SYM) == 0)
2251                         relent->sym_ptr_ptr = ps;
2252                       else
2253                         relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
2254                     }
2255
2256                   used_sym = TRUE;
2257                 }
2258               else if (! used_ssym)
2259                 {
2260                   switch (rela.r_ssym)
2261                     {
2262                     case RSS_UNDEF:
2263                       relent->sym_ptr_ptr =
2264                         bfd_abs_section_ptr->symbol_ptr_ptr;
2265                       break;
2266
2267                     case RSS_GP:
2268                     case RSS_GP0:
2269                     case RSS_LOC:
2270                       /* FIXME: I think these need to be handled using
2271                          special howto structures.  */
2272                       BFD_ASSERT (0);
2273                       break;
2274
2275                     default:
2276                       BFD_ASSERT (0);
2277                       break;
2278                     }
2279
2280                   used_ssym = TRUE;
2281                 }
2282               else
2283                 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2284
2285               break;
2286             }
2287
2288           /* The address of an ELF reloc is section relative for an
2289              object file, and absolute for an executable file or
2290              shared library.  The address of a BFD reloc is always
2291              section relative.  */
2292           if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
2293             relent->address = rela.r_offset;
2294           else
2295             relent->address = rela.r_offset - asect->vma;
2296
2297           relent->addend = rela.r_addend;
2298
2299           relent->howto = &howto_table[(int) type];
2300
2301           ++relent;
2302         }
2303     }
2304
2305   asect->reloc_count += (relent - relents) / 3;
2306
2307   if (allocated != NULL)
2308     free (allocated);
2309
2310   return TRUE;
2311
2312  error_return:
2313   if (allocated != NULL)
2314     free (allocated);
2315   return FALSE;
2316 }
2317
2318 /* Read the relocations.  On Irix 6, there can be two reloc sections
2319    associated with a single data section.  This is copied from
2320    elfcode.h as well, with changes as small as accounting for 3
2321    internal relocs per external reloc and resetting reloc_count to
2322    zero before processing the relocs of a section.  */
2323
2324 static bfd_boolean
2325 mips_elf64_slurp_reloc_table (abfd, asect, symbols, dynamic)
2326      bfd *abfd;
2327      asection *asect;
2328      asymbol **symbols;
2329      bfd_boolean dynamic;
2330 {
2331   struct bfd_elf_section_data * const d = elf_section_data (asect);
2332   Elf_Internal_Shdr *rel_hdr;
2333   Elf_Internal_Shdr *rel_hdr2;
2334   bfd_size_type reloc_count;
2335   bfd_size_type reloc_count2;
2336   arelent *relents;
2337   bfd_size_type amt;
2338
2339   if (asect->relocation != NULL)
2340     return TRUE;
2341
2342   if (! dynamic)
2343     {
2344       if ((asect->flags & SEC_RELOC) == 0
2345           || asect->reloc_count == 0)
2346         return TRUE;
2347
2348       rel_hdr = &d->rel_hdr;
2349       reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2350       rel_hdr2 = d->rel_hdr2;
2351       reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
2352
2353       BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
2354       BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
2355                   || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
2356
2357     }
2358   else
2359     {
2360       /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
2361          case because relocations against this section may use the
2362          dynamic symbol table, and in that case bfd_section_from_shdr
2363          in elf.c does not update the RELOC_COUNT.  */
2364       if (asect->_raw_size == 0)
2365         return TRUE;
2366
2367       rel_hdr = &d->this_hdr;
2368       reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2369       rel_hdr2 = NULL;
2370       reloc_count2 = 0;
2371     }
2372
2373   /* Allocate space for 3 arelent structures for each Rel structure.  */
2374   amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
2375   relents = (arelent *) bfd_alloc (abfd, amt);
2376   if (relents == NULL)
2377     return FALSE;
2378
2379   /* The slurp_one_reloc_table routine increments reloc_count.  */
2380   asect->reloc_count = 0;
2381
2382   if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2383                                           rel_hdr, reloc_count,
2384                                           relents,
2385                                           symbols, dynamic))
2386     return FALSE;
2387   if (d->rel_hdr2 != NULL)
2388     {
2389       if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2390                                               rel_hdr2, reloc_count2,
2391                                               relents + reloc_count * 3,
2392                                               symbols, dynamic))
2393         return FALSE;
2394     }
2395
2396   asect->relocation = relents;
2397   return TRUE;
2398 }
2399
2400 /* Write out the relocations.  */
2401
2402 static void
2403 mips_elf64_write_relocs (abfd, sec, data)
2404      bfd *abfd;
2405      asection *sec;
2406      PTR data;
2407 {
2408   bfd_boolean *failedp = (bfd_boolean *) data;
2409   int count;
2410   Elf_Internal_Shdr *rel_hdr;
2411   unsigned int idx;
2412
2413   /* If we have already failed, don't do anything.  */
2414   if (*failedp)
2415     return;
2416
2417   if ((sec->flags & SEC_RELOC) == 0)
2418     return;
2419
2420   /* The linker backend writes the relocs out itself, and sets the
2421      reloc_count field to zero to inhibit writing them here.  Also,
2422      sometimes the SEC_RELOC flag gets set even when there aren't any
2423      relocs.  */
2424   if (sec->reloc_count == 0)
2425     return;
2426
2427   /* We can combine up to three relocs that refer to the same address
2428      if the latter relocs have no associated symbol.  */
2429   count = 0;
2430   for (idx = 0; idx < sec->reloc_count; idx++)
2431     {
2432       bfd_vma addr;
2433       unsigned int i;
2434
2435       ++count;
2436
2437       addr = sec->orelocation[idx]->address;
2438       for (i = 0; i < 2; i++)
2439         {
2440           arelent *r;
2441
2442           if (idx + 1 >= sec->reloc_count)
2443             break;
2444           r = sec->orelocation[idx + 1];
2445           if (r->address != addr
2446               || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2447               || (*r->sym_ptr_ptr)->value != 0)
2448             break;
2449
2450           /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
2451
2452           ++idx;
2453         }
2454     }
2455
2456   rel_hdr = &elf_section_data (sec)->rel_hdr;
2457
2458   /* Do the actual relocation.  */
2459
2460   if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
2461     mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
2462   else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
2463     mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
2464   else
2465     BFD_ASSERT (0);
2466 }
2467
2468 static void
2469 mips_elf64_write_rel (abfd, sec, rel_hdr, count, data)
2470      bfd *abfd;
2471      asection *sec;
2472      Elf_Internal_Shdr *rel_hdr;
2473      int *count;
2474      PTR data;
2475 {
2476   bfd_boolean *failedp = (bfd_boolean *) data;
2477   Elf64_Mips_External_Rel *ext_rel;
2478   unsigned int idx;
2479   asymbol *last_sym = 0;
2480   int last_sym_idx = 0;
2481
2482   rel_hdr->sh_size = (bfd_vma)(rel_hdr->sh_entsize * *count);
2483   rel_hdr->contents = (PTR) bfd_alloc (abfd, rel_hdr->sh_size);
2484   if (rel_hdr->contents == NULL)
2485     {
2486       *failedp = TRUE;
2487       return;
2488     }
2489
2490   ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
2491   for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
2492     {
2493       arelent *ptr;
2494       Elf64_Mips_Internal_Rela int_rel;
2495       asymbol *sym;
2496       int n;
2497       unsigned int i;
2498
2499       ptr = sec->orelocation[idx];
2500
2501       /* The address of an ELF reloc is section relative for an object
2502          file, and absolute for an executable file or shared library.
2503          The address of a BFD reloc is always section relative.  */
2504       if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2505         int_rel.r_offset = ptr->address;
2506       else
2507         int_rel.r_offset = ptr->address + sec->vma;
2508
2509       sym = *ptr->sym_ptr_ptr;
2510       if (sym == last_sym)
2511         n = last_sym_idx;
2512       else
2513         {
2514           last_sym = sym;
2515           n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2516           if (n < 0)
2517             {
2518               *failedp = TRUE;
2519               return;
2520             }
2521           last_sym_idx = n;
2522         }
2523
2524       int_rel.r_sym = n;
2525       int_rel.r_ssym = RSS_UNDEF;
2526
2527       if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2528           && ! _bfd_elf_validate_reloc (abfd, ptr))
2529         {
2530           *failedp = TRUE;
2531           return;
2532         }
2533
2534       int_rel.r_type = ptr->howto->type;
2535       int_rel.r_type2 = (int) R_MIPS_NONE;
2536       int_rel.r_type3 = (int) R_MIPS_NONE;
2537
2538       for (i = 0; i < 2; i++)
2539         {
2540           arelent *r;
2541
2542           if (idx + 1 >= sec->reloc_count)
2543             break;
2544           r = sec->orelocation[idx + 1];
2545           if (r->address != ptr->address
2546               || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2547               || (*r->sym_ptr_ptr)->value != 0)
2548             break;
2549
2550           /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
2551
2552           if (i == 0)
2553             int_rel.r_type2 = r->howto->type;
2554           else
2555             int_rel.r_type3 = r->howto->type;
2556
2557           ++idx;
2558         }
2559
2560       mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
2561     }
2562
2563   BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
2564               == *count);
2565 }
2566
2567 static void
2568 mips_elf64_write_rela (abfd, sec, rela_hdr, count, data)
2569      bfd *abfd;
2570      asection *sec;
2571      Elf_Internal_Shdr *rela_hdr;
2572      int *count;
2573      PTR data;
2574 {
2575   bfd_boolean *failedp = (bfd_boolean *) data;
2576   Elf64_Mips_External_Rela *ext_rela;
2577   unsigned int idx;
2578   asymbol *last_sym = 0;
2579   int last_sym_idx = 0;
2580
2581   rela_hdr->sh_size = (bfd_vma)(rela_hdr->sh_entsize * *count);
2582   rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
2583   if (rela_hdr->contents == NULL)
2584     {
2585       *failedp = TRUE;
2586       return;
2587     }
2588
2589   ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
2590   for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
2591     {
2592       arelent *ptr;
2593       Elf64_Mips_Internal_Rela int_rela;
2594       asymbol *sym;
2595       int n;
2596       unsigned int i;
2597
2598       ptr = sec->orelocation[idx];
2599
2600       /* The address of an ELF reloc is section relative for an object
2601          file, and absolute for an executable file or shared library.
2602          The address of a BFD reloc is always section relative.  */
2603       if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2604         int_rela.r_offset = ptr->address;
2605       else
2606         int_rela.r_offset = ptr->address + sec->vma;
2607
2608       sym = *ptr->sym_ptr_ptr;
2609       if (sym == last_sym)
2610         n = last_sym_idx;
2611       else
2612         {
2613           last_sym = sym;
2614           n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2615           if (n < 0)
2616             {
2617               *failedp = TRUE;
2618               return;
2619             }
2620           last_sym_idx = n;
2621         }
2622
2623       int_rela.r_sym = n;
2624       int_rela.r_addend = ptr->addend;
2625       int_rela.r_ssym = RSS_UNDEF;
2626
2627       if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2628           && ! _bfd_elf_validate_reloc (abfd, ptr))
2629         {
2630           *failedp = TRUE;
2631           return;
2632         }
2633
2634       int_rela.r_type = ptr->howto->type;
2635       int_rela.r_type2 = (int) R_MIPS_NONE;
2636       int_rela.r_type3 = (int) R_MIPS_NONE;
2637
2638       for (i = 0; i < 2; i++)
2639         {
2640           arelent *r;
2641
2642           if (idx + 1 >= sec->reloc_count)
2643             break;
2644           r = sec->orelocation[idx + 1];
2645           if (r->address != ptr->address
2646               || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2647               || (*r->sym_ptr_ptr)->value != 0)
2648             break;
2649
2650           /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
2651
2652           if (i == 0)
2653             int_rela.r_type2 = r->howto->type;
2654           else
2655             int_rela.r_type3 = r->howto->type;
2656
2657           ++idx;
2658         }
2659
2660       mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
2661     }
2662
2663   BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
2664               == *count);
2665 }
2666 \f
2667 /* Set the right machine number for a MIPS ELF file.  */
2668
2669 static bfd_boolean
2670 mips_elf64_object_p (abfd)
2671      bfd *abfd;
2672 {
2673   unsigned long mach;
2674
2675   /* Irix 6 is broken.  Object file symbol tables are not always
2676      sorted correctly such that local symbols precede global symbols,
2677      and the sh_info field in the symbol table is not always right.  */
2678   if (elf64_mips_irix_compat (abfd) != ict_none)
2679     elf_bad_symtab (abfd) = TRUE;
2680
2681   mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
2682   bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
2683   return TRUE;
2684 }
2685
2686 /* Depending on the target vector we generate some version of Irix
2687    executables or "normal" MIPS ELF ABI executables.  */
2688 static irix_compat_t
2689 elf64_mips_irix_compat (abfd)
2690      bfd *abfd;
2691 {
2692   if ((abfd->xvec == &bfd_elf64_bigmips_vec)
2693       || (abfd->xvec == &bfd_elf64_littlemips_vec))
2694     return ict_irix6;
2695   else
2696     return ict_none;
2697 }
2698 \f
2699 /* Support for core dump NOTE sections.  */
2700 static bfd_boolean
2701 elf64_mips_grok_prstatus (abfd, note)
2702      bfd *abfd;
2703      Elf_Internal_Note *note;
2704 {
2705   int offset;
2706   unsigned int raw_size;
2707
2708   switch (note->descsz)
2709     {
2710       default:
2711         return FALSE;
2712
2713       case 480:         /* Linux/MIPS - N64 kernel */
2714         /* pr_cursig */
2715         elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
2716
2717         /* pr_pid */
2718         elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 32);
2719
2720         /* pr_reg */
2721         offset = 112;
2722         raw_size = 360;
2723
2724         break;
2725     }
2726
2727   /* Make a ".reg/999" section.  */
2728   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
2729                                           raw_size, note->descpos + offset);
2730 }
2731
2732 static bfd_boolean
2733 elf64_mips_grok_psinfo (abfd, note)
2734      bfd *abfd;
2735      Elf_Internal_Note *note;
2736 {
2737   switch (note->descsz)
2738     {
2739       default:
2740         return FALSE;
2741
2742       case 136:         /* Linux/MIPS - N64 kernel elf_prpsinfo */
2743         elf_tdata (abfd)->core_program
2744          = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
2745         elf_tdata (abfd)->core_command
2746          = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
2747     }
2748
2749   /* Note that for some reason, a spurious space is tacked
2750      onto the end of the args in some (at least one anyway)
2751      implementations, so strip it off if it exists.  */
2752
2753   {
2754     char *command = elf_tdata (abfd)->core_command;
2755     int n = strlen (command);
2756
2757     if (0 < n && command[n - 1] == ' ')
2758       command[n - 1] = '\0';
2759   }
2760
2761   return TRUE;
2762 }
2763 \f
2764 /* ECOFF swapping routines.  These are used when dealing with the
2765    .mdebug section, which is in the ECOFF debugging format.  */
2766 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
2767 {
2768   /* Symbol table magic number.  */
2769   magicSym2,
2770   /* Alignment of debugging information.  E.g., 4.  */
2771   8,
2772   /* Sizes of external symbolic information.  */
2773   sizeof (struct hdr_ext),
2774   sizeof (struct dnr_ext),
2775   sizeof (struct pdr_ext),
2776   sizeof (struct sym_ext),
2777   sizeof (struct opt_ext),
2778   sizeof (struct fdr_ext),
2779   sizeof (struct rfd_ext),
2780   sizeof (struct ext_ext),
2781   /* Functions to swap in external symbolic data.  */
2782   ecoff_swap_hdr_in,
2783   ecoff_swap_dnr_in,
2784   ecoff_swap_pdr_in,
2785   ecoff_swap_sym_in,
2786   ecoff_swap_opt_in,
2787   ecoff_swap_fdr_in,
2788   ecoff_swap_rfd_in,
2789   ecoff_swap_ext_in,
2790   _bfd_ecoff_swap_tir_in,
2791   _bfd_ecoff_swap_rndx_in,
2792   /* Functions to swap out external symbolic data.  */
2793   ecoff_swap_hdr_out,
2794   ecoff_swap_dnr_out,
2795   ecoff_swap_pdr_out,
2796   ecoff_swap_sym_out,
2797   ecoff_swap_opt_out,
2798   ecoff_swap_fdr_out,
2799   ecoff_swap_rfd_out,
2800   ecoff_swap_ext_out,
2801   _bfd_ecoff_swap_tir_out,
2802   _bfd_ecoff_swap_rndx_out,
2803   /* Function to read in symbolic data.  */
2804   _bfd_mips_elf_read_ecoff_info
2805 };
2806 \f
2807 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
2808    standard ELF.  This structure is used to redirect the relocation
2809    handling routines.  */
2810
2811 const struct elf_size_info mips_elf64_size_info =
2812 {
2813   sizeof (Elf64_External_Ehdr),
2814   sizeof (Elf64_External_Phdr),
2815   sizeof (Elf64_External_Shdr),
2816   sizeof (Elf64_Mips_External_Rel),
2817   sizeof (Elf64_Mips_External_Rela),
2818   sizeof (Elf64_External_Sym),
2819   sizeof (Elf64_External_Dyn),
2820   sizeof (Elf_External_Note),
2821   4,            /* hash-table entry size */
2822   3,            /* internal relocations per external relocations */
2823   64,           /* arch_size */
2824   3,            /* log_file_align */
2825   ELFCLASS64,
2826   EV_CURRENT,
2827   bfd_elf64_write_out_phdrs,
2828   bfd_elf64_write_shdrs_and_ehdr,
2829   mips_elf64_write_relocs,
2830   bfd_elf64_swap_symbol_in,
2831   bfd_elf64_swap_symbol_out,
2832   mips_elf64_slurp_reloc_table,
2833   bfd_elf64_slurp_symbol_table,
2834   bfd_elf64_swap_dyn_in,
2835   bfd_elf64_swap_dyn_out,
2836   mips_elf64_be_swap_reloc_in,
2837   mips_elf64_be_swap_reloc_out,
2838   mips_elf64_be_swap_reloca_in,
2839   mips_elf64_be_swap_reloca_out
2840 };
2841
2842 #define ELF_ARCH                        bfd_arch_mips
2843 #define ELF_MACHINE_CODE                EM_MIPS
2844
2845 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
2846    a value of 0x1000, and we are compatible.
2847    FIXME: How does this affect NewABI?  */
2848 #define ELF_MAXPAGESIZE                 0x1000
2849
2850 #define elf_backend_collect             TRUE
2851 #define elf_backend_type_change_ok      TRUE
2852 #define elf_backend_can_gc_sections     TRUE
2853 #define elf_info_to_howto               mips_elf64_info_to_howto_rela
2854 #define elf_info_to_howto_rel           mips_elf64_info_to_howto_rel
2855 #define elf_backend_object_p            mips_elf64_object_p
2856 #define elf_backend_symbol_processing   _bfd_mips_elf_symbol_processing
2857 #define elf_backend_section_processing  _bfd_mips_elf_section_processing
2858 #define elf_backend_section_from_shdr   _bfd_mips_elf_section_from_shdr
2859 #define elf_backend_fake_sections       _bfd_mips_elf_fake_sections
2860 #define elf_backend_section_from_bfd_section \
2861                                 _bfd_mips_elf_section_from_bfd_section
2862 #define elf_backend_add_symbol_hook     _bfd_mips_elf_add_symbol_hook
2863 #define elf_backend_link_output_symbol_hook \
2864                                 _bfd_mips_elf_link_output_symbol_hook
2865 #define elf_backend_create_dynamic_sections \
2866                                 _bfd_mips_elf_create_dynamic_sections
2867 #define elf_backend_check_relocs        _bfd_mips_elf_check_relocs
2868 #define elf_backend_adjust_dynamic_symbol \
2869                                 _bfd_mips_elf_adjust_dynamic_symbol
2870 #define elf_backend_always_size_sections \
2871                                 _bfd_mips_elf_always_size_sections
2872 #define elf_backend_size_dynamic_sections \
2873                                 _bfd_mips_elf_size_dynamic_sections
2874 #define elf_backend_relocate_section    _bfd_mips_elf_relocate_section
2875 #define elf_backend_finish_dynamic_symbol \
2876                                 _bfd_mips_elf_finish_dynamic_symbol
2877 #define elf_backend_finish_dynamic_sections \
2878                                 _bfd_mips_elf_finish_dynamic_sections
2879 #define elf_backend_final_write_processing \
2880                                 _bfd_mips_elf_final_write_processing
2881 #define elf_backend_additional_program_headers \
2882                                 _bfd_mips_elf_additional_program_headers
2883 #define elf_backend_modify_segment_map  _bfd_mips_elf_modify_segment_map
2884 #define elf_backend_gc_mark_hook        _bfd_mips_elf_gc_mark_hook
2885 #define elf_backend_gc_sweep_hook       _bfd_mips_elf_gc_sweep_hook
2886 #define elf_backend_hide_symbol         _bfd_mips_elf_hide_symbol
2887 #define elf_backend_ignore_discarded_relocs \
2888                                         _bfd_mips_elf_ignore_discarded_relocs
2889 #define elf_backend_mips_irix_compat    elf64_mips_irix_compat
2890 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
2891 #define elf_backend_ecoff_debug_swap    &mips_elf64_ecoff_debug_swap
2892 #define elf_backend_size_info           mips_elf64_size_info
2893
2894 #define elf_backend_grok_prstatus       elf64_mips_grok_prstatus
2895 #define elf_backend_grok_psinfo         elf64_mips_grok_psinfo
2896
2897 #define elf_backend_got_header_size     (4 * MIPS_RESERVED_GOTNO)
2898 #define elf_backend_plt_header_size     0
2899
2900 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
2901    work better/work only in RELA, so we default to this.  */
2902 #define elf_backend_may_use_rel_p       1
2903 #define elf_backend_may_use_rela_p      1
2904 #define elf_backend_default_use_rela_p  1
2905
2906 #define elf_backend_write_section       _bfd_mips_elf_write_section
2907
2908 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
2909    MIPS-specific function only applies to IRIX5, which had no 64-bit
2910    ABI.  */
2911 #define bfd_elf64_find_nearest_line     _bfd_mips_elf_find_nearest_line
2912 #define bfd_elf64_new_section_hook      _bfd_mips_elf_new_section_hook
2913 #define bfd_elf64_set_section_contents  _bfd_mips_elf_set_section_contents
2914 #define bfd_elf64_bfd_get_relocated_section_contents \
2915                                 _bfd_elf_mips_get_relocated_section_contents
2916 #define bfd_elf64_bfd_link_hash_table_create \
2917                                 _bfd_mips_elf_link_hash_table_create
2918 #define bfd_elf64_bfd_final_link        _bfd_mips_elf_final_link
2919 #define bfd_elf64_bfd_merge_private_bfd_data \
2920                                 _bfd_mips_elf_merge_private_bfd_data
2921 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
2922 #define bfd_elf64_bfd_print_private_bfd_data \
2923                                 _bfd_mips_elf_print_private_bfd_data
2924
2925 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
2926 #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
2927 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
2928 #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
2929 #define bfd_elf64_bfd_relax_section     _bfd_mips_relax_section
2930
2931 /* MIPS ELF64 archive functions.  */
2932 #define bfd_elf64_archive_functions
2933 extern bfd_boolean bfd_elf64_archive_slurp_armap
2934   PARAMS ((bfd *));
2935 extern bfd_boolean bfd_elf64_archive_write_armap
2936   PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
2937 #define bfd_elf64_archive_slurp_extended_name_table \
2938                         _bfd_archive_coff_slurp_extended_name_table
2939 #define bfd_elf64_archive_construct_extended_name_table \
2940                         _bfd_archive_coff_construct_extended_name_table
2941 #define bfd_elf64_archive_truncate_arname \
2942                         _bfd_archive_coff_truncate_arname
2943 #define bfd_elf64_archive_read_ar_hdr   _bfd_archive_coff_read_ar_hdr
2944 #define bfd_elf64_archive_openr_next_archived_file \
2945                         _bfd_archive_coff_openr_next_archived_file
2946 #define bfd_elf64_archive_get_elt_at_index \
2947                         _bfd_archive_coff_get_elt_at_index
2948 #define bfd_elf64_archive_generic_stat_arch_elt \
2949                         _bfd_archive_coff_generic_stat_arch_elt
2950 #define bfd_elf64_archive_update_armap_timestamp \
2951                         _bfd_archive_coff_update_armap_timestamp
2952
2953 /* The SGI style (n)64 NewABI.  */
2954 #define TARGET_LITTLE_SYM               bfd_elf64_littlemips_vec
2955 #define TARGET_LITTLE_NAME              "elf64-littlemips"
2956 #define TARGET_BIG_SYM                  bfd_elf64_bigmips_vec
2957 #define TARGET_BIG_NAME                 "elf64-bigmips"
2958
2959 #include "elf64-target.h"
2960
2961 #define INCLUDED_TARGET_FILE            /* More a type of flag.  */
2962
2963 /* The SYSV-style 'traditional' (n)64 NewABI.  */
2964 #undef TARGET_LITTLE_SYM
2965 #undef TARGET_LITTLE_NAME
2966 #undef TARGET_BIG_SYM
2967 #undef TARGET_BIG_NAME
2968
2969 #define TARGET_LITTLE_SYM               bfd_elf64_tradlittlemips_vec
2970 #define TARGET_LITTLE_NAME              "elf64-tradlittlemips"
2971 #define TARGET_BIG_SYM                  bfd_elf64_tradbigmips_vec
2972 #define TARGET_BIG_NAME                 "elf64-tradbigmips"
2973
2974 /* Include the target file again for this target.  */
2975 #include "elf64-target.h"