1 /* MIPS-specific support for 64-bit ELF
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5 Ian Lance Taylor, Cygnus Support
6 Linker support added by Mark Mitchell, CodeSourcery, LLC.
7 <mark@codesourcery.com>
9 This file is part of BFD, the Binary File Descriptor library.
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
24 MA 02110-1301, USA. */
27 /* This file supports the 64-bit MIPS ELF ABI.
29 The MIPS 64-bit ELF ABI uses an unusual reloc format. This file
30 overrides the usual ELF reloc handling, and handles reading and
31 writing the relocations here. */
33 /* TODO: Many things are unsupported, even if there is some code for it
34 . (which was mostly stolen from elf32-mips.c and slightly adapted).
36 . - Relocation handling for REL relocs is wrong in many cases and
38 . - Relocation handling for RELA relocs related to GOT support are
39 . also likely to be wrong.
40 . - Support for MIPS16 is untested.
41 . - Combined relocs with RSS_* entries are unsupported.
42 . - The whole GOT handling for NewABI is missing, some parts of
43 . the OldABI version is still lying around and should be removed.
53 #include "elfxx-mips.h"
56 /* Get the ECOFF swapping routines. The 64-bit ABI is not supposed to
57 use ECOFF. However, we support it anyhow for an easier changeover. */
59 #include "coff/symconst.h"
60 #include "coff/internal.h"
61 #include "coff/ecoff.h"
62 /* The 64 bit versions of the mdebug data structures are in alpha.h. */
63 #include "coff/alpha.h"
64 #define ECOFF_SIGNED_64
65 #include "ecoffswap.h"
67 static void mips_elf64_swap_reloc_in
68 (bfd *, const Elf64_Mips_External_Rel *, Elf64_Mips_Internal_Rela *);
69 static void mips_elf64_swap_reloca_in
70 (bfd *, const Elf64_Mips_External_Rela *, Elf64_Mips_Internal_Rela *);
71 static void mips_elf64_swap_reloc_out
72 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rel *);
73 static void mips_elf64_swap_reloca_out
74 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rela *);
75 static void mips_elf64_be_swap_reloc_in
76 (bfd *, const bfd_byte *, Elf_Internal_Rela *);
77 static void mips_elf64_be_swap_reloc_out
78 (bfd *, const Elf_Internal_Rela *, bfd_byte *);
79 static void mips_elf64_be_swap_reloca_in
80 (bfd *, const bfd_byte *, Elf_Internal_Rela *);
81 static void mips_elf64_be_swap_reloca_out
82 (bfd *, const Elf_Internal_Rela *, bfd_byte *);
83 static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup
84 (bfd *, bfd_reloc_code_real_type);
85 static reloc_howto_type *mips_elf64_rtype_to_howto
86 (unsigned int, bfd_boolean);
87 static void mips_elf64_info_to_howto_rel
88 (bfd *, arelent *, Elf_Internal_Rela *);
89 static void mips_elf64_info_to_howto_rela
90 (bfd *, arelent *, Elf_Internal_Rela *);
91 static long mips_elf64_get_reloc_upper_bound
93 static long mips_elf64_canonicalize_reloc
94 (bfd *, asection *, arelent **, asymbol **);
95 static long mips_elf64_get_dynamic_reloc_upper_bound
97 static long mips_elf64_canonicalize_dynamic_reloc
98 (bfd *, arelent **, asymbol **);
99 static bfd_boolean mips_elf64_slurp_one_reloc_table
100 (bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type, arelent *,
101 asymbol **, bfd_boolean);
102 static bfd_boolean mips_elf64_slurp_reloc_table
103 (bfd *, asection *, asymbol **, bfd_boolean);
104 static void mips_elf64_write_relocs
105 (bfd *, asection *, void *);
106 static void mips_elf64_write_rel
107 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
108 static void mips_elf64_write_rela
109 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
110 static bfd_reloc_status_type mips_elf64_gprel16_reloc
111 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
112 static bfd_reloc_status_type mips_elf64_literal_reloc
113 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
114 static bfd_reloc_status_type mips_elf64_gprel32_reloc
115 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
116 static bfd_reloc_status_type mips_elf64_shift6_reloc
117 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
118 static bfd_reloc_status_type mips16_gprel_reloc
119 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
120 static bfd_boolean mips_elf64_assign_gp
122 static bfd_reloc_status_type mips_elf64_final_gp
123 (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
124 static bfd_boolean mips_elf64_object_p
126 static irix_compat_t elf64_mips_irix_compat
128 static bfd_boolean elf64_mips_grok_prstatus
129 (bfd *, Elf_Internal_Note *);
130 static bfd_boolean elf64_mips_grok_psinfo
131 (bfd *, Elf_Internal_Note *);
133 extern const bfd_target bfd_elf64_bigmips_vec;
134 extern const bfd_target bfd_elf64_littlemips_vec;
136 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
137 from smaller values. Start with zero, widen, *then* decrement. */
138 #define MINUS_ONE (((bfd_vma)0) - 1)
140 /* The number of local .got entries we reserve. */
141 #define MIPS_RESERVED_GOTNO (2)
143 /* The relocation table used for SHT_REL sections. */
145 static reloc_howto_type mips_elf64_howto_table_rel[] =
148 HOWTO (R_MIPS_NONE, /* type */
150 0, /* size (0 = byte, 1 = short, 2 = long) */
152 FALSE, /* pc_relative */
154 complain_overflow_dont, /* complain_on_overflow */
155 _bfd_mips_elf_generic_reloc, /* special_function */
156 "R_MIPS_NONE", /* name */
157 FALSE, /* partial_inplace */
160 FALSE), /* pcrel_offset */
162 /* 16 bit relocation. */
163 HOWTO (R_MIPS_16, /* type */
165 2, /* size (0 = byte, 1 = short, 2 = long) */
167 FALSE, /* pc_relative */
169 complain_overflow_signed, /* complain_on_overflow */
170 _bfd_mips_elf_generic_reloc, /* special_function */
171 "R_MIPS_16", /* name */
172 TRUE, /* partial_inplace */
173 0x0000ffff, /* src_mask */
174 0x0000ffff, /* dst_mask */
175 FALSE), /* pcrel_offset */
177 /* 32 bit relocation. */
178 HOWTO (R_MIPS_32, /* type */
180 2, /* size (0 = byte, 1 = short, 2 = long) */
182 FALSE, /* pc_relative */
184 complain_overflow_dont, /* complain_on_overflow */
185 _bfd_mips_elf_generic_reloc, /* special_function */
186 "R_MIPS_32", /* name */
187 TRUE, /* partial_inplace */
188 0xffffffff, /* src_mask */
189 0xffffffff, /* dst_mask */
190 FALSE), /* pcrel_offset */
192 /* 32 bit symbol relative relocation. */
193 HOWTO (R_MIPS_REL32, /* type */
195 2, /* size (0 = byte, 1 = short, 2 = long) */
197 FALSE, /* pc_relative */
199 complain_overflow_dont, /* complain_on_overflow */
200 _bfd_mips_elf_generic_reloc, /* special_function */
201 "R_MIPS_REL32", /* name */
202 TRUE, /* partial_inplace */
203 0xffffffff, /* src_mask */
204 0xffffffff, /* dst_mask */
205 FALSE), /* pcrel_offset */
207 /* 26 bit jump address. */
208 HOWTO (R_MIPS_26, /* type */
210 2, /* size (0 = byte, 1 = short, 2 = long) */
212 FALSE, /* pc_relative */
214 complain_overflow_dont, /* complain_on_overflow */
215 /* This needs complex overflow
216 detection, because the upper 36
217 bits must match the PC + 4. */
218 _bfd_mips_elf_generic_reloc, /* special_function */
219 "R_MIPS_26", /* name */
220 TRUE, /* partial_inplace */
221 0x03ffffff, /* src_mask */
222 0x03ffffff, /* dst_mask */
223 FALSE), /* pcrel_offset */
225 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
226 However, the native IRIX6 tools use them, so we try our best. */
228 /* High 16 bits of symbol value. */
229 HOWTO (R_MIPS_HI16, /* type */
231 2, /* size (0 = byte, 1 = short, 2 = long) */
233 FALSE, /* pc_relative */
235 complain_overflow_dont, /* complain_on_overflow */
236 _bfd_mips_elf_hi16_reloc, /* special_function */
237 "R_MIPS_HI16", /* name */
238 TRUE, /* partial_inplace */
239 0x0000ffff, /* src_mask */
240 0x0000ffff, /* dst_mask */
241 FALSE), /* pcrel_offset */
243 /* Low 16 bits of symbol value. */
244 HOWTO (R_MIPS_LO16, /* type */
246 2, /* size (0 = byte, 1 = short, 2 = long) */
248 FALSE, /* pc_relative */
250 complain_overflow_dont, /* complain_on_overflow */
251 _bfd_mips_elf_lo16_reloc, /* special_function */
252 "R_MIPS_LO16", /* name */
253 TRUE, /* partial_inplace */
254 0x0000ffff, /* src_mask */
255 0x0000ffff, /* dst_mask */
256 FALSE), /* pcrel_offset */
258 /* GP relative reference. */
259 HOWTO (R_MIPS_GPREL16, /* type */
261 2, /* size (0 = byte, 1 = short, 2 = long) */
263 FALSE, /* pc_relative */
265 complain_overflow_signed, /* complain_on_overflow */
266 mips_elf64_gprel16_reloc, /* special_function */
267 "R_MIPS_GPREL16", /* name */
268 TRUE, /* partial_inplace */
269 0x0000ffff, /* src_mask */
270 0x0000ffff, /* dst_mask */
271 FALSE), /* pcrel_offset */
273 /* Reference to literal section. */
274 HOWTO (R_MIPS_LITERAL, /* type */
276 2, /* size (0 = byte, 1 = short, 2 = long) */
278 FALSE, /* pc_relative */
280 complain_overflow_signed, /* complain_on_overflow */
281 mips_elf64_literal_reloc, /* special_function */
282 "R_MIPS_LITERAL", /* name */
283 TRUE, /* partial_inplace */
284 0x0000ffff, /* src_mask */
285 0x0000ffff, /* dst_mask */
286 FALSE), /* pcrel_offset */
288 /* Reference to global offset table. */
289 HOWTO (R_MIPS_GOT16, /* type */
291 2, /* size (0 = byte, 1 = short, 2 = long) */
293 FALSE, /* pc_relative */
295 complain_overflow_signed, /* complain_on_overflow */
296 _bfd_mips_elf_got16_reloc, /* special_function */
297 "R_MIPS_GOT16", /* name */
298 TRUE, /* partial_inplace */
299 0x0000ffff, /* src_mask */
300 0x0000ffff, /* dst_mask */
301 FALSE), /* pcrel_offset */
303 /* 16 bit PC relative reference. Note that the ABI document has a typo
304 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
305 We do the right thing here. */
306 HOWTO (R_MIPS_PC16, /* type */
308 2, /* size (0 = byte, 1 = short, 2 = long) */
310 TRUE, /* pc_relative */
312 complain_overflow_signed, /* complain_on_overflow */
313 _bfd_mips_elf_generic_reloc, /* special_function */
314 "R_MIPS_PC16", /* name */
315 TRUE, /* partial_inplace */
316 0x0000ffff, /* src_mask */
317 0x0000ffff, /* dst_mask */
318 TRUE), /* pcrel_offset */
320 /* 16 bit call through global offset table. */
321 HOWTO (R_MIPS_CALL16, /* type */
323 2, /* size (0 = byte, 1 = short, 2 = long) */
325 FALSE, /* pc_relative */
327 complain_overflow_signed, /* complain_on_overflow */
328 _bfd_mips_elf_generic_reloc, /* special_function */
329 "R_MIPS_CALL16", /* name */
330 TRUE, /* partial_inplace */
331 0x0000ffff, /* src_mask */
332 0x0000ffff, /* dst_mask */
333 FALSE), /* pcrel_offset */
335 /* 32 bit GP relative reference. */
336 HOWTO (R_MIPS_GPREL32, /* type */
338 2, /* size (0 = byte, 1 = short, 2 = long) */
340 FALSE, /* pc_relative */
342 complain_overflow_dont, /* complain_on_overflow */
343 mips_elf64_gprel32_reloc, /* special_function */
344 "R_MIPS_GPREL32", /* name */
345 TRUE, /* partial_inplace */
346 0xffffffff, /* src_mask */
347 0xffffffff, /* dst_mask */
348 FALSE), /* pcrel_offset */
354 /* A 5 bit shift field. */
355 HOWTO (R_MIPS_SHIFT5, /* type */
357 2, /* size (0 = byte, 1 = short, 2 = long) */
359 FALSE, /* pc_relative */
361 complain_overflow_bitfield, /* complain_on_overflow */
362 _bfd_mips_elf_generic_reloc, /* special_function */
363 "R_MIPS_SHIFT5", /* name */
364 TRUE, /* partial_inplace */
365 0x000007c0, /* src_mask */
366 0x000007c0, /* dst_mask */
367 FALSE), /* pcrel_offset */
369 /* A 6 bit shift field. */
370 HOWTO (R_MIPS_SHIFT6, /* type */
372 2, /* size (0 = byte, 1 = short, 2 = long) */
374 FALSE, /* pc_relative */
376 complain_overflow_bitfield, /* complain_on_overflow */
377 mips_elf64_shift6_reloc, /* special_function */
378 "R_MIPS_SHIFT6", /* name */
379 TRUE, /* partial_inplace */
380 0x000007c4, /* src_mask */
381 0x000007c4, /* dst_mask */
382 FALSE), /* pcrel_offset */
384 /* 64 bit relocation. */
385 HOWTO (R_MIPS_64, /* type */
387 4, /* size (0 = byte, 1 = short, 2 = long) */
389 FALSE, /* pc_relative */
391 complain_overflow_dont, /* complain_on_overflow */
392 _bfd_mips_elf_generic_reloc, /* special_function */
393 "R_MIPS_64", /* name */
394 TRUE, /* partial_inplace */
395 MINUS_ONE, /* src_mask */
396 MINUS_ONE, /* dst_mask */
397 FALSE), /* pcrel_offset */
399 /* Displacement in the global offset table. */
400 HOWTO (R_MIPS_GOT_DISP, /* type */
402 2, /* size (0 = byte, 1 = short, 2 = long) */
404 FALSE, /* pc_relative */
406 complain_overflow_signed, /* complain_on_overflow */
407 _bfd_mips_elf_generic_reloc, /* special_function */
408 "R_MIPS_GOT_DISP", /* name */
409 TRUE, /* partial_inplace */
410 0x0000ffff, /* src_mask */
411 0x0000ffff, /* dst_mask */
412 FALSE), /* pcrel_offset */
414 /* Displacement to page pointer in the global offset table. */
415 HOWTO (R_MIPS_GOT_PAGE, /* type */
417 2, /* size (0 = byte, 1 = short, 2 = long) */
419 FALSE, /* pc_relative */
421 complain_overflow_signed, /* complain_on_overflow */
422 _bfd_mips_elf_generic_reloc, /* special_function */
423 "R_MIPS_GOT_PAGE", /* name */
424 TRUE, /* partial_inplace */
425 0x0000ffff, /* src_mask */
426 0x0000ffff, /* dst_mask */
427 FALSE), /* pcrel_offset */
429 /* Offset from page pointer in the global offset table. */
430 HOWTO (R_MIPS_GOT_OFST, /* type */
432 2, /* size (0 = byte, 1 = short, 2 = long) */
434 FALSE, /* pc_relative */
436 complain_overflow_signed, /* complain_on_overflow */
437 _bfd_mips_elf_generic_reloc, /* special_function */
438 "R_MIPS_GOT_OFST", /* name */
439 TRUE, /* partial_inplace */
440 0x0000ffff, /* src_mask */
441 0x0000ffff, /* dst_mask */
442 FALSE), /* pcrel_offset */
444 /* High 16 bits of displacement in global offset table. */
445 HOWTO (R_MIPS_GOT_HI16, /* type */
447 2, /* size (0 = byte, 1 = short, 2 = long) */
449 FALSE, /* pc_relative */
451 complain_overflow_dont, /* complain_on_overflow */
452 _bfd_mips_elf_generic_reloc, /* special_function */
453 "R_MIPS_GOT_HI16", /* name */
454 TRUE, /* partial_inplace */
455 0x0000ffff, /* src_mask */
456 0x0000ffff, /* dst_mask */
457 FALSE), /* pcrel_offset */
459 /* Low 16 bits of displacement in global offset table. */
460 HOWTO (R_MIPS_GOT_LO16, /* type */
462 2, /* size (0 = byte, 1 = short, 2 = long) */
464 FALSE, /* pc_relative */
466 complain_overflow_dont, /* complain_on_overflow */
467 _bfd_mips_elf_generic_reloc, /* special_function */
468 "R_MIPS_GOT_LO16", /* name */
469 TRUE, /* partial_inplace */
470 0x0000ffff, /* src_mask */
471 0x0000ffff, /* dst_mask */
472 FALSE), /* pcrel_offset */
474 /* 64 bit subtraction. */
475 HOWTO (R_MIPS_SUB, /* type */
477 4, /* size (0 = byte, 1 = short, 2 = long) */
479 FALSE, /* pc_relative */
481 complain_overflow_dont, /* complain_on_overflow */
482 _bfd_mips_elf_generic_reloc, /* special_function */
483 "R_MIPS_SUB", /* name */
484 TRUE, /* partial_inplace */
485 MINUS_ONE, /* src_mask */
486 MINUS_ONE, /* dst_mask */
487 FALSE), /* pcrel_offset */
489 /* Insert the addend as an instruction. */
490 /* FIXME: Not handled correctly. */
491 HOWTO (R_MIPS_INSERT_A, /* type */
493 2, /* size (0 = byte, 1 = short, 2 = long) */
495 FALSE, /* pc_relative */
497 complain_overflow_dont, /* complain_on_overflow */
498 _bfd_mips_elf_generic_reloc, /* special_function */
499 "R_MIPS_INSERT_A", /* name */
500 TRUE, /* partial_inplace */
501 0xffffffff, /* src_mask */
502 0xffffffff, /* dst_mask */
503 FALSE), /* pcrel_offset */
505 /* Insert the addend as an instruction, and change all relocations
506 to refer to the old instruction at the address. */
507 /* FIXME: Not handled correctly. */
508 HOWTO (R_MIPS_INSERT_B, /* type */
510 2, /* size (0 = byte, 1 = short, 2 = long) */
512 FALSE, /* pc_relative */
514 complain_overflow_dont, /* complain_on_overflow */
515 _bfd_mips_elf_generic_reloc, /* special_function */
516 "R_MIPS_INSERT_B", /* name */
517 TRUE, /* partial_inplace */
518 0xffffffff, /* src_mask */
519 0xffffffff, /* dst_mask */
520 FALSE), /* pcrel_offset */
522 /* Delete a 32 bit instruction. */
523 /* FIXME: Not handled correctly. */
524 HOWTO (R_MIPS_DELETE, /* type */
526 2, /* size (0 = byte, 1 = short, 2 = long) */
528 FALSE, /* pc_relative */
530 complain_overflow_dont, /* complain_on_overflow */
531 _bfd_mips_elf_generic_reloc, /* special_function */
532 "R_MIPS_DELETE", /* name */
533 TRUE, /* partial_inplace */
534 0xffffffff, /* src_mask */
535 0xffffffff, /* dst_mask */
536 FALSE), /* pcrel_offset */
538 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
540 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
541 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
543 b) No other NewABI toolchain actually emits such relocations. */
544 EMPTY_HOWTO (R_MIPS_HIGHER),
545 EMPTY_HOWTO (R_MIPS_HIGHEST),
547 /* High 16 bits of displacement in global offset table. */
548 HOWTO (R_MIPS_CALL_HI16, /* type */
550 2, /* size (0 = byte, 1 = short, 2 = long) */
552 FALSE, /* pc_relative */
554 complain_overflow_dont, /* complain_on_overflow */
555 _bfd_mips_elf_generic_reloc, /* special_function */
556 "R_MIPS_CALL_HI16", /* name */
557 TRUE, /* partial_inplace */
558 0x0000ffff, /* src_mask */
559 0x0000ffff, /* dst_mask */
560 FALSE), /* pcrel_offset */
562 /* Low 16 bits of displacement in global offset table. */
563 HOWTO (R_MIPS_CALL_LO16, /* type */
565 2, /* size (0 = byte, 1 = short, 2 = long) */
567 FALSE, /* pc_relative */
569 complain_overflow_dont, /* complain_on_overflow */
570 _bfd_mips_elf_generic_reloc, /* special_function */
571 "R_MIPS_CALL_LO16", /* name */
572 TRUE, /* partial_inplace */
573 0x0000ffff, /* src_mask */
574 0x0000ffff, /* dst_mask */
575 FALSE), /* pcrel_offset */
577 /* Section displacement, used by an associated event location section. */
578 HOWTO (R_MIPS_SCN_DISP, /* type */
580 2, /* size (0 = byte, 1 = short, 2 = long) */
582 FALSE, /* pc_relative */
584 complain_overflow_dont, /* complain_on_overflow */
585 _bfd_mips_elf_generic_reloc, /* special_function */
586 "R_MIPS_SCN_DISP", /* name */
587 TRUE, /* partial_inplace */
588 0xffffffff, /* src_mask */
589 0xffffffff, /* dst_mask */
590 FALSE), /* pcrel_offset */
592 HOWTO (R_MIPS_REL16, /* type */
594 1, /* size (0 = byte, 1 = short, 2 = long) */
596 FALSE, /* pc_relative */
598 complain_overflow_signed, /* complain_on_overflow */
599 _bfd_mips_elf_generic_reloc, /* special_function */
600 "R_MIPS_REL16", /* name */
601 TRUE, /* partial_inplace */
602 0xffff, /* src_mask */
603 0xffff, /* dst_mask */
604 FALSE), /* pcrel_offset */
606 /* These two are obsolete. */
607 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
608 EMPTY_HOWTO (R_MIPS_PJUMP),
610 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
611 It must be used for multigot GOT's (and only there). */
612 HOWTO (R_MIPS_RELGOT, /* type */
614 2, /* size (0 = byte, 1 = short, 2 = long) */
616 FALSE, /* pc_relative */
618 complain_overflow_dont, /* complain_on_overflow */
619 _bfd_mips_elf_generic_reloc, /* special_function */
620 "R_MIPS_RELGOT", /* name */
621 TRUE, /* partial_inplace */
622 0xffffffff, /* src_mask */
623 0xffffffff, /* dst_mask */
624 FALSE), /* pcrel_offset */
626 /* Protected jump conversion. This is an optimization hint. No
627 relocation is required for correctness. */
628 HOWTO (R_MIPS_JALR, /* type */
630 2, /* size (0 = byte, 1 = short, 2 = long) */
632 FALSE, /* pc_relative */
634 complain_overflow_dont, /* complain_on_overflow */
635 _bfd_mips_elf_generic_reloc, /* special_function */
636 "R_MIPS_JALR", /* name */
637 FALSE, /* partial_inplace */
639 0x00000000, /* dst_mask */
640 FALSE), /* pcrel_offset */
642 /* TLS relocations. */
643 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
644 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
646 HOWTO (R_MIPS_TLS_DTPMOD64, /* type */
648 4, /* size (0 = byte, 1 = short, 2 = long) */
650 FALSE, /* pc_relative */
652 complain_overflow_dont, /* complain_on_overflow */
653 _bfd_mips_elf_generic_reloc, /* special_function */
654 "R_MIPS_TLS_DTPMOD64", /* name */
655 TRUE, /* partial_inplace */
656 MINUS_ONE, /* src_mask */
657 MINUS_ONE, /* dst_mask */
658 FALSE), /* pcrel_offset */
660 HOWTO (R_MIPS_TLS_DTPREL64, /* type */
662 4, /* size (0 = byte, 1 = short, 2 = long) */
664 FALSE, /* pc_relative */
666 complain_overflow_dont, /* complain_on_overflow */
667 _bfd_mips_elf_generic_reloc, /* special_function */
668 "R_MIPS_TLS_DTPREL64", /* name */
669 TRUE, /* partial_inplace */
670 MINUS_ONE, /* src_mask */
671 MINUS_ONE, /* dst_mask */
672 FALSE), /* pcrel_offset */
674 /* TLS general dynamic variable reference. */
675 HOWTO (R_MIPS_TLS_GD, /* type */
677 2, /* size (0 = byte, 1 = short, 2 = long) */
679 FALSE, /* pc_relative */
681 complain_overflow_signed, /* complain_on_overflow */
682 _bfd_mips_elf_generic_reloc, /* special_function */
683 "R_MIPS_TLS_GD", /* name */
684 TRUE, /* partial_inplace */
685 0x0000ffff, /* src_mask */
686 0x0000ffff, /* dst_mask */
687 FALSE), /* pcrel_offset */
689 /* TLS local dynamic variable reference. */
690 HOWTO (R_MIPS_TLS_LDM, /* type */
692 2, /* size (0 = byte, 1 = short, 2 = long) */
694 FALSE, /* pc_relative */
696 complain_overflow_signed, /* complain_on_overflow */
697 _bfd_mips_elf_generic_reloc, /* special_function */
698 "R_MIPS_TLS_LDM", /* name */
699 TRUE, /* partial_inplace */
700 0x0000ffff, /* src_mask */
701 0x0000ffff, /* dst_mask */
702 FALSE), /* pcrel_offset */
704 /* TLS local dynamic offset. */
705 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
707 2, /* size (0 = byte, 1 = short, 2 = long) */
709 FALSE, /* pc_relative */
711 complain_overflow_signed, /* complain_on_overflow */
712 _bfd_mips_elf_generic_reloc, /* special_function */
713 "R_MIPS_TLS_DTPREL_HI16", /* name */
714 TRUE, /* partial_inplace */
715 0x0000ffff, /* src_mask */
716 0x0000ffff, /* dst_mask */
717 FALSE), /* pcrel_offset */
719 /* TLS local dynamic offset. */
720 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
722 2, /* size (0 = byte, 1 = short, 2 = long) */
724 FALSE, /* pc_relative */
726 complain_overflow_signed, /* complain_on_overflow */
727 _bfd_mips_elf_generic_reloc, /* special_function */
728 "R_MIPS_TLS_DTPREL_LO16", /* name */
729 TRUE, /* partial_inplace */
730 0x0000ffff, /* src_mask */
731 0x0000ffff, /* dst_mask */
732 FALSE), /* pcrel_offset */
734 /* TLS thread pointer offset. */
735 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
737 2, /* size (0 = byte, 1 = short, 2 = long) */
739 FALSE, /* pc_relative */
741 complain_overflow_signed, /* complain_on_overflow */
742 _bfd_mips_elf_generic_reloc, /* special_function */
743 "R_MIPS_TLS_GOTTPREL", /* name */
744 TRUE, /* partial_inplace */
745 0x0000ffff, /* src_mask */
746 0x0000ffff, /* dst_mask */
747 FALSE), /* pcrel_offset */
749 /* TLS IE dynamic relocations. */
750 EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
752 HOWTO (R_MIPS_TLS_TPREL64, /* type */
754 4, /* size (0 = byte, 1 = short, 2 = long) */
756 FALSE, /* pc_relative */
758 complain_overflow_dont, /* complain_on_overflow */
759 _bfd_mips_elf_generic_reloc, /* special_function */
760 "R_MIPS_TLS_TPREL64", /* name */
761 TRUE, /* partial_inplace */
762 MINUS_ONE, /* src_mask */
763 MINUS_ONE, /* dst_mask */
764 FALSE), /* pcrel_offset */
766 /* TLS thread pointer offset. */
767 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
769 2, /* size (0 = byte, 1 = short, 2 = long) */
771 FALSE, /* pc_relative */
773 complain_overflow_signed, /* complain_on_overflow */
774 _bfd_mips_elf_generic_reloc, /* special_function */
775 "R_MIPS_TLS_TPREL_HI16", /* name */
776 TRUE, /* partial_inplace */
777 0x0000ffff, /* src_mask */
778 0x0000ffff, /* dst_mask */
779 FALSE), /* pcrel_offset */
781 /* TLS thread pointer offset. */
782 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
784 2, /* size (0 = byte, 1 = short, 2 = long) */
786 FALSE, /* pc_relative */
788 complain_overflow_signed, /* complain_on_overflow */
789 _bfd_mips_elf_generic_reloc, /* special_function */
790 "R_MIPS_TLS_TPREL_LO16", /* name */
791 TRUE, /* partial_inplace */
792 0x0000ffff, /* src_mask */
793 0x0000ffff, /* dst_mask */
794 FALSE), /* pcrel_offset */
796 /* 32 bit relocation with no addend. */
797 HOWTO (R_MIPS_GLOB_DAT, /* type */
799 2, /* size (0 = byte, 1 = short, 2 = long) */
801 FALSE, /* pc_relative */
803 complain_overflow_dont, /* complain_on_overflow */
804 _bfd_mips_elf_generic_reloc, /* special_function */
805 "R_MIPS_GLOB_DAT", /* name */
806 FALSE, /* partial_inplace */
808 0xffffffff, /* dst_mask */
809 FALSE), /* pcrel_offset */
812 /* The relocation table used for SHT_RELA sections. */
814 static reloc_howto_type mips_elf64_howto_table_rela[] =
817 HOWTO (R_MIPS_NONE, /* type */
819 0, /* size (0 = byte, 1 = short, 2 = long) */
821 FALSE, /* pc_relative */
823 complain_overflow_dont, /* complain_on_overflow */
824 _bfd_mips_elf_generic_reloc, /* special_function */
825 "R_MIPS_NONE", /* name */
826 FALSE, /* partial_inplace */
829 FALSE), /* pcrel_offset */
831 /* 16 bit relocation. */
832 HOWTO (R_MIPS_16, /* type */
834 2, /* size (0 = byte, 1 = short, 2 = long) */
836 FALSE, /* pc_relative */
838 complain_overflow_signed, /* complain_on_overflow */
839 _bfd_mips_elf_generic_reloc, /* special_function */
840 "R_MIPS_16", /* name */
841 FALSE, /* partial_inplace */
843 0x0000ffff, /* dst_mask */
844 FALSE), /* pcrel_offset */
846 /* 32 bit relocation. */
847 HOWTO (R_MIPS_32, /* type */
849 2, /* size (0 = byte, 1 = short, 2 = long) */
851 FALSE, /* pc_relative */
853 complain_overflow_dont, /* complain_on_overflow */
854 _bfd_mips_elf_generic_reloc, /* special_function */
855 "R_MIPS_32", /* name */
856 FALSE, /* partial_inplace */
858 0xffffffff, /* dst_mask */
859 FALSE), /* pcrel_offset */
861 /* 32 bit symbol relative relocation. */
862 HOWTO (R_MIPS_REL32, /* type */
864 2, /* size (0 = byte, 1 = short, 2 = long) */
866 FALSE, /* pc_relative */
868 complain_overflow_dont, /* complain_on_overflow */
869 _bfd_mips_elf_generic_reloc, /* special_function */
870 "R_MIPS_REL32", /* name */
871 FALSE, /* partial_inplace */
873 0xffffffff, /* dst_mask */
874 FALSE), /* pcrel_offset */
876 /* 26 bit jump address. */
877 HOWTO (R_MIPS_26, /* type */
879 2, /* size (0 = byte, 1 = short, 2 = long) */
881 FALSE, /* pc_relative */
883 complain_overflow_dont, /* complain_on_overflow */
884 /* This needs complex overflow
885 detection, because the upper 36
886 bits must match the PC + 4. */
887 _bfd_mips_elf_generic_reloc, /* special_function */
888 "R_MIPS_26", /* name */
889 FALSE, /* partial_inplace */
891 0x03ffffff, /* dst_mask */
892 FALSE), /* pcrel_offset */
894 /* High 16 bits of symbol value. */
895 HOWTO (R_MIPS_HI16, /* type */
897 2, /* size (0 = byte, 1 = short, 2 = long) */
899 FALSE, /* pc_relative */
901 complain_overflow_dont, /* complain_on_overflow */
902 _bfd_mips_elf_generic_reloc, /* special_function */
903 "R_MIPS_HI16", /* name */
904 FALSE, /* partial_inplace */
906 0x0000ffff, /* dst_mask */
907 FALSE), /* pcrel_offset */
909 /* Low 16 bits of symbol value. */
910 HOWTO (R_MIPS_LO16, /* type */
912 2, /* size (0 = byte, 1 = short, 2 = long) */
914 FALSE, /* pc_relative */
916 complain_overflow_dont, /* complain_on_overflow */
917 _bfd_mips_elf_generic_reloc, /* special_function */
918 "R_MIPS_LO16", /* name */
919 FALSE, /* partial_inplace */
921 0x0000ffff, /* dst_mask */
922 FALSE), /* pcrel_offset */
924 /* GP relative reference. */
925 HOWTO (R_MIPS_GPREL16, /* type */
927 2, /* size (0 = byte, 1 = short, 2 = long) */
929 FALSE, /* pc_relative */
931 complain_overflow_signed, /* complain_on_overflow */
932 mips_elf64_gprel16_reloc, /* special_function */
933 "R_MIPS_GPREL16", /* name */
934 FALSE, /* partial_inplace */
936 0x0000ffff, /* dst_mask */
937 FALSE), /* pcrel_offset */
939 /* Reference to literal section. */
940 HOWTO (R_MIPS_LITERAL, /* type */
942 2, /* size (0 = byte, 1 = short, 2 = long) */
944 FALSE, /* pc_relative */
946 complain_overflow_signed, /* complain_on_overflow */
947 mips_elf64_literal_reloc, /* special_function */
948 "R_MIPS_LITERAL", /* name */
949 FALSE, /* partial_inplace */
951 0x0000ffff, /* dst_mask */
952 FALSE), /* pcrel_offset */
954 /* Reference to global offset table. */
955 HOWTO (R_MIPS_GOT16, /* type */
957 2, /* size (0 = byte, 1 = short, 2 = long) */
959 FALSE, /* pc_relative */
961 complain_overflow_signed, /* complain_on_overflow */
962 _bfd_mips_elf_generic_reloc, /* special_function */
963 "R_MIPS_GOT16", /* name */
964 FALSE, /* partial_inplace */
966 0x0000ffff, /* dst_mask */
967 FALSE), /* pcrel_offset */
969 /* 16 bit PC relative reference. Note that the ABI document has a typo
970 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
971 We do the right thing here. */
972 HOWTO (R_MIPS_PC16, /* type */
974 2, /* size (0 = byte, 1 = short, 2 = long) */
976 TRUE, /* pc_relative */
978 complain_overflow_signed, /* complain_on_overflow */
979 _bfd_mips_elf_generic_reloc, /* special_function */
980 "R_MIPS_PC16", /* name */
981 FALSE, /* partial_inplace */
983 0x0000ffff, /* dst_mask */
984 TRUE), /* pcrel_offset */
986 /* 16 bit call through global offset table. */
987 HOWTO (R_MIPS_CALL16, /* type */
989 2, /* size (0 = byte, 1 = short, 2 = long) */
991 FALSE, /* pc_relative */
993 complain_overflow_signed, /* complain_on_overflow */
994 _bfd_mips_elf_generic_reloc, /* special_function */
995 "R_MIPS_CALL16", /* name */
996 FALSE, /* partial_inplace */
998 0x0000ffff, /* dst_mask */
999 FALSE), /* pcrel_offset */
1001 /* 32 bit GP relative reference. */
1002 HOWTO (R_MIPS_GPREL32, /* type */
1004 2, /* size (0 = byte, 1 = short, 2 = long) */
1006 FALSE, /* pc_relative */
1008 complain_overflow_dont, /* complain_on_overflow */
1009 mips_elf64_gprel32_reloc, /* special_function */
1010 "R_MIPS_GPREL32", /* name */
1011 FALSE, /* partial_inplace */
1013 0xffffffff, /* dst_mask */
1014 FALSE), /* pcrel_offset */
1020 /* A 5 bit shift field. */
1021 HOWTO (R_MIPS_SHIFT5, /* type */
1023 2, /* size (0 = byte, 1 = short, 2 = long) */
1025 FALSE, /* pc_relative */
1027 complain_overflow_bitfield, /* complain_on_overflow */
1028 _bfd_mips_elf_generic_reloc, /* special_function */
1029 "R_MIPS_SHIFT5", /* name */
1030 FALSE, /* partial_inplace */
1032 0x000007c0, /* dst_mask */
1033 FALSE), /* pcrel_offset */
1035 /* A 6 bit shift field. */
1036 HOWTO (R_MIPS_SHIFT6, /* type */
1038 2, /* size (0 = byte, 1 = short, 2 = long) */
1040 FALSE, /* pc_relative */
1042 complain_overflow_bitfield, /* complain_on_overflow */
1043 mips_elf64_shift6_reloc, /* special_function */
1044 "R_MIPS_SHIFT6", /* name */
1045 FALSE, /* partial_inplace */
1047 0x000007c4, /* dst_mask */
1048 FALSE), /* pcrel_offset */
1050 /* 64 bit relocation. */
1051 HOWTO (R_MIPS_64, /* type */
1053 4, /* size (0 = byte, 1 = short, 2 = long) */
1055 FALSE, /* pc_relative */
1057 complain_overflow_dont, /* complain_on_overflow */
1058 _bfd_mips_elf_generic_reloc, /* special_function */
1059 "R_MIPS_64", /* name */
1060 FALSE, /* partial_inplace */
1062 MINUS_ONE, /* dst_mask */
1063 FALSE), /* pcrel_offset */
1065 /* Displacement in the global offset table. */
1066 HOWTO (R_MIPS_GOT_DISP, /* type */
1068 2, /* size (0 = byte, 1 = short, 2 = long) */
1070 FALSE, /* pc_relative */
1072 complain_overflow_signed, /* complain_on_overflow */
1073 _bfd_mips_elf_generic_reloc, /* special_function */
1074 "R_MIPS_GOT_DISP", /* name */
1075 FALSE, /* partial_inplace */
1077 0x0000ffff, /* dst_mask */
1078 FALSE), /* pcrel_offset */
1080 /* Displacement to page pointer in the global offset table. */
1081 HOWTO (R_MIPS_GOT_PAGE, /* type */
1083 2, /* size (0 = byte, 1 = short, 2 = long) */
1085 FALSE, /* pc_relative */
1087 complain_overflow_signed, /* complain_on_overflow */
1088 _bfd_mips_elf_generic_reloc, /* special_function */
1089 "R_MIPS_GOT_PAGE", /* name */
1090 FALSE, /* partial_inplace */
1092 0x0000ffff, /* dst_mask */
1093 FALSE), /* pcrel_offset */
1095 /* Offset from page pointer in the global offset table. */
1096 HOWTO (R_MIPS_GOT_OFST, /* type */
1098 2, /* size (0 = byte, 1 = short, 2 = long) */
1100 FALSE, /* pc_relative */
1102 complain_overflow_signed, /* complain_on_overflow */
1103 _bfd_mips_elf_generic_reloc, /* special_function */
1104 "R_MIPS_GOT_OFST", /* name */
1105 FALSE, /* partial_inplace */
1107 0x0000ffff, /* dst_mask */
1108 FALSE), /* pcrel_offset */
1110 /* High 16 bits of displacement in global offset table. */
1111 HOWTO (R_MIPS_GOT_HI16, /* type */
1113 2, /* size (0 = byte, 1 = short, 2 = long) */
1115 FALSE, /* pc_relative */
1117 complain_overflow_dont, /* complain_on_overflow */
1118 _bfd_mips_elf_generic_reloc, /* special_function */
1119 "R_MIPS_GOT_HI16", /* name */
1120 FALSE, /* partial_inplace */
1122 0x0000ffff, /* dst_mask */
1123 FALSE), /* pcrel_offset */
1125 /* Low 16 bits of displacement in global offset table. */
1126 HOWTO (R_MIPS_GOT_LO16, /* type */
1128 2, /* size (0 = byte, 1 = short, 2 = long) */
1130 FALSE, /* pc_relative */
1132 complain_overflow_dont, /* complain_on_overflow */
1133 _bfd_mips_elf_generic_reloc, /* special_function */
1134 "R_MIPS_GOT_LO16", /* name */
1135 FALSE, /* partial_inplace */
1137 0x0000ffff, /* dst_mask */
1138 FALSE), /* pcrel_offset */
1140 /* 64 bit subtraction. */
1141 HOWTO (R_MIPS_SUB, /* type */
1143 4, /* size (0 = byte, 1 = short, 2 = long) */
1145 FALSE, /* pc_relative */
1147 complain_overflow_dont, /* complain_on_overflow */
1148 _bfd_mips_elf_generic_reloc, /* special_function */
1149 "R_MIPS_SUB", /* name */
1150 FALSE, /* partial_inplace */
1152 MINUS_ONE, /* dst_mask */
1153 FALSE), /* pcrel_offset */
1155 /* Insert the addend as an instruction. */
1156 /* FIXME: Not handled correctly. */
1157 HOWTO (R_MIPS_INSERT_A, /* type */
1159 2, /* size (0 = byte, 1 = short, 2 = long) */
1161 FALSE, /* pc_relative */
1163 complain_overflow_dont, /* complain_on_overflow */
1164 _bfd_mips_elf_generic_reloc, /* special_function */
1165 "R_MIPS_INSERT_A", /* name */
1166 FALSE, /* partial_inplace */
1168 0xffffffff, /* dst_mask */
1169 FALSE), /* pcrel_offset */
1171 /* Insert the addend as an instruction, and change all relocations
1172 to refer to the old instruction at the address. */
1173 /* FIXME: Not handled correctly. */
1174 HOWTO (R_MIPS_INSERT_B, /* type */
1176 2, /* size (0 = byte, 1 = short, 2 = long) */
1178 FALSE, /* pc_relative */
1180 complain_overflow_dont, /* complain_on_overflow */
1181 _bfd_mips_elf_generic_reloc, /* special_function */
1182 "R_MIPS_INSERT_B", /* name */
1183 FALSE, /* partial_inplace */
1185 0xffffffff, /* dst_mask */
1186 FALSE), /* pcrel_offset */
1188 /* Delete a 32 bit instruction. */
1189 /* FIXME: Not handled correctly. */
1190 HOWTO (R_MIPS_DELETE, /* type */
1192 2, /* size (0 = byte, 1 = short, 2 = long) */
1194 FALSE, /* pc_relative */
1196 complain_overflow_dont, /* complain_on_overflow */
1197 _bfd_mips_elf_generic_reloc, /* special_function */
1198 "R_MIPS_DELETE", /* name */
1199 FALSE, /* partial_inplace */
1201 0xffffffff, /* dst_mask */
1202 FALSE), /* pcrel_offset */
1204 /* Get the higher value of a 64 bit addend. */
1205 HOWTO (R_MIPS_HIGHER, /* type */
1207 2, /* size (0 = byte, 1 = short, 2 = long) */
1209 FALSE, /* pc_relative */
1211 complain_overflow_dont, /* complain_on_overflow */
1212 _bfd_mips_elf_generic_reloc, /* special_function */
1213 "R_MIPS_HIGHER", /* name */
1214 FALSE, /* partial_inplace */
1216 0x0000ffff, /* dst_mask */
1217 FALSE), /* pcrel_offset */
1219 /* Get the highest value of a 64 bit addend. */
1220 HOWTO (R_MIPS_HIGHEST, /* type */
1222 2, /* size (0 = byte, 1 = short, 2 = long) */
1224 FALSE, /* pc_relative */
1226 complain_overflow_dont, /* complain_on_overflow */
1227 _bfd_mips_elf_generic_reloc, /* special_function */
1228 "R_MIPS_HIGHEST", /* name */
1229 FALSE, /* partial_inplace */
1231 0x0000ffff, /* dst_mask */
1232 FALSE), /* pcrel_offset */
1234 /* High 16 bits of displacement in global offset table. */
1235 HOWTO (R_MIPS_CALL_HI16, /* type */
1237 2, /* size (0 = byte, 1 = short, 2 = long) */
1239 FALSE, /* pc_relative */
1241 complain_overflow_dont, /* complain_on_overflow */
1242 _bfd_mips_elf_generic_reloc, /* special_function */
1243 "R_MIPS_CALL_HI16", /* name */
1244 FALSE, /* partial_inplace */
1246 0x0000ffff, /* dst_mask */
1247 FALSE), /* pcrel_offset */
1249 /* Low 16 bits of displacement in global offset table. */
1250 HOWTO (R_MIPS_CALL_LO16, /* type */
1252 2, /* size (0 = byte, 1 = short, 2 = long) */
1254 FALSE, /* pc_relative */
1256 complain_overflow_dont, /* complain_on_overflow */
1257 _bfd_mips_elf_generic_reloc, /* special_function */
1258 "R_MIPS_CALL_LO16", /* name */
1259 FALSE, /* partial_inplace */
1261 0x0000ffff, /* dst_mask */
1262 FALSE), /* pcrel_offset */
1264 /* Section displacement, used by an associated event location section. */
1265 HOWTO (R_MIPS_SCN_DISP, /* type */
1267 2, /* size (0 = byte, 1 = short, 2 = long) */
1269 FALSE, /* pc_relative */
1271 complain_overflow_dont, /* complain_on_overflow */
1272 _bfd_mips_elf_generic_reloc, /* special_function */
1273 "R_MIPS_SCN_DISP", /* name */
1274 FALSE, /* partial_inplace */
1276 0xffffffff, /* dst_mask */
1277 FALSE), /* pcrel_offset */
1279 HOWTO (R_MIPS_REL16, /* type */
1281 1, /* size (0 = byte, 1 = short, 2 = long) */
1283 FALSE, /* pc_relative */
1285 complain_overflow_signed, /* complain_on_overflow */
1286 _bfd_mips_elf_generic_reloc, /* special_function */
1287 "R_MIPS_REL16", /* name */
1288 FALSE, /* partial_inplace */
1290 0xffff, /* dst_mask */
1291 FALSE), /* pcrel_offset */
1293 /* These two are obsolete. */
1294 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1295 EMPTY_HOWTO (R_MIPS_PJUMP),
1297 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1298 It must be used for multigot GOT's (and only there). */
1299 HOWTO (R_MIPS_RELGOT, /* type */
1301 2, /* size (0 = byte, 1 = short, 2 = long) */
1303 FALSE, /* pc_relative */
1305 complain_overflow_dont, /* complain_on_overflow */
1306 _bfd_mips_elf_generic_reloc, /* special_function */
1307 "R_MIPS_RELGOT", /* name */
1308 FALSE, /* partial_inplace */
1310 0xffffffff, /* dst_mask */
1311 FALSE), /* pcrel_offset */
1313 /* Protected jump conversion. This is an optimization hint. No
1314 relocation is required for correctness. */
1315 HOWTO (R_MIPS_JALR, /* type */
1317 2, /* size (0 = byte, 1 = short, 2 = long) */
1319 FALSE, /* pc_relative */
1321 complain_overflow_dont, /* complain_on_overflow */
1322 _bfd_mips_elf_generic_reloc, /* special_function */
1323 "R_MIPS_JALR", /* name */
1324 FALSE, /* partial_inplace */
1326 0x00000000, /* dst_mask */
1327 FALSE), /* pcrel_offset */
1329 /* TLS relocations. */
1330 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
1331 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
1333 HOWTO (R_MIPS_TLS_DTPMOD64, /* type */
1335 4, /* size (0 = byte, 1 = short, 2 = long) */
1337 FALSE, /* pc_relative */
1339 complain_overflow_dont, /* complain_on_overflow */
1340 _bfd_mips_elf_generic_reloc, /* special_function */
1341 "R_MIPS_TLS_DTPMOD64", /* name */
1342 FALSE, /* partial_inplace */
1344 MINUS_ONE, /* dst_mask */
1345 FALSE), /* pcrel_offset */
1347 HOWTO (R_MIPS_TLS_DTPREL64, /* type */
1349 4, /* size (0 = byte, 1 = short, 2 = long) */
1351 FALSE, /* pc_relative */
1353 complain_overflow_dont, /* complain_on_overflow */
1354 _bfd_mips_elf_generic_reloc, /* special_function */
1355 "R_MIPS_TLS_DTPREL64", /* name */
1356 FALSE, /* partial_inplace */
1358 MINUS_ONE, /* dst_mask */
1359 FALSE), /* pcrel_offset */
1361 /* TLS general dynamic variable reference. */
1362 HOWTO (R_MIPS_TLS_GD, /* type */
1364 2, /* size (0 = byte, 1 = short, 2 = long) */
1366 FALSE, /* pc_relative */
1368 complain_overflow_signed, /* complain_on_overflow */
1369 _bfd_mips_elf_generic_reloc, /* special_function */
1370 "R_MIPS_TLS_GD", /* name */
1371 FALSE, /* partial_inplace */
1373 0x0000ffff, /* dst_mask */
1374 FALSE), /* pcrel_offset */
1376 /* TLS local dynamic variable reference. */
1377 HOWTO (R_MIPS_TLS_LDM, /* type */
1379 2, /* size (0 = byte, 1 = short, 2 = long) */
1381 FALSE, /* pc_relative */
1383 complain_overflow_signed, /* complain_on_overflow */
1384 _bfd_mips_elf_generic_reloc, /* special_function */
1385 "R_MIPS_TLS_LDM", /* name */
1386 FALSE, /* partial_inplace */
1388 0x0000ffff, /* dst_mask */
1389 FALSE), /* pcrel_offset */
1391 /* TLS local dynamic offset. */
1392 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
1394 2, /* size (0 = byte, 1 = short, 2 = long) */
1396 FALSE, /* pc_relative */
1398 complain_overflow_signed, /* complain_on_overflow */
1399 _bfd_mips_elf_generic_reloc, /* special_function */
1400 "R_MIPS_TLS_DTPREL_HI16", /* name */
1401 FALSE, /* partial_inplace */
1403 0x0000ffff, /* dst_mask */
1404 FALSE), /* pcrel_offset */
1406 /* TLS local dynamic offset. */
1407 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
1409 2, /* size (0 = byte, 1 = short, 2 = long) */
1411 FALSE, /* pc_relative */
1413 complain_overflow_signed, /* complain_on_overflow */
1414 _bfd_mips_elf_generic_reloc, /* special_function */
1415 "R_MIPS_TLS_DTPREL_LO16", /* name */
1416 FALSE, /* partial_inplace */
1418 0x0000ffff, /* dst_mask */
1419 FALSE), /* pcrel_offset */
1421 /* TLS thread pointer offset. */
1422 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
1424 2, /* size (0 = byte, 1 = short, 2 = long) */
1426 FALSE, /* pc_relative */
1428 complain_overflow_signed, /* complain_on_overflow */
1429 _bfd_mips_elf_generic_reloc, /* special_function */
1430 "R_MIPS_TLS_GOTTPREL", /* name */
1431 FALSE, /* partial_inplace */
1433 0x0000ffff, /* dst_mask */
1434 FALSE), /* pcrel_offset */
1436 /* TLS IE dynamic relocations. */
1437 EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
1439 HOWTO (R_MIPS_TLS_TPREL64, /* type */
1441 4, /* size (0 = byte, 1 = short, 2 = long) */
1443 FALSE, /* pc_relative */
1445 complain_overflow_dont, /* complain_on_overflow */
1446 _bfd_mips_elf_generic_reloc, /* special_function */
1447 "R_MIPS_TLS_TPREL64", /* name */
1448 FALSE, /* partial_inplace */
1450 MINUS_ONE, /* dst_mask */
1451 FALSE), /* pcrel_offset */
1453 /* TLS thread pointer offset. */
1454 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
1456 2, /* size (0 = byte, 1 = short, 2 = long) */
1458 FALSE, /* pc_relative */
1460 complain_overflow_signed, /* complain_on_overflow */
1461 _bfd_mips_elf_generic_reloc, /* special_function */
1462 "R_MIPS_TLS_TPREL_HI16", /* name */
1463 FALSE, /* partial_inplace */
1465 0x0000ffff, /* dst_mask */
1466 FALSE), /* pcrel_offset */
1468 /* TLS thread pointer offset. */
1469 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
1471 2, /* size (0 = byte, 1 = short, 2 = long) */
1473 FALSE, /* pc_relative */
1475 complain_overflow_signed, /* complain_on_overflow */
1476 _bfd_mips_elf_generic_reloc, /* special_function */
1477 "R_MIPS_TLS_TPREL_LO16", /* name */
1478 FALSE, /* partial_inplace */
1480 0x0000ffff, /* dst_mask */
1481 FALSE), /* pcrel_offset */
1483 /* 32 bit relocation with no addend. */
1484 HOWTO (R_MIPS_GLOB_DAT, /* type */
1486 2, /* size (0 = byte, 1 = short, 2 = long) */
1488 FALSE, /* pc_relative */
1490 complain_overflow_dont, /* complain_on_overflow */
1491 _bfd_mips_elf_generic_reloc, /* special_function */
1492 "R_MIPS_GLOB_DAT", /* name */
1493 FALSE, /* partial_inplace */
1495 0xffffffff, /* dst_mask */
1496 FALSE), /* pcrel_offset */
1499 static reloc_howto_type mips16_elf64_howto_table_rel[] =
1501 /* The reloc used for the mips16 jump instruction. */
1502 HOWTO (R_MIPS16_26, /* type */
1504 2, /* size (0 = byte, 1 = short, 2 = long) */
1506 FALSE, /* pc_relative */
1508 complain_overflow_dont, /* complain_on_overflow */
1509 /* This needs complex overflow
1510 detection, because the upper four
1511 bits must match the PC. */
1512 _bfd_mips_elf_generic_reloc, /* special_function */
1513 "R_MIPS16_26", /* name */
1514 TRUE, /* partial_inplace */
1515 0x3ffffff, /* src_mask */
1516 0x3ffffff, /* dst_mask */
1517 FALSE), /* pcrel_offset */
1519 /* The reloc used for the mips16 gprel instruction. */
1520 HOWTO (R_MIPS16_GPREL, /* type */
1522 2, /* size (0 = byte, 1 = short, 2 = long) */
1524 FALSE, /* pc_relative */
1526 complain_overflow_signed, /* complain_on_overflow */
1527 mips16_gprel_reloc, /* special_function */
1528 "R_MIPS16_GPREL", /* name */
1529 TRUE, /* partial_inplace */
1530 0x0000ffff, /* src_mask */
1531 0x0000ffff, /* dst_mask */
1532 FALSE), /* pcrel_offset */
1534 /* A MIPS16 reference to the global offset table. */
1535 HOWTO (R_MIPS16_GOT16, /* type */
1537 2, /* size (0 = byte, 1 = short, 2 = long) */
1539 FALSE, /* pc_relative */
1541 complain_overflow_dont, /* complain_on_overflow */
1542 _bfd_mips_elf_got16_reloc, /* special_function */
1543 "R_MIPS16_GOT16", /* name */
1544 TRUE, /* partial_inplace */
1545 0x0000ffff, /* src_mask */
1546 0x0000ffff, /* dst_mask */
1547 FALSE), /* pcrel_offset */
1549 /* A MIPS16 call through the global offset table. */
1550 HOWTO (R_MIPS16_CALL16, /* type */
1552 2, /* size (0 = byte, 1 = short, 2 = long) */
1554 FALSE, /* pc_relative */
1556 complain_overflow_dont, /* complain_on_overflow */
1557 _bfd_mips_elf_generic_reloc, /* special_function */
1558 "R_MIPS16_CALL16", /* name */
1559 TRUE, /* partial_inplace */
1560 0x0000ffff, /* src_mask */
1561 0x0000ffff, /* dst_mask */
1562 FALSE), /* pcrel_offset */
1564 /* MIPS16 high 16 bits of symbol value. */
1565 HOWTO (R_MIPS16_HI16, /* type */
1566 16, /* rightshift */
1567 2, /* size (0 = byte, 1 = short, 2 = long) */
1569 FALSE, /* pc_relative */
1571 complain_overflow_dont, /* complain_on_overflow */
1572 _bfd_mips_elf_hi16_reloc, /* special_function */
1573 "R_MIPS16_HI16", /* name */
1574 TRUE, /* partial_inplace */
1575 0x0000ffff, /* src_mask */
1576 0x0000ffff, /* dst_mask */
1577 FALSE), /* pcrel_offset */
1579 /* MIPS16 low 16 bits of symbol value. */
1580 HOWTO (R_MIPS16_LO16, /* type */
1582 2, /* size (0 = byte, 1 = short, 2 = long) */
1584 FALSE, /* pc_relative */
1586 complain_overflow_dont, /* complain_on_overflow */
1587 _bfd_mips_elf_lo16_reloc, /* special_function */
1588 "R_MIPS16_LO16", /* name */
1589 TRUE, /* partial_inplace */
1590 0x0000ffff, /* src_mask */
1591 0x0000ffff, /* dst_mask */
1592 FALSE), /* pcrel_offset */
1594 /* MIPS16 TLS general dynamic variable reference. */
1595 HOWTO (R_MIPS16_TLS_GD, /* type */
1597 2, /* size (0 = byte, 1 = short, 2 = long) */
1599 FALSE, /* pc_relative */
1601 complain_overflow_signed, /* complain_on_overflow */
1602 _bfd_mips_elf_generic_reloc, /* special_function */
1603 "R_MIPS16_TLS_GD", /* name */
1604 TRUE, /* partial_inplace */
1605 0x0000ffff, /* src_mask */
1606 0x0000ffff, /* dst_mask */
1607 FALSE), /* pcrel_offset */
1609 /* MIPS16 TLS local dynamic variable reference. */
1610 HOWTO (R_MIPS16_TLS_LDM, /* type */
1612 2, /* size (0 = byte, 1 = short, 2 = long) */
1614 FALSE, /* pc_relative */
1616 complain_overflow_signed, /* complain_on_overflow */
1617 _bfd_mips_elf_generic_reloc, /* special_function */
1618 "R_MIPS16_TLS_LDM", /* name */
1619 TRUE, /* partial_inplace */
1620 0x0000ffff, /* src_mask */
1621 0x0000ffff, /* dst_mask */
1622 FALSE), /* pcrel_offset */
1624 /* MIPS16 TLS local dynamic offset. */
1625 HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */
1627 2, /* size (0 = byte, 1 = short, 2 = long) */
1629 FALSE, /* pc_relative */
1631 complain_overflow_signed, /* complain_on_overflow */
1632 _bfd_mips_elf_generic_reloc, /* special_function */
1633 "R_MIPS16_TLS_DTPREL_HI16", /* name */
1634 TRUE, /* partial_inplace */
1635 0x0000ffff, /* src_mask */
1636 0x0000ffff, /* dst_mask */
1637 FALSE), /* pcrel_offset */
1639 /* MIPS16 TLS local dynamic offset. */
1640 HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */
1642 2, /* size (0 = byte, 1 = short, 2 = long) */
1644 FALSE, /* pc_relative */
1646 complain_overflow_signed, /* complain_on_overflow */
1647 _bfd_mips_elf_generic_reloc, /* special_function */
1648 "R_MIPS16_TLS_DTPREL_LO16", /* name */
1649 TRUE, /* partial_inplace */
1650 0x0000ffff, /* src_mask */
1651 0x0000ffff, /* dst_mask */
1652 FALSE), /* pcrel_offset */
1654 /* MIPS16 TLS thread pointer offset. */
1655 HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */
1657 2, /* size (0 = byte, 1 = short, 2 = long) */
1659 FALSE, /* pc_relative */
1661 complain_overflow_signed, /* complain_on_overflow */
1662 _bfd_mips_elf_generic_reloc, /* special_function */
1663 "R_MIPS16_TLS_GOTTPREL", /* name */
1664 TRUE, /* partial_inplace */
1665 0x0000ffff, /* src_mask */
1666 0x0000ffff, /* dst_mask */
1667 FALSE), /* pcrel_offset */
1669 /* MIPS16 TLS thread pointer offset. */
1670 HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */
1672 2, /* size (0 = byte, 1 = short, 2 = long) */
1674 FALSE, /* pc_relative */
1676 complain_overflow_signed, /* complain_on_overflow */
1677 _bfd_mips_elf_generic_reloc, /* special_function */
1678 "R_MIPS16_TLS_TPREL_HI16", /* name */
1679 TRUE, /* partial_inplace */
1680 0x0000ffff, /* src_mask */
1681 0x0000ffff, /* dst_mask */
1682 FALSE), /* pcrel_offset */
1684 /* MIPS16 TLS thread pointer offset. */
1685 HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */
1687 2, /* size (0 = byte, 1 = short, 2 = long) */
1689 FALSE, /* pc_relative */
1691 complain_overflow_signed, /* complain_on_overflow */
1692 _bfd_mips_elf_generic_reloc, /* special_function */
1693 "R_MIPS16_TLS_TPREL_LO16", /* name */
1694 TRUE, /* partial_inplace */
1695 0x0000ffff, /* src_mask */
1696 0x0000ffff, /* dst_mask */
1697 FALSE), /* pcrel_offset */
1700 static reloc_howto_type mips16_elf64_howto_table_rela[] =
1702 /* The reloc used for the mips16 jump instruction. */
1703 HOWTO (R_MIPS16_26, /* type */
1705 2, /* size (0 = byte, 1 = short, 2 = long) */
1707 FALSE, /* pc_relative */
1709 complain_overflow_dont, /* complain_on_overflow */
1710 /* This needs complex overflow
1711 detection, because the upper four
1712 bits must match the PC. */
1713 _bfd_mips_elf_generic_reloc, /* special_function */
1714 "R_MIPS16_26", /* name */
1715 FALSE, /* partial_inplace */
1717 0x3ffffff, /* dst_mask */
1718 FALSE), /* pcrel_offset */
1720 /* The reloc used for the mips16 gprel instruction. */
1721 HOWTO (R_MIPS16_GPREL, /* type */
1723 2, /* size (0 = byte, 1 = short, 2 = long) */
1725 FALSE, /* pc_relative */
1727 complain_overflow_signed, /* complain_on_overflow */
1728 mips16_gprel_reloc, /* special_function */
1729 "R_MIPS16_GPREL", /* name */
1730 FALSE, /* partial_inplace */
1732 0x0000ffff, /* dst_mask */
1733 FALSE), /* pcrel_offset */
1735 /* A MIPS16 reference to the global offset table. */
1736 HOWTO (R_MIPS16_GOT16, /* type */
1738 2, /* size (0 = byte, 1 = short, 2 = long) */
1740 FALSE, /* pc_relative */
1742 complain_overflow_dont, /* complain_on_overflow */
1743 _bfd_mips_elf_got16_reloc, /* special_function */
1744 "R_MIPS16_GOT16", /* name */
1745 FALSE, /* partial_inplace */
1747 0x0000ffff, /* dst_mask */
1748 FALSE), /* pcrel_offset */
1750 /* A MIPS16 call through the global offset table. */
1751 HOWTO (R_MIPS16_CALL16, /* type */
1753 2, /* size (0 = byte, 1 = short, 2 = long) */
1755 FALSE, /* pc_relative */
1757 complain_overflow_dont, /* complain_on_overflow */
1758 _bfd_mips_elf_generic_reloc, /* special_function */
1759 "R_MIPS16_CALL16", /* name */
1760 FALSE, /* partial_inplace */
1762 0x0000ffff, /* dst_mask */
1763 FALSE), /* pcrel_offset */
1765 /* MIPS16 high 16 bits of symbol value. */
1766 HOWTO (R_MIPS16_HI16, /* type */
1767 16, /* rightshift */
1768 2, /* size (0 = byte, 1 = short, 2 = long) */
1770 FALSE, /* pc_relative */
1772 complain_overflow_dont, /* complain_on_overflow */
1773 _bfd_mips_elf_hi16_reloc, /* special_function */
1774 "R_MIPS16_HI16", /* name */
1775 FALSE, /* partial_inplace */
1777 0x0000ffff, /* dst_mask */
1778 FALSE), /* pcrel_offset */
1780 /* MIPS16 low 16 bits of symbol value. */
1781 HOWTO (R_MIPS16_LO16, /* type */
1783 2, /* size (0 = byte, 1 = short, 2 = long) */
1785 FALSE, /* pc_relative */
1787 complain_overflow_dont, /* complain_on_overflow */
1788 _bfd_mips_elf_lo16_reloc, /* special_function */
1789 "R_MIPS16_LO16", /* name */
1790 FALSE, /* partial_inplace */
1792 0x0000ffff, /* dst_mask */
1793 FALSE), /* pcrel_offset */
1795 /* MIPS16 TLS general dynamic variable reference. */
1796 HOWTO (R_MIPS16_TLS_GD, /* type */
1798 2, /* size (0 = byte, 1 = short, 2 = long) */
1800 FALSE, /* pc_relative */
1802 complain_overflow_signed, /* complain_on_overflow */
1803 _bfd_mips_elf_generic_reloc, /* special_function */
1804 "R_MIPS16_TLS_GD", /* name */
1805 FALSE, /* partial_inplace */
1807 0x0000ffff, /* dst_mask */
1808 FALSE), /* pcrel_offset */
1810 /* MIPS16 TLS local dynamic variable reference. */
1811 HOWTO (R_MIPS16_TLS_LDM, /* type */
1813 2, /* size (0 = byte, 1 = short, 2 = long) */
1815 FALSE, /* pc_relative */
1817 complain_overflow_signed, /* complain_on_overflow */
1818 _bfd_mips_elf_generic_reloc, /* special_function */
1819 "R_MIPS16_TLS_LDM", /* name */
1820 FALSE, /* partial_inplace */
1822 0x0000ffff, /* dst_mask */
1823 FALSE), /* pcrel_offset */
1825 /* MIPS16 TLS local dynamic offset. */
1826 HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */
1828 2, /* size (0 = byte, 1 = short, 2 = long) */
1830 FALSE, /* pc_relative */
1832 complain_overflow_signed, /* complain_on_overflow */
1833 _bfd_mips_elf_generic_reloc, /* special_function */
1834 "R_MIPS16_TLS_DTPREL_HI16", /* name */
1835 FALSE, /* partial_inplace */
1837 0x0000ffff, /* dst_mask */
1838 FALSE), /* pcrel_offset */
1840 /* MIPS16 TLS local dynamic offset. */
1841 HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */
1843 2, /* size (0 = byte, 1 = short, 2 = long) */
1845 FALSE, /* pc_relative */
1847 complain_overflow_signed, /* complain_on_overflow */
1848 _bfd_mips_elf_generic_reloc, /* special_function */
1849 "R_MIPS16_TLS_DTPREL_LO16", /* name */
1850 FALSE, /* partial_inplace */
1852 0x0000ffff, /* dst_mask */
1853 FALSE), /* pcrel_offset */
1855 /* MIPS16 TLS thread pointer offset. */
1856 HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */
1858 2, /* size (0 = byte, 1 = short, 2 = long) */
1860 FALSE, /* pc_relative */
1862 complain_overflow_signed, /* complain_on_overflow */
1863 _bfd_mips_elf_generic_reloc, /* special_function */
1864 "R_MIPS16_TLS_GOTTPREL", /* name */
1865 FALSE, /* partial_inplace */
1867 0x0000ffff, /* dst_mask */
1868 FALSE), /* pcrel_offset */
1870 /* MIPS16 TLS thread pointer offset. */
1871 HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */
1873 2, /* size (0 = byte, 1 = short, 2 = long) */
1875 FALSE, /* pc_relative */
1877 complain_overflow_signed, /* complain_on_overflow */
1878 _bfd_mips_elf_generic_reloc, /* special_function */
1879 "R_MIPS16_TLS_TPREL_HI16", /* name */
1880 FALSE, /* partial_inplace */
1882 0x0000ffff, /* dst_mask */
1883 FALSE), /* pcrel_offset */
1885 /* MIPS16 TLS thread pointer offset. */
1886 HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */
1888 2, /* size (0 = byte, 1 = short, 2 = long) */
1890 FALSE, /* pc_relative */
1892 complain_overflow_signed, /* complain_on_overflow */
1893 _bfd_mips_elf_generic_reloc, /* special_function */
1894 "R_MIPS16_TLS_TPREL_LO16", /* name */
1895 FALSE, /* partial_inplace */
1897 0x0000ffff, /* dst_mask */
1898 FALSE), /* pcrel_offset */
1901 static reloc_howto_type micromips_elf64_howto_table_rel[] =
1907 /* 26 bit jump address. */
1908 HOWTO (R_MICROMIPS_26_S1, /* type */
1910 2, /* size (0 = byte, 1 = short, 2 = long) */
1912 FALSE, /* pc_relative */
1914 complain_overflow_dont, /* complain_on_overflow */
1915 /* This needs complex overflow
1916 detection, because the upper four
1917 bits must match the PC. */
1918 _bfd_mips_elf_generic_reloc, /* special_function */
1919 "R_MICROMIPS_26_S1", /* name */
1920 TRUE, /* partial_inplace */
1921 0x3ffffff, /* src_mask */
1922 0x3ffffff, /* dst_mask */
1923 FALSE), /* pcrel_offset */
1925 /* High 16 bits of symbol value. */
1926 HOWTO (R_MICROMIPS_HI16, /* type */
1927 16, /* rightshift */
1928 2, /* size (0 = byte, 1 = short, 2 = long) */
1930 FALSE, /* pc_relative */
1932 complain_overflow_dont, /* complain_on_overflow */
1933 _bfd_mips_elf_hi16_reloc, /* special_function */
1934 "R_MICROMIPS_HI16", /* name */
1935 TRUE, /* partial_inplace */
1936 0x0000ffff, /* src_mask */
1937 0x0000ffff, /* dst_mask */
1938 FALSE), /* pcrel_offset */
1940 /* Low 16 bits of symbol value. */
1941 HOWTO (R_MICROMIPS_LO16, /* type */
1943 2, /* size (0 = byte, 1 = short, 2 = long) */
1945 FALSE, /* pc_relative */
1947 complain_overflow_dont, /* complain_on_overflow */
1948 _bfd_mips_elf_lo16_reloc, /* special_function */
1949 "R_MICROMIPS_LO16", /* name */
1950 TRUE, /* partial_inplace */
1951 0x0000ffff, /* src_mask */
1952 0x0000ffff, /* dst_mask */
1953 FALSE), /* pcrel_offset */
1955 /* GP relative reference. */
1956 HOWTO (R_MICROMIPS_GPREL16, /* type */
1958 2, /* size (0 = byte, 1 = short, 2 = long) */
1960 FALSE, /* pc_relative */
1962 complain_overflow_signed, /* complain_on_overflow */
1963 _bfd_mips_elf32_gprel16_reloc, /* special_function */
1964 "R_MICROMIPS_GPREL16", /* name */
1965 TRUE, /* partial_inplace */
1966 0x0000ffff, /* src_mask */
1967 0x0000ffff, /* dst_mask */
1968 FALSE), /* pcrel_offset */
1970 /* Reference to literal section. */
1971 HOWTO (R_MICROMIPS_LITERAL, /* type */
1973 2, /* size (0 = byte, 1 = short, 2 = long) */
1975 FALSE, /* pc_relative */
1977 complain_overflow_signed, /* complain_on_overflow */
1978 _bfd_mips_elf32_gprel16_reloc, /* special_function */
1979 "R_MICROMIPS_LITERAL", /* name */
1980 TRUE, /* partial_inplace */
1981 0x0000ffff, /* src_mask */
1982 0x0000ffff, /* dst_mask */
1983 FALSE), /* pcrel_offset */
1985 /* Reference to global offset table. */
1986 HOWTO (R_MICROMIPS_GOT16, /* type */
1988 2, /* size (0 = byte, 1 = short, 2 = long) */
1990 FALSE, /* pc_relative */
1992 complain_overflow_signed, /* complain_on_overflow */
1993 _bfd_mips_elf_got16_reloc, /* special_function */
1994 "R_MICROMIPS_GOT16", /* name */
1995 TRUE, /* partial_inplace */
1996 0x0000ffff, /* src_mask */
1997 0x0000ffff, /* dst_mask */
1998 FALSE), /* pcrel_offset */
2000 /* This is for microMIPS branches. */
2001 HOWTO (R_MICROMIPS_PC7_S1, /* type */
2003 1, /* size (0 = byte, 1 = short, 2 = long) */
2005 TRUE, /* pc_relative */
2007 complain_overflow_signed, /* complain_on_overflow */
2008 _bfd_mips_elf_generic_reloc, /* special_function */
2009 "R_MICROMIPS_PC7_S1", /* name */
2010 TRUE, /* partial_inplace */
2011 0x0000007f, /* src_mask */
2012 0x0000007f, /* dst_mask */
2013 TRUE), /* pcrel_offset */
2015 HOWTO (R_MICROMIPS_PC10_S1, /* type */
2017 1, /* size (0 = byte, 1 = short, 2 = long) */
2019 TRUE, /* pc_relative */
2021 complain_overflow_signed, /* complain_on_overflow */
2022 _bfd_mips_elf_generic_reloc, /* special_function */
2023 "R_MICROMIPS_PC10_S1", /* name */
2024 TRUE, /* partial_inplace */
2025 0x000003ff, /* src_mask */
2026 0x000003ff, /* dst_mask */
2027 TRUE), /* pcrel_offset */
2029 HOWTO (R_MICROMIPS_PC16_S1, /* type */
2031 2, /* size (0 = byte, 1 = short, 2 = long) */
2033 TRUE, /* pc_relative */
2035 complain_overflow_signed, /* complain_on_overflow */
2036 _bfd_mips_elf_generic_reloc, /* special_function */
2037 "R_MICROMIPS_PC16_S1", /* name */
2038 TRUE, /* partial_inplace */
2039 0x0000ffff, /* src_mask */
2040 0x0000ffff, /* dst_mask */
2041 TRUE), /* pcrel_offset */
2043 /* 16 bit call through global offset table. */
2044 HOWTO (R_MICROMIPS_CALL16, /* type */
2046 2, /* size (0 = byte, 1 = short, 2 = long) */
2048 FALSE, /* pc_relative */
2050 complain_overflow_signed, /* complain_on_overflow */
2051 _bfd_mips_elf_generic_reloc, /* special_function */
2052 "R_MICROMIPS_CALL16", /* name */
2053 TRUE, /* partial_inplace */
2054 0x0000ffff, /* src_mask */
2055 0x0000ffff, /* dst_mask */
2056 FALSE), /* pcrel_offset */
2061 /* Displacement in the global offset table. */
2062 HOWTO (R_MICROMIPS_GOT_DISP, /* type */
2064 2, /* size (0 = byte, 1 = short, 2 = long) */
2066 FALSE, /* pc_relative */
2068 complain_overflow_signed, /* complain_on_overflow */
2069 _bfd_mips_elf_generic_reloc, /* special_function */
2070 "R_MICROMIPS_GOT_DISP",/* name */
2071 TRUE, /* partial_inplace */
2072 0x0000ffff, /* src_mask */
2073 0x0000ffff, /* dst_mask */
2074 FALSE), /* pcrel_offset */
2076 /* Displacement to page pointer in the global offset table. */
2077 HOWTO (R_MICROMIPS_GOT_PAGE, /* type */
2079 2, /* size (0 = byte, 1 = short, 2 = long) */
2081 FALSE, /* pc_relative */
2083 complain_overflow_signed, /* complain_on_overflow */
2084 _bfd_mips_elf_generic_reloc, /* special_function */
2085 "R_MICROMIPS_GOT_PAGE",/* name */
2086 TRUE, /* partial_inplace */
2087 0x0000ffff, /* src_mask */
2088 0x0000ffff, /* dst_mask */
2089 FALSE), /* pcrel_offset */
2091 /* Offset from page pointer in the global offset table. */
2092 HOWTO (R_MICROMIPS_GOT_OFST, /* type */
2094 2, /* size (0 = byte, 1 = short, 2 = long) */
2096 FALSE, /* pc_relative */
2098 complain_overflow_signed, /* complain_on_overflow */
2099 _bfd_mips_elf_generic_reloc, /* special_function */
2100 "R_MICROMIPS_GOT_OFST",/* name */
2101 TRUE, /* partial_inplace */
2102 0x0000ffff, /* src_mask */
2103 0x0000ffff, /* dst_mask */
2104 FALSE), /* pcrel_offset */
2106 /* High 16 bits of displacement in global offset table. */
2107 HOWTO (R_MICROMIPS_GOT_HI16, /* type */
2109 2, /* size (0 = byte, 1 = short, 2 = long) */
2111 FALSE, /* pc_relative */
2113 complain_overflow_dont, /* complain_on_overflow */
2114 _bfd_mips_elf_generic_reloc, /* special_function */
2115 "R_MICROMIPS_GOT_HI16",/* name */
2116 TRUE, /* partial_inplace */
2117 0x0000ffff, /* src_mask */
2118 0x0000ffff, /* dst_mask */
2119 FALSE), /* pcrel_offset */
2121 /* Low 16 bits of displacement in global offset table. */
2122 HOWTO (R_MICROMIPS_GOT_LO16, /* type */
2124 2, /* size (0 = byte, 1 = short, 2 = long) */
2126 FALSE, /* pc_relative */
2128 complain_overflow_dont, /* complain_on_overflow */
2129 _bfd_mips_elf_generic_reloc, /* special_function */
2130 "R_MICROMIPS_GOT_LO16",/* name */
2131 TRUE, /* partial_inplace */
2132 0x0000ffff, /* src_mask */
2133 0x0000ffff, /* dst_mask */
2134 FALSE), /* pcrel_offset */
2136 /* 64 bit subtraction. Used in the N32 ABI. */
2137 HOWTO (R_MICROMIPS_SUB, /* type */
2139 4, /* size (0 = byte, 1 = short, 2 = long) */
2141 FALSE, /* pc_relative */
2143 complain_overflow_dont, /* complain_on_overflow */
2144 _bfd_mips_elf_generic_reloc, /* special_function */
2145 "R_MICROMIPS_SUB", /* name */
2146 TRUE, /* partial_inplace */
2147 MINUS_ONE, /* src_mask */
2148 MINUS_ONE, /* dst_mask */
2149 FALSE), /* pcrel_offset */
2151 /* We don't support these for REL relocations, because it means building
2152 the addend from a R_MICROMIPS_HIGHEST/R_MICROMIPS_HIGHER/
2153 R_MICROMIPS_HI16/R_MICROMIPS_LO16 sequence with varying ordering,
2154 using fallable heuristics. */
2155 EMPTY_HOWTO (R_MICROMIPS_HIGHER),
2156 EMPTY_HOWTO (R_MICROMIPS_HIGHEST),
2158 /* High 16 bits of displacement in global offset table. */
2159 HOWTO (R_MICROMIPS_CALL_HI16, /* type */
2161 2, /* size (0 = byte, 1 = short, 2 = long) */
2163 FALSE, /* pc_relative */
2165 complain_overflow_dont, /* complain_on_overflow */
2166 _bfd_mips_elf_generic_reloc, /* special_function */
2167 "R_MICROMIPS_CALL_HI16",/* name */
2168 TRUE, /* partial_inplace */
2169 0x0000ffff, /* src_mask */
2170 0x0000ffff, /* dst_mask */
2171 FALSE), /* pcrel_offset */
2173 /* Low 16 bits of displacement in global offset table. */
2174 HOWTO (R_MICROMIPS_CALL_LO16, /* type */
2176 2, /* size (0 = byte, 1 = short, 2 = long) */
2178 FALSE, /* pc_relative */
2180 complain_overflow_dont, /* complain_on_overflow */
2181 _bfd_mips_elf_generic_reloc, /* special_function */
2182 "R_MICROMIPS_CALL_LO16",/* name */
2183 TRUE, /* partial_inplace */
2184 0x0000ffff, /* src_mask */
2185 0x0000ffff, /* dst_mask */
2186 FALSE), /* pcrel_offset */
2189 static reloc_howto_type micromips_elf64_howto_table_rela[] =
2195 /* 26 bit jump address. */
2196 HOWTO (R_MICROMIPS_26_S1, /* type */
2198 2, /* size (0 = byte, 1 = short, 2 = long) */
2200 FALSE, /* pc_relative */
2202 complain_overflow_dont, /* complain_on_overflow */
2203 /* This needs complex overflow
2204 detection, because the upper four
2205 bits must match the PC. */
2206 _bfd_mips_elf_generic_reloc, /* special_function */
2207 "R_MICROMIPS_26_S1", /* name */
2208 FALSE, /* partial_inplace */
2210 0x3ffffff, /* dst_mask */
2211 FALSE), /* pcrel_offset */
2213 /* High 16 bits of symbol value. */
2214 HOWTO (R_MICROMIPS_HI16, /* type */
2215 16, /* rightshift */
2216 2, /* size (0 = byte, 1 = short, 2 = long) */
2218 FALSE, /* pc_relative */
2220 complain_overflow_dont, /* complain_on_overflow */
2221 _bfd_mips_elf_hi16_reloc, /* special_function */
2222 "R_MICROMIPS_HI16", /* name */
2223 FALSE, /* partial_inplace */
2225 0x0000ffff, /* dst_mask */
2226 FALSE), /* pcrel_offset */
2228 /* Low 16 bits of symbol value. */
2229 HOWTO (R_MICROMIPS_LO16, /* type */
2231 2, /* size (0 = byte, 1 = short, 2 = long) */
2233 FALSE, /* pc_relative */
2235 complain_overflow_dont, /* complain_on_overflow */
2236 _bfd_mips_elf_lo16_reloc, /* special_function */
2237 "R_MICROMIPS_LO16", /* name */
2238 FALSE, /* partial_inplace */
2240 0x0000ffff, /* dst_mask */
2241 FALSE), /* pcrel_offset */
2243 /* GP relative reference. */
2244 HOWTO (R_MICROMIPS_GPREL16, /* type */
2246 2, /* size (0 = byte, 1 = short, 2 = long) */
2248 FALSE, /* pc_relative */
2250 complain_overflow_signed, /* complain_on_overflow */
2251 _bfd_mips_elf32_gprel16_reloc, /* special_function */
2252 "R_MICROMIPS_GPREL16", /* name */
2253 FALSE, /* partial_inplace */
2255 0x0000ffff, /* dst_mask */
2256 FALSE), /* pcrel_offset */
2258 /* Reference to literal section. */
2259 HOWTO (R_MICROMIPS_LITERAL, /* type */
2261 2, /* size (0 = byte, 1 = short, 2 = long) */
2263 FALSE, /* pc_relative */
2265 complain_overflow_signed, /* complain_on_overflow */
2266 _bfd_mips_elf32_gprel16_reloc, /* special_function */
2267 "R_MICROMIPS_LITERAL", /* name */
2268 FALSE, /* partial_inplace */
2270 0x0000ffff, /* dst_mask */
2271 FALSE), /* pcrel_offset */
2273 /* Reference to global offset table. */
2274 HOWTO (R_MICROMIPS_GOT16, /* type */
2276 2, /* size (0 = byte, 1 = short, 2 = long) */
2278 FALSE, /* pc_relative */
2280 complain_overflow_signed, /* complain_on_overflow */
2281 _bfd_mips_elf_got16_reloc, /* special_function */
2282 "R_MICROMIPS_GOT16", /* name */
2283 FALSE, /* partial_inplace */
2285 0x0000ffff, /* dst_mask */
2286 FALSE), /* pcrel_offset */
2288 /* This is for microMIPS branches. */
2289 HOWTO (R_MICROMIPS_PC7_S1, /* type */
2291 1, /* size (0 = byte, 1 = short, 2 = long) */
2293 TRUE, /* pc_relative */
2295 complain_overflow_signed, /* complain_on_overflow */
2296 _bfd_mips_elf_generic_reloc, /* special_function */
2297 "R_MICROMIPS_PC7_S1", /* name */
2298 FALSE, /* partial_inplace */
2300 0x0000007f, /* dst_mask */
2301 TRUE), /* pcrel_offset */
2303 HOWTO (R_MICROMIPS_PC10_S1, /* type */
2305 1, /* size (0 = byte, 1 = short, 2 = long) */
2307 TRUE, /* pc_relative */
2309 complain_overflow_signed, /* complain_on_overflow */
2310 _bfd_mips_elf_generic_reloc, /* special_function */
2311 "R_MICROMIPS_PC10_S1", /* name */
2312 FALSE, /* partial_inplace */
2314 0x000003ff, /* dst_mask */
2315 TRUE), /* pcrel_offset */
2317 HOWTO (R_MICROMIPS_PC16_S1, /* type */
2319 2, /* size (0 = byte, 1 = short, 2 = long) */
2321 TRUE, /* pc_relative */
2323 complain_overflow_signed, /* complain_on_overflow */
2324 _bfd_mips_elf_generic_reloc, /* special_function */
2325 "R_MICROMIPS_PC16_S1", /* name */
2326 FALSE, /* partial_inplace */
2328 0x0000ffff, /* dst_mask */
2329 TRUE), /* pcrel_offset */
2331 /* 16 bit call through global offset table. */
2332 HOWTO (R_MICROMIPS_CALL16, /* type */
2334 2, /* size (0 = byte, 1 = short, 2 = long) */
2336 FALSE, /* pc_relative */
2338 complain_overflow_signed, /* complain_on_overflow */
2339 _bfd_mips_elf_generic_reloc, /* special_function */
2340 "R_MICROMIPS_CALL16", /* name */
2341 FALSE, /* partial_inplace */
2343 0x0000ffff, /* dst_mask */
2344 FALSE), /* pcrel_offset */
2349 /* Displacement in the global offset table. */
2350 HOWTO (R_MICROMIPS_GOT_DISP, /* type */
2352 2, /* size (0 = byte, 1 = short, 2 = long) */
2354 FALSE, /* pc_relative */
2356 complain_overflow_signed, /* complain_on_overflow */
2357 _bfd_mips_elf_generic_reloc, /* special_function */
2358 "R_MICROMIPS_GOT_DISP",/* name */
2359 FALSE, /* partial_inplace */
2361 0x0000ffff, /* dst_mask */
2362 FALSE), /* pcrel_offset */
2364 /* Displacement to page pointer in the global offset table. */
2365 HOWTO (R_MICROMIPS_GOT_PAGE, /* type */
2367 2, /* size (0 = byte, 1 = short, 2 = long) */
2369 FALSE, /* pc_relative */
2371 complain_overflow_signed, /* complain_on_overflow */
2372 _bfd_mips_elf_generic_reloc, /* special_function */
2373 "R_MICROMIPS_GOT_PAGE",/* name */
2374 FALSE, /* partial_inplace */
2376 0x0000ffff, /* dst_mask */
2377 FALSE), /* pcrel_offset */
2379 /* Offset from page pointer in the global offset table. */
2380 HOWTO (R_MICROMIPS_GOT_OFST, /* type */
2382 2, /* size (0 = byte, 1 = short, 2 = long) */
2384 FALSE, /* pc_relative */
2386 complain_overflow_signed, /* complain_on_overflow */
2387 _bfd_mips_elf_generic_reloc, /* special_function */
2388 "R_MICROMIPS_GOT_OFST",/* name */
2389 FALSE, /* partial_inplace */
2391 0x0000ffff, /* dst_mask */
2392 FALSE), /* pcrel_offset */
2394 /* High 16 bits of displacement in global offset table. */
2395 HOWTO (R_MICROMIPS_GOT_HI16, /* type */
2397 2, /* size (0 = byte, 1 = short, 2 = long) */
2399 FALSE, /* pc_relative */
2401 complain_overflow_dont, /* complain_on_overflow */
2402 _bfd_mips_elf_generic_reloc, /* special_function */
2403 "R_MICROMIPS_GOT_HI16",/* name */
2404 FALSE, /* partial_inplace */
2406 0x0000ffff, /* dst_mask */
2407 FALSE), /* pcrel_offset */
2409 /* Low 16 bits of displacement in global offset table. */
2410 HOWTO (R_MICROMIPS_GOT_LO16, /* type */
2412 2, /* size (0 = byte, 1 = short, 2 = long) */
2414 FALSE, /* pc_relative */
2416 complain_overflow_dont, /* complain_on_overflow */
2417 _bfd_mips_elf_generic_reloc, /* special_function */
2418 "R_MICROMIPS_GOT_LO16",/* name */
2419 FALSE, /* partial_inplace */
2421 0x0000ffff, /* dst_mask */
2422 FALSE), /* pcrel_offset */
2424 /* 64 bit subtraction. Used in the N32 ABI. */
2425 HOWTO (R_MICROMIPS_SUB, /* type */
2427 4, /* size (0 = byte, 1 = short, 2 = long) */
2429 FALSE, /* pc_relative */
2431 complain_overflow_dont, /* complain_on_overflow */
2432 _bfd_mips_elf_generic_reloc, /* special_function */
2433 "R_MICROMIPS_SUB", /* name */
2434 FALSE, /* partial_inplace */
2436 MINUS_ONE, /* dst_mask */
2437 FALSE), /* pcrel_offset */
2439 /* Get the higher value of a 64 bit addend. */
2440 HOWTO (R_MICROMIPS_HIGHER, /* type */
2442 2, /* size (0 = byte, 1 = short, 2 = long) */
2444 FALSE, /* pc_relative */
2446 complain_overflow_dont, /* complain_on_overflow */
2447 _bfd_mips_elf_generic_reloc, /* special_function */
2448 "R_MICROMIPS_HIGHER", /* name */
2449 FALSE, /* partial_inplace */
2451 0x0000ffff, /* dst_mask */
2452 FALSE), /* pcrel_offset */
2454 /* Get the highest value of a 64 bit addend. */
2455 HOWTO (R_MICROMIPS_HIGHEST, /* type */
2457 2, /* size (0 = byte, 1 = short, 2 = long) */
2459 FALSE, /* pc_relative */
2461 complain_overflow_dont, /* complain_on_overflow */
2462 _bfd_mips_elf_generic_reloc, /* special_function */
2463 "R_MICROMIPS_HIGHEST", /* name */
2464 FALSE, /* partial_inplace */
2466 0x0000ffff, /* dst_mask */
2467 FALSE), /* pcrel_offset */
2469 /* High 16 bits of displacement in global offset table. */
2470 HOWTO (R_MICROMIPS_CALL_HI16, /* type */
2472 2, /* size (0 = byte, 1 = short, 2 = long) */
2474 FALSE, /* pc_relative */
2476 complain_overflow_dont, /* complain_on_overflow */
2477 _bfd_mips_elf_generic_reloc, /* special_function */
2478 "R_MICROMIPS_CALL_HI16",/* name */
2479 FALSE, /* partial_inplace */
2481 0x0000ffff, /* dst_mask */
2482 FALSE), /* pcrel_offset */
2484 /* Low 16 bits of displacement in global offset table. */
2485 HOWTO (R_MICROMIPS_CALL_LO16, /* type */
2487 2, /* size (0 = byte, 1 = short, 2 = long) */
2489 FALSE, /* pc_relative */
2491 complain_overflow_dont, /* complain_on_overflow */
2492 _bfd_mips_elf_generic_reloc, /* special_function */
2493 "R_MICROMIPS_CALL_LO16",/* name */
2494 FALSE, /* partial_inplace */
2496 0x0000ffff, /* dst_mask */
2497 FALSE), /* pcrel_offset */
2500 /* GNU extension to record C++ vtable hierarchy */
2501 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
2502 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
2504 2, /* size (0 = byte, 1 = short, 2 = long) */
2506 FALSE, /* pc_relative */
2508 complain_overflow_dont, /* complain_on_overflow */
2509 NULL, /* special_function */
2510 "R_MIPS_GNU_VTINHERIT", /* name */
2511 FALSE, /* partial_inplace */
2514 FALSE); /* pcrel_offset */
2516 /* GNU extension to record C++ vtable member usage */
2517 static reloc_howto_type elf_mips_gnu_vtentry_howto =
2518 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
2520 2, /* size (0 = byte, 1 = short, 2 = long) */
2522 FALSE, /* pc_relative */
2524 complain_overflow_dont, /* complain_on_overflow */
2525 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
2526 "R_MIPS_GNU_VTENTRY", /* name */
2527 FALSE, /* partial_inplace */
2530 FALSE); /* pcrel_offset */
2532 /* 16 bit offset for pc-relative branches. */
2533 static reloc_howto_type elf_mips_gnu_rel16_s2 =
2534 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
2536 2, /* size (0 = byte, 1 = short, 2 = long) */
2538 TRUE, /* pc_relative */
2540 complain_overflow_signed, /* complain_on_overflow */
2541 _bfd_mips_elf_generic_reloc, /* special_function */
2542 "R_MIPS_GNU_REL16_S2", /* name */
2543 TRUE, /* partial_inplace */
2544 0x0000ffff, /* src_mask */
2545 0x0000ffff, /* dst_mask */
2546 TRUE); /* pcrel_offset */
2548 /* 16 bit offset for pc-relative branches. */
2549 static reloc_howto_type elf_mips_gnu_rela16_s2 =
2550 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
2552 2, /* size (0 = byte, 1 = short, 2 = long) */
2554 TRUE, /* pc_relative */
2556 complain_overflow_signed, /* complain_on_overflow */
2557 _bfd_mips_elf_generic_reloc, /* special_function */
2558 "R_MIPS_GNU_REL16_S2", /* name */
2559 FALSE, /* partial_inplace */
2561 0x0000ffff, /* dst_mask */
2562 TRUE); /* pcrel_offset */
2564 /* Originally a VxWorks extension, but now used for other systems too. */
2565 static reloc_howto_type elf_mips_copy_howto =
2566 HOWTO (R_MIPS_COPY, /* type */
2568 0, /* this one is variable size */
2570 FALSE, /* pc_relative */
2572 complain_overflow_bitfield, /* complain_on_overflow */
2573 bfd_elf_generic_reloc, /* special_function */
2574 "R_MIPS_COPY", /* name */
2575 FALSE, /* partial_inplace */
2578 FALSE); /* pcrel_offset */
2580 /* Originally a VxWorks extension, but now used for other systems too. */
2581 static reloc_howto_type elf_mips_jump_slot_howto =
2582 HOWTO (R_MIPS_JUMP_SLOT, /* type */
2584 4, /* size (0 = byte, 1 = short, 2 = long) */
2586 FALSE, /* pc_relative */
2588 complain_overflow_bitfield, /* complain_on_overflow */
2589 bfd_elf_generic_reloc, /* special_function */
2590 "R_MIPS_JUMP_SLOT", /* name */
2591 FALSE, /* partial_inplace */
2594 FALSE); /* pcrel_offset */
2596 /* Swap in a MIPS 64-bit Rel reloc. */
2599 mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src,
2600 Elf64_Mips_Internal_Rela *dst)
2602 dst->r_offset = H_GET_64 (abfd, src->r_offset);
2603 dst->r_sym = H_GET_32 (abfd, src->r_sym);
2604 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
2605 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
2606 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
2607 dst->r_type = H_GET_8 (abfd, src->r_type);
2611 /* Swap in a MIPS 64-bit Rela reloc. */
2614 mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src,
2615 Elf64_Mips_Internal_Rela *dst)
2617 dst->r_offset = H_GET_64 (abfd, src->r_offset);
2618 dst->r_sym = H_GET_32 (abfd, src->r_sym);
2619 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
2620 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
2621 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
2622 dst->r_type = H_GET_8 (abfd, src->r_type);
2623 dst->r_addend = H_GET_S64 (abfd, src->r_addend);
2626 /* Swap out a MIPS 64-bit Rel reloc. */
2629 mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
2630 Elf64_Mips_External_Rel *dst)
2632 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
2633 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
2634 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
2635 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
2636 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
2637 H_PUT_8 (abfd, src->r_type, dst->r_type);
2640 /* Swap out a MIPS 64-bit Rela reloc. */
2643 mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
2644 Elf64_Mips_External_Rela *dst)
2646 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
2647 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
2648 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
2649 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
2650 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
2651 H_PUT_8 (abfd, src->r_type, dst->r_type);
2652 H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
2655 /* Swap in a MIPS 64-bit Rel reloc. */
2658 mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src,
2659 Elf_Internal_Rela *dst)
2661 Elf64_Mips_Internal_Rela mirel;
2663 mips_elf64_swap_reloc_in (abfd,
2664 (const Elf64_Mips_External_Rel *) src,
2667 dst[0].r_offset = mirel.r_offset;
2668 dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
2669 dst[0].r_addend = 0;
2670 dst[1].r_offset = mirel.r_offset;
2671 dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
2672 dst[1].r_addend = 0;
2673 dst[2].r_offset = mirel.r_offset;
2674 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
2675 dst[2].r_addend = 0;
2678 /* Swap in a MIPS 64-bit Rela reloc. */
2681 mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src,
2682 Elf_Internal_Rela *dst)
2684 Elf64_Mips_Internal_Rela mirela;
2686 mips_elf64_swap_reloca_in (abfd,
2687 (const Elf64_Mips_External_Rela *) src,
2690 dst[0].r_offset = mirela.r_offset;
2691 dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
2692 dst[0].r_addend = mirela.r_addend;
2693 dst[1].r_offset = mirela.r_offset;
2694 dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
2695 dst[1].r_addend = 0;
2696 dst[2].r_offset = mirela.r_offset;
2697 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
2698 dst[2].r_addend = 0;
2701 /* Swap out a MIPS 64-bit Rel reloc. */
2704 mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src,
2707 Elf64_Mips_Internal_Rela mirel;
2709 mirel.r_offset = src[0].r_offset;
2710 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
2711 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
2713 mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
2714 mirel.r_sym = ELF64_R_SYM (src[0].r_info);
2715 mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
2716 mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
2717 mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
2719 mips_elf64_swap_reloc_out (abfd, &mirel,
2720 (Elf64_Mips_External_Rel *) dst);
2723 /* Swap out a MIPS 64-bit Rela reloc. */
2726 mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src,
2729 Elf64_Mips_Internal_Rela mirela;
2731 mirela.r_offset = src[0].r_offset;
2732 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
2733 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
2735 mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
2736 mirela.r_sym = ELF64_R_SYM (src[0].r_info);
2737 mirela.r_addend = src[0].r_addend;
2738 BFD_ASSERT(src[1].r_addend == 0);
2739 BFD_ASSERT(src[2].r_addend == 0);
2741 mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
2742 mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
2743 mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
2745 mips_elf64_swap_reloca_out (abfd, &mirela,
2746 (Elf64_Mips_External_Rela *) dst);
2749 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
2750 dangerous relocation. */
2753 mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp)
2759 /* If we've already figured out what GP will be, just return it. */
2760 *pgp = _bfd_get_gp_value (output_bfd);
2764 count = bfd_get_symcount (output_bfd);
2765 sym = bfd_get_outsymbols (output_bfd);
2767 /* The linker script will have created a symbol named `_gp' with the
2768 appropriate value. */
2773 for (i = 0; i < count; i++, sym++)
2775 register const char *name;
2777 name = bfd_asymbol_name (*sym);
2778 if (*name == '_' && strcmp (name, "_gp") == 0)
2780 *pgp = bfd_asymbol_value (*sym);
2781 _bfd_set_gp_value (output_bfd, *pgp);
2789 /* Only get the error once. */
2791 _bfd_set_gp_value (output_bfd, *pgp);
2798 /* We have to figure out the gp value, so that we can adjust the
2799 symbol value correctly. We look up the symbol _gp in the output
2800 BFD. If we can't find it, we're stuck. We cache it in the ELF
2801 target data. We don't need to adjust the symbol value for an
2802 external symbol if we are producing relocatable output. */
2804 static bfd_reloc_status_type
2805 mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
2806 char **error_message, bfd_vma *pgp)
2808 if (bfd_is_und_section (symbol->section)
2812 return bfd_reloc_undefined;
2815 *pgp = _bfd_get_gp_value (output_bfd);
2818 || (symbol->flags & BSF_SECTION_SYM) != 0))
2822 /* Make up a value. */
2823 *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
2824 _bfd_set_gp_value (output_bfd, *pgp);
2826 else if (!mips_elf64_assign_gp (output_bfd, pgp))
2829 (char *) _("GP relative relocation when _gp not defined");
2830 return bfd_reloc_dangerous;
2834 return bfd_reloc_ok;
2837 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
2838 become the offset from the gp register. */
2840 static bfd_reloc_status_type
2841 mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2842 void *data, asection *input_section, bfd *output_bfd,
2843 char **error_message)
2845 bfd_boolean relocatable;
2846 bfd_reloc_status_type ret;
2849 /* If we're relocating, and this is an external symbol, we don't want
2850 to change anything. */
2851 if (output_bfd != NULL
2852 && (symbol->flags & BSF_SECTION_SYM) == 0
2853 && (symbol->flags & BSF_LOCAL) != 0)
2855 reloc_entry->address += input_section->output_offset;
2856 return bfd_reloc_ok;
2859 if (output_bfd != NULL)
2863 relocatable = FALSE;
2864 output_bfd = symbol->section->output_section->owner;
2867 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
2869 if (ret != bfd_reloc_ok)
2872 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2873 input_section, relocatable,
2877 /* Do a R_MIPS_LITERAL relocation. */
2879 static bfd_reloc_status_type
2880 mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2881 void *data, asection *input_section, bfd *output_bfd,
2882 char **error_message)
2884 bfd_boolean relocatable;
2885 bfd_reloc_status_type ret;
2888 /* R_MIPS_LITERAL relocations are defined for local symbols only. */
2889 if (output_bfd != NULL
2890 && (symbol->flags & BSF_SECTION_SYM) == 0
2891 && (symbol->flags & BSF_LOCAL) != 0)
2893 *error_message = (char *)
2894 _("literal relocation occurs for an external symbol");
2895 return bfd_reloc_outofrange;
2898 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
2899 if (output_bfd != NULL)
2903 relocatable = FALSE;
2904 output_bfd = symbol->section->output_section->owner;
2907 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
2909 if (ret != bfd_reloc_ok)
2912 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2913 input_section, relocatable,
2917 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
2918 become the offset from the gp register. */
2920 static bfd_reloc_status_type
2921 mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2922 void *data, asection *input_section, bfd *output_bfd,
2923 char **error_message)
2925 bfd_boolean relocatable;
2926 bfd_reloc_status_type ret;
2931 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
2932 if (output_bfd != NULL
2933 && (symbol->flags & BSF_SECTION_SYM) == 0
2934 && (symbol->flags & BSF_LOCAL) != 0)
2936 *error_message = (char *)
2937 _("32bits gp relative relocation occurs for an external symbol");
2938 return bfd_reloc_outofrange;
2941 if (output_bfd != NULL)
2945 relocatable = FALSE;
2946 output_bfd = symbol->section->output_section->owner;
2949 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable,
2950 error_message, &gp);
2951 if (ret != bfd_reloc_ok)
2954 if (bfd_is_com_section (symbol->section))
2957 relocation = symbol->value;
2959 relocation += symbol->section->output_section->vma;
2960 relocation += symbol->section->output_offset;
2962 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
2963 return bfd_reloc_outofrange;
2965 /* Set val to the offset into the section or symbol. */
2966 val = reloc_entry->addend;
2968 if (reloc_entry->howto->partial_inplace)
2969 val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
2971 /* Adjust val for the final section location and GP value. If we
2972 are producing relocatable output, we don't want to do this for
2973 an external symbol. */
2975 || (symbol->flags & BSF_SECTION_SYM) != 0)
2976 val += relocation - gp;
2978 if (reloc_entry->howto->partial_inplace)
2979 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
2981 reloc_entry->addend = val;
2984 reloc_entry->address += input_section->output_offset;
2986 return bfd_reloc_ok;
2989 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
2990 the rest is at bits 6-10. The bitpos already got right by the howto. */
2992 static bfd_reloc_status_type
2993 mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2994 void *data, asection *input_section, bfd *output_bfd,
2995 char **error_message)
2997 if (reloc_entry->howto->partial_inplace)
2999 reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
3000 | (reloc_entry->addend & 0x00000800) >> 9);
3003 return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
3004 input_section, output_bfd,
3008 /* Handle a mips16 GP relative reloc. */
3010 static bfd_reloc_status_type
3011 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3012 void *data, asection *input_section, bfd *output_bfd,
3013 char **error_message)
3015 bfd_boolean relocatable;
3016 bfd_reloc_status_type ret;
3020 /* If we're relocating, and this is an external symbol, we don't want
3021 to change anything. */
3022 if (output_bfd != NULL
3023 && (symbol->flags & BSF_SECTION_SYM) == 0
3024 && (symbol->flags & BSF_LOCAL) != 0)
3026 reloc_entry->address += input_section->output_offset;
3027 return bfd_reloc_ok;
3030 if (output_bfd != NULL)
3034 relocatable = FALSE;
3035 output_bfd = symbol->section->output_section->owner;
3038 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
3040 if (ret != bfd_reloc_ok)
3043 location = (bfd_byte *) data + reloc_entry->address;
3044 _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
3046 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
3047 input_section, relocatable,
3049 _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
3055 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
3057 struct elf_reloc_map {
3058 bfd_reloc_code_real_type bfd_val;
3059 enum elf_mips_reloc_type elf_val;
3062 static const struct elf_reloc_map mips_reloc_map[] =
3064 { BFD_RELOC_NONE, R_MIPS_NONE },
3065 { BFD_RELOC_16, R_MIPS_16 },
3066 { BFD_RELOC_32, R_MIPS_32 },
3067 /* There is no BFD reloc for R_MIPS_REL32. */
3068 { BFD_RELOC_64, R_MIPS_64 },
3069 { BFD_RELOC_CTOR, R_MIPS_64 },
3070 { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
3071 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
3072 { BFD_RELOC_LO16, R_MIPS_LO16 },
3073 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
3074 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
3075 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
3076 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
3077 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
3078 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
3079 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
3080 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
3081 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
3082 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
3083 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
3084 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
3085 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
3086 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
3087 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
3088 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
3089 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
3090 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
3091 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
3092 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
3093 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
3094 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
3095 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
3096 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
3097 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
3098 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
3099 { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
3100 { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
3101 { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
3102 { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
3103 { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
3104 { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
3105 { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
3106 { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
3107 { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
3108 { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
3109 { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
3110 { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
3111 { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
3114 static const struct elf_reloc_map mips16_reloc_map[] =
3116 { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
3117 { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
3118 { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
3119 { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
3120 { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
3121 { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
3122 { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
3123 { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
3124 { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
3125 R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
3126 { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
3127 R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
3128 { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
3129 { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
3130 { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
3133 static const struct elf_reloc_map micromips_reloc_map[] =
3135 { BFD_RELOC_MICROMIPS_JMP, R_MICROMIPS_26_S1 - R_MICROMIPS_min },
3136 { BFD_RELOC_MICROMIPS_HI16_S, R_MICROMIPS_HI16 - R_MICROMIPS_min },
3137 { BFD_RELOC_MICROMIPS_LO16, R_MICROMIPS_LO16 - R_MICROMIPS_min },
3138 { BFD_RELOC_MICROMIPS_GPREL16, R_MICROMIPS_GPREL16 - R_MICROMIPS_min },
3139 { BFD_RELOC_MICROMIPS_LITERAL, R_MICROMIPS_LITERAL - R_MICROMIPS_min },
3140 { BFD_RELOC_MICROMIPS_GOT16, R_MICROMIPS_GOT16 - R_MICROMIPS_min },
3141 { BFD_RELOC_MICROMIPS_7_PCREL_S1, R_MICROMIPS_PC7_S1 - R_MICROMIPS_min },
3142 { BFD_RELOC_MICROMIPS_10_PCREL_S1, R_MICROMIPS_PC10_S1 - R_MICROMIPS_min },
3143 { BFD_RELOC_MICROMIPS_16_PCREL_S1, R_MICROMIPS_PC16_S1 - R_MICROMIPS_min },
3144 { BFD_RELOC_MICROMIPS_CALL16, R_MICROMIPS_CALL16 - R_MICROMIPS_min },
3145 { BFD_RELOC_MICROMIPS_GOT_DISP, R_MICROMIPS_GOT_DISP - R_MICROMIPS_min },
3146 { BFD_RELOC_MICROMIPS_GOT_PAGE, R_MICROMIPS_GOT_PAGE - R_MICROMIPS_min },
3147 { BFD_RELOC_MICROMIPS_GOT_OFST, R_MICROMIPS_GOT_OFST - R_MICROMIPS_min },
3148 { BFD_RELOC_MICROMIPS_GOT_HI16, R_MICROMIPS_GOT_HI16 - R_MICROMIPS_min },
3149 { BFD_RELOC_MICROMIPS_GOT_LO16, R_MICROMIPS_GOT_LO16 - R_MICROMIPS_min },
3150 { BFD_RELOC_MICROMIPS_SUB, R_MICROMIPS_SUB - R_MICROMIPS_min },
3151 { BFD_RELOC_MICROMIPS_HIGHER, R_MICROMIPS_HIGHER - R_MICROMIPS_min },
3152 { BFD_RELOC_MICROMIPS_HIGHEST, R_MICROMIPS_HIGHEST - R_MICROMIPS_min },
3153 { BFD_RELOC_MICROMIPS_CALL_HI16, R_MICROMIPS_CALL_HI16 - R_MICROMIPS_min },
3154 { BFD_RELOC_MICROMIPS_CALL_LO16, R_MICROMIPS_CALL_LO16 - R_MICROMIPS_min },
3156 /* Given a BFD reloc type, return a howto structure. */
3158 static reloc_howto_type *
3159 bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3160 bfd_reloc_code_real_type code)
3163 /* FIXME: We default to RELA here instead of choosing the right
3164 relocation variant. */
3165 reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
3166 reloc_howto_type *howto16_table = mips16_elf64_howto_table_rela;
3167 reloc_howto_type *howto_micromips_table = micromips_elf64_howto_table_rela;
3169 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
3172 if (mips_reloc_map[i].bfd_val == code)
3173 return &howto_table[(int) mips_reloc_map[i].elf_val];
3176 for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
3179 if (mips16_reloc_map[i].bfd_val == code)
3180 return &howto16_table[(int) mips16_reloc_map[i].elf_val];
3183 for (i = 0; i < sizeof (micromips_reloc_map) / sizeof (struct elf_reloc_map);
3186 if (micromips_reloc_map[i].bfd_val == code)
3187 return &howto_micromips_table[(int) micromips_reloc_map[i].elf_val];
3192 case BFD_RELOC_VTABLE_INHERIT:
3193 return &elf_mips_gnu_vtinherit_howto;
3194 case BFD_RELOC_VTABLE_ENTRY:
3195 return &elf_mips_gnu_vtentry_howto;
3196 case BFD_RELOC_MIPS_COPY:
3197 return &elf_mips_copy_howto;
3198 case BFD_RELOC_MIPS_JUMP_SLOT:
3199 return &elf_mips_jump_slot_howto;
3201 bfd_set_error (bfd_error_bad_value);
3206 static reloc_howto_type *
3207 bfd_elf64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3213 i < (sizeof (mips_elf64_howto_table_rela)
3214 / sizeof (mips_elf64_howto_table_rela[0])); i++)
3215 if (mips_elf64_howto_table_rela[i].name != NULL
3216 && strcasecmp (mips_elf64_howto_table_rela[i].name, r_name) == 0)
3217 return &mips_elf64_howto_table_rela[i];
3220 i < (sizeof (mips16_elf64_howto_table_rela)
3221 / sizeof (mips16_elf64_howto_table_rela[0]));
3223 if (mips16_elf64_howto_table_rela[i].name != NULL
3224 && strcasecmp (mips16_elf64_howto_table_rela[i].name, r_name) == 0)
3225 return &mips16_elf64_howto_table_rela[i];
3228 i < (sizeof (micromips_elf64_howto_table_rela)
3229 / sizeof (micromips_elf64_howto_table_rela[0]));
3231 if (micromips_elf64_howto_table_rela[i].name != NULL
3232 && strcasecmp (micromips_elf64_howto_table_rela[i].name, r_name) == 0)
3233 return µmips_elf64_howto_table_rela[i];
3235 if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
3236 return &elf_mips_gnu_vtinherit_howto;
3237 if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
3238 return &elf_mips_gnu_vtentry_howto;
3239 if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
3240 return &elf_mips_gnu_rel16_s2;
3241 if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
3242 return &elf_mips_gnu_rela16_s2;
3243 if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
3244 return &elf_mips_copy_howto;
3245 if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
3246 return &elf_mips_jump_slot_howto;
3251 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
3253 static reloc_howto_type *
3254 mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
3258 case R_MIPS_GNU_VTINHERIT:
3259 return &elf_mips_gnu_vtinherit_howto;
3260 case R_MIPS_GNU_VTENTRY:
3261 return &elf_mips_gnu_vtentry_howto;
3262 case R_MIPS_GNU_REL16_S2:
3264 return &elf_mips_gnu_rela16_s2;
3266 return &elf_mips_gnu_rel16_s2;
3268 return &elf_mips_copy_howto;
3269 case R_MIPS_JUMP_SLOT:
3270 return &elf_mips_jump_slot_howto;
3272 if (r_type >= R_MICROMIPS_min && r_type < R_MICROMIPS_max)
3275 return µmips_elf64_howto_table_rela[r_type - R_MICROMIPS_min];
3277 return µmips_elf64_howto_table_rel[r_type - R_MICROMIPS_min];
3279 if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
3282 return &mips16_elf64_howto_table_rela[r_type - R_MIPS16_min];
3284 return &mips16_elf64_howto_table_rel[r_type - R_MIPS16_min];
3286 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
3288 return &mips_elf64_howto_table_rela[r_type];
3290 return &mips_elf64_howto_table_rel[r_type];
3295 /* Prevent relocation handling by bfd for MIPS ELF64. */
3298 mips_elf64_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
3299 arelent *cache_ptr ATTRIBUTE_UNUSED,
3300 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
3306 mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
3307 arelent *cache_ptr ATTRIBUTE_UNUSED,
3308 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
3313 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
3314 to three relocs, we must tell the user to allocate more space. */
3317 mips_elf64_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
3319 return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
3323 mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd)
3325 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
3328 /* We must also copy more relocations than the corresponding functions
3329 in elf.c would, so the two following functions are slightly
3330 modified from elf.c, that multiply the external relocation count by
3331 3 to obtain the internal relocation count. */
3334 mips_elf64_canonicalize_reloc (bfd *abfd, sec_ptr section,
3335 arelent **relptr, asymbol **symbols)
3339 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
3341 if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
3344 tblptr = section->relocation;
3345 for (i = 0; i < section->reloc_count * 3; i++)
3346 *relptr++ = tblptr++;
3350 return section->reloc_count * 3;
3354 mips_elf64_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
3357 bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
3361 if (elf_dynsymtab (abfd) == 0)
3363 bfd_set_error (bfd_error_invalid_operation);
3367 slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
3369 for (s = abfd->sections; s != NULL; s = s->next)
3371 if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
3372 && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
3373 || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
3378 if (! (*slurp_relocs) (abfd, s, syms, TRUE))
3380 count = s->size / elf_section_data (s)->this_hdr.sh_entsize * 3;
3382 for (i = 0; i < count; i++)
3393 /* Read the relocations from one reloc section. This is mostly copied
3394 from elfcode.h, except for the changes to expand one external
3395 relocation to 3 internal ones. We must unfortunately set
3396 reloc_count to the number of external relocations, because a lot of
3397 generic code seems to depend on this. */
3400 mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
3401 Elf_Internal_Shdr *rel_hdr,
3402 bfd_size_type reloc_count,
3403 arelent *relents, asymbol **symbols,
3404 bfd_boolean dynamic)
3407 bfd_byte *native_relocs;
3413 allocated = bfd_malloc (rel_hdr->sh_size);
3414 if (allocated == NULL)
3417 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
3418 || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
3419 != rel_hdr->sh_size))
3422 native_relocs = allocated;
3424 entsize = rel_hdr->sh_entsize;
3425 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
3426 || entsize == sizeof (Elf64_Mips_External_Rela));
3428 if (entsize == sizeof (Elf64_Mips_External_Rel))
3433 for (i = 0, relent = relents;
3435 i++, native_relocs += entsize)
3437 Elf64_Mips_Internal_Rela rela;
3438 bfd_boolean used_sym, used_ssym;
3441 if (entsize == sizeof (Elf64_Mips_External_Rela))
3442 mips_elf64_swap_reloca_in (abfd,
3443 (Elf64_Mips_External_Rela *) native_relocs,
3446 mips_elf64_swap_reloc_in (abfd,
3447 (Elf64_Mips_External_Rel *) native_relocs,
3450 /* Each entry represents exactly three actual relocations. */
3454 for (ir = 0; ir < 3; ir++)
3456 enum elf_mips_reloc_type type;
3463 type = (enum elf_mips_reloc_type) rela.r_type;
3466 type = (enum elf_mips_reloc_type) rela.r_type2;
3469 type = (enum elf_mips_reloc_type) rela.r_type3;
3473 /* Some types require symbols, whereas some do not. */
3477 case R_MIPS_LITERAL:
3478 case R_MIPS_INSERT_A:
3479 case R_MIPS_INSERT_B:
3481 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3487 if (rela.r_sym == STN_UNDEF)
3488 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3493 ps = symbols + rela.r_sym - 1;
3495 if ((s->flags & BSF_SECTION_SYM) == 0)
3496 relent->sym_ptr_ptr = ps;
3498 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
3503 else if (! used_ssym)
3505 switch (rela.r_ssym)
3508 relent->sym_ptr_ptr =
3509 bfd_abs_section_ptr->symbol_ptr_ptr;
3515 /* FIXME: I think these need to be handled using
3516 special howto structures. */
3528 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3533 /* The address of an ELF reloc is section relative for an
3534 object file, and absolute for an executable file or
3535 shared library. The address of a BFD reloc is always
3536 section relative. */
3537 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
3538 relent->address = rela.r_offset;
3540 relent->address = rela.r_offset - asect->vma;
3542 relent->addend = rela.r_addend;
3544 relent->howto = mips_elf64_rtype_to_howto (type, rela_p);
3550 asect->reloc_count += (relent - relents) / 3;
3552 if (allocated != NULL)
3558 if (allocated != NULL)
3563 /* Read the relocations. On Irix 6, there can be two reloc sections
3564 associated with a single data section. This is copied from
3565 elfcode.h as well, with changes as small as accounting for 3
3566 internal relocs per external reloc and resetting reloc_count to
3567 zero before processing the relocs of a section. */
3570 mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
3571 asymbol **symbols, bfd_boolean dynamic)
3573 struct bfd_elf_section_data * const d = elf_section_data (asect);
3574 Elf_Internal_Shdr *rel_hdr;
3575 Elf_Internal_Shdr *rel_hdr2;
3576 bfd_size_type reloc_count;
3577 bfd_size_type reloc_count2;
3581 if (asect->relocation != NULL)
3586 if ((asect->flags & SEC_RELOC) == 0
3587 || asect->reloc_count == 0)
3590 rel_hdr = d->rel.hdr;
3591 reloc_count = rel_hdr ? NUM_SHDR_ENTRIES (rel_hdr) : 0;
3592 rel_hdr2 = d->rela.hdr;
3593 reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
3595 BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
3596 BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
3597 || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
3602 /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
3603 case because relocations against this section may use the
3604 dynamic symbol table, and in that case bfd_section_from_shdr
3605 in elf.c does not update the RELOC_COUNT. */
3606 if (asect->size == 0)
3609 rel_hdr = &d->this_hdr;
3610 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
3615 /* Allocate space for 3 arelent structures for each Rel structure. */
3616 amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
3617 relents = bfd_alloc (abfd, amt);
3618 if (relents == NULL)
3621 /* The slurp_one_reloc_table routine increments reloc_count. */
3622 asect->reloc_count = 0;
3625 && ! mips_elf64_slurp_one_reloc_table (abfd, asect,
3626 rel_hdr, reloc_count,
3630 if (rel_hdr2 != NULL
3631 && ! mips_elf64_slurp_one_reloc_table (abfd, asect,
3632 rel_hdr2, reloc_count2,
3633 relents + reloc_count * 3,
3637 asect->relocation = relents;
3641 /* Write out the relocations. */
3644 mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
3646 bfd_boolean *failedp = data;
3648 Elf_Internal_Shdr *rel_hdr;
3651 /* If we have already failed, don't do anything. */
3655 if ((sec->flags & SEC_RELOC) == 0)
3658 /* The linker backend writes the relocs out itself, and sets the
3659 reloc_count field to zero to inhibit writing them here. Also,
3660 sometimes the SEC_RELOC flag gets set even when there aren't any
3662 if (sec->reloc_count == 0)
3665 /* We can combine up to three relocs that refer to the same address
3666 if the latter relocs have no associated symbol. */
3668 for (idx = 0; idx < sec->reloc_count; idx++)
3675 addr = sec->orelocation[idx]->address;
3676 for (i = 0; i < 2; i++)
3680 if (idx + 1 >= sec->reloc_count)
3682 r = sec->orelocation[idx + 1];
3683 if (r->address != addr
3684 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
3685 || (*r->sym_ptr_ptr)->value != 0)
3688 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
3694 rel_hdr = _bfd_elf_single_rel_hdr (sec);
3696 /* Do the actual relocation. */
3698 if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
3699 mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
3700 else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
3701 mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
3707 mips_elf64_write_rel (bfd *abfd, asection *sec,
3708 Elf_Internal_Shdr *rel_hdr,
3709 int *count, void *data)
3711 bfd_boolean *failedp = data;
3712 Elf64_Mips_External_Rel *ext_rel;
3714 asymbol *last_sym = 0;
3715 int last_sym_idx = 0;
3717 rel_hdr->sh_size = rel_hdr->sh_entsize * *count;
3718 rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size);
3719 if (rel_hdr->contents == NULL)
3725 ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
3726 for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
3729 Elf64_Mips_Internal_Rela int_rel;
3734 ptr = sec->orelocation[idx];
3736 /* The address of an ELF reloc is section relative for an object
3737 file, and absolute for an executable file or shared library.
3738 The address of a BFD reloc is always section relative. */
3739 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
3740 int_rel.r_offset = ptr->address;
3742 int_rel.r_offset = ptr->address + sec->vma;
3744 sym = *ptr->sym_ptr_ptr;
3745 if (sym == last_sym)
3747 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
3752 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
3762 int_rel.r_ssym = RSS_UNDEF;
3764 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
3765 && ! _bfd_elf_validate_reloc (abfd, ptr))
3771 int_rel.r_type = ptr->howto->type;
3772 int_rel.r_type2 = (int) R_MIPS_NONE;
3773 int_rel.r_type3 = (int) R_MIPS_NONE;
3775 for (i = 0; i < 2; i++)
3779 if (idx + 1 >= sec->reloc_count)
3781 r = sec->orelocation[idx + 1];
3782 if (r->address != ptr->address
3783 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
3784 || (*r->sym_ptr_ptr)->value != 0)
3787 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
3790 int_rel.r_type2 = r->howto->type;
3792 int_rel.r_type3 = r->howto->type;
3797 mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
3800 BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
3805 mips_elf64_write_rela (bfd *abfd, asection *sec,
3806 Elf_Internal_Shdr *rela_hdr,
3807 int *count, void *data)
3809 bfd_boolean *failedp = data;
3810 Elf64_Mips_External_Rela *ext_rela;
3812 asymbol *last_sym = 0;
3813 int last_sym_idx = 0;
3815 rela_hdr->sh_size = rela_hdr->sh_entsize * *count;
3816 rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
3817 if (rela_hdr->contents == NULL)
3823 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
3824 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
3827 Elf64_Mips_Internal_Rela int_rela;
3832 ptr = sec->orelocation[idx];
3834 /* The address of an ELF reloc is section relative for an object
3835 file, and absolute for an executable file or shared library.
3836 The address of a BFD reloc is always section relative. */
3837 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
3838 int_rela.r_offset = ptr->address;
3840 int_rela.r_offset = ptr->address + sec->vma;
3842 sym = *ptr->sym_ptr_ptr;
3843 if (sym == last_sym)
3845 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
3850 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
3860 int_rela.r_addend = ptr->addend;
3861 int_rela.r_ssym = RSS_UNDEF;
3863 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
3864 && ! _bfd_elf_validate_reloc (abfd, ptr))
3870 int_rela.r_type = ptr->howto->type;
3871 int_rela.r_type2 = (int) R_MIPS_NONE;
3872 int_rela.r_type3 = (int) R_MIPS_NONE;
3874 for (i = 0; i < 2; i++)
3878 if (idx + 1 >= sec->reloc_count)
3880 r = sec->orelocation[idx + 1];
3881 if (r->address != ptr->address
3882 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
3883 || (*r->sym_ptr_ptr)->value != 0)
3886 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
3889 int_rela.r_type2 = r->howto->type;
3891 int_rela.r_type3 = r->howto->type;
3896 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
3899 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
3903 /* Set the right machine number for a MIPS ELF file. */
3906 mips_elf64_object_p (bfd *abfd)
3910 /* Irix 6 is broken. Object file symbol tables are not always
3911 sorted correctly such that local symbols precede global symbols,
3912 and the sh_info field in the symbol table is not always right. */
3913 if (elf64_mips_irix_compat (abfd) != ict_none)
3914 elf_bad_symtab (abfd) = TRUE;
3916 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
3917 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
3921 /* Depending on the target vector we generate some version of Irix
3922 executables or "normal" MIPS ELF ABI executables. */
3923 static irix_compat_t
3924 elf64_mips_irix_compat (bfd *abfd)
3926 if ((abfd->xvec == &bfd_elf64_bigmips_vec)
3927 || (abfd->xvec == &bfd_elf64_littlemips_vec))
3933 /* Support for core dump NOTE sections. */
3935 elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3940 switch (note->descsz)
3945 case 480: /* Linux/MIPS - N64 kernel */
3947 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
3950 elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 32);
3959 /* Make a ".reg/999" section. */
3960 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
3961 size, note->descpos + offset);
3965 elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3967 switch (note->descsz)
3972 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
3973 elf_tdata (abfd)->core_program
3974 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
3975 elf_tdata (abfd)->core_command
3976 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
3979 /* Note that for some reason, a spurious space is tacked
3980 onto the end of the args in some (at least one anyway)
3981 implementations, so strip it off if it exists. */
3984 char *command = elf_tdata (abfd)->core_command;
3985 int n = strlen (command);
3987 if (0 < n && command[n - 1] == ' ')
3988 command[n - 1] = '\0';
3994 /* ECOFF swapping routines. These are used when dealing with the
3995 .mdebug section, which is in the ECOFF debugging format. */
3996 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
3998 /* Symbol table magic number. */
4000 /* Alignment of debugging information. E.g., 4. */
4002 /* Sizes of external symbolic information. */
4003 sizeof (struct hdr_ext),
4004 sizeof (struct dnr_ext),
4005 sizeof (struct pdr_ext),
4006 sizeof (struct sym_ext),
4007 sizeof (struct opt_ext),
4008 sizeof (struct fdr_ext),
4009 sizeof (struct rfd_ext),
4010 sizeof (struct ext_ext),
4011 /* Functions to swap in external symbolic data. */
4020 _bfd_ecoff_swap_tir_in,
4021 _bfd_ecoff_swap_rndx_in,
4022 /* Functions to swap out external symbolic data. */
4031 _bfd_ecoff_swap_tir_out,
4032 _bfd_ecoff_swap_rndx_out,
4033 /* Function to read in symbolic data. */
4034 _bfd_mips_elf_read_ecoff_info
4037 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
4038 standard ELF. This structure is used to redirect the relocation
4039 handling routines. */
4041 const struct elf_size_info mips_elf64_size_info =
4043 sizeof (Elf64_External_Ehdr),
4044 sizeof (Elf64_External_Phdr),
4045 sizeof (Elf64_External_Shdr),
4046 sizeof (Elf64_Mips_External_Rel),
4047 sizeof (Elf64_Mips_External_Rela),
4048 sizeof (Elf64_External_Sym),
4049 sizeof (Elf64_External_Dyn),
4050 sizeof (Elf_External_Note),
4051 4, /* hash-table entry size */
4052 3, /* internal relocations per external relocations */
4054 3, /* log_file_align */
4057 bfd_elf64_write_out_phdrs,
4058 bfd_elf64_write_shdrs_and_ehdr,
4059 bfd_elf64_checksum_contents,
4060 mips_elf64_write_relocs,
4061 bfd_elf64_swap_symbol_in,
4062 bfd_elf64_swap_symbol_out,
4063 mips_elf64_slurp_reloc_table,
4064 bfd_elf64_slurp_symbol_table,
4065 bfd_elf64_swap_dyn_in,
4066 bfd_elf64_swap_dyn_out,
4067 mips_elf64_be_swap_reloc_in,
4068 mips_elf64_be_swap_reloc_out,
4069 mips_elf64_be_swap_reloca_in,
4070 mips_elf64_be_swap_reloca_out
4073 #define ELF_ARCH bfd_arch_mips
4074 #define ELF_TARGET_ID MIPS_ELF_DATA
4075 #define ELF_MACHINE_CODE EM_MIPS
4077 #define elf_backend_collect TRUE
4078 #define elf_backend_type_change_ok TRUE
4079 #define elf_backend_can_gc_sections TRUE
4080 #define elf_info_to_howto mips_elf64_info_to_howto_rela
4081 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
4082 #define elf_backend_object_p mips_elf64_object_p
4083 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
4084 #define elf_backend_section_processing _bfd_mips_elf_section_processing
4085 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
4086 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
4087 #define elf_backend_section_from_bfd_section \
4088 _bfd_mips_elf_section_from_bfd_section
4089 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
4090 #define elf_backend_link_output_symbol_hook \
4091 _bfd_mips_elf_link_output_symbol_hook
4092 #define elf_backend_create_dynamic_sections \
4093 _bfd_mips_elf_create_dynamic_sections
4094 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
4095 #define elf_backend_merge_symbol_attribute \
4096 _bfd_mips_elf_merge_symbol_attribute
4097 #define elf_backend_get_target_dtag _bfd_mips_elf_get_target_dtag
4098 #define elf_backend_adjust_dynamic_symbol \
4099 _bfd_mips_elf_adjust_dynamic_symbol
4100 #define elf_backend_always_size_sections \
4101 _bfd_mips_elf_always_size_sections
4102 #define elf_backend_size_dynamic_sections \
4103 _bfd_mips_elf_size_dynamic_sections
4104 #define elf_backend_init_index_section _bfd_elf_init_1_index_section
4105 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
4106 #define elf_backend_finish_dynamic_symbol \
4107 _bfd_mips_elf_finish_dynamic_symbol
4108 #define elf_backend_finish_dynamic_sections \
4109 _bfd_mips_elf_finish_dynamic_sections
4110 #define elf_backend_final_write_processing \
4111 _bfd_mips_elf_final_write_processing
4112 #define elf_backend_additional_program_headers \
4113 _bfd_mips_elf_additional_program_headers
4114 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
4115 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
4116 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
4117 #define elf_backend_copy_indirect_symbol \
4118 _bfd_mips_elf_copy_indirect_symbol
4119 #define elf_backend_ignore_discarded_relocs \
4120 _bfd_mips_elf_ignore_discarded_relocs
4121 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
4122 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
4123 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
4124 #define elf_backend_size_info mips_elf64_size_info
4126 #define elf_backend_grok_prstatus elf64_mips_grok_prstatus
4127 #define elf_backend_grok_psinfo elf64_mips_grok_psinfo
4129 #define elf_backend_got_header_size (8 * MIPS_RESERVED_GOTNO)
4131 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
4132 work better/work only in RELA, so we default to this. */
4133 #define elf_backend_may_use_rel_p 1
4134 #define elf_backend_may_use_rela_p 1
4135 #define elf_backend_default_use_rela_p 1
4136 #define elf_backend_rela_plts_and_copies_p 0
4137 #define elf_backend_plt_readonly 1
4138 #define elf_backend_plt_sym_val _bfd_mips_elf_plt_sym_val
4140 #define elf_backend_sign_extend_vma TRUE
4142 #define elf_backend_write_section _bfd_mips_elf_write_section
4144 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
4145 MIPS-specific function only applies to IRIX5, which had no 64-bit
4147 #define bfd_elf64_bfd_is_target_special_symbol \
4148 _bfd_mips_elf_is_target_special_symbol
4149 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
4150 #define bfd_elf64_find_inliner_info _bfd_mips_elf_find_inliner_info
4151 #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
4152 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
4153 #define bfd_elf64_bfd_get_relocated_section_contents \
4154 _bfd_elf_mips_get_relocated_section_contents
4155 #define bfd_elf64_bfd_link_hash_table_create \
4156 _bfd_mips_elf_link_hash_table_create
4157 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
4158 #define bfd_elf64_bfd_merge_private_bfd_data \
4159 _bfd_mips_elf_merge_private_bfd_data
4160 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
4161 #define bfd_elf64_bfd_print_private_bfd_data \
4162 _bfd_mips_elf_print_private_bfd_data
4164 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
4165 #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
4166 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
4167 #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
4168 #define bfd_elf64_bfd_relax_section _bfd_mips_relax_section
4169 #define bfd_elf64_mkobject _bfd_mips_elf_mkobject
4171 /* MIPS ELF64 archive functions. */
4172 #define bfd_elf64_archive_functions
4173 extern bfd_boolean bfd_elf64_archive_slurp_armap
4175 extern bfd_boolean bfd_elf64_archive_write_armap
4176 (bfd *, unsigned int, struct orl *, unsigned int, int);
4177 #define bfd_elf64_archive_slurp_extended_name_table \
4178 _bfd_archive_coff_slurp_extended_name_table
4179 #define bfd_elf64_archive_construct_extended_name_table \
4180 _bfd_archive_coff_construct_extended_name_table
4181 #define bfd_elf64_archive_truncate_arname \
4182 _bfd_archive_coff_truncate_arname
4183 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
4184 #define bfd_elf64_archive_write_ar_hdr _bfd_archive_coff_write_ar_hdr
4185 #define bfd_elf64_archive_openr_next_archived_file \
4186 _bfd_archive_coff_openr_next_archived_file
4187 #define bfd_elf64_archive_get_elt_at_index \
4188 _bfd_archive_coff_get_elt_at_index
4189 #define bfd_elf64_archive_generic_stat_arch_elt \
4190 _bfd_archive_coff_generic_stat_arch_elt
4191 #define bfd_elf64_archive_update_armap_timestamp \
4192 _bfd_archive_coff_update_armap_timestamp
4194 /* The SGI style (n)64 NewABI. */
4195 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
4196 #define TARGET_LITTLE_NAME "elf64-littlemips"
4197 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec
4198 #define TARGET_BIG_NAME "elf64-bigmips"
4200 #define ELF_MAXPAGESIZE 0x10000
4201 #define ELF_COMMONPAGESIZE 0x1000
4203 #include "elf64-target.h"
4205 /* The SYSV-style 'traditional' (n)64 NewABI. */
4206 #undef TARGET_LITTLE_SYM
4207 #undef TARGET_LITTLE_NAME
4208 #undef TARGET_BIG_SYM
4209 #undef TARGET_BIG_NAME
4211 #undef ELF_MAXPAGESIZE
4212 #undef ELF_COMMONPAGESIZE
4214 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
4215 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
4216 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
4217 #define TARGET_BIG_NAME "elf64-tradbigmips"
4219 #define ELF_MAXPAGESIZE 0x10000
4220 #define ELF_COMMONPAGESIZE 0x1000
4221 #define elf64_bed elf64_tradbed
4223 /* Include the target file again for this target. */
4224 #include "elf64-target.h"
4227 /* FreeBSD support. */
4229 #undef TARGET_LITTLE_SYM
4230 #undef TARGET_LITTLE_NAME
4231 #undef TARGET_BIG_SYM
4232 #undef TARGET_BIG_NAME
4234 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_freebsd_vec
4235 #define TARGET_LITTLE_NAME "elf64-tradlittlemips-freebsd"
4236 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_freebsd_vec
4237 #define TARGET_BIG_NAME "elf64-tradbigmips-freebsd"
4240 #define ELF_OSABI ELFOSABI_FREEBSD
4242 /* The kernel recognizes executables as valid only if they carry a
4243 "FreeBSD" label in the ELF header. So we put this label on all
4244 executables and (for simplicity) also all other object files. */
4247 elf_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info)
4249 _bfd_elf_set_osabi (abfd, info);
4252 #undef elf_backend_post_process_headers
4253 #define elf_backend_post_process_headers elf_fbsd_post_process_headers
4255 #define elf64_bed elf64_fbsd_tradbed
4257 #include "elf64-target.h"