OSDN Git Service

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