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