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