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