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