* Makefile.am: split up BFD_LIBS like statements in BFD32_LIBS and
[external/binutils.git] / bfd / elf64-mips.c
1 /* MIPS-specific support for 64-bit ELF
2    Copyright 1996, 1997, 1998, 1999, 2000, 2001
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 #include "bfd.h"
31 #include "sysdep.h"
32 #include "libbfd.h"
33 #include "aout/ar.h"
34 #include "bfdlink.h"
35 #include "genlink.h"
36 #include "elf-bfd.h"
37 #include "elf/mips.h"
38
39 /* Get the ECOFF swapping routines.  The 64-bit ABI is not supposed to
40    use ECOFF.  However, we support it anyhow for an easier changeover.  */
41 #include "coff/sym.h"
42 #include "coff/symconst.h"
43 #include "coff/internal.h"
44 #include "coff/ecoff.h"
45 /* The 64 bit versions of the mdebug data structures are in alpha.h.  */
46 #include "coff/alpha.h"
47 #define ECOFF_SIGNED_64
48 #include "ecoffswap.h"
49
50 static void mips_elf64_swap_reloc_in
51   PARAMS ((bfd *, const Elf64_Mips_External_Rel *,
52            Elf64_Mips_Internal_Rel *));
53 static void mips_elf64_swap_reloca_in
54   PARAMS ((bfd *, const Elf64_Mips_External_Rela *,
55            Elf64_Mips_Internal_Rela *));
56 static void mips_elf64_swap_reloc_out
57   PARAMS ((bfd *, const Elf64_Mips_Internal_Rel *,
58            Elf64_Mips_External_Rel *));
59 static void mips_elf64_swap_reloca_out
60   PARAMS ((bfd *, const Elf64_Mips_Internal_Rela *,
61            Elf64_Mips_External_Rela *));
62 static void mips_elf64_be_swap_reloc_in
63   PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rel *));
64 static void mips_elf64_be_swap_reloc_out
65   PARAMS ((bfd *, const Elf_Internal_Rel *, bfd_byte *));
66 static void mips_elf64_be_swap_reloca_in
67   PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *));
68 static void mips_elf64_be_swap_reloca_out
69   PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *));
70 static reloc_howto_type *mips_elf64_reloc_type_lookup
71   PARAMS ((bfd *, bfd_reloc_code_real_type));
72 static long mips_elf64_get_reloc_upper_bound PARAMS ((bfd *, asection *));
73 static boolean mips_elf64_slurp_one_reloc_table
74   PARAMS ((bfd *, asection *, asymbol **, const Elf_Internal_Shdr *));
75 static boolean mips_elf64_slurp_reloc_table
76   PARAMS ((bfd *, asection *, asymbol **, boolean));
77 static void mips_elf64_write_relocs PARAMS ((bfd *, asection *, PTR));
78
79 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
80    from smaller values.  Start with zero, widen, *then* decrement.  */
81 #define MINUS_ONE       (((bfd_vma)0) - 1)
82
83 /* The number of local .got entries we reserve.  */
84 #define MIPS_RESERVED_GOTNO (2)
85
86 /* The relocation table used for SHT_REL sections.  */
87
88 #define UNUSED_RELOC(num) { num, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
89
90 static reloc_howto_type mips_elf64_howto_table_rel[] =
91 {
92   /* No relocation.  */
93   HOWTO (R_MIPS_NONE,           /* type */
94          0,                     /* rightshift */
95          0,                     /* size (0 = byte, 1 = short, 2 = long) */
96          0,                     /* bitsize */
97          false,                 /* pc_relative */
98          0,                     /* bitpos */
99          complain_overflow_dont, /* complain_on_overflow */
100          bfd_elf_generic_reloc, /* special_function */
101          "R_MIPS_NONE",         /* name */
102          false,                 /* partial_inplace */
103          0,                     /* src_mask */
104          0,                     /* dst_mask */
105          false),                /* pcrel_offset */
106
107   /* 16 bit relocation.  */
108   HOWTO (R_MIPS_16,             /* type */
109          0,                     /* rightshift */
110          1,                     /* size (0 = byte, 1 = short, 2 = long) */
111          16,                    /* bitsize */
112          false,                 /* pc_relative */
113          0,                     /* bitpos */
114          complain_overflow_bitfield, /* complain_on_overflow */
115          bfd_elf_generic_reloc, /* special_function */
116          "R_MIPS_16",           /* name */
117          true,                  /* partial_inplace */
118          0xffff,                /* src_mask */
119          0xffff,                /* dst_mask */
120          false),                /* pcrel_offset */
121
122   /* 32 bit relocation.  */
123   HOWTO (R_MIPS_32,             /* type */
124          0,                     /* rightshift */
125          2,                     /* size (0 = byte, 1 = short, 2 = long) */
126          32,                    /* bitsize */
127          false,                 /* pc_relative */
128          0,                     /* bitpos */
129          complain_overflow_dont, /* complain_on_overflow */
130          bfd_elf_generic_reloc, /* special_function */
131          "R_MIPS_32",           /* name */
132          true,                  /* partial_inplace */
133          0xffffffff,            /* src_mask */
134          0xffffffff,            /* dst_mask */
135          false),                /* pcrel_offset */
136
137   /* 32 bit symbol relative relocation.  */
138   HOWTO (R_MIPS_REL32,          /* type */
139          0,                     /* rightshift */
140          2,                     /* size (0 = byte, 1 = short, 2 = long) */
141          32,                    /* bitsize */
142          false,                 /* pc_relative */
143          0,                     /* bitpos */
144          complain_overflow_dont, /* complain_on_overflow */
145          bfd_elf_generic_reloc, /* special_function */
146          "R_MIPS_REL32",        /* name */
147          true,                  /* partial_inplace */
148          0xffffffff,            /* src_mask */
149          0xffffffff,            /* dst_mask */
150          false),                /* pcrel_offset */
151
152   /* 26 bit jump address.  */
153   HOWTO (R_MIPS_26,             /* type */
154          2,                     /* rightshift */
155          2,                     /* size (0 = byte, 1 = short, 2 = long) */
156          26,                    /* bitsize */
157          false,                 /* pc_relative */
158          0,                     /* bitpos */
159          complain_overflow_dont, /* complain_on_overflow */
160                                 /* This needs complex overflow
161                                    detection, because the upper 36
162                                    bits must match the PC + 4.  */
163          bfd_elf_generic_reloc, /* special_function */
164          "R_MIPS_26",           /* name */
165          true,                  /* partial_inplace */
166          0x3ffffff,             /* src_mask */
167          0x3ffffff,             /* dst_mask */
168          false),                /* pcrel_offset */
169
170   /* High 16 bits of symbol value.  */
171   HOWTO (R_MIPS_HI16,           /* type */
172          0,                     /* rightshift */
173          2,                     /* size (0 = byte, 1 = short, 2 = long) */
174          16,                    /* bitsize */
175          false,                 /* pc_relative */
176          0,                     /* bitpos */
177          complain_overflow_dont, /* complain_on_overflow */
178          _bfd_mips_elf_hi16_reloc,      /* special_function */
179          "R_MIPS_HI16",         /* name */
180          true,                  /* partial_inplace */
181          0xffff,                /* src_mask */
182          0xffff,                /* dst_mask */
183          false),                /* pcrel_offset */
184
185   /* Low 16 bits of symbol value.  */
186   HOWTO (R_MIPS_LO16,           /* type */
187          0,                     /* rightshift */
188          2,                     /* size (0 = byte, 1 = short, 2 = long) */
189          16,                    /* bitsize */
190          false,                 /* pc_relative */
191          0,                     /* bitpos */
192          complain_overflow_dont, /* complain_on_overflow */
193          _bfd_mips_elf_lo16_reloc,      /* special_function */
194          "R_MIPS_LO16",         /* name */
195          true,                  /* partial_inplace */
196          0xffff,                /* src_mask */
197          0xffff,                /* dst_mask */
198          false),                /* pcrel_offset */
199
200   /* GP relative reference.  */
201   HOWTO (R_MIPS_GPREL16,        /* type */
202          0,                     /* rightshift */
203          2,                     /* size (0 = byte, 1 = short, 2 = long) */
204          16,                    /* bitsize */
205          false,                 /* pc_relative */
206          0,                     /* bitpos */
207          complain_overflow_signed, /* complain_on_overflow */
208          _bfd_mips_elf_gprel16_reloc, /* special_function */
209          "R_MIPS_GPREL16",      /* name */
210          true,                  /* partial_inplace */
211          0xffff,                /* src_mask */
212          0xffff,                /* dst_mask */
213          false),                /* pcrel_offset */
214
215   /* Reference to literal section.  */
216   HOWTO (R_MIPS_LITERAL,        /* type */
217          0,                     /* rightshift */
218          2,                     /* size (0 = byte, 1 = short, 2 = long) */
219          16,                    /* bitsize */
220          false,                 /* pc_relative */
221          0,                     /* bitpos */
222          complain_overflow_signed, /* complain_on_overflow */
223          _bfd_mips_elf_gprel16_reloc, /* special_function */
224          "R_MIPS_LITERAL",      /* name */
225          true,                  /* partial_inplace */
226          0xffff,                /* src_mask */
227          0xffff,                /* dst_mask */
228          false),                /* pcrel_offset */
229
230   /* Reference to global offset table.  */
231   HOWTO (R_MIPS_GOT16,          /* type */
232          0,                     /* rightshift */
233          2,                     /* size (0 = byte, 1 = short, 2 = long) */
234          16,                    /* bitsize */
235          false,                 /* pc_relative */
236          0,                     /* bitpos */
237          complain_overflow_signed, /* complain_on_overflow */
238          _bfd_mips_elf_got16_reloc,     /* special_function */
239          "R_MIPS_GOT16",        /* name */
240          false,                 /* partial_inplace */
241          0,                     /* src_mask */
242          0xffff,                /* dst_mask */
243          false),                /* pcrel_offset */
244
245   /* 16 bit PC relative reference.  */
246   HOWTO (R_MIPS_PC16,           /* type */
247          0,                     /* rightshift */
248          2,                     /* size (0 = byte, 1 = short, 2 = long) */
249          16,                    /* bitsize */
250          true,                  /* pc_relative */
251          0,                     /* bitpos */
252          complain_overflow_signed, /* complain_on_overflow */
253          bfd_elf_generic_reloc, /* special_function */
254          "R_MIPS_PC16",         /* name */
255          true,                  /* partial_inplace */
256          0xffff,                /* src_mask */
257          0xffff,                /* dst_mask */
258          false),                /* pcrel_offset */
259
260   /* 16 bit call through global offset table.  */
261   /* FIXME: This is not handled correctly.  */
262   HOWTO (R_MIPS_CALL16,         /* type */
263          0,                     /* rightshift */
264          2,                     /* size (0 = byte, 1 = short, 2 = long) */
265          16,                    /* bitsize */
266          false,                 /* pc_relative */
267          0,                     /* bitpos */
268          complain_overflow_signed, /* complain_on_overflow */
269          bfd_elf_generic_reloc, /* special_function */
270          "R_MIPS_CALL16",       /* name */
271          false,                 /* partial_inplace */
272          0,                     /* src_mask */
273          0xffff,                /* dst_mask */
274          false),                /* pcrel_offset */
275
276   /* 32 bit GP relative reference.  */
277   HOWTO (R_MIPS_GPREL32,        /* type */
278          0,                     /* rightshift */
279          2,                     /* size (0 = byte, 1 = short, 2 = long) */
280          32,                    /* bitsize */
281          false,                 /* pc_relative */
282          0,                     /* bitpos */
283          complain_overflow_bitfield, /* complain_on_overflow */
284          _bfd_mips_elf_gprel32_reloc, /* special_function */
285          "R_MIPS_GPREL32",      /* name */
286          true,                  /* partial_inplace */
287          0xffffffff,            /* src_mask */
288          0xffffffff,            /* dst_mask */
289          false),                /* pcrel_offset */
290
291   UNUSED_RELOC (13),
292   UNUSED_RELOC (14),
293   UNUSED_RELOC (15),
294
295   /* A 5 bit shift field.  */
296   HOWTO (R_MIPS_SHIFT5,         /* type */
297          0,                     /* rightshift */
298          2,                     /* size (0 = byte, 1 = short, 2 = long) */
299          5,                     /* bitsize */
300          false,                 /* pc_relative */
301          6,                     /* bitpos */
302          complain_overflow_bitfield, /* complain_on_overflow */
303          bfd_elf_generic_reloc, /* special_function */
304          "R_MIPS_SHIFT5",       /* name */
305          true,                  /* partial_inplace */
306          0x000007c0,            /* src_mask */
307          0x000007c0,            /* dst_mask */
308          false),                /* pcrel_offset */
309
310   /* A 6 bit shift field.  */
311   /* FIXME: This is not handled correctly; a special function is
312      needed to put the most significant bit in the right place.  */
313   HOWTO (R_MIPS_SHIFT6,         /* type */
314          0,                     /* rightshift */
315          2,                     /* size (0 = byte, 1 = short, 2 = long) */
316          6,                     /* bitsize */
317          false,                 /* pc_relative */
318          6,                     /* bitpos */
319          complain_overflow_bitfield, /* complain_on_overflow */
320          bfd_elf_generic_reloc, /* special_function */
321          "R_MIPS_SHIFT6",       /* name */
322          true,                  /* partial_inplace */
323          0x000007c4,            /* src_mask */
324          0x000007c4,            /* dst_mask */
325          false),                /* pcrel_offset */
326
327   /* 64 bit relocation.  */
328   HOWTO (R_MIPS_64,             /* type */
329          0,                     /* rightshift */
330          4,                     /* size (0 = byte, 1 = short, 2 = long) */
331          64,                    /* bitsize */
332          false,                 /* pc_relative */
333          0,                     /* bitpos */
334          complain_overflow_dont, /* complain_on_overflow */
335          bfd_elf_generic_reloc, /* special_function */
336          "R_MIPS_64",           /* name */
337          true,                  /* partial_inplace */
338          MINUS_ONE,             /* src_mask */
339          MINUS_ONE,             /* dst_mask */
340          false),                /* pcrel_offset */
341
342   /* Displacement in the global offset table.  */
343   /* FIXME: Not handled correctly.  */
344   HOWTO (R_MIPS_GOT_DISP,       /* type */
345          0,                     /* rightshift */
346          2,                     /* size (0 = byte, 1 = short, 2 = long) */
347          16,                    /* bitsize */
348          false,                 /* pc_relative */
349          0,                     /* bitpos */
350          complain_overflow_signed, /* complain_on_overflow */
351          bfd_elf_generic_reloc, /* special_function */
352          "R_MIPS_GOT_DISP",     /* name */
353          false,                 /* partial_inplace */
354          0x0000ffff,            /* src_mask */
355          0x0000ffff,            /* dst_mask */
356          false),                /* pcrel_offset */
357
358   /* Displacement to page pointer in the global offset table.  */
359   /* FIXME: Not handled correctly.  */
360   HOWTO (R_MIPS_GOT_PAGE,       /* type */
361          0,                     /* rightshift */
362          2,                     /* size (0 = byte, 1 = short, 2 = long) */
363          16,                    /* bitsize */
364          false,                 /* pc_relative */
365          0,                     /* bitpos */
366          complain_overflow_signed, /* complain_on_overflow */
367          bfd_elf_generic_reloc, /* special_function */
368          "R_MIPS_GOT_PAGE",     /* name */
369          false,                 /* partial_inplace */
370          0x0000ffff,            /* src_mask */
371          0x0000ffff,            /* dst_mask */
372          false),                /* pcrel_offset */
373
374   /* Offset from page pointer in the global offset table.  */
375   /* FIXME: Not handled correctly.  */
376   HOWTO (R_MIPS_GOT_OFST,       /* type */
377          0,                     /* rightshift */
378          2,                     /* size (0 = byte, 1 = short, 2 = long) */
379          16,                    /* bitsize */
380          false,                 /* pc_relative */
381          0,                     /* bitpos */
382          complain_overflow_signed, /* complain_on_overflow */
383          bfd_elf_generic_reloc, /* special_function */
384          "R_MIPS_GOT_OFST",     /* name */
385          false,                 /* partial_inplace */
386          0x0000ffff,            /* src_mask */
387          0x0000ffff,            /* dst_mask */
388          false),                /* pcrel_offset */
389
390   /* High 16 bits of displacement in global offset table.  */
391   /* FIXME: Not handled correctly.  */
392   HOWTO (R_MIPS_GOT_HI16,       /* type */
393          0,                     /* rightshift */
394          2,                     /* size (0 = byte, 1 = short, 2 = long) */
395          16,                    /* bitsize */
396          false,                 /* pc_relative */
397          0,                     /* bitpos */
398          complain_overflow_dont, /* complain_on_overflow */
399          bfd_elf_generic_reloc, /* special_function */
400          "R_MIPS_GOT_HI16",     /* name */
401          false,                 /* partial_inplace */
402          0x0000ffff,            /* src_mask */
403          0x0000ffff,            /* dst_mask */
404          false),                /* pcrel_offset */
405
406   /* Low 16 bits of displacement in global offset table.  */
407   /* FIXME: Not handled correctly.  */
408   HOWTO (R_MIPS_GOT_LO16,       /* type */
409          0,                     /* rightshift */
410          2,                     /* size (0 = byte, 1 = short, 2 = long) */
411          16,                    /* bitsize */
412          false,                 /* pc_relative */
413          0,                     /* bitpos */
414          complain_overflow_dont, /* complain_on_overflow */
415          bfd_elf_generic_reloc, /* special_function */
416          "R_MIPS_GOT_LO16",     /* name */
417          false,                 /* partial_inplace */
418          0x0000ffff,            /* src_mask */
419          0x0000ffff,            /* dst_mask */
420          false),                /* pcrel_offset */
421
422   /* 64 bit substraction.  */
423   /* FIXME: Not handled correctly.  */
424   HOWTO (R_MIPS_SUB,            /* type */
425          0,                     /* rightshift */
426          4,                     /* size (0 = byte, 1 = short, 2 = long) */
427          64,                    /* bitsize */
428          false,                 /* pc_relative */
429          0,                     /* bitpos */
430          complain_overflow_dont, /* complain_on_overflow */
431          bfd_elf_generic_reloc, /* special_function */
432          "R_MIPS_SUB",          /* name */
433          true,                  /* partial_inplace */
434          MINUS_ONE,             /* src_mask */
435          MINUS_ONE,             /* dst_mask */
436          false),                /* pcrel_offset */
437
438   /* Insert the addend as an instruction.  */
439   /* FIXME: Not handled correctly.  */
440   HOWTO (R_MIPS_INSERT_A,       /* type */
441          0,                     /* rightshift */
442          2,                     /* size (0 = byte, 1 = short, 2 = long) */
443          32,                    /* bitsize */
444          false,                 /* pc_relative */
445          0,                     /* bitpos */
446          complain_overflow_dont, /* complain_on_overflow */
447          bfd_elf_generic_reloc, /* special_function */
448          "R_MIPS_INSERT_A",     /* name */
449          true,                  /* partial_inplace */
450          0xffffffff,            /* src_mask */
451          0xffffffff,            /* dst_mask */
452          false),                /* pcrel_offset */
453
454   /* Insert the addend as an instruction, and change all relocations
455      to refer to the old instruction at the address.  */
456   /* FIXME: Not handled correctly.  */
457   HOWTO (R_MIPS_INSERT_B,       /* type */
458          0,                     /* rightshift */
459          2,                     /* size (0 = byte, 1 = short, 2 = long) */
460          32,                    /* bitsize */
461          false,                 /* pc_relative */
462          0,                     /* bitpos */
463          complain_overflow_dont, /* complain_on_overflow */
464          bfd_elf_generic_reloc, /* special_function */
465          "R_MIPS_INSERT_B",     /* name */
466          true,                  /* partial_inplace */
467          0xffffffff,            /* src_mask */
468          0xffffffff,            /* dst_mask */
469          false),                /* pcrel_offset */
470
471   /* Delete a 32 bit instruction.  */
472   /* FIXME: Not handled correctly.  */
473   HOWTO (R_MIPS_DELETE,         /* type */
474          0,                     /* rightshift */
475          2,                     /* size (0 = byte, 1 = short, 2 = long) */
476          32,                    /* bitsize */
477          false,                 /* pc_relative */
478          0,                     /* bitpos */
479          complain_overflow_dont, /* complain_on_overflow */
480          bfd_elf_generic_reloc, /* special_function */
481          "R_MIPS_DELETE",       /* name */
482          true,                  /* partial_inplace */
483          0xffffffff,            /* src_mask */
484          0xffffffff,            /* dst_mask */
485          false),                /* pcrel_offset */
486
487   /* Get the higher value of a 64 bit addend.  */
488   HOWTO (R_MIPS_HIGHER,         /* type */
489          0,                     /* rightshift */
490          2,                     /* size (0 = byte, 1 = short, 2 = long) */
491          16,                    /* bitsize */
492          false,                 /* pc_relative */
493          0,                     /* bitpos */
494          complain_overflow_dont, /* complain_on_overflow */
495          bfd_elf_generic_reloc, /* special_function */
496          "R_MIPS_HIGHER",       /* name */
497          true,                  /* partial_inplace */
498          0xffff,                /* src_mask */
499          0xffff,                /* dst_mask */
500          false),                /* pcrel_offset */
501
502   /* Get the highest value of a 64 bit addend.  */
503   /* FIXME: Not handled correctly.  */
504   HOWTO (R_MIPS_HIGHEST,        /* type */
505          0,                     /* rightshift */
506          2,                     /* size (0 = byte, 1 = short, 2 = long) */
507          16,                    /* bitsize */
508          false,                 /* pc_relative */
509          0,                     /* bitpos */
510          complain_overflow_dont, /* complain_on_overflow */
511          bfd_elf_generic_reloc, /* special_function */
512          "R_MIPS_HIGHEST",      /* name */
513          true,                  /* partial_inplace */
514          0xffff,                /* src_mask */
515          0xffff,                /* dst_mask */
516          false),                /* pcrel_offset */
517
518   /* High 16 bits of displacement in global offset table.  */
519   /* FIXME: Not handled correctly.  */
520   HOWTO (R_MIPS_CALL_HI16,      /* type */
521          0,                     /* rightshift */
522          2,                     /* size (0 = byte, 1 = short, 2 = long) */
523          16,                    /* bitsize */
524          false,                 /* pc_relative */
525          0,                     /* bitpos */
526          complain_overflow_dont, /* complain_on_overflow */
527          bfd_elf_generic_reloc, /* special_function */
528          "R_MIPS_CALL_HI16",    /* name */
529          true,                  /* partial_inplace */
530          0xffff,                /* src_mask */
531          0xffff,                /* dst_mask */
532          false),                /* pcrel_offset */
533
534   /* Low 16 bits of displacement in global offset table.  */
535   /* FIXME: Not handled correctly.  */
536   HOWTO (R_MIPS_CALL_LO16,      /* type */
537          0,                     /* rightshift */
538          2,                     /* size (0 = byte, 1 = short, 2 = long) */
539          16,                    /* bitsize */
540          false,                 /* pc_relative */
541          0,                     /* bitpos */
542          complain_overflow_dont, /* complain_on_overflow */
543          bfd_elf_generic_reloc, /* special_function */
544          "R_MIPS_CALL_LO16",    /* name */
545          true,                  /* partial_inplace */
546          0xffff,                /* src_mask */
547          0xffff,                /* dst_mask */
548          false),                /* pcrel_offset */
549
550   /* I'm not sure what the remaining relocs are, but they are defined
551      on Irix 6.  */
552
553   HOWTO (R_MIPS_SCN_DISP,       /* type */
554          0,                     /* rightshift */
555          2,                     /* size (0 = byte, 1 = short, 2 = long) */
556          32,                    /* bitsize */
557          false,                 /* pc_relative */
558          0,                     /* bitpos */
559          complain_overflow_dont, /* complain_on_overflow */
560          bfd_elf_generic_reloc, /* special_function */
561          "R_MIPS_SCN_DISP",     /* name */
562          true,                  /* partial_inplace */
563          0xffffffff,            /* src_mask */
564          0xffffffff,            /* dst_mask */
565          false),                /* pcrel_offset */
566
567   HOWTO (R_MIPS_REL16,          /* type */
568          0,                     /* rightshift */
569          1,                     /* size (0 = byte, 1 = short, 2 = long) */
570          16,                    /* bitsize */
571          false,                 /* pc_relative */
572          0,                     /* bitpos */
573          complain_overflow_signed, /* complain_on_overflow */
574          bfd_elf_generic_reloc, /* special_function */
575          "R_MIPS_REL16",        /* name */
576          true,                  /* partial_inplace */
577          0xffff,                /* src_mask */
578          0xffff,                /* dst_mask */
579          false),                /* pcrel_offset */
580
581   /* These two are obsolete.  */
582   EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
583   EMPTY_HOWTO (R_MIPS_PJUMP),
584
585   HOWTO (R_MIPS_RELGOT,         /* type */
586          0,                     /* rightshift */
587          2,                     /* size (0 = byte, 1 = short, 2 = long) */
588          32,                    /* bitsize */
589          false,                 /* pc_relative */
590          0,                     /* bitpos */
591          complain_overflow_dont, /* complain_on_overflow */
592          bfd_elf_generic_reloc, /* special_function */
593          "R_MIPS_RELGOT",       /* name */
594          true,                  /* partial_inplace */
595          0xffffffff,            /* src_mask */
596          0xffffffff,            /* dst_mask */
597          false),                /* pcrel_offset */
598
599   /* Protected jump conversion.  This is an optimization hint.  No
600      relocation is required for correctness.  */
601   HOWTO (R_MIPS_JALR,           /* type */
602          0,                     /* rightshift */
603          2,                     /* size (0 = byte, 1 = short, 2 = long) */
604          0,                     /* bitsize */
605          false,                 /* pc_relative */
606          0,                     /* bitpos */
607          complain_overflow_dont, /* complain_on_overflow */
608          bfd_elf_generic_reloc, /* special_function */
609          "R_MIPS_JALR",         /* name */
610          false,                 /* partial_inplace */
611          0,                     /* src_mask */
612          0,                     /* dst_mask */
613          false),                /* pcrel_offset */
614 };
615
616 /* The relocation table used for SHT_RELA sections.  */
617
618 static reloc_howto_type mips_elf64_howto_table_rela[] =
619 {
620   /* No relocation.  */
621   HOWTO (R_MIPS_NONE,           /* type */
622          0,                     /* rightshift */
623          0,                     /* size (0 = byte, 1 = short, 2 = long) */
624          0,                     /* bitsize */
625          false,                 /* pc_relative */
626          0,                     /* bitpos */
627          complain_overflow_dont, /* complain_on_overflow */
628          bfd_elf_generic_reloc, /* special_function */
629          "R_MIPS_NONE",         /* name */
630          false,                 /* partial_inplace */
631          0,                     /* src_mask */
632          0,                     /* dst_mask */
633          false),                /* pcrel_offset */
634
635   /* 16 bit relocation.  */
636   HOWTO (R_MIPS_16,             /* type */
637          0,                     /* rightshift */
638          1,                     /* size (0 = byte, 1 = short, 2 = long) */
639          16,                    /* bitsize */
640          false,                 /* pc_relative */
641          0,                     /* bitpos */
642          complain_overflow_bitfield, /* complain_on_overflow */
643          bfd_elf_generic_reloc, /* special_function */
644          "R_MIPS_16",           /* name */
645          false,                 /* partial_inplace */
646          0,                     /* src_mask */
647          0xffff,                /* dst_mask */
648          false),                /* pcrel_offset */
649
650   /* 32 bit relocation.  */
651   HOWTO (R_MIPS_32,             /* type */
652          0,                     /* rightshift */
653          2,                     /* size (0 = byte, 1 = short, 2 = long) */
654          32,                    /* bitsize */
655          false,                 /* pc_relative */
656          0,                     /* bitpos */
657          complain_overflow_dont, /* complain_on_overflow */
658          bfd_elf_generic_reloc, /* special_function */
659          "R_MIPS_32",           /* name */
660          false,                 /* partial_inplace */
661          0,                     /* src_mask */
662          0xffffffff,            /* dst_mask */
663          false),                /* pcrel_offset */
664
665   /* 32 bit symbol relative relocation.  */
666   HOWTO (R_MIPS_REL32,          /* type */
667          0,                     /* rightshift */
668          2,                     /* size (0 = byte, 1 = short, 2 = long) */
669          32,                    /* bitsize */
670          false,                 /* pc_relative */
671          0,                     /* bitpos */
672          complain_overflow_dont, /* complain_on_overflow */
673          bfd_elf_generic_reloc, /* special_function */
674          "R_MIPS_REL32",        /* name */
675          false,                 /* partial_inplace */
676          0,                     /* src_mask */
677          0xffffffff,            /* dst_mask */
678          false),                /* pcrel_offset */
679
680   /* 26 bit jump address.  */
681   HOWTO (R_MIPS_26,             /* type */
682          2,                     /* rightshift */
683          2,                     /* size (0 = byte, 1 = short, 2 = long) */
684          26,                    /* bitsize */
685          false,                 /* pc_relative */
686          0,                     /* bitpos */
687          complain_overflow_dont, /* complain_on_overflow */
688                                 /* This needs complex overflow
689                                    detection, because the upper 36
690                                    bits must match the PC + 4.  */
691          bfd_elf_generic_reloc, /* special_function */
692          "R_MIPS_26",           /* name */
693          false,                 /* partial_inplace */
694          0,                     /* src_mask */
695          0x3ffffff,             /* dst_mask */
696          false),                /* pcrel_offset */
697
698   /* High 16 bits of symbol value.  */
699   HOWTO (R_MIPS_HI16,           /* type */
700          0,                     /* rightshift */
701          2,                     /* size (0 = byte, 1 = short, 2 = long) */
702          16,                    /* bitsize */
703          false,                 /* pc_relative */
704          0,                     /* bitpos */
705          complain_overflow_dont, /* complain_on_overflow */
706          bfd_elf_generic_reloc, /* special_function */
707          "R_MIPS_HI16",         /* name */
708          false,                 /* partial_inplace */
709          0,                     /* src_mask */
710          0xffff,                /* dst_mask */
711          false),                /* pcrel_offset */
712
713   /* Low 16 bits of symbol value.  */
714   HOWTO (R_MIPS_LO16,           /* type */
715          0,                     /* rightshift */
716          2,                     /* size (0 = byte, 1 = short, 2 = long) */
717          16,                    /* bitsize */
718          false,                 /* pc_relative */
719          0,                     /* bitpos */
720          complain_overflow_dont, /* complain_on_overflow */
721          bfd_elf_generic_reloc, /* special_function */
722          "R_MIPS_LO16",         /* name */
723          false,                 /* partial_inplace */
724          0,                     /* src_mask */
725          0xffff,                /* dst_mask */
726          false),                /* pcrel_offset */
727
728   /* GP relative reference.  */
729   HOWTO (R_MIPS_GPREL16,        /* type */
730          0,                     /* rightshift */
731          2,                     /* size (0 = byte, 1 = short, 2 = long) */
732          16,                    /* bitsize */
733          false,                 /* pc_relative */
734          0,                     /* bitpos */
735          complain_overflow_signed, /* complain_on_overflow */
736          _bfd_mips_elf_gprel16_reloc, /* special_function */
737          "R_MIPS_GPREL16",      /* name */
738          true,                  /* partial_inplace */
739          0,                     /* src_mask */
740          0xffff,                /* dst_mask */
741          false),                /* pcrel_offset */
742
743   /* Reference to literal section.  */
744   HOWTO (R_MIPS_LITERAL,        /* type */
745          0,                     /* rightshift */
746          2,                     /* size (0 = byte, 1 = short, 2 = long) */
747          16,                    /* bitsize */
748          false,                 /* pc_relative */
749          0,                     /* bitpos */
750          complain_overflow_signed, /* complain_on_overflow */
751          _bfd_mips_elf_gprel16_reloc, /* special_function */
752          "R_MIPS_LITERAL",      /* name */
753          true,                  /* partial_inplace */
754          0,                     /* src_mask */
755          0xffff,                /* dst_mask */
756          false),                /* pcrel_offset */
757
758   /* Reference to global offset table.  */
759   /* FIXME: This is not handled correctly.  */
760   HOWTO (R_MIPS_GOT16,          /* type */
761          0,                     /* rightshift */
762          2,                     /* size (0 = byte, 1 = short, 2 = long) */
763          16,                    /* bitsize */
764          false,                 /* pc_relative */
765          0,                     /* bitpos */
766          complain_overflow_signed, /* complain_on_overflow */
767          bfd_elf_generic_reloc, /* special_function */
768          "R_MIPS_GOT16",        /* name */
769          false,                 /* partial_inplace */
770          0,                     /* src_mask */
771          0xffff,                /* dst_mask */
772          false),                /* pcrel_offset */
773
774   /* 16 bit PC relative reference.  */
775   HOWTO (R_MIPS_PC16,           /* type */
776          0,                     /* rightshift */
777          2,                     /* size (0 = byte, 1 = short, 2 = long) */
778          16,                    /* bitsize */
779          true,                  /* pc_relative */
780          0,                     /* bitpos */
781          complain_overflow_signed, /* complain_on_overflow */
782          bfd_elf_generic_reloc, /* special_function */
783          "R_MIPS_PC16",         /* name */
784          false,                 /* partial_inplace */
785          0,                     /* src_mask */
786          0xffff,                /* dst_mask */
787          false),                /* pcrel_offset */
788
789   /* 16 bit call through global offset table.  */
790   /* FIXME: This is not handled correctly.  */
791   HOWTO (R_MIPS_CALL16,         /* type */
792          0,                     /* rightshift */
793          2,                     /* size (0 = byte, 1 = short, 2 = long) */
794          16,                    /* bitsize */
795          false,                 /* pc_relative */
796          0,                     /* bitpos */
797          complain_overflow_signed, /* complain_on_overflow */
798          bfd_elf_generic_reloc, /* special_function */
799          "R_MIPS_CALL16",       /* name */
800          false,                 /* partial_inplace */
801          0,                     /* src_mask */
802          0xffff,                /* dst_mask */
803          false),                /* pcrel_offset */
804
805   /* 32 bit GP relative reference.  */
806   HOWTO (R_MIPS_GPREL32,        /* type */
807          0,                     /* rightshift */
808          2,                     /* size (0 = byte, 1 = short, 2 = long) */
809          32,                    /* bitsize */
810          false,                 /* pc_relative */
811          0,                     /* bitpos */
812          complain_overflow_bitfield, /* complain_on_overflow */
813          _bfd_mips_elf_gprel32_reloc, /* special_function */
814          "R_MIPS_GPREL32",      /* name */
815          true,                  /* partial_inplace */
816          0,                     /* src_mask */
817          0xffffffff,            /* dst_mask */
818          false),                /* pcrel_offset */
819
820   UNUSED_RELOC (13),
821   UNUSED_RELOC (14),
822   UNUSED_RELOC (15),
823
824   /* A 5 bit shift field.  */
825   HOWTO (R_MIPS_SHIFT5,         /* type */
826          0,                     /* rightshift */
827          2,                     /* size (0 = byte, 1 = short, 2 = long) */
828          5,                     /* bitsize */
829          false,                 /* pc_relative */
830          6,                     /* bitpos */
831          complain_overflow_bitfield, /* complain_on_overflow */
832          bfd_elf_generic_reloc, /* special_function */
833          "R_MIPS_SHIFT5",       /* name */
834          false,                 /* partial_inplace */
835          0,                     /* src_mask */
836          0x000007c0,            /* dst_mask */
837          false),                /* pcrel_offset */
838
839   /* A 6 bit shift field.  */
840   /* FIXME: This is not handled correctly; a special function is
841      needed to put the most significant bit in the right place.  */
842   HOWTO (R_MIPS_SHIFT6,         /* type */
843          0,                     /* rightshift */
844          2,                     /* size (0 = byte, 1 = short, 2 = long) */
845          6,                     /* bitsize */
846          false,                 /* pc_relative */
847          6,                     /* bitpos */
848          complain_overflow_bitfield, /* complain_on_overflow */
849          bfd_elf_generic_reloc, /* special_function */
850          "R_MIPS_SHIFT6",       /* name */
851          false,                 /* partial_inplace */
852          0,                     /* src_mask */
853          0x000007c4,            /* dst_mask */
854          false),                /* pcrel_offset */
855
856   /* 64 bit relocation.  */
857   HOWTO (R_MIPS_64,             /* type */
858          0,                     /* rightshift */
859          4,                     /* size (0 = byte, 1 = short, 2 = long) */
860          64,                    /* bitsize */
861          false,                 /* pc_relative */
862          0,                     /* bitpos */
863          complain_overflow_dont, /* complain_on_overflow */
864          bfd_elf_generic_reloc, /* special_function */
865          "R_MIPS_64",           /* name */
866          false,                 /* partial_inplace */
867          0,                     /* src_mask */
868          MINUS_ONE,             /* dst_mask */
869          false),                /* pcrel_offset */
870
871   /* Displacement in the global offset table.  */
872   /* FIXME: Not handled correctly.  */
873   HOWTO (R_MIPS_GOT_DISP,       /* type */
874          0,                     /* rightshift */
875          2,                     /* size (0 = byte, 1 = short, 2 = long) */
876          16,                    /* bitsize */
877          false,                 /* pc_relative */
878          0,                     /* bitpos */
879          complain_overflow_signed, /* complain_on_overflow */
880          bfd_elf_generic_reloc, /* special_function */
881          "R_MIPS_GOT_DISP",     /* name */
882          false,                 /* partial_inplace */
883          0,                     /* src_mask */
884          0x0000ffff,            /* dst_mask */
885          false),                /* pcrel_offset */
886
887   /* Displacement to page pointer in the global offset table.  */
888   /* FIXME: Not handled correctly.  */
889   HOWTO (R_MIPS_GOT_PAGE,       /* type */
890          0,                     /* rightshift */
891          2,                     /* size (0 = byte, 1 = short, 2 = long) */
892          16,                    /* bitsize */
893          false,                 /* pc_relative */
894          0,                     /* bitpos */
895          complain_overflow_signed, /* complain_on_overflow */
896          bfd_elf_generic_reloc, /* special_function */
897          "R_MIPS_GOT_PAGE",     /* name */
898          false,                 /* partial_inplace */
899          0,                     /* src_mask */
900          0x0000ffff,            /* dst_mask */
901          false),                /* pcrel_offset */
902
903   /* Offset from page pointer in the global offset table.  */
904   /* FIXME: Not handled correctly.  */
905   HOWTO (R_MIPS_GOT_OFST,       /* type */
906          0,                     /* rightshift */
907          2,                     /* size (0 = byte, 1 = short, 2 = long) */
908          16,                    /* bitsize */
909          false,                 /* pc_relative */
910          0,                     /* bitpos */
911          complain_overflow_signed, /* complain_on_overflow */
912          bfd_elf_generic_reloc, /* special_function */
913          "R_MIPS_GOT_OFST",     /* name */
914          false,                 /* partial_inplace */
915          0,                     /* src_mask */
916          0x0000ffff,            /* dst_mask */
917          false),                /* pcrel_offset */
918
919   /* High 16 bits of displacement in global offset table.  */
920   /* FIXME: Not handled correctly.  */
921   HOWTO (R_MIPS_GOT_HI16,       /* type */
922          0,                     /* rightshift */
923          2,                     /* size (0 = byte, 1 = short, 2 = long) */
924          16,                    /* bitsize */
925          false,                 /* pc_relative */
926          0,                     /* bitpos */
927          complain_overflow_dont, /* complain_on_overflow */
928          bfd_elf_generic_reloc, /* special_function */
929          "R_MIPS_GOT_HI16",     /* name */
930          false,                 /* partial_inplace */
931          0,                     /* src_mask */
932          0x0000ffff,            /* dst_mask */
933          false),                /* pcrel_offset */
934
935   /* Low 16 bits of displacement in global offset table.  */
936   /* FIXME: Not handled correctly.  */
937   HOWTO (R_MIPS_GOT_LO16,       /* 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_elf_generic_reloc, /* special_function */
945          "R_MIPS_GOT_LO16",     /* name */
946          false,                 /* partial_inplace */
947          0,                     /* src_mask */
948          0x0000ffff,            /* dst_mask */
949          false),                /* pcrel_offset */
950
951   /* 64 bit substraction.  */
952   /* FIXME: Not handled correctly.  */
953   HOWTO (R_MIPS_SUB,            /* type */
954          0,                     /* rightshift */
955          4,                     /* size (0 = byte, 1 = short, 2 = long) */
956          64,                    /* bitsize */
957          false,                 /* pc_relative */
958          0,                     /* bitpos */
959          complain_overflow_dont, /* complain_on_overflow */
960          bfd_elf_generic_reloc, /* special_function */
961          "R_MIPS_SUB",          /* name */
962          false,                 /* partial_inplace */
963          0,                     /* src_mask */
964          MINUS_ONE,             /* dst_mask */
965          false),                /* pcrel_offset */
966
967   /* Insert the addend as an instruction.  */
968   /* FIXME: Not handled correctly.  */
969   HOWTO (R_MIPS_INSERT_A,       /* type */
970          0,                     /* rightshift */
971          2,                     /* size (0 = byte, 1 = short, 2 = long) */
972          32,                    /* bitsize */
973          false,                 /* pc_relative */
974          0,                     /* bitpos */
975          complain_overflow_dont, /* complain_on_overflow */
976          bfd_elf_generic_reloc, /* special_function */
977          "R_MIPS_INSERT_A",     /* name */
978          false,                 /* partial_inplace */
979          0,                     /* src_mask */
980          0xffffffff,            /* dst_mask */
981          false),                /* pcrel_offset */
982
983   /* Insert the addend as an instruction, and change all relocations
984      to refer to the old instruction at the address.  */
985   /* FIXME: Not handled correctly.  */
986   HOWTO (R_MIPS_INSERT_B,       /* type */
987          0,                     /* rightshift */
988          2,                     /* size (0 = byte, 1 = short, 2 = long) */
989          32,                    /* bitsize */
990          false,                 /* pc_relative */
991          0,                     /* bitpos */
992          complain_overflow_dont, /* complain_on_overflow */
993          bfd_elf_generic_reloc, /* special_function */
994          "R_MIPS_INSERT_B",     /* name */
995          false,                 /* partial_inplace */
996          0,                     /* src_mask */
997          0xffffffff,            /* dst_mask */
998          false),                /* pcrel_offset */
999
1000   /* Delete a 32 bit instruction.  */
1001   /* FIXME: Not handled correctly.  */
1002   HOWTO (R_MIPS_DELETE,         /* type */
1003          0,                     /* rightshift */
1004          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1005          32,                    /* bitsize */
1006          false,                 /* pc_relative */
1007          0,                     /* bitpos */
1008          complain_overflow_dont, /* complain_on_overflow */
1009          bfd_elf_generic_reloc, /* special_function */
1010          "R_MIPS_DELETE",       /* name */
1011          false,                 /* partial_inplace */
1012          0,                     /* src_mask */
1013          0xffffffff,            /* dst_mask */
1014          false),                /* pcrel_offset */
1015
1016   /* Get the higher value of a 64 bit addend.  */
1017   HOWTO (R_MIPS_HIGHER,         /* type */
1018          0,                     /* rightshift */
1019          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1020          16,                    /* bitsize */
1021          false,                 /* pc_relative */
1022          0,                     /* bitpos */
1023          complain_overflow_dont, /* complain_on_overflow */
1024          bfd_elf_generic_reloc, /* special_function */
1025          "R_MIPS_HIGHER",       /* name */
1026          false,                 /* partial_inplace */
1027          0,                     /* src_mask */
1028          0xffff,                /* dst_mask */
1029          false),                /* pcrel_offset */
1030
1031   /* Get the highest value of a 64 bit addend.  */
1032   HOWTO (R_MIPS_HIGHEST,        /* type */
1033          0,                     /* rightshift */
1034          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1035          16,                    /* bitsize */
1036          false,                 /* pc_relative */
1037          0,                     /* bitpos */
1038          complain_overflow_dont, /* complain_on_overflow */
1039          bfd_elf_generic_reloc, /* special_function */
1040          "R_MIPS_HIGHEST",      /* name */
1041          false,                 /* partial_inplace */
1042          0,                     /* src_mask */
1043          0xffff,                /* dst_mask */
1044          false),                /* pcrel_offset */
1045
1046   /* High 16 bits of displacement in global offset table.  */
1047   /* FIXME: Not handled correctly.  */
1048   HOWTO (R_MIPS_CALL_HI16,      /* type */
1049          0,                     /* rightshift */
1050          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1051          16,                    /* bitsize */
1052          false,                 /* pc_relative */
1053          0,                     /* bitpos */
1054          complain_overflow_dont, /* complain_on_overflow */
1055          bfd_elf_generic_reloc, /* special_function */
1056          "R_MIPS_CALL_HI16",    /* name */
1057          false,                 /* partial_inplace */
1058          0,                     /* src_mask */
1059          0xffff,                /* dst_mask */
1060          false),                /* pcrel_offset */
1061
1062   /* Low 16 bits of displacement in global offset table.  */
1063   /* FIXME: Not handled correctly.  */
1064   HOWTO (R_MIPS_CALL_LO16,      /* type */
1065          0,                     /* rightshift */
1066          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1067          16,                    /* bitsize */
1068          false,                 /* pc_relative */
1069          0,                     /* bitpos */
1070          complain_overflow_dont, /* complain_on_overflow */
1071          bfd_elf_generic_reloc, /* special_function */
1072          "R_MIPS_CALL_LO16",    /* name */
1073          false,                 /* partial_inplace */
1074          0,                     /* src_mask */
1075          0xffff,                /* dst_mask */
1076          false),                /* pcrel_offset */
1077
1078   /* I'm not sure what the remaining relocs are, but they are defined
1079      on Irix 6.  */
1080
1081   HOWTO (R_MIPS_SCN_DISP,       /* type */
1082          0,                     /* rightshift */
1083          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1084          32,                    /* bitsize */
1085          false,                 /* pc_relative */
1086          0,                     /* bitpos */
1087          complain_overflow_dont, /* complain_on_overflow */
1088          bfd_elf_generic_reloc, /* special_function */
1089          "R_MIPS_SCN_DISP",     /* name */
1090          false,                 /* partial_inplace */
1091          0,                     /* src_mask */
1092          0xffffffff,            /* dst_mask */
1093          false),                /* pcrel_offset */
1094
1095   HOWTO (R_MIPS_REL16,          /* type */
1096          0,                     /* rightshift */
1097          1,                     /* size (0 = byte, 1 = short, 2 = long) */
1098          16,                    /* bitsize */
1099          false,                 /* pc_relative */
1100          0,                     /* bitpos */
1101          complain_overflow_signed, /* complain_on_overflow */
1102          bfd_elf_generic_reloc, /* special_function */
1103          "R_MIPS_REL16",        /* name */
1104          false,                 /* partial_inplace */
1105          0,                     /* src_mask */
1106          0xffff,                /* dst_mask */
1107          false),                /* pcrel_offset */
1108
1109   /* These two are obsolete.  */
1110   EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1111   EMPTY_HOWTO (R_MIPS_PJUMP),
1112
1113   HOWTO (R_MIPS_RELGOT,         /* type */
1114          0,                     /* rightshift */
1115          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1116          32,                    /* bitsize */
1117          false,                 /* pc_relative */
1118          0,                     /* bitpos */
1119          complain_overflow_dont, /* complain_on_overflow */
1120          bfd_elf_generic_reloc, /* special_function */
1121          "R_MIPS_RELGOT",       /* name */
1122          false,                 /* partial_inplace */
1123          0,                     /* src_mask */
1124          0xffffffff,            /* dst_mask */
1125          false),                /* pcrel_offset */
1126
1127   /* Protected jump conversion.  This is an optimization hint.  No
1128      relocation is required for correctness.  */
1129   HOWTO (R_MIPS_JALR,           /* type */
1130          0,                     /* rightshift */
1131          2,                     /* size (0 = byte, 1 = short, 2 = long) */
1132          0,                     /* bitsize */
1133          false,                 /* pc_relative */
1134          0,                     /* bitpos */
1135          complain_overflow_dont, /* complain_on_overflow */
1136          bfd_elf_generic_reloc, /* special_function */
1137          "R_MIPS_JALR",         /* name */
1138          false,                 /* partial_inplace */
1139          0,                     /* src_mask */
1140          0,                     /* dst_mask */
1141          false),                /* pcrel_offset */
1142 };
1143
1144 /* Swap in a MIPS 64-bit Rel reloc.  */
1145
1146 static void
1147 mips_elf64_swap_reloc_in (abfd, src, dst)
1148      bfd *abfd;
1149      const Elf64_Mips_External_Rel *src;
1150      Elf64_Mips_Internal_Rel *dst;
1151 {
1152   dst->r_offset = H_GET_64 (abfd, src->r_offset);
1153   dst->r_sym = H_GET_32 (abfd, src->r_sym);
1154   dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1155   dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1156   dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1157   dst->r_type = H_GET_8 (abfd, src->r_type);
1158 }
1159
1160 /* Swap in a MIPS 64-bit Rela reloc.  */
1161
1162 static void
1163 mips_elf64_swap_reloca_in (abfd, src, dst)
1164      bfd *abfd;
1165      const Elf64_Mips_External_Rela *src;
1166      Elf64_Mips_Internal_Rela *dst;
1167 {
1168   dst->r_offset = H_GET_64 (abfd, src->r_offset);
1169   dst->r_sym = H_GET_32 (abfd, src->r_sym);
1170   dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1171   dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1172   dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1173   dst->r_type = H_GET_8 (abfd, src->r_type);
1174   dst->r_addend = H_GET_S64 (abfd, src->r_addend);
1175 }
1176
1177 /* Swap out a MIPS 64-bit Rel reloc.  */
1178
1179 static void
1180 mips_elf64_swap_reloc_out (abfd, src, dst)
1181      bfd *abfd;
1182      const Elf64_Mips_Internal_Rel *src;
1183      Elf64_Mips_External_Rel *dst;
1184 {
1185   H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1186   H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1187   H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1188   H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1189   H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1190   H_PUT_8 (abfd, src->r_type, dst->r_type);
1191 }
1192
1193 /* Swap out a MIPS 64-bit Rela reloc.  */
1194
1195 static void
1196 mips_elf64_swap_reloca_out (abfd, src, dst)
1197      bfd *abfd;
1198      const Elf64_Mips_Internal_Rela *src;
1199      Elf64_Mips_External_Rela *dst;
1200 {
1201   H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1202   H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1203   H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1204   H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1205   H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1206   H_PUT_8 (abfd, src->r_type, dst->r_type);
1207   H_PUT_64 (abfd, src->r_addend, dst->r_addend);
1208 }
1209
1210 /* Swap in a MIPS 64-bit Rel reloc.  */
1211
1212 static void
1213 mips_elf64_be_swap_reloc_in (abfd, src, dst)
1214      bfd *abfd;
1215      const bfd_byte *src;
1216      Elf_Internal_Rel *dst;
1217 {
1218   Elf64_Mips_Internal_Rel mirel;
1219
1220   mips_elf64_swap_reloc_in (abfd,
1221                             (const Elf64_Mips_External_Rel *) src,
1222                             &mirel);
1223
1224   dst[0].r_offset = mirel.r_offset;
1225   dst[0].r_info = ELF32_R_INFO (mirel.r_sym, mirel.r_type);
1226   dst[1].r_offset = mirel.r_offset;
1227   dst[1].r_info = ELF32_R_INFO (mirel.r_ssym, mirel.r_type2);
1228   dst[2].r_offset = mirel.r_offset;
1229   dst[2].r_info = ELF32_R_INFO (STN_UNDEF, mirel.r_type3);
1230 }
1231
1232 /* Swap in a MIPS 64-bit Rela reloc.  */
1233
1234 static void
1235 mips_elf64_be_swap_reloca_in (abfd, src, dst)
1236      bfd *abfd;
1237      const bfd_byte *src;
1238      Elf_Internal_Rela *dst;
1239 {
1240   Elf64_Mips_Internal_Rela mirela;
1241
1242   mips_elf64_swap_reloca_in (abfd,
1243                              (const Elf64_Mips_External_Rela *) src,
1244                              &mirela);
1245
1246   dst[0].r_offset = mirela.r_offset;
1247   dst[0].r_info = ELF32_R_INFO (mirela.r_sym, mirela.r_type);
1248   dst[0].r_addend = mirela.r_addend;
1249   dst[1].r_offset = mirela.r_offset;
1250   dst[1].r_info = ELF32_R_INFO (mirela.r_ssym, mirela.r_type2);
1251   dst[1].r_addend = 0;
1252   dst[2].r_offset = mirela.r_offset;
1253   dst[2].r_info = ELF32_R_INFO (STN_UNDEF, mirela.r_type3);
1254   dst[2].r_addend = 0;
1255 }
1256
1257 /* Swap out a MIPS 64-bit Rel reloc.  */
1258
1259 static void
1260 mips_elf64_be_swap_reloc_out (abfd, src, dst)
1261      bfd *abfd;
1262      const Elf_Internal_Rel *src;
1263      bfd_byte *dst;
1264 {
1265   Elf64_Mips_Internal_Rel mirel;
1266
1267   mirel.r_offset = src->r_offset;
1268   mirel.r_type = ELF32_R_TYPE (src->r_info);
1269   mirel.r_sym = ELF32_R_SYM (src->r_info);
1270   mirel.r_type2 = R_MIPS_NONE;
1271   mirel.r_ssym = STN_UNDEF;
1272   mirel.r_type3 = R_MIPS_NONE;
1273
1274   mips_elf64_swap_reloc_out (abfd, &mirel,
1275                              (Elf64_Mips_External_Rel *) dst);
1276 }
1277
1278 /* Swap out a MIPS 64-bit Rela reloc.  */
1279
1280 static void
1281 mips_elf64_be_swap_reloca_out (abfd, src, dst)
1282      bfd *abfd;
1283      const Elf_Internal_Rela *src;
1284      bfd_byte *dst;
1285 {
1286   Elf64_Mips_Internal_Rela mirela;
1287
1288   mirela.r_offset = src->r_offset;
1289   mirela.r_type = ELF32_R_TYPE (src->r_info);
1290   mirela.r_addend = src->r_addend;
1291   mirela.r_sym = ELF32_R_SYM (src->r_info);
1292   mirela.r_type2 = R_MIPS_NONE;
1293   mirela.r_ssym = STN_UNDEF;
1294   mirela.r_type3 = R_MIPS_NONE;
1295
1296   mips_elf64_swap_reloca_out (abfd, &mirela,
1297                               (Elf64_Mips_External_Rela *) dst);
1298 }
1299
1300 /* A mapping from BFD reloc types to MIPS ELF reloc types.  */
1301
1302 struct elf_reloc_map
1303 {
1304   bfd_reloc_code_real_type bfd_reloc_val;
1305   enum elf_mips_reloc_type elf_reloc_val;
1306 };
1307
1308 static const struct elf_reloc_map mips_reloc_map[] =
1309 {
1310   { BFD_RELOC_NONE, R_MIPS_NONE, },
1311   { BFD_RELOC_16, R_MIPS_16 },
1312   { BFD_RELOC_32, R_MIPS_32 },
1313   { BFD_RELOC_64, R_MIPS_64 },
1314   { BFD_RELOC_CTOR, R_MIPS_64 },
1315   { BFD_RELOC_32_PCREL, R_MIPS_REL32 },
1316   { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1317   { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1318   { BFD_RELOC_LO16, R_MIPS_LO16 },
1319   { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
1320   { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1321   { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
1322   { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
1323   { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
1324   { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
1325   { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1326   { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1327   { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
1328   { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1329   { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1330   { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1331   { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
1332   { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP }
1333 };
1334
1335 /* Given a BFD reloc type, return a howto structure.  */
1336
1337 static reloc_howto_type *
1338 mips_elf64_reloc_type_lookup (abfd, code)
1339      bfd *abfd ATTRIBUTE_UNUSED;
1340      bfd_reloc_code_real_type code;
1341 {
1342   unsigned int i;
1343
1344   for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map); i++)
1345     {
1346       if (mips_reloc_map[i].bfd_reloc_val == code)
1347         {
1348           int v;
1349
1350           v = (int) mips_reloc_map[i].elf_reloc_val;
1351           return &mips_elf64_howto_table_rel[v];
1352         }
1353     }
1354
1355   return NULL;
1356 }
1357
1358 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
1359    to three relocs, we must tell the user to allocate more space.  */
1360
1361 static long
1362 mips_elf64_get_reloc_upper_bound (abfd, sec)
1363      bfd *abfd ATTRIBUTE_UNUSED;
1364      asection *sec;
1365 {
1366   return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
1367 }
1368
1369 /* Read the relocations from one reloc section.  */
1370
1371 static boolean
1372 mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, rel_hdr)
1373      bfd *abfd;
1374      asection *asect;
1375      asymbol **symbols;
1376      const Elf_Internal_Shdr *rel_hdr;
1377 {
1378   PTR allocated = NULL;
1379   bfd_byte *native_relocs;
1380   arelent *relents;
1381   arelent *relent;
1382   unsigned int count;
1383   unsigned int i;
1384   int entsize;
1385   reloc_howto_type *howto_table;
1386
1387   allocated = (PTR) bfd_malloc (rel_hdr->sh_size);
1388   if (allocated == NULL)
1389     return false;
1390
1391   if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
1392       || (bfd_bread (allocated, rel_hdr->sh_size, abfd) != rel_hdr->sh_size))
1393     goto error_return;
1394
1395   native_relocs = (bfd_byte *) allocated;
1396
1397   relents = asect->relocation + asect->reloc_count;
1398
1399   entsize = rel_hdr->sh_entsize;
1400   BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
1401               || entsize == sizeof (Elf64_Mips_External_Rela));
1402
1403   count = rel_hdr->sh_size / entsize;
1404
1405   if (entsize == sizeof (Elf64_Mips_External_Rel))
1406     howto_table = mips_elf64_howto_table_rel;
1407   else
1408     howto_table = mips_elf64_howto_table_rela;
1409
1410   relent = relents;
1411   for (i = 0; i < count; i++, native_relocs += entsize)
1412     {
1413       Elf64_Mips_Internal_Rela rela;
1414       boolean used_sym, used_ssym;
1415       int ir;
1416
1417       if (entsize == sizeof (Elf64_Mips_External_Rela))
1418         mips_elf64_swap_reloca_in (abfd,
1419                                    (Elf64_Mips_External_Rela *) native_relocs,
1420                                    &rela);
1421       else
1422         {
1423           Elf64_Mips_Internal_Rel rel;
1424
1425           mips_elf64_swap_reloc_in (abfd,
1426                                     (Elf64_Mips_External_Rel *) native_relocs,
1427                                     &rel);
1428           rela.r_offset = rel.r_offset;
1429           rela.r_sym = rel.r_sym;
1430           rela.r_ssym = rel.r_ssym;
1431           rela.r_type3 = rel.r_type3;
1432           rela.r_type2 = rel.r_type2;
1433           rela.r_type = rel.r_type;
1434           rela.r_addend = 0;
1435         }
1436
1437       /* Each entry represents up to three actual relocations.  */
1438
1439       used_sym = false;
1440       used_ssym = false;
1441       for (ir = 0; ir < 3; ir++)
1442         {
1443           enum elf_mips_reloc_type type;
1444
1445           switch (ir)
1446             {
1447             default:
1448               abort ();
1449             case 0:
1450               type = (enum elf_mips_reloc_type) rela.r_type;
1451               break;
1452             case 1:
1453               type = (enum elf_mips_reloc_type) rela.r_type2;
1454               break;
1455             case 2:
1456               type = (enum elf_mips_reloc_type) rela.r_type3;
1457               break;
1458             }
1459
1460           if (type == R_MIPS_NONE)
1461             {
1462               /* There are no more relocations in this entry.  If this
1463                  is the first entry, we need to generate a dummy
1464                  relocation so that the generic linker knows that
1465                  there has been a break in the sequence of relocations
1466                  applying to a particular address.  */
1467               if (ir == 0)
1468                 {
1469                   relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1470                   if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
1471                     relent->address = rela.r_offset;
1472                   else
1473                     relent->address = rela.r_offset - asect->vma;
1474                   relent->addend = 0;
1475                   relent->howto = &howto_table[(int) R_MIPS_NONE];
1476                   ++relent;
1477                 }
1478               break;
1479             }
1480
1481           /* Some types require symbols, whereas some do not.  */
1482           switch (type)
1483             {
1484             case R_MIPS_NONE:
1485             case R_MIPS_LITERAL:
1486             case R_MIPS_INSERT_A:
1487             case R_MIPS_INSERT_B:
1488             case R_MIPS_DELETE:
1489               relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1490               break;
1491
1492             default:
1493               if (! used_sym)
1494                 {
1495                   if (rela.r_sym == 0)
1496                     relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1497                   else
1498                     {
1499                       asymbol **ps, *s;
1500
1501                       ps = symbols + rela.r_sym - 1;
1502                       s = *ps;
1503                       if ((s->flags & BSF_SECTION_SYM) == 0)
1504                         relent->sym_ptr_ptr = ps;
1505                       else
1506                         relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
1507                     }
1508
1509                   used_sym = true;
1510                 }
1511               else if (! used_ssym)
1512                 {
1513                   switch (rela.r_ssym)
1514                     {
1515                     case RSS_UNDEF:
1516                       relent->sym_ptr_ptr =
1517                         bfd_abs_section_ptr->symbol_ptr_ptr;
1518                       break;
1519
1520                     case RSS_GP:
1521                     case RSS_GP0:
1522                     case RSS_LOC:
1523                       /* FIXME: I think these need to be handled using
1524                          special howto structures.  */
1525                       BFD_ASSERT (0);
1526                       break;
1527
1528                     default:
1529                       BFD_ASSERT (0);
1530                       break;
1531                     }
1532
1533                   used_ssym = true;
1534                 }
1535               else
1536                 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1537
1538               break;
1539             }
1540
1541           /* The address of an ELF reloc is section relative for an
1542              object file, and absolute for an executable file or
1543              shared library.  The address of a BFD reloc is always
1544              section relative.  */
1545           if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
1546             relent->address = rela.r_offset;
1547           else
1548             relent->address = rela.r_offset - asect->vma;
1549
1550           relent->addend = rela.r_addend;
1551
1552           relent->howto = &howto_table[(int) type];
1553
1554           ++relent;
1555         }
1556     }
1557
1558   asect->reloc_count += relent - relents;
1559
1560   if (allocated != NULL)
1561     free (allocated);
1562
1563   return true;
1564
1565  error_return:
1566   if (allocated != NULL)
1567     free (allocated);
1568   return false;
1569 }
1570
1571 /* Read the relocations.  On Irix 6, there can be two reloc sections
1572    associated with a single data section.  */
1573
1574 static boolean
1575 mips_elf64_slurp_reloc_table (abfd, asect, symbols, dynamic)
1576      bfd *abfd;
1577      asection *asect;
1578      asymbol **symbols;
1579      boolean dynamic;
1580 {
1581   bfd_size_type amt;
1582   struct bfd_elf_section_data * const d = elf_section_data (asect);
1583
1584   if (dynamic)
1585     {
1586       bfd_set_error (bfd_error_invalid_operation);
1587       return false;
1588     }
1589
1590   if (asect->relocation != NULL
1591       || (asect->flags & SEC_RELOC) == 0
1592       || asect->reloc_count == 0)
1593     return true;
1594
1595   /* Allocate space for 3 arelent structures for each Rel structure.  */
1596   amt = asect->reloc_count;
1597   amt *= 3 * sizeof (arelent);
1598   asect->relocation = (arelent *) bfd_alloc (abfd, amt);
1599   if (asect->relocation == NULL)
1600     return false;
1601
1602   /* The slurp_one_reloc_table routine increments reloc_count.  */
1603   asect->reloc_count = 0;
1604
1605   if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, &d->rel_hdr))
1606     return false;
1607   if (d->rel_hdr2 != NULL)
1608     {
1609       if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols,
1610                                               d->rel_hdr2))
1611         return false;
1612     }
1613
1614   return true;
1615 }
1616
1617 /* Write out the relocations.  */
1618
1619 static void
1620 mips_elf64_write_relocs (abfd, sec, data)
1621      bfd *abfd;
1622      asection *sec;
1623      PTR data;
1624 {
1625   boolean *failedp = (boolean *) data;
1626   unsigned int count;
1627   Elf_Internal_Shdr *rela_hdr;
1628   Elf64_Mips_External_Rela *ext_rela;
1629   unsigned int idx;
1630   asymbol *last_sym = 0;
1631   int last_sym_idx = 0;
1632
1633   /* If we have already failed, don't do anything.  */
1634   if (*failedp)
1635     return;
1636
1637   if ((sec->flags & SEC_RELOC) == 0)
1638     return;
1639
1640   /* The linker backend writes the relocs out itself, and sets the
1641      reloc_count field to zero to inhibit writing them here.  Also,
1642      sometimes the SEC_RELOC flag gets set even when there aren't any
1643      relocs.  */
1644   if (sec->reloc_count == 0)
1645     return;
1646
1647   /* We can combine up to three relocs that refer to the same address
1648      if the latter relocs have no associated symbol.  */
1649   count = 0;
1650   for (idx = 0; idx < sec->reloc_count; idx++)
1651     {
1652       bfd_vma addr;
1653       unsigned int i;
1654
1655       ++count;
1656
1657       addr = sec->orelocation[idx]->address;
1658       for (i = 0; i < 2; i++)
1659         {
1660           arelent *r;
1661
1662           if (idx + 1 >= sec->reloc_count)
1663             break;
1664           r = sec->orelocation[idx + 1];
1665           if (r->address != addr
1666               || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
1667               || (*r->sym_ptr_ptr)->value != 0)
1668             break;
1669
1670           /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
1671
1672           ++idx;
1673         }
1674     }
1675
1676   rela_hdr = &elf_section_data (sec)->rel_hdr;
1677
1678   rela_hdr->sh_size = rela_hdr->sh_entsize * count;
1679   rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
1680   if (rela_hdr->contents == NULL)
1681     {
1682       *failedp = true;
1683       return;
1684     }
1685
1686   ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
1687   for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
1688     {
1689       arelent *ptr;
1690       Elf64_Mips_Internal_Rela int_rela;
1691       asymbol *sym;
1692       int n;
1693       unsigned int i;
1694
1695       ptr = sec->orelocation[idx];
1696
1697       /* The address of an ELF reloc is section relative for an object
1698          file, and absolute for an executable file or shared library.
1699          The address of a BFD reloc is always section relative.  */
1700       if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
1701         int_rela.r_offset = ptr->address;
1702       else
1703         int_rela.r_offset = ptr->address + sec->vma;
1704
1705       sym = *ptr->sym_ptr_ptr;
1706       if (sym == last_sym)
1707         n = last_sym_idx;
1708       else
1709         {
1710           last_sym = sym;
1711           n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
1712           if (n < 0)
1713             {
1714               *failedp = true;
1715               return;
1716             }
1717           last_sym_idx = n;
1718         }
1719
1720       int_rela.r_sym = n;
1721
1722       int_rela.r_addend = ptr->addend;
1723
1724       int_rela.r_ssym = RSS_UNDEF;
1725
1726       if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
1727           && ! _bfd_elf_validate_reloc (abfd, ptr))
1728         {
1729           *failedp = true;
1730           return;
1731         }
1732
1733       int_rela.r_type = ptr->howto->type;
1734       int_rela.r_type2 = (int) R_MIPS_NONE;
1735       int_rela.r_type3 = (int) R_MIPS_NONE;
1736
1737       for (i = 0; i < 2; i++)
1738         {
1739           arelent *r;
1740
1741           if (idx + 1 >= sec->reloc_count)
1742             break;
1743           r = sec->orelocation[idx + 1];
1744           if (r->address != ptr->address
1745               || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
1746               || (*r->sym_ptr_ptr)->value != 0)
1747             break;
1748
1749           /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
1750
1751           if (i == 0)
1752             int_rela.r_type2 = r->howto->type;
1753           else
1754             int_rela.r_type3 = r->howto->type;
1755
1756           ++idx;
1757         }
1758
1759       mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
1760     }
1761
1762   BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
1763               == (int) count);
1764 }
1765 \f
1766 /* ECOFF swapping routines.  These are used when dealing with the
1767    .mdebug section, which is in the ECOFF debugging format.  */
1768 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
1769 {
1770   /* Symbol table magic number.  */
1771   magicSym2,
1772   /* Alignment of debugging information.  E.g., 4.  */
1773   8,
1774   /* Sizes of external symbolic information.  */
1775   sizeof (struct hdr_ext),
1776   sizeof (struct dnr_ext),
1777   sizeof (struct pdr_ext),
1778   sizeof (struct sym_ext),
1779   sizeof (struct opt_ext),
1780   sizeof (struct fdr_ext),
1781   sizeof (struct rfd_ext),
1782   sizeof (struct ext_ext),
1783   /* Functions to swap in external symbolic data.  */
1784   ecoff_swap_hdr_in,
1785   ecoff_swap_dnr_in,
1786   ecoff_swap_pdr_in,
1787   ecoff_swap_sym_in,
1788   ecoff_swap_opt_in,
1789   ecoff_swap_fdr_in,
1790   ecoff_swap_rfd_in,
1791   ecoff_swap_ext_in,
1792   _bfd_ecoff_swap_tir_in,
1793   _bfd_ecoff_swap_rndx_in,
1794   /* Functions to swap out external symbolic data.  */
1795   ecoff_swap_hdr_out,
1796   ecoff_swap_dnr_out,
1797   ecoff_swap_pdr_out,
1798   ecoff_swap_sym_out,
1799   ecoff_swap_opt_out,
1800   ecoff_swap_fdr_out,
1801   ecoff_swap_rfd_out,
1802   ecoff_swap_ext_out,
1803   _bfd_ecoff_swap_tir_out,
1804   _bfd_ecoff_swap_rndx_out,
1805   /* Function to read in symbolic data.  */
1806   _bfd_mips_elf_read_ecoff_info
1807 };
1808 \f
1809 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
1810    standard ELF.  This structure is used to redirect the relocation
1811    handling routines.  */
1812
1813 const struct elf_size_info mips_elf64_size_info =
1814 {
1815   sizeof (Elf64_External_Ehdr),
1816   sizeof (Elf64_External_Phdr),
1817   sizeof (Elf64_External_Shdr),
1818   sizeof (Elf64_Mips_External_Rel),
1819   sizeof (Elf64_Mips_External_Rela),
1820   sizeof (Elf64_External_Sym),
1821   sizeof (Elf64_External_Dyn),
1822   sizeof (Elf_External_Note),
1823   4,            /* hash-table entry size */
1824   3,            /* internal relocations per external relocations */
1825   64,           /* arch_size */
1826   8,            /* file_align */
1827   ELFCLASS64,
1828   EV_CURRENT,
1829   bfd_elf64_write_out_phdrs,
1830   bfd_elf64_write_shdrs_and_ehdr,
1831   mips_elf64_write_relocs,
1832   bfd_elf64_swap_symbol_out,
1833   mips_elf64_slurp_reloc_table,
1834   bfd_elf64_slurp_symbol_table,
1835   bfd_elf64_swap_dyn_in,
1836   bfd_elf64_swap_dyn_out,
1837   mips_elf64_be_swap_reloc_in,
1838   mips_elf64_be_swap_reloc_out,
1839   mips_elf64_be_swap_reloca_in,
1840   mips_elf64_be_swap_reloca_out
1841 };
1842
1843 #define TARGET_LITTLE_SYM               bfd_elf64_littlemips_vec
1844 #define TARGET_LITTLE_NAME              "elf64-littlemips"
1845 #define TARGET_BIG_SYM                  bfd_elf64_bigmips_vec
1846 #define TARGET_BIG_NAME                 "elf64-bigmips"
1847 #define ELF_ARCH                        bfd_arch_mips
1848 #define ELF_MACHINE_CODE                EM_MIPS
1849
1850 #define ELF_MAXPAGESIZE                 0x1000
1851
1852 #define elf_backend_collect             true
1853 #define elf_backend_type_change_ok      true
1854 #define elf_backend_can_gc_sections     true
1855 #define elf_backend_size_info           mips_elf64_size_info
1856 #define elf_backend_object_p            _bfd_mips_elf_object_p
1857 #define elf_backend_section_from_shdr   _bfd_mips_elf_section_from_shdr
1858 #define elf_backend_fake_sections       _bfd_mips_elf_fake_sections
1859 #define elf_backend_section_from_bfd_section \
1860                                         _bfd_mips_elf_section_from_bfd_section
1861 #define elf_backend_section_processing  _bfd_mips_elf_section_processing
1862 #define elf_backend_symbol_processing   _bfd_mips_elf_symbol_processing
1863 #define elf_backend_additional_program_headers \
1864                                         _bfd_mips_elf_additional_program_headers
1865 #define elf_backend_modify_segment_map  _bfd_mips_elf_modify_segment_map
1866 #define elf_backend_final_write_processing \
1867                                         _bfd_mips_elf_final_write_processing
1868 #define elf_backend_ecoff_debug_swap    &mips_elf64_ecoff_debug_swap
1869 #define elf_backend_add_symbol_hook     _bfd_mips_elf_add_symbol_hook
1870 #define elf_backend_create_dynamic_sections \
1871                                         _bfd_mips_elf_create_dynamic_sections
1872 #define elf_backend_check_relocs        _bfd_mips_elf_check_relocs
1873 #define elf_backend_adjust_dynamic_symbol \
1874                                         _bfd_mips_elf_adjust_dynamic_symbol
1875 #define elf_backend_always_size_sections \
1876                                         _bfd_mips_elf_always_size_sections
1877 #define elf_backend_size_dynamic_sections \
1878                                         _bfd_mips_elf_size_dynamic_sections
1879 #define elf_backend_relocate_section    _bfd_mips_elf_relocate_section
1880 #define elf_backend_link_output_symbol_hook \
1881                                         _bfd_mips_elf_link_output_symbol_hook
1882 #define elf_backend_finish_dynamic_symbol \
1883                                         _bfd_mips_elf_finish_dynamic_symbol
1884 #define elf_backend_finish_dynamic_sections \
1885                                         _bfd_mips_elf_finish_dynamic_sections
1886 #define elf_backend_gc_mark_hook        _bfd_mips_elf_gc_mark_hook
1887 #define elf_backend_gc_sweep_hook       _bfd_mips_elf_gc_sweep_hook
1888 #define elf_backend_got_header_size     (4*MIPS_RESERVED_GOTNO)
1889 #define elf_backend_plt_header_size     0
1890
1891 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
1892  * work better/work only in RELA, so we default to this.  */
1893 #define elf_backend_may_use_rel_p       1
1894 #define elf_backend_may_use_rela_p      1
1895 #define elf_backend_default_use_rela_p  1
1896
1897 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
1898    MIPS-specific function only applies to IRIX5, which had no 64-bit
1899    ABI.  */
1900 #define bfd_elf64_find_nearest_line     _bfd_mips_elf_find_nearest_line
1901 #define bfd_elf64_set_section_contents  _bfd_mips_elf_set_section_contents
1902 #define bfd_elf64_bfd_link_hash_table_create \
1903                                         _bfd_mips_elf_link_hash_table_create
1904 #define bfd_elf64_bfd_final_link        _bfd_mips_elf_final_link
1905 #define bfd_elf64_bfd_copy_private_bfd_data \
1906                                         _bfd_mips_elf_copy_private_bfd_data
1907 #define bfd_elf64_bfd_merge_private_bfd_data \
1908                                         _bfd_mips_elf_merge_private_bfd_data
1909 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
1910 #define bfd_elf64_bfd_print_private_bfd_data \
1911                                         _bfd_mips_elf_print_private_bfd_data
1912
1913 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
1914 #define bfd_elf64_bfd_reloc_type_lookup mips_elf64_reloc_type_lookup
1915 #define bfd_elf64_archive_functions
1916 extern boolean bfd_elf64_archive_slurp_armap
1917   PARAMS((bfd *));
1918 extern boolean bfd_elf64_archive_write_armap
1919   PARAMS((bfd *, unsigned int, struct orl *, unsigned int, int));
1920 #define bfd_elf64_archive_slurp_extended_name_table \
1921                                 _bfd_archive_coff_slurp_extended_name_table
1922 #define bfd_elf64_archive_construct_extended_name_table \
1923                                 _bfd_archive_coff_construct_extended_name_table
1924 #define bfd_elf64_archive_truncate_arname \
1925                                         _bfd_archive_coff_truncate_arname
1926 #define bfd_elf64_archive_read_ar_hdr   _bfd_archive_coff_read_ar_hdr
1927 #define bfd_elf64_archive_openr_next_archived_file \
1928                                 _bfd_archive_coff_openr_next_archived_file
1929 #define bfd_elf64_archive_get_elt_at_index \
1930                                         _bfd_archive_coff_get_elt_at_index
1931 #define bfd_elf64_archive_generic_stat_arch_elt \
1932                                         _bfd_archive_coff_generic_stat_arch_elt
1933 #define bfd_elf64_archive_update_armap_timestamp \
1934                                 _bfd_archive_coff_update_armap_timestamp
1935
1936 #include "elf64-target.h"
1937
1938 /* Support for traditional mips targets */
1939
1940 #define INCLUDED_TARGET_FILE            /* More a type of flag */
1941
1942 #undef TARGET_LITTLE_SYM
1943 #undef TARGET_LITTLE_NAME
1944 #undef TARGET_BIG_SYM
1945 #undef TARGET_BIG_NAME
1946
1947 #define TARGET_LITTLE_SYM               bfd_elf64_tradlittlemips_vec
1948 #define TARGET_LITTLE_NAME              "elf64-tradlittlemips"
1949 #define TARGET_BIG_SYM                  bfd_elf64_tradbigmips_vec
1950 #define TARGET_BIG_NAME                 "elf64-tradbigmips"
1951
1952 /* Include the target file again for this target */
1953 #include "elf64-target.h"