OSDN Git Service

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