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