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