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