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