1 /* MIPS-specific support for 64-bit ELF
2 Copyright (C) 1996-2014 Free Software Foundation, Inc.
3 Ian Lance Taylor, Cygnus Support
4 Linker support added by Mark Mitchell, CodeSourcery, LLC.
5 <mark@codesourcery.com>
7 This file is part of BFD, the Binary File Descriptor library.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
25 /* This file supports the 64-bit MIPS ELF ABI.
27 The MIPS 64-bit ELF ABI uses an unusual reloc format. This file
28 overrides the usual ELF reloc handling, and handles reading and
29 writing the relocations here. */
31 /* TODO: Many things are unsupported, even if there is some code for it
32 . (which was mostly stolen from elf32-mips.c and slightly adapted).
34 . - Relocation handling for REL relocs is wrong in many cases and
36 . - Relocation handling for RELA relocs related to GOT support are
37 . also likely to be wrong.
38 . - Support for MIPS16 is untested.
39 . - Combined relocs with RSS_* entries are unsupported.
40 . - The whole GOT handling for NewABI is missing, some parts of
41 . the OldABI version is still lying around and should be removed.
51 #include "elfxx-mips.h"
54 /* Get the ECOFF swapping routines. The 64-bit ABI is not supposed to
55 use ECOFF. However, we support it anyhow for an easier changeover. */
57 #include "coff/symconst.h"
58 #include "coff/internal.h"
59 #include "coff/ecoff.h"
60 /* The 64 bit versions of the mdebug data structures are in alpha.h. */
61 #include "coff/alpha.h"
62 #define ECOFF_SIGNED_64
63 #include "ecoffswap.h"
65 static void mips_elf64_swap_reloc_in
66 (bfd *, const Elf64_Mips_External_Rel *, Elf64_Mips_Internal_Rela *);
67 static void mips_elf64_swap_reloca_in
68 (bfd *, const Elf64_Mips_External_Rela *, Elf64_Mips_Internal_Rela *);
69 static void mips_elf64_swap_reloc_out
70 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rel *);
71 static void mips_elf64_swap_reloca_out
72 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rela *);
73 static void mips_elf64_be_swap_reloc_in
74 (bfd *, const bfd_byte *, Elf_Internal_Rela *);
75 static void mips_elf64_be_swap_reloc_out
76 (bfd *, const Elf_Internal_Rela *, bfd_byte *);
77 static void mips_elf64_be_swap_reloca_in
78 (bfd *, const bfd_byte *, Elf_Internal_Rela *);
79 static void mips_elf64_be_swap_reloca_out
80 (bfd *, const Elf_Internal_Rela *, bfd_byte *);
81 static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup
82 (bfd *, bfd_reloc_code_real_type);
83 static reloc_howto_type *mips_elf64_rtype_to_howto
84 (unsigned int, bfd_boolean);
85 static void mips_elf64_info_to_howto_rel
86 (bfd *, arelent *, Elf_Internal_Rela *);
87 static void mips_elf64_info_to_howto_rela
88 (bfd *, arelent *, Elf_Internal_Rela *);
89 static long mips_elf64_get_reloc_upper_bound
91 static long mips_elf64_canonicalize_reloc
92 (bfd *, asection *, arelent **, asymbol **);
93 static long mips_elf64_get_dynamic_reloc_upper_bound
95 static long mips_elf64_canonicalize_dynamic_reloc
96 (bfd *, arelent **, asymbol **);
97 static bfd_boolean mips_elf64_slurp_one_reloc_table
98 (bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type, arelent *,
99 asymbol **, bfd_boolean);
100 static bfd_boolean mips_elf64_slurp_reloc_table
101 (bfd *, asection *, asymbol **, bfd_boolean);
102 static void mips_elf64_write_relocs
103 (bfd *, asection *, void *);
104 static void mips_elf64_write_rel
105 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
106 static void mips_elf64_write_rela
107 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
108 static bfd_reloc_status_type mips_elf64_gprel16_reloc
109 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
110 static bfd_reloc_status_type mips_elf64_literal_reloc
111 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
112 static bfd_reloc_status_type mips_elf64_gprel32_reloc
113 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
114 static bfd_reloc_status_type mips_elf64_shift6_reloc
115 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
116 static bfd_reloc_status_type mips16_gprel_reloc
117 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
118 static bfd_boolean mips_elf64_assign_gp
120 static bfd_reloc_status_type mips_elf64_final_gp
121 (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
122 static bfd_boolean mips_elf64_object_p
124 static irix_compat_t elf64_mips_irix_compat
126 static bfd_boolean elf64_mips_grok_prstatus
127 (bfd *, Elf_Internal_Note *);
128 static bfd_boolean elf64_mips_grok_psinfo
129 (bfd *, Elf_Internal_Note *);
131 extern const bfd_target mips_elf64_be_vec;
132 extern const bfd_target mips_elf64_le_vec;
134 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
135 from smaller values. Start with zero, widen, *then* decrement. */
136 #define MINUS_ONE (((bfd_vma)0) - 1)
138 /* The number of local .got entries we reserve. */
139 #define MIPS_RESERVED_GOTNO (2)
141 /* The relocation table used for SHT_REL sections. */
143 static reloc_howto_type mips_elf64_howto_table_rel[] =
146 HOWTO (R_MIPS_NONE, /* type */
148 0, /* size (0 = byte, 1 = short, 2 = long) */
150 FALSE, /* pc_relative */
152 complain_overflow_dont, /* complain_on_overflow */
153 _bfd_mips_elf_generic_reloc, /* special_function */
154 "R_MIPS_NONE", /* name */
155 FALSE, /* partial_inplace */
158 FALSE), /* pcrel_offset */
160 /* 16 bit relocation. */
161 HOWTO (R_MIPS_16, /* type */
163 2, /* size (0 = byte, 1 = short, 2 = long) */
165 FALSE, /* pc_relative */
167 complain_overflow_signed, /* complain_on_overflow */
168 _bfd_mips_elf_generic_reloc, /* special_function */
169 "R_MIPS_16", /* name */
170 TRUE, /* partial_inplace */
171 0x0000ffff, /* src_mask */
172 0x0000ffff, /* dst_mask */
173 FALSE), /* pcrel_offset */
175 /* 32 bit relocation. */
176 HOWTO (R_MIPS_32, /* type */
178 2, /* size (0 = byte, 1 = short, 2 = long) */
180 FALSE, /* pc_relative */
182 complain_overflow_dont, /* complain_on_overflow */
183 _bfd_mips_elf_generic_reloc, /* special_function */
184 "R_MIPS_32", /* name */
185 TRUE, /* partial_inplace */
186 0xffffffff, /* src_mask */
187 0xffffffff, /* dst_mask */
188 FALSE), /* pcrel_offset */
190 /* 32 bit symbol relative relocation. */
191 HOWTO (R_MIPS_REL32, /* type */
193 2, /* size (0 = byte, 1 = short, 2 = long) */
195 FALSE, /* pc_relative */
197 complain_overflow_dont, /* complain_on_overflow */
198 _bfd_mips_elf_generic_reloc, /* special_function */
199 "R_MIPS_REL32", /* name */
200 TRUE, /* partial_inplace */
201 0xffffffff, /* src_mask */
202 0xffffffff, /* dst_mask */
203 FALSE), /* pcrel_offset */
205 /* 26 bit jump address. */
206 HOWTO (R_MIPS_26, /* type */
208 2, /* size (0 = byte, 1 = short, 2 = long) */
210 FALSE, /* pc_relative */
212 complain_overflow_dont, /* complain_on_overflow */
213 /* This needs complex overflow
214 detection, because the upper 36
215 bits must match the PC + 4. */
216 _bfd_mips_elf_generic_reloc, /* special_function */
217 "R_MIPS_26", /* name */
218 TRUE, /* partial_inplace */
219 0x03ffffff, /* src_mask */
220 0x03ffffff, /* dst_mask */
221 FALSE), /* pcrel_offset */
223 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
224 However, the native IRIX6 tools use them, so we try our best. */
226 /* High 16 bits of symbol value. */
227 HOWTO (R_MIPS_HI16, /* type */
229 2, /* size (0 = byte, 1 = short, 2 = long) */
231 FALSE, /* pc_relative */
233 complain_overflow_dont, /* complain_on_overflow */
234 _bfd_mips_elf_hi16_reloc, /* special_function */
235 "R_MIPS_HI16", /* name */
236 TRUE, /* partial_inplace */
237 0x0000ffff, /* src_mask */
238 0x0000ffff, /* dst_mask */
239 FALSE), /* pcrel_offset */
241 /* Low 16 bits of symbol value. */
242 HOWTO (R_MIPS_LO16, /* type */
244 2, /* size (0 = byte, 1 = short, 2 = long) */
246 FALSE, /* pc_relative */
248 complain_overflow_dont, /* complain_on_overflow */
249 _bfd_mips_elf_lo16_reloc, /* special_function */
250 "R_MIPS_LO16", /* name */
251 TRUE, /* partial_inplace */
252 0x0000ffff, /* src_mask */
253 0x0000ffff, /* dst_mask */
254 FALSE), /* pcrel_offset */
256 /* GP relative reference. */
257 HOWTO (R_MIPS_GPREL16, /* type */
259 2, /* size (0 = byte, 1 = short, 2 = long) */
261 FALSE, /* pc_relative */
263 complain_overflow_signed, /* complain_on_overflow */
264 mips_elf64_gprel16_reloc, /* special_function */
265 "R_MIPS_GPREL16", /* name */
266 TRUE, /* partial_inplace */
267 0x0000ffff, /* src_mask */
268 0x0000ffff, /* dst_mask */
269 FALSE), /* pcrel_offset */
271 /* Reference to literal section. */
272 HOWTO (R_MIPS_LITERAL, /* type */
274 2, /* size (0 = byte, 1 = short, 2 = long) */
276 FALSE, /* pc_relative */
278 complain_overflow_signed, /* complain_on_overflow */
279 mips_elf64_literal_reloc, /* special_function */
280 "R_MIPS_LITERAL", /* name */
281 TRUE, /* partial_inplace */
282 0x0000ffff, /* src_mask */
283 0x0000ffff, /* dst_mask */
284 FALSE), /* pcrel_offset */
286 /* Reference to global offset table. */
287 HOWTO (R_MIPS_GOT16, /* type */
289 2, /* size (0 = byte, 1 = short, 2 = long) */
291 FALSE, /* pc_relative */
293 complain_overflow_signed, /* complain_on_overflow */
294 _bfd_mips_elf_got16_reloc, /* special_function */
295 "R_MIPS_GOT16", /* name */
296 TRUE, /* partial_inplace */
297 0x0000ffff, /* src_mask */
298 0x0000ffff, /* dst_mask */
299 FALSE), /* pcrel_offset */
301 /* 16 bit PC relative reference. Note that the ABI document has a typo
302 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
303 We do the right thing here. */
304 HOWTO (R_MIPS_PC16, /* type */
306 2, /* size (0 = byte, 1 = short, 2 = long) */
308 TRUE, /* pc_relative */
310 complain_overflow_signed, /* complain_on_overflow */
311 _bfd_mips_elf_generic_reloc, /* special_function */
312 "R_MIPS_PC16", /* name */
313 TRUE, /* partial_inplace */
314 0x0000ffff, /* src_mask */
315 0x0000ffff, /* dst_mask */
316 TRUE), /* pcrel_offset */
318 /* 16 bit call through global offset table. */
319 HOWTO (R_MIPS_CALL16, /* type */
321 2, /* size (0 = byte, 1 = short, 2 = long) */
323 FALSE, /* pc_relative */
325 complain_overflow_signed, /* complain_on_overflow */
326 _bfd_mips_elf_generic_reloc, /* special_function */
327 "R_MIPS_CALL16", /* name */
328 TRUE, /* partial_inplace */
329 0x0000ffff, /* src_mask */
330 0x0000ffff, /* dst_mask */
331 FALSE), /* pcrel_offset */
333 /* 32 bit GP relative reference. */
334 HOWTO (R_MIPS_GPREL32, /* type */
336 2, /* size (0 = byte, 1 = short, 2 = long) */
338 FALSE, /* pc_relative */
340 complain_overflow_dont, /* complain_on_overflow */
341 mips_elf64_gprel32_reloc, /* special_function */
342 "R_MIPS_GPREL32", /* name */
343 TRUE, /* partial_inplace */
344 0xffffffff, /* src_mask */
345 0xffffffff, /* dst_mask */
346 FALSE), /* pcrel_offset */
352 /* A 5 bit shift field. */
353 HOWTO (R_MIPS_SHIFT5, /* type */
355 2, /* size (0 = byte, 1 = short, 2 = long) */
357 FALSE, /* pc_relative */
359 complain_overflow_bitfield, /* complain_on_overflow */
360 _bfd_mips_elf_generic_reloc, /* special_function */
361 "R_MIPS_SHIFT5", /* name */
362 TRUE, /* partial_inplace */
363 0x000007c0, /* src_mask */
364 0x000007c0, /* dst_mask */
365 FALSE), /* pcrel_offset */
367 /* A 6 bit shift field. */
368 HOWTO (R_MIPS_SHIFT6, /* type */
370 2, /* size (0 = byte, 1 = short, 2 = long) */
372 FALSE, /* pc_relative */
374 complain_overflow_bitfield, /* complain_on_overflow */
375 mips_elf64_shift6_reloc, /* special_function */
376 "R_MIPS_SHIFT6", /* name */
377 TRUE, /* partial_inplace */
378 0x000007c4, /* src_mask */
379 0x000007c4, /* dst_mask */
380 FALSE), /* pcrel_offset */
382 /* 64 bit relocation. */
383 HOWTO (R_MIPS_64, /* type */
385 4, /* size (0 = byte, 1 = short, 2 = long) */
387 FALSE, /* pc_relative */
389 complain_overflow_dont, /* complain_on_overflow */
390 _bfd_mips_elf_generic_reloc, /* special_function */
391 "R_MIPS_64", /* name */
392 TRUE, /* partial_inplace */
393 MINUS_ONE, /* src_mask */
394 MINUS_ONE, /* dst_mask */
395 FALSE), /* pcrel_offset */
397 /* Displacement in the global offset table. */
398 HOWTO (R_MIPS_GOT_DISP, /* type */
400 2, /* size (0 = byte, 1 = short, 2 = long) */
402 FALSE, /* pc_relative */
404 complain_overflow_signed, /* complain_on_overflow */
405 _bfd_mips_elf_generic_reloc, /* special_function */
406 "R_MIPS_GOT_DISP", /* name */
407 TRUE, /* partial_inplace */
408 0x0000ffff, /* src_mask */
409 0x0000ffff, /* dst_mask */
410 FALSE), /* pcrel_offset */
412 /* Displacement to page pointer in the global offset table. */
413 HOWTO (R_MIPS_GOT_PAGE, /* type */
415 2, /* size (0 = byte, 1 = short, 2 = long) */
417 FALSE, /* pc_relative */
419 complain_overflow_signed, /* complain_on_overflow */
420 _bfd_mips_elf_generic_reloc, /* special_function */
421 "R_MIPS_GOT_PAGE", /* name */
422 TRUE, /* partial_inplace */
423 0x0000ffff, /* src_mask */
424 0x0000ffff, /* dst_mask */
425 FALSE), /* pcrel_offset */
427 /* Offset from page pointer in the global offset table. */
428 HOWTO (R_MIPS_GOT_OFST, /* type */
430 2, /* size (0 = byte, 1 = short, 2 = long) */
432 FALSE, /* pc_relative */
434 complain_overflow_signed, /* complain_on_overflow */
435 _bfd_mips_elf_generic_reloc, /* special_function */
436 "R_MIPS_GOT_OFST", /* name */
437 TRUE, /* partial_inplace */
438 0x0000ffff, /* src_mask */
439 0x0000ffff, /* dst_mask */
440 FALSE), /* pcrel_offset */
442 /* High 16 bits of displacement in global offset table. */
443 HOWTO (R_MIPS_GOT_HI16, /* type */
445 2, /* size (0 = byte, 1 = short, 2 = long) */
447 FALSE, /* pc_relative */
449 complain_overflow_dont, /* complain_on_overflow */
450 _bfd_mips_elf_generic_reloc, /* special_function */
451 "R_MIPS_GOT_HI16", /* name */
452 TRUE, /* partial_inplace */
453 0x0000ffff, /* src_mask */
454 0x0000ffff, /* dst_mask */
455 FALSE), /* pcrel_offset */
457 /* Low 16 bits of displacement in global offset table. */
458 HOWTO (R_MIPS_GOT_LO16, /* type */
460 2, /* size (0 = byte, 1 = short, 2 = long) */
462 FALSE, /* pc_relative */
464 complain_overflow_dont, /* complain_on_overflow */
465 _bfd_mips_elf_generic_reloc, /* special_function */
466 "R_MIPS_GOT_LO16", /* name */
467 TRUE, /* partial_inplace */
468 0x0000ffff, /* src_mask */
469 0x0000ffff, /* dst_mask */
470 FALSE), /* pcrel_offset */
472 /* 64 bit subtraction. */
473 HOWTO (R_MIPS_SUB, /* type */
475 4, /* size (0 = byte, 1 = short, 2 = long) */
477 FALSE, /* pc_relative */
479 complain_overflow_dont, /* complain_on_overflow */
480 _bfd_mips_elf_generic_reloc, /* special_function */
481 "R_MIPS_SUB", /* name */
482 TRUE, /* partial_inplace */
483 MINUS_ONE, /* src_mask */
484 MINUS_ONE, /* dst_mask */
485 FALSE), /* pcrel_offset */
487 /* Insert the addend as an instruction. */
488 /* FIXME: Not handled correctly. */
489 HOWTO (R_MIPS_INSERT_A, /* type */
491 2, /* size (0 = byte, 1 = short, 2 = long) */
493 FALSE, /* pc_relative */
495 complain_overflow_dont, /* complain_on_overflow */
496 _bfd_mips_elf_generic_reloc, /* special_function */
497 "R_MIPS_INSERT_A", /* name */
498 TRUE, /* partial_inplace */
499 0xffffffff, /* src_mask */
500 0xffffffff, /* dst_mask */
501 FALSE), /* pcrel_offset */
503 /* Insert the addend as an instruction, and change all relocations
504 to refer to the old instruction at the address. */
505 /* FIXME: Not handled correctly. */
506 HOWTO (R_MIPS_INSERT_B, /* type */
508 2, /* size (0 = byte, 1 = short, 2 = long) */
510 FALSE, /* pc_relative */
512 complain_overflow_dont, /* complain_on_overflow */
513 _bfd_mips_elf_generic_reloc, /* special_function */
514 "R_MIPS_INSERT_B", /* name */
515 TRUE, /* partial_inplace */
516 0xffffffff, /* src_mask */
517 0xffffffff, /* dst_mask */
518 FALSE), /* pcrel_offset */
520 /* Delete a 32 bit instruction. */
521 /* FIXME: Not handled correctly. */
522 HOWTO (R_MIPS_DELETE, /* type */
524 2, /* size (0 = byte, 1 = short, 2 = long) */
526 FALSE, /* pc_relative */
528 complain_overflow_dont, /* complain_on_overflow */
529 _bfd_mips_elf_generic_reloc, /* special_function */
530 "R_MIPS_DELETE", /* name */
531 TRUE, /* partial_inplace */
532 0xffffffff, /* src_mask */
533 0xffffffff, /* dst_mask */
534 FALSE), /* pcrel_offset */
536 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
538 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
539 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
541 b) No other NewABI toolchain actually emits such relocations. */
542 EMPTY_HOWTO (R_MIPS_HIGHER),
543 EMPTY_HOWTO (R_MIPS_HIGHEST),
545 /* High 16 bits of displacement in global offset table. */
546 HOWTO (R_MIPS_CALL_HI16, /* type */
548 2, /* size (0 = byte, 1 = short, 2 = long) */
550 FALSE, /* pc_relative */
552 complain_overflow_dont, /* complain_on_overflow */
553 _bfd_mips_elf_generic_reloc, /* special_function */
554 "R_MIPS_CALL_HI16", /* name */
555 TRUE, /* partial_inplace */
556 0x0000ffff, /* src_mask */
557 0x0000ffff, /* dst_mask */
558 FALSE), /* pcrel_offset */
560 /* Low 16 bits of displacement in global offset table. */
561 HOWTO (R_MIPS_CALL_LO16, /* type */
563 2, /* size (0 = byte, 1 = short, 2 = long) */
565 FALSE, /* pc_relative */
567 complain_overflow_dont, /* complain_on_overflow */
568 _bfd_mips_elf_generic_reloc, /* special_function */
569 "R_MIPS_CALL_LO16", /* name */
570 TRUE, /* partial_inplace */
571 0x0000ffff, /* src_mask */
572 0x0000ffff, /* dst_mask */
573 FALSE), /* pcrel_offset */
575 /* Section displacement, used by an associated event location section. */
576 HOWTO (R_MIPS_SCN_DISP, /* type */
578 2, /* size (0 = byte, 1 = short, 2 = long) */
580 FALSE, /* pc_relative */
582 complain_overflow_dont, /* complain_on_overflow */
583 _bfd_mips_elf_generic_reloc, /* special_function */
584 "R_MIPS_SCN_DISP", /* name */
585 TRUE, /* partial_inplace */
586 0xffffffff, /* src_mask */
587 0xffffffff, /* dst_mask */
588 FALSE), /* pcrel_offset */
590 HOWTO (R_MIPS_REL16, /* type */
592 1, /* size (0 = byte, 1 = short, 2 = long) */
594 FALSE, /* pc_relative */
596 complain_overflow_signed, /* complain_on_overflow */
597 _bfd_mips_elf_generic_reloc, /* special_function */
598 "R_MIPS_REL16", /* name */
599 TRUE, /* partial_inplace */
600 0xffff, /* src_mask */
601 0xffff, /* dst_mask */
602 FALSE), /* pcrel_offset */
604 /* These two are obsolete. */
605 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
606 EMPTY_HOWTO (R_MIPS_PJUMP),
608 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
609 It must be used for multigot GOT's (and only there). */
610 HOWTO (R_MIPS_RELGOT, /* type */
612 2, /* size (0 = byte, 1 = short, 2 = long) */
614 FALSE, /* pc_relative */
616 complain_overflow_dont, /* complain_on_overflow */
617 _bfd_mips_elf_generic_reloc, /* special_function */
618 "R_MIPS_RELGOT", /* name */
619 TRUE, /* partial_inplace */
620 0xffffffff, /* src_mask */
621 0xffffffff, /* dst_mask */
622 FALSE), /* pcrel_offset */
624 /* Protected jump conversion. This is an optimization hint. No
625 relocation is required for correctness. */
626 HOWTO (R_MIPS_JALR, /* type */
628 2, /* size (0 = byte, 1 = short, 2 = long) */
630 FALSE, /* pc_relative */
632 complain_overflow_dont, /* complain_on_overflow */
633 _bfd_mips_elf_generic_reloc, /* special_function */
634 "R_MIPS_JALR", /* name */
635 FALSE, /* partial_inplace */
637 0x00000000, /* dst_mask */
638 FALSE), /* pcrel_offset */
640 /* TLS relocations. */
641 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
642 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
644 HOWTO (R_MIPS_TLS_DTPMOD64, /* type */
646 4, /* size (0 = byte, 1 = short, 2 = long) */
648 FALSE, /* pc_relative */
650 complain_overflow_dont, /* complain_on_overflow */
651 _bfd_mips_elf_generic_reloc, /* special_function */
652 "R_MIPS_TLS_DTPMOD64", /* name */
653 TRUE, /* partial_inplace */
654 MINUS_ONE, /* src_mask */
655 MINUS_ONE, /* dst_mask */
656 FALSE), /* pcrel_offset */
658 HOWTO (R_MIPS_TLS_DTPREL64, /* type */
660 4, /* size (0 = byte, 1 = short, 2 = long) */
662 FALSE, /* pc_relative */
664 complain_overflow_dont, /* complain_on_overflow */
665 _bfd_mips_elf_generic_reloc, /* special_function */
666 "R_MIPS_TLS_DTPREL64", /* name */
667 TRUE, /* partial_inplace */
668 MINUS_ONE, /* src_mask */
669 MINUS_ONE, /* dst_mask */
670 FALSE), /* pcrel_offset */
672 /* TLS general dynamic variable reference. */
673 HOWTO (R_MIPS_TLS_GD, /* type */
675 2, /* size (0 = byte, 1 = short, 2 = long) */
677 FALSE, /* pc_relative */
679 complain_overflow_signed, /* complain_on_overflow */
680 _bfd_mips_elf_generic_reloc, /* special_function */
681 "R_MIPS_TLS_GD", /* name */
682 TRUE, /* partial_inplace */
683 0x0000ffff, /* src_mask */
684 0x0000ffff, /* dst_mask */
685 FALSE), /* pcrel_offset */
687 /* TLS local dynamic variable reference. */
688 HOWTO (R_MIPS_TLS_LDM, /* type */
690 2, /* size (0 = byte, 1 = short, 2 = long) */
692 FALSE, /* pc_relative */
694 complain_overflow_signed, /* complain_on_overflow */
695 _bfd_mips_elf_generic_reloc, /* special_function */
696 "R_MIPS_TLS_LDM", /* name */
697 TRUE, /* partial_inplace */
698 0x0000ffff, /* src_mask */
699 0x0000ffff, /* dst_mask */
700 FALSE), /* pcrel_offset */
702 /* TLS local dynamic offset. */
703 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
705 2, /* size (0 = byte, 1 = short, 2 = long) */
707 FALSE, /* pc_relative */
709 complain_overflow_signed, /* complain_on_overflow */
710 _bfd_mips_elf_generic_reloc, /* special_function */
711 "R_MIPS_TLS_DTPREL_HI16", /* name */
712 TRUE, /* partial_inplace */
713 0x0000ffff, /* src_mask */
714 0x0000ffff, /* dst_mask */
715 FALSE), /* pcrel_offset */
717 /* TLS local dynamic offset. */
718 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
720 2, /* size (0 = byte, 1 = short, 2 = long) */
722 FALSE, /* pc_relative */
724 complain_overflow_signed, /* complain_on_overflow */
725 _bfd_mips_elf_generic_reloc, /* special_function */
726 "R_MIPS_TLS_DTPREL_LO16", /* name */
727 TRUE, /* partial_inplace */
728 0x0000ffff, /* src_mask */
729 0x0000ffff, /* dst_mask */
730 FALSE), /* pcrel_offset */
732 /* TLS thread pointer offset. */
733 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
735 2, /* size (0 = byte, 1 = short, 2 = long) */
737 FALSE, /* pc_relative */
739 complain_overflow_signed, /* complain_on_overflow */
740 _bfd_mips_elf_generic_reloc, /* special_function */
741 "R_MIPS_TLS_GOTTPREL", /* name */
742 TRUE, /* partial_inplace */
743 0x0000ffff, /* src_mask */
744 0x0000ffff, /* dst_mask */
745 FALSE), /* pcrel_offset */
747 /* TLS IE dynamic relocations. */
748 EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
750 HOWTO (R_MIPS_TLS_TPREL64, /* type */
752 4, /* size (0 = byte, 1 = short, 2 = long) */
754 FALSE, /* pc_relative */
756 complain_overflow_dont, /* complain_on_overflow */
757 _bfd_mips_elf_generic_reloc, /* special_function */
758 "R_MIPS_TLS_TPREL64", /* name */
759 TRUE, /* partial_inplace */
760 MINUS_ONE, /* src_mask */
761 MINUS_ONE, /* dst_mask */
762 FALSE), /* pcrel_offset */
764 /* TLS thread pointer offset. */
765 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
767 2, /* size (0 = byte, 1 = short, 2 = long) */
769 FALSE, /* pc_relative */
771 complain_overflow_signed, /* complain_on_overflow */
772 _bfd_mips_elf_generic_reloc, /* special_function */
773 "R_MIPS_TLS_TPREL_HI16", /* name */
774 TRUE, /* partial_inplace */
775 0x0000ffff, /* src_mask */
776 0x0000ffff, /* dst_mask */
777 FALSE), /* pcrel_offset */
779 /* TLS thread pointer offset. */
780 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
782 2, /* size (0 = byte, 1 = short, 2 = long) */
784 FALSE, /* pc_relative */
786 complain_overflow_signed, /* complain_on_overflow */
787 _bfd_mips_elf_generic_reloc, /* special_function */
788 "R_MIPS_TLS_TPREL_LO16", /* name */
789 TRUE, /* partial_inplace */
790 0x0000ffff, /* src_mask */
791 0x0000ffff, /* dst_mask */
792 FALSE), /* pcrel_offset */
794 /* 32 bit relocation with no addend. */
795 HOWTO (R_MIPS_GLOB_DAT, /* type */
797 2, /* size (0 = byte, 1 = short, 2 = long) */
799 FALSE, /* pc_relative */
801 complain_overflow_dont, /* complain_on_overflow */
802 _bfd_mips_elf_generic_reloc, /* special_function */
803 "R_MIPS_GLOB_DAT", /* name */
804 FALSE, /* partial_inplace */
806 0xffffffff, /* dst_mask */
807 FALSE), /* pcrel_offset */
810 /* The relocation table used for SHT_RELA sections. */
812 static reloc_howto_type mips_elf64_howto_table_rela[] =
815 HOWTO (R_MIPS_NONE, /* type */
817 0, /* size (0 = byte, 1 = short, 2 = long) */
819 FALSE, /* pc_relative */
821 complain_overflow_dont, /* complain_on_overflow */
822 _bfd_mips_elf_generic_reloc, /* special_function */
823 "R_MIPS_NONE", /* name */
824 FALSE, /* partial_inplace */
827 FALSE), /* pcrel_offset */
829 /* 16 bit relocation. */
830 HOWTO (R_MIPS_16, /* type */
832 2, /* size (0 = byte, 1 = short, 2 = long) */
834 FALSE, /* pc_relative */
836 complain_overflow_signed, /* complain_on_overflow */
837 _bfd_mips_elf_generic_reloc, /* special_function */
838 "R_MIPS_16", /* name */
839 FALSE, /* partial_inplace */
841 0x0000ffff, /* dst_mask */
842 FALSE), /* pcrel_offset */
844 /* 32 bit relocation. */
845 HOWTO (R_MIPS_32, /* type */
847 2, /* size (0 = byte, 1 = short, 2 = long) */
849 FALSE, /* pc_relative */
851 complain_overflow_dont, /* complain_on_overflow */
852 _bfd_mips_elf_generic_reloc, /* special_function */
853 "R_MIPS_32", /* name */
854 FALSE, /* partial_inplace */
856 0xffffffff, /* dst_mask */
857 FALSE), /* pcrel_offset */
859 /* 32 bit symbol relative relocation. */
860 HOWTO (R_MIPS_REL32, /* type */
862 2, /* size (0 = byte, 1 = short, 2 = long) */
864 FALSE, /* pc_relative */
866 complain_overflow_dont, /* complain_on_overflow */
867 _bfd_mips_elf_generic_reloc, /* special_function */
868 "R_MIPS_REL32", /* name */
869 FALSE, /* partial_inplace */
871 0xffffffff, /* dst_mask */
872 FALSE), /* pcrel_offset */
874 /* 26 bit jump address. */
875 HOWTO (R_MIPS_26, /* type */
877 2, /* size (0 = byte, 1 = short, 2 = long) */
879 FALSE, /* pc_relative */
881 complain_overflow_dont, /* complain_on_overflow */
882 /* This needs complex overflow
883 detection, because the upper 36
884 bits must match the PC + 4. */
885 _bfd_mips_elf_generic_reloc, /* special_function */
886 "R_MIPS_26", /* name */
887 FALSE, /* partial_inplace */
889 0x03ffffff, /* dst_mask */
890 FALSE), /* pcrel_offset */
892 /* High 16 bits of symbol value. */
893 HOWTO (R_MIPS_HI16, /* type */
895 2, /* size (0 = byte, 1 = short, 2 = long) */
897 FALSE, /* pc_relative */
899 complain_overflow_dont, /* complain_on_overflow */
900 _bfd_mips_elf_generic_reloc, /* special_function */
901 "R_MIPS_HI16", /* name */
902 FALSE, /* partial_inplace */
904 0x0000ffff, /* dst_mask */
905 FALSE), /* pcrel_offset */
907 /* Low 16 bits of symbol value. */
908 HOWTO (R_MIPS_LO16, /* type */
910 2, /* size (0 = byte, 1 = short, 2 = long) */
912 FALSE, /* pc_relative */
914 complain_overflow_dont, /* complain_on_overflow */
915 _bfd_mips_elf_generic_reloc, /* special_function */
916 "R_MIPS_LO16", /* name */
917 FALSE, /* partial_inplace */
919 0x0000ffff, /* dst_mask */
920 FALSE), /* pcrel_offset */
922 /* GP relative reference. */
923 HOWTO (R_MIPS_GPREL16, /* type */
925 2, /* size (0 = byte, 1 = short, 2 = long) */
927 FALSE, /* pc_relative */
929 complain_overflow_signed, /* complain_on_overflow */
930 mips_elf64_gprel16_reloc, /* special_function */
931 "R_MIPS_GPREL16", /* name */
932 FALSE, /* partial_inplace */
934 0x0000ffff, /* dst_mask */
935 FALSE), /* pcrel_offset */
937 /* Reference to literal section. */
938 HOWTO (R_MIPS_LITERAL, /* type */
940 2, /* size (0 = byte, 1 = short, 2 = long) */
942 FALSE, /* pc_relative */
944 complain_overflow_signed, /* complain_on_overflow */
945 mips_elf64_literal_reloc, /* special_function */
946 "R_MIPS_LITERAL", /* name */
947 FALSE, /* partial_inplace */
949 0x0000ffff, /* dst_mask */
950 FALSE), /* pcrel_offset */
952 /* Reference to global offset table. */
953 HOWTO (R_MIPS_GOT16, /* type */
955 2, /* size (0 = byte, 1 = short, 2 = long) */
957 FALSE, /* pc_relative */
959 complain_overflow_signed, /* complain_on_overflow */
960 _bfd_mips_elf_generic_reloc, /* special_function */
961 "R_MIPS_GOT16", /* name */
962 FALSE, /* partial_inplace */
964 0x0000ffff, /* dst_mask */
965 FALSE), /* pcrel_offset */
967 /* 16 bit PC relative reference. Note that the ABI document has a typo
968 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
969 We do the right thing here. */
970 HOWTO (R_MIPS_PC16, /* type */
972 2, /* size (0 = byte, 1 = short, 2 = long) */
974 TRUE, /* pc_relative */
976 complain_overflow_signed, /* complain_on_overflow */
977 _bfd_mips_elf_generic_reloc, /* special_function */
978 "R_MIPS_PC16", /* name */
979 FALSE, /* partial_inplace */
981 0x0000ffff, /* dst_mask */
982 TRUE), /* pcrel_offset */
984 /* 16 bit call through global offset table. */
985 HOWTO (R_MIPS_CALL16, /* type */
987 2, /* size (0 = byte, 1 = short, 2 = long) */
989 FALSE, /* pc_relative */
991 complain_overflow_signed, /* complain_on_overflow */
992 _bfd_mips_elf_generic_reloc, /* special_function */
993 "R_MIPS_CALL16", /* name */
994 FALSE, /* partial_inplace */
996 0x0000ffff, /* dst_mask */
997 FALSE), /* pcrel_offset */
999 /* 32 bit GP relative reference. */
1000 HOWTO (R_MIPS_GPREL32, /* type */
1002 2, /* size (0 = byte, 1 = short, 2 = long) */
1004 FALSE, /* pc_relative */
1006 complain_overflow_dont, /* complain_on_overflow */
1007 mips_elf64_gprel32_reloc, /* special_function */
1008 "R_MIPS_GPREL32", /* name */
1009 FALSE, /* partial_inplace */
1011 0xffffffff, /* dst_mask */
1012 FALSE), /* pcrel_offset */
1018 /* A 5 bit shift field. */
1019 HOWTO (R_MIPS_SHIFT5, /* type */
1021 2, /* size (0 = byte, 1 = short, 2 = long) */
1023 FALSE, /* pc_relative */
1025 complain_overflow_bitfield, /* complain_on_overflow */
1026 _bfd_mips_elf_generic_reloc, /* special_function */
1027 "R_MIPS_SHIFT5", /* name */
1028 FALSE, /* partial_inplace */
1030 0x000007c0, /* dst_mask */
1031 FALSE), /* pcrel_offset */
1033 /* A 6 bit shift field. */
1034 HOWTO (R_MIPS_SHIFT6, /* type */
1036 2, /* size (0 = byte, 1 = short, 2 = long) */
1038 FALSE, /* pc_relative */
1040 complain_overflow_bitfield, /* complain_on_overflow */
1041 mips_elf64_shift6_reloc, /* special_function */
1042 "R_MIPS_SHIFT6", /* name */
1043 FALSE, /* partial_inplace */
1045 0x000007c4, /* dst_mask */
1046 FALSE), /* pcrel_offset */
1048 /* 64 bit relocation. */
1049 HOWTO (R_MIPS_64, /* type */
1051 4, /* size (0 = byte, 1 = short, 2 = long) */
1053 FALSE, /* pc_relative */
1055 complain_overflow_dont, /* complain_on_overflow */
1056 _bfd_mips_elf_generic_reloc, /* special_function */
1057 "R_MIPS_64", /* name */
1058 FALSE, /* partial_inplace */
1060 MINUS_ONE, /* dst_mask */
1061 FALSE), /* pcrel_offset */
1063 /* Displacement in the global offset table. */
1064 HOWTO (R_MIPS_GOT_DISP, /* type */
1066 2, /* size (0 = byte, 1 = short, 2 = long) */
1068 FALSE, /* pc_relative */
1070 complain_overflow_signed, /* complain_on_overflow */
1071 _bfd_mips_elf_generic_reloc, /* special_function */
1072 "R_MIPS_GOT_DISP", /* name */
1073 FALSE, /* partial_inplace */
1075 0x0000ffff, /* dst_mask */
1076 FALSE), /* pcrel_offset */
1078 /* Displacement to page pointer in the global offset table. */
1079 HOWTO (R_MIPS_GOT_PAGE, /* type */
1081 2, /* size (0 = byte, 1 = short, 2 = long) */
1083 FALSE, /* pc_relative */
1085 complain_overflow_signed, /* complain_on_overflow */
1086 _bfd_mips_elf_generic_reloc, /* special_function */
1087 "R_MIPS_GOT_PAGE", /* name */
1088 FALSE, /* partial_inplace */
1090 0x0000ffff, /* dst_mask */
1091 FALSE), /* pcrel_offset */
1093 /* Offset from page pointer in the global offset table. */
1094 HOWTO (R_MIPS_GOT_OFST, /* type */
1096 2, /* size (0 = byte, 1 = short, 2 = long) */
1098 FALSE, /* pc_relative */
1100 complain_overflow_signed, /* complain_on_overflow */
1101 _bfd_mips_elf_generic_reloc, /* special_function */
1102 "R_MIPS_GOT_OFST", /* name */
1103 FALSE, /* partial_inplace */
1105 0x0000ffff, /* dst_mask */
1106 FALSE), /* pcrel_offset */
1108 /* High 16 bits of displacement in global offset table. */
1109 HOWTO (R_MIPS_GOT_HI16, /* type */
1111 2, /* size (0 = byte, 1 = short, 2 = long) */
1113 FALSE, /* pc_relative */
1115 complain_overflow_dont, /* complain_on_overflow */
1116 _bfd_mips_elf_generic_reloc, /* special_function */
1117 "R_MIPS_GOT_HI16", /* name */
1118 FALSE, /* partial_inplace */
1120 0x0000ffff, /* dst_mask */
1121 FALSE), /* pcrel_offset */
1123 /* Low 16 bits of displacement in global offset table. */
1124 HOWTO (R_MIPS_GOT_LO16, /* type */
1126 2, /* size (0 = byte, 1 = short, 2 = long) */
1128 FALSE, /* pc_relative */
1130 complain_overflow_dont, /* complain_on_overflow */
1131 _bfd_mips_elf_generic_reloc, /* special_function */
1132 "R_MIPS_GOT_LO16", /* name */
1133 FALSE, /* partial_inplace */
1135 0x0000ffff, /* dst_mask */
1136 FALSE), /* pcrel_offset */
1138 /* 64 bit subtraction. */
1139 HOWTO (R_MIPS_SUB, /* type */
1141 4, /* size (0 = byte, 1 = short, 2 = long) */
1143 FALSE, /* pc_relative */
1145 complain_overflow_dont, /* complain_on_overflow */
1146 _bfd_mips_elf_generic_reloc, /* special_function */
1147 "R_MIPS_SUB", /* name */
1148 FALSE, /* partial_inplace */
1150 MINUS_ONE, /* dst_mask */
1151 FALSE), /* pcrel_offset */
1153 /* Insert the addend as an instruction. */
1154 /* FIXME: Not handled correctly. */
1155 HOWTO (R_MIPS_INSERT_A, /* type */
1157 2, /* size (0 = byte, 1 = short, 2 = long) */
1159 FALSE, /* pc_relative */
1161 complain_overflow_dont, /* complain_on_overflow */
1162 _bfd_mips_elf_generic_reloc, /* special_function */
1163 "R_MIPS_INSERT_A", /* name */
1164 FALSE, /* partial_inplace */
1166 0xffffffff, /* dst_mask */
1167 FALSE), /* pcrel_offset */
1169 /* Insert the addend as an instruction, and change all relocations
1170 to refer to the old instruction at the address. */
1171 /* FIXME: Not handled correctly. */
1172 HOWTO (R_MIPS_INSERT_B, /* type */
1174 2, /* size (0 = byte, 1 = short, 2 = long) */
1176 FALSE, /* pc_relative */
1178 complain_overflow_dont, /* complain_on_overflow */
1179 _bfd_mips_elf_generic_reloc, /* special_function */
1180 "R_MIPS_INSERT_B", /* name */
1181 FALSE, /* partial_inplace */
1183 0xffffffff, /* dst_mask */
1184 FALSE), /* pcrel_offset */
1186 /* Delete a 32 bit instruction. */
1187 /* FIXME: Not handled correctly. */
1188 HOWTO (R_MIPS_DELETE, /* type */
1190 2, /* size (0 = byte, 1 = short, 2 = long) */
1192 FALSE, /* pc_relative */
1194 complain_overflow_dont, /* complain_on_overflow */
1195 _bfd_mips_elf_generic_reloc, /* special_function */
1196 "R_MIPS_DELETE", /* name */
1197 FALSE, /* partial_inplace */
1199 0xffffffff, /* dst_mask */
1200 FALSE), /* pcrel_offset */
1202 /* Get the higher value of a 64 bit addend. */
1203 HOWTO (R_MIPS_HIGHER, /* type */
1205 2, /* size (0 = byte, 1 = short, 2 = long) */
1207 FALSE, /* pc_relative */
1209 complain_overflow_dont, /* complain_on_overflow */
1210 _bfd_mips_elf_generic_reloc, /* special_function */
1211 "R_MIPS_HIGHER", /* name */
1212 FALSE, /* partial_inplace */
1214 0x0000ffff, /* dst_mask */
1215 FALSE), /* pcrel_offset */
1217 /* Get the highest value of a 64 bit addend. */
1218 HOWTO (R_MIPS_HIGHEST, /* type */
1220 2, /* size (0 = byte, 1 = short, 2 = long) */
1222 FALSE, /* pc_relative */
1224 complain_overflow_dont, /* complain_on_overflow */
1225 _bfd_mips_elf_generic_reloc, /* special_function */
1226 "R_MIPS_HIGHEST", /* name */
1227 FALSE, /* partial_inplace */
1229 0x0000ffff, /* dst_mask */
1230 FALSE), /* pcrel_offset */
1232 /* High 16 bits of displacement in global offset table. */
1233 HOWTO (R_MIPS_CALL_HI16, /* type */
1235 2, /* size (0 = byte, 1 = short, 2 = long) */
1237 FALSE, /* pc_relative */
1239 complain_overflow_dont, /* complain_on_overflow */
1240 _bfd_mips_elf_generic_reloc, /* special_function */
1241 "R_MIPS_CALL_HI16", /* name */
1242 FALSE, /* partial_inplace */
1244 0x0000ffff, /* dst_mask */
1245 FALSE), /* pcrel_offset */
1247 /* Low 16 bits of displacement in global offset table. */
1248 HOWTO (R_MIPS_CALL_LO16, /* type */
1250 2, /* size (0 = byte, 1 = short, 2 = long) */
1252 FALSE, /* pc_relative */
1254 complain_overflow_dont, /* complain_on_overflow */
1255 _bfd_mips_elf_generic_reloc, /* special_function */
1256 "R_MIPS_CALL_LO16", /* name */
1257 FALSE, /* partial_inplace */
1259 0x0000ffff, /* dst_mask */
1260 FALSE), /* pcrel_offset */
1262 /* Section displacement, used by an associated event location section. */
1263 HOWTO (R_MIPS_SCN_DISP, /* type */
1265 2, /* size (0 = byte, 1 = short, 2 = long) */
1267 FALSE, /* pc_relative */
1269 complain_overflow_dont, /* complain_on_overflow */
1270 _bfd_mips_elf_generic_reloc, /* special_function */
1271 "R_MIPS_SCN_DISP", /* name */
1272 FALSE, /* partial_inplace */
1274 0xffffffff, /* dst_mask */
1275 FALSE), /* pcrel_offset */
1277 HOWTO (R_MIPS_REL16, /* type */
1279 1, /* size (0 = byte, 1 = short, 2 = long) */
1281 FALSE, /* pc_relative */
1283 complain_overflow_signed, /* complain_on_overflow */
1284 _bfd_mips_elf_generic_reloc, /* special_function */
1285 "R_MIPS_REL16", /* name */
1286 FALSE, /* partial_inplace */
1288 0xffff, /* dst_mask */
1289 FALSE), /* pcrel_offset */
1291 /* These two are obsolete. */
1292 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1293 EMPTY_HOWTO (R_MIPS_PJUMP),
1295 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1296 It must be used for multigot GOT's (and only there). */
1297 HOWTO (R_MIPS_RELGOT, /* type */
1299 2, /* size (0 = byte, 1 = short, 2 = long) */
1301 FALSE, /* pc_relative */
1303 complain_overflow_dont, /* complain_on_overflow */
1304 _bfd_mips_elf_generic_reloc, /* special_function */
1305 "R_MIPS_RELGOT", /* name */
1306 FALSE, /* partial_inplace */
1308 0xffffffff, /* dst_mask */
1309 FALSE), /* pcrel_offset */
1311 /* Protected jump conversion. This is an optimization hint. No
1312 relocation is required for correctness. */
1313 HOWTO (R_MIPS_JALR, /* type */
1315 2, /* size (0 = byte, 1 = short, 2 = long) */
1317 FALSE, /* pc_relative */
1319 complain_overflow_dont, /* complain_on_overflow */
1320 _bfd_mips_elf_generic_reloc, /* special_function */
1321 "R_MIPS_JALR", /* name */
1322 FALSE, /* partial_inplace */
1324 0x00000000, /* dst_mask */
1325 FALSE), /* pcrel_offset */
1327 /* TLS relocations. */
1328 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
1329 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
1331 HOWTO (R_MIPS_TLS_DTPMOD64, /* type */
1333 4, /* size (0 = byte, 1 = short, 2 = long) */
1335 FALSE, /* pc_relative */
1337 complain_overflow_dont, /* complain_on_overflow */
1338 _bfd_mips_elf_generic_reloc, /* special_function */
1339 "R_MIPS_TLS_DTPMOD64", /* name */
1340 FALSE, /* partial_inplace */
1342 MINUS_ONE, /* dst_mask */
1343 FALSE), /* pcrel_offset */
1345 HOWTO (R_MIPS_TLS_DTPREL64, /* type */
1347 4, /* size (0 = byte, 1 = short, 2 = long) */
1349 FALSE, /* pc_relative */
1351 complain_overflow_dont, /* complain_on_overflow */
1352 _bfd_mips_elf_generic_reloc, /* special_function */
1353 "R_MIPS_TLS_DTPREL64", /* name */
1354 FALSE, /* partial_inplace */
1356 MINUS_ONE, /* dst_mask */
1357 FALSE), /* pcrel_offset */
1359 /* TLS general dynamic variable reference. */
1360 HOWTO (R_MIPS_TLS_GD, /* type */
1362 2, /* size (0 = byte, 1 = short, 2 = long) */
1364 FALSE, /* pc_relative */
1366 complain_overflow_signed, /* complain_on_overflow */
1367 _bfd_mips_elf_generic_reloc, /* special_function */
1368 "R_MIPS_TLS_GD", /* name */
1369 FALSE, /* partial_inplace */
1371 0x0000ffff, /* dst_mask */
1372 FALSE), /* pcrel_offset */
1374 /* TLS local dynamic variable reference. */
1375 HOWTO (R_MIPS_TLS_LDM, /* type */
1377 2, /* size (0 = byte, 1 = short, 2 = long) */
1379 FALSE, /* pc_relative */
1381 complain_overflow_signed, /* complain_on_overflow */
1382 _bfd_mips_elf_generic_reloc, /* special_function */
1383 "R_MIPS_TLS_LDM", /* name */
1384 FALSE, /* partial_inplace */
1386 0x0000ffff, /* dst_mask */
1387 FALSE), /* pcrel_offset */
1389 /* TLS local dynamic offset. */
1390 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
1392 2, /* size (0 = byte, 1 = short, 2 = long) */
1394 FALSE, /* pc_relative */
1396 complain_overflow_signed, /* complain_on_overflow */
1397 _bfd_mips_elf_generic_reloc, /* special_function */
1398 "R_MIPS_TLS_DTPREL_HI16", /* name */
1399 FALSE, /* partial_inplace */
1401 0x0000ffff, /* dst_mask */
1402 FALSE), /* pcrel_offset */
1404 /* TLS local dynamic offset. */
1405 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
1407 2, /* size (0 = byte, 1 = short, 2 = long) */
1409 FALSE, /* pc_relative */
1411 complain_overflow_signed, /* complain_on_overflow */
1412 _bfd_mips_elf_generic_reloc, /* special_function */
1413 "R_MIPS_TLS_DTPREL_LO16", /* name */
1414 FALSE, /* partial_inplace */
1416 0x0000ffff, /* dst_mask */
1417 FALSE), /* pcrel_offset */
1419 /* TLS thread pointer offset. */
1420 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
1422 2, /* size (0 = byte, 1 = short, 2 = long) */
1424 FALSE, /* pc_relative */
1426 complain_overflow_signed, /* complain_on_overflow */
1427 _bfd_mips_elf_generic_reloc, /* special_function */
1428 "R_MIPS_TLS_GOTTPREL", /* name */
1429 FALSE, /* partial_inplace */
1431 0x0000ffff, /* dst_mask */
1432 FALSE), /* pcrel_offset */
1434 /* TLS IE dynamic relocations. */
1435 EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
1437 HOWTO (R_MIPS_TLS_TPREL64, /* type */
1439 4, /* size (0 = byte, 1 = short, 2 = long) */
1441 FALSE, /* pc_relative */
1443 complain_overflow_dont, /* complain_on_overflow */
1444 _bfd_mips_elf_generic_reloc, /* special_function */
1445 "R_MIPS_TLS_TPREL64", /* name */
1446 FALSE, /* partial_inplace */
1448 MINUS_ONE, /* dst_mask */
1449 FALSE), /* pcrel_offset */
1451 /* TLS thread pointer offset. */
1452 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
1454 2, /* size (0 = byte, 1 = short, 2 = long) */
1456 FALSE, /* pc_relative */
1458 complain_overflow_signed, /* complain_on_overflow */
1459 _bfd_mips_elf_generic_reloc, /* special_function */
1460 "R_MIPS_TLS_TPREL_HI16", /* name */
1461 FALSE, /* partial_inplace */
1463 0x0000ffff, /* dst_mask */
1464 FALSE), /* pcrel_offset */
1466 /* TLS thread pointer offset. */
1467 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
1469 2, /* size (0 = byte, 1 = short, 2 = long) */
1471 FALSE, /* pc_relative */
1473 complain_overflow_signed, /* complain_on_overflow */
1474 _bfd_mips_elf_generic_reloc, /* special_function */
1475 "R_MIPS_TLS_TPREL_LO16", /* name */
1476 FALSE, /* partial_inplace */
1478 0x0000ffff, /* dst_mask */
1479 FALSE), /* pcrel_offset */
1481 /* 32 bit relocation with no addend. */
1482 HOWTO (R_MIPS_GLOB_DAT, /* type */
1484 2, /* size (0 = byte, 1 = short, 2 = long) */
1486 FALSE, /* pc_relative */
1488 complain_overflow_dont, /* complain_on_overflow */
1489 _bfd_mips_elf_generic_reloc, /* special_function */
1490 "R_MIPS_GLOB_DAT", /* name */
1491 FALSE, /* partial_inplace */
1493 0xffffffff, /* dst_mask */
1494 FALSE), /* pcrel_offset */
1497 static reloc_howto_type mips16_elf64_howto_table_rel[] =
1499 /* The reloc used for the mips16 jump instruction. */
1500 HOWTO (R_MIPS16_26, /* type */
1502 2, /* size (0 = byte, 1 = short, 2 = long) */
1504 FALSE, /* pc_relative */
1506 complain_overflow_dont, /* complain_on_overflow */
1507 /* This needs complex overflow
1508 detection, because the upper four
1509 bits must match the PC. */
1510 _bfd_mips_elf_generic_reloc, /* special_function */
1511 "R_MIPS16_26", /* name */
1512 TRUE, /* partial_inplace */
1513 0x3ffffff, /* src_mask */
1514 0x3ffffff, /* dst_mask */
1515 FALSE), /* pcrel_offset */
1517 /* The reloc used for the mips16 gprel instruction. */
1518 HOWTO (R_MIPS16_GPREL, /* type */
1520 2, /* size (0 = byte, 1 = short, 2 = long) */
1522 FALSE, /* pc_relative */
1524 complain_overflow_signed, /* complain_on_overflow */
1525 mips16_gprel_reloc, /* special_function */
1526 "R_MIPS16_GPREL", /* name */
1527 TRUE, /* partial_inplace */
1528 0x0000ffff, /* src_mask */
1529 0x0000ffff, /* dst_mask */
1530 FALSE), /* pcrel_offset */
1532 /* A MIPS16 reference to the global offset table. */
1533 HOWTO (R_MIPS16_GOT16, /* type */
1535 2, /* size (0 = byte, 1 = short, 2 = long) */
1537 FALSE, /* pc_relative */
1539 complain_overflow_dont, /* complain_on_overflow */
1540 _bfd_mips_elf_got16_reloc, /* special_function */
1541 "R_MIPS16_GOT16", /* name */
1542 TRUE, /* partial_inplace */
1543 0x0000ffff, /* src_mask */
1544 0x0000ffff, /* dst_mask */
1545 FALSE), /* pcrel_offset */
1547 /* A MIPS16 call through the global offset table. */
1548 HOWTO (R_MIPS16_CALL16, /* type */
1550 2, /* size (0 = byte, 1 = short, 2 = long) */
1552 FALSE, /* pc_relative */
1554 complain_overflow_dont, /* complain_on_overflow */
1555 _bfd_mips_elf_generic_reloc, /* special_function */
1556 "R_MIPS16_CALL16", /* name */
1557 TRUE, /* partial_inplace */
1558 0x0000ffff, /* src_mask */
1559 0x0000ffff, /* dst_mask */
1560 FALSE), /* pcrel_offset */
1562 /* MIPS16 high 16 bits of symbol value. */
1563 HOWTO (R_MIPS16_HI16, /* type */
1564 16, /* rightshift */
1565 2, /* size (0 = byte, 1 = short, 2 = long) */
1567 FALSE, /* pc_relative */
1569 complain_overflow_dont, /* complain_on_overflow */
1570 _bfd_mips_elf_hi16_reloc, /* special_function */
1571 "R_MIPS16_HI16", /* name */
1572 TRUE, /* partial_inplace */
1573 0x0000ffff, /* src_mask */
1574 0x0000ffff, /* dst_mask */
1575 FALSE), /* pcrel_offset */
1577 /* MIPS16 low 16 bits of symbol value. */
1578 HOWTO (R_MIPS16_LO16, /* type */
1580 2, /* size (0 = byte, 1 = short, 2 = long) */
1582 FALSE, /* pc_relative */
1584 complain_overflow_dont, /* complain_on_overflow */
1585 _bfd_mips_elf_lo16_reloc, /* special_function */
1586 "R_MIPS16_LO16", /* name */
1587 TRUE, /* partial_inplace */
1588 0x0000ffff, /* src_mask */
1589 0x0000ffff, /* dst_mask */
1590 FALSE), /* pcrel_offset */
1592 /* MIPS16 TLS general dynamic variable reference. */
1593 HOWTO (R_MIPS16_TLS_GD, /* type */
1595 2, /* size (0 = byte, 1 = short, 2 = long) */
1597 FALSE, /* pc_relative */
1599 complain_overflow_signed, /* complain_on_overflow */
1600 _bfd_mips_elf_generic_reloc, /* special_function */
1601 "R_MIPS16_TLS_GD", /* name */
1602 TRUE, /* partial_inplace */
1603 0x0000ffff, /* src_mask */
1604 0x0000ffff, /* dst_mask */
1605 FALSE), /* pcrel_offset */
1607 /* MIPS16 TLS local dynamic variable reference. */
1608 HOWTO (R_MIPS16_TLS_LDM, /* type */
1610 2, /* size (0 = byte, 1 = short, 2 = long) */
1612 FALSE, /* pc_relative */
1614 complain_overflow_signed, /* complain_on_overflow */
1615 _bfd_mips_elf_generic_reloc, /* special_function */
1616 "R_MIPS16_TLS_LDM", /* name */
1617 TRUE, /* partial_inplace */
1618 0x0000ffff, /* src_mask */
1619 0x0000ffff, /* dst_mask */
1620 FALSE), /* pcrel_offset */
1622 /* MIPS16 TLS local dynamic offset. */
1623 HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */
1625 2, /* size (0 = byte, 1 = short, 2 = long) */
1627 FALSE, /* pc_relative */
1629 complain_overflow_signed, /* complain_on_overflow */
1630 _bfd_mips_elf_generic_reloc, /* special_function */
1631 "R_MIPS16_TLS_DTPREL_HI16", /* name */
1632 TRUE, /* partial_inplace */
1633 0x0000ffff, /* src_mask */
1634 0x0000ffff, /* dst_mask */
1635 FALSE), /* pcrel_offset */
1637 /* MIPS16 TLS local dynamic offset. */
1638 HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */
1640 2, /* size (0 = byte, 1 = short, 2 = long) */
1642 FALSE, /* pc_relative */
1644 complain_overflow_signed, /* complain_on_overflow */
1645 _bfd_mips_elf_generic_reloc, /* special_function */
1646 "R_MIPS16_TLS_DTPREL_LO16", /* name */
1647 TRUE, /* partial_inplace */
1648 0x0000ffff, /* src_mask */
1649 0x0000ffff, /* dst_mask */
1650 FALSE), /* pcrel_offset */
1652 /* MIPS16 TLS thread pointer offset. */
1653 HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */
1655 2, /* size (0 = byte, 1 = short, 2 = long) */
1657 FALSE, /* pc_relative */
1659 complain_overflow_signed, /* complain_on_overflow */
1660 _bfd_mips_elf_generic_reloc, /* special_function */
1661 "R_MIPS16_TLS_GOTTPREL", /* name */
1662 TRUE, /* partial_inplace */
1663 0x0000ffff, /* src_mask */
1664 0x0000ffff, /* dst_mask */
1665 FALSE), /* pcrel_offset */
1667 /* MIPS16 TLS thread pointer offset. */
1668 HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */
1670 2, /* size (0 = byte, 1 = short, 2 = long) */
1672 FALSE, /* pc_relative */
1674 complain_overflow_signed, /* complain_on_overflow */
1675 _bfd_mips_elf_generic_reloc, /* special_function */
1676 "R_MIPS16_TLS_TPREL_HI16", /* name */
1677 TRUE, /* partial_inplace */
1678 0x0000ffff, /* src_mask */
1679 0x0000ffff, /* dst_mask */
1680 FALSE), /* pcrel_offset */
1682 /* MIPS16 TLS thread pointer offset. */
1683 HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */
1685 2, /* size (0 = byte, 1 = short, 2 = long) */
1687 FALSE, /* pc_relative */
1689 complain_overflow_signed, /* complain_on_overflow */
1690 _bfd_mips_elf_generic_reloc, /* special_function */
1691 "R_MIPS16_TLS_TPREL_LO16", /* name */
1692 TRUE, /* partial_inplace */
1693 0x0000ffff, /* src_mask */
1694 0x0000ffff, /* dst_mask */
1695 FALSE), /* pcrel_offset */
1698 static reloc_howto_type mips16_elf64_howto_table_rela[] =
1700 /* The reloc used for the mips16 jump instruction. */
1701 HOWTO (R_MIPS16_26, /* type */
1703 2, /* size (0 = byte, 1 = short, 2 = long) */
1705 FALSE, /* pc_relative */
1707 complain_overflow_dont, /* complain_on_overflow */
1708 /* This needs complex overflow
1709 detection, because the upper four
1710 bits must match the PC. */
1711 _bfd_mips_elf_generic_reloc, /* special_function */
1712 "R_MIPS16_26", /* name */
1713 FALSE, /* partial_inplace */
1715 0x3ffffff, /* dst_mask */
1716 FALSE), /* pcrel_offset */
1718 /* The reloc used for the mips16 gprel instruction. */
1719 HOWTO (R_MIPS16_GPREL, /* type */
1721 2, /* size (0 = byte, 1 = short, 2 = long) */
1723 FALSE, /* pc_relative */
1725 complain_overflow_signed, /* complain_on_overflow */
1726 mips16_gprel_reloc, /* special_function */
1727 "R_MIPS16_GPREL", /* name */
1728 FALSE, /* partial_inplace */
1730 0x0000ffff, /* dst_mask */
1731 FALSE), /* pcrel_offset */
1733 /* A MIPS16 reference to the global offset table. */
1734 HOWTO (R_MIPS16_GOT16, /* type */
1736 2, /* size (0 = byte, 1 = short, 2 = long) */
1738 FALSE, /* pc_relative */
1740 complain_overflow_dont, /* complain_on_overflow */
1741 _bfd_mips_elf_got16_reloc, /* special_function */
1742 "R_MIPS16_GOT16", /* name */
1743 FALSE, /* partial_inplace */
1745 0x0000ffff, /* dst_mask */
1746 FALSE), /* pcrel_offset */
1748 /* A MIPS16 call through the global offset table. */
1749 HOWTO (R_MIPS16_CALL16, /* type */
1751 2, /* size (0 = byte, 1 = short, 2 = long) */
1753 FALSE, /* pc_relative */
1755 complain_overflow_dont, /* complain_on_overflow */
1756 _bfd_mips_elf_generic_reloc, /* special_function */
1757 "R_MIPS16_CALL16", /* name */
1758 FALSE, /* partial_inplace */
1760 0x0000ffff, /* dst_mask */
1761 FALSE), /* pcrel_offset */
1763 /* MIPS16 high 16 bits of symbol value. */
1764 HOWTO (R_MIPS16_HI16, /* type */
1765 16, /* rightshift */
1766 2, /* size (0 = byte, 1 = short, 2 = long) */
1768 FALSE, /* pc_relative */
1770 complain_overflow_dont, /* complain_on_overflow */
1771 _bfd_mips_elf_hi16_reloc, /* special_function */
1772 "R_MIPS16_HI16", /* name */
1773 FALSE, /* partial_inplace */
1775 0x0000ffff, /* dst_mask */
1776 FALSE), /* pcrel_offset */
1778 /* MIPS16 low 16 bits of symbol value. */
1779 HOWTO (R_MIPS16_LO16, /* type */
1781 2, /* size (0 = byte, 1 = short, 2 = long) */
1783 FALSE, /* pc_relative */
1785 complain_overflow_dont, /* complain_on_overflow */
1786 _bfd_mips_elf_lo16_reloc, /* special_function */
1787 "R_MIPS16_LO16", /* name */
1788 FALSE, /* partial_inplace */
1790 0x0000ffff, /* dst_mask */
1791 FALSE), /* pcrel_offset */
1793 /* MIPS16 TLS general dynamic variable reference. */
1794 HOWTO (R_MIPS16_TLS_GD, /* type */
1796 2, /* size (0 = byte, 1 = short, 2 = long) */
1798 FALSE, /* pc_relative */
1800 complain_overflow_signed, /* complain_on_overflow */
1801 _bfd_mips_elf_generic_reloc, /* special_function */
1802 "R_MIPS16_TLS_GD", /* name */
1803 FALSE, /* partial_inplace */
1805 0x0000ffff, /* dst_mask */
1806 FALSE), /* pcrel_offset */
1808 /* MIPS16 TLS local dynamic variable reference. */
1809 HOWTO (R_MIPS16_TLS_LDM, /* type */
1811 2, /* size (0 = byte, 1 = short, 2 = long) */
1813 FALSE, /* pc_relative */
1815 complain_overflow_signed, /* complain_on_overflow */
1816 _bfd_mips_elf_generic_reloc, /* special_function */
1817 "R_MIPS16_TLS_LDM", /* name */
1818 FALSE, /* partial_inplace */
1820 0x0000ffff, /* dst_mask */
1821 FALSE), /* pcrel_offset */
1823 /* MIPS16 TLS local dynamic offset. */
1824 HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */
1826 2, /* size (0 = byte, 1 = short, 2 = long) */
1828 FALSE, /* pc_relative */
1830 complain_overflow_signed, /* complain_on_overflow */
1831 _bfd_mips_elf_generic_reloc, /* special_function */
1832 "R_MIPS16_TLS_DTPREL_HI16", /* name */
1833 FALSE, /* partial_inplace */
1835 0x0000ffff, /* dst_mask */
1836 FALSE), /* pcrel_offset */
1838 /* MIPS16 TLS local dynamic offset. */
1839 HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */
1841 2, /* size (0 = byte, 1 = short, 2 = long) */
1843 FALSE, /* pc_relative */
1845 complain_overflow_signed, /* complain_on_overflow */
1846 _bfd_mips_elf_generic_reloc, /* special_function */
1847 "R_MIPS16_TLS_DTPREL_LO16", /* name */
1848 FALSE, /* partial_inplace */
1850 0x0000ffff, /* dst_mask */
1851 FALSE), /* pcrel_offset */
1853 /* MIPS16 TLS thread pointer offset. */
1854 HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */
1856 2, /* size (0 = byte, 1 = short, 2 = long) */
1858 FALSE, /* pc_relative */
1860 complain_overflow_signed, /* complain_on_overflow */
1861 _bfd_mips_elf_generic_reloc, /* special_function */
1862 "R_MIPS16_TLS_GOTTPREL", /* name */
1863 FALSE, /* partial_inplace */
1865 0x0000ffff, /* dst_mask */
1866 FALSE), /* pcrel_offset */
1868 /* MIPS16 TLS thread pointer offset. */
1869 HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */
1871 2, /* size (0 = byte, 1 = short, 2 = long) */
1873 FALSE, /* pc_relative */
1875 complain_overflow_signed, /* complain_on_overflow */
1876 _bfd_mips_elf_generic_reloc, /* special_function */
1877 "R_MIPS16_TLS_TPREL_HI16", /* name */
1878 FALSE, /* partial_inplace */
1880 0x0000ffff, /* dst_mask */
1881 FALSE), /* pcrel_offset */
1883 /* MIPS16 TLS thread pointer offset. */
1884 HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */
1886 2, /* size (0 = byte, 1 = short, 2 = long) */
1888 FALSE, /* pc_relative */
1890 complain_overflow_signed, /* complain_on_overflow */
1891 _bfd_mips_elf_generic_reloc, /* special_function */
1892 "R_MIPS16_TLS_TPREL_LO16", /* name */
1893 FALSE, /* partial_inplace */
1895 0x0000ffff, /* dst_mask */
1896 FALSE), /* pcrel_offset */
1899 static reloc_howto_type micromips_elf64_howto_table_rel[] =
1905 /* 26 bit jump address. */
1906 HOWTO (R_MICROMIPS_26_S1, /* type */
1908 2, /* size (0 = byte, 1 = short, 2 = long) */
1910 FALSE, /* pc_relative */
1912 complain_overflow_dont, /* complain_on_overflow */
1913 /* This needs complex overflow
1914 detection, because the upper four
1915 bits must match the PC. */
1916 _bfd_mips_elf_generic_reloc, /* special_function */
1917 "R_MICROMIPS_26_S1", /* name */
1918 TRUE, /* partial_inplace */
1919 0x3ffffff, /* src_mask */
1920 0x3ffffff, /* dst_mask */
1921 FALSE), /* pcrel_offset */
1923 /* High 16 bits of symbol value. */
1924 HOWTO (R_MICROMIPS_HI16, /* type */
1925 16, /* rightshift */
1926 2, /* size (0 = byte, 1 = short, 2 = long) */
1928 FALSE, /* pc_relative */
1930 complain_overflow_dont, /* complain_on_overflow */
1931 _bfd_mips_elf_hi16_reloc, /* special_function */
1932 "R_MICROMIPS_HI16", /* name */
1933 TRUE, /* partial_inplace */
1934 0x0000ffff, /* src_mask */
1935 0x0000ffff, /* dst_mask */
1936 FALSE), /* pcrel_offset */
1938 /* Low 16 bits of symbol value. */
1939 HOWTO (R_MICROMIPS_LO16, /* type */
1941 2, /* size (0 = byte, 1 = short, 2 = long) */
1943 FALSE, /* pc_relative */
1945 complain_overflow_dont, /* complain_on_overflow */
1946 _bfd_mips_elf_lo16_reloc, /* special_function */
1947 "R_MICROMIPS_LO16", /* name */
1948 TRUE, /* partial_inplace */
1949 0x0000ffff, /* src_mask */
1950 0x0000ffff, /* dst_mask */
1951 FALSE), /* pcrel_offset */
1953 /* GP relative reference. */
1954 HOWTO (R_MICROMIPS_GPREL16, /* type */
1956 2, /* size (0 = byte, 1 = short, 2 = long) */
1958 FALSE, /* pc_relative */
1960 complain_overflow_signed, /* complain_on_overflow */
1961 _bfd_mips_elf32_gprel16_reloc, /* special_function */
1962 "R_MICROMIPS_GPREL16", /* name */
1963 TRUE, /* partial_inplace */
1964 0x0000ffff, /* src_mask */
1965 0x0000ffff, /* dst_mask */
1966 FALSE), /* pcrel_offset */
1968 /* Reference to literal section. */
1969 HOWTO (R_MICROMIPS_LITERAL, /* type */
1971 2, /* size (0 = byte, 1 = short, 2 = long) */
1973 FALSE, /* pc_relative */
1975 complain_overflow_signed, /* complain_on_overflow */
1976 _bfd_mips_elf32_gprel16_reloc, /* special_function */
1977 "R_MICROMIPS_LITERAL", /* name */
1978 TRUE, /* partial_inplace */
1979 0x0000ffff, /* src_mask */
1980 0x0000ffff, /* dst_mask */
1981 FALSE), /* pcrel_offset */
1983 /* Reference to global offset table. */
1984 HOWTO (R_MICROMIPS_GOT16, /* type */
1986 2, /* size (0 = byte, 1 = short, 2 = long) */
1988 FALSE, /* pc_relative */
1990 complain_overflow_signed, /* complain_on_overflow */
1991 _bfd_mips_elf_got16_reloc, /* special_function */
1992 "R_MICROMIPS_GOT16", /* name */
1993 TRUE, /* partial_inplace */
1994 0x0000ffff, /* src_mask */
1995 0x0000ffff, /* dst_mask */
1996 FALSE), /* pcrel_offset */
1998 /* This is for microMIPS branches. */
1999 HOWTO (R_MICROMIPS_PC7_S1, /* type */
2001 1, /* size (0 = byte, 1 = short, 2 = long) */
2003 TRUE, /* pc_relative */
2005 complain_overflow_signed, /* complain_on_overflow */
2006 _bfd_mips_elf_generic_reloc, /* special_function */
2007 "R_MICROMIPS_PC7_S1", /* name */
2008 TRUE, /* partial_inplace */
2009 0x0000007f, /* src_mask */
2010 0x0000007f, /* dst_mask */
2011 TRUE), /* pcrel_offset */
2013 HOWTO (R_MICROMIPS_PC10_S1, /* type */
2015 1, /* size (0 = byte, 1 = short, 2 = long) */
2017 TRUE, /* pc_relative */
2019 complain_overflow_signed, /* complain_on_overflow */
2020 _bfd_mips_elf_generic_reloc, /* special_function */
2021 "R_MICROMIPS_PC10_S1", /* name */
2022 TRUE, /* partial_inplace */
2023 0x000003ff, /* src_mask */
2024 0x000003ff, /* dst_mask */
2025 TRUE), /* pcrel_offset */
2027 HOWTO (R_MICROMIPS_PC16_S1, /* type */
2029 2, /* size (0 = byte, 1 = short, 2 = long) */
2031 TRUE, /* pc_relative */
2033 complain_overflow_signed, /* complain_on_overflow */
2034 _bfd_mips_elf_generic_reloc, /* special_function */
2035 "R_MICROMIPS_PC16_S1", /* name */
2036 TRUE, /* partial_inplace */
2037 0x0000ffff, /* src_mask */
2038 0x0000ffff, /* dst_mask */
2039 TRUE), /* pcrel_offset */
2041 /* 16 bit call through global offset table. */
2042 HOWTO (R_MICROMIPS_CALL16, /* type */
2044 2, /* size (0 = byte, 1 = short, 2 = long) */
2046 FALSE, /* pc_relative */
2048 complain_overflow_signed, /* complain_on_overflow */
2049 _bfd_mips_elf_generic_reloc, /* special_function */
2050 "R_MICROMIPS_CALL16", /* name */
2051 TRUE, /* partial_inplace */
2052 0x0000ffff, /* src_mask */
2053 0x0000ffff, /* dst_mask */
2054 FALSE), /* pcrel_offset */
2059 /* Displacement in the global offset table. */
2060 HOWTO (R_MICROMIPS_GOT_DISP, /* type */
2062 2, /* size (0 = byte, 1 = short, 2 = long) */
2064 FALSE, /* pc_relative */
2066 complain_overflow_signed, /* complain_on_overflow */
2067 _bfd_mips_elf_generic_reloc, /* special_function */
2068 "R_MICROMIPS_GOT_DISP",/* name */
2069 TRUE, /* partial_inplace */
2070 0x0000ffff, /* src_mask */
2071 0x0000ffff, /* dst_mask */
2072 FALSE), /* pcrel_offset */
2074 /* Displacement to page pointer in the global offset table. */
2075 HOWTO (R_MICROMIPS_GOT_PAGE, /* type */
2077 2, /* size (0 = byte, 1 = short, 2 = long) */
2079 FALSE, /* pc_relative */
2081 complain_overflow_signed, /* complain_on_overflow */
2082 _bfd_mips_elf_generic_reloc, /* special_function */
2083 "R_MICROMIPS_GOT_PAGE",/* name */
2084 TRUE, /* partial_inplace */
2085 0x0000ffff, /* src_mask */
2086 0x0000ffff, /* dst_mask */
2087 FALSE), /* pcrel_offset */
2089 /* Offset from page pointer in the global offset table. */
2090 HOWTO (R_MICROMIPS_GOT_OFST, /* type */
2092 2, /* size (0 = byte, 1 = short, 2 = long) */
2094 FALSE, /* pc_relative */
2096 complain_overflow_signed, /* complain_on_overflow */
2097 _bfd_mips_elf_generic_reloc, /* special_function */
2098 "R_MICROMIPS_GOT_OFST",/* name */
2099 TRUE, /* partial_inplace */
2100 0x0000ffff, /* src_mask */
2101 0x0000ffff, /* dst_mask */
2102 FALSE), /* pcrel_offset */
2104 /* High 16 bits of displacement in global offset table. */
2105 HOWTO (R_MICROMIPS_GOT_HI16, /* type */
2107 2, /* size (0 = byte, 1 = short, 2 = long) */
2109 FALSE, /* pc_relative */
2111 complain_overflow_dont, /* complain_on_overflow */
2112 _bfd_mips_elf_generic_reloc, /* special_function */
2113 "R_MICROMIPS_GOT_HI16",/* name */
2114 TRUE, /* partial_inplace */
2115 0x0000ffff, /* src_mask */
2116 0x0000ffff, /* dst_mask */
2117 FALSE), /* pcrel_offset */
2119 /* Low 16 bits of displacement in global offset table. */
2120 HOWTO (R_MICROMIPS_GOT_LO16, /* type */
2122 2, /* size (0 = byte, 1 = short, 2 = long) */
2124 FALSE, /* pc_relative */
2126 complain_overflow_dont, /* complain_on_overflow */
2127 _bfd_mips_elf_generic_reloc, /* special_function */
2128 "R_MICROMIPS_GOT_LO16",/* name */
2129 TRUE, /* partial_inplace */
2130 0x0000ffff, /* src_mask */
2131 0x0000ffff, /* dst_mask */
2132 FALSE), /* pcrel_offset */
2134 /* 64 bit subtraction. Used in the N32 ABI. */
2135 HOWTO (R_MICROMIPS_SUB, /* type */
2137 4, /* size (0 = byte, 1 = short, 2 = long) */
2139 FALSE, /* pc_relative */
2141 complain_overflow_dont, /* complain_on_overflow */
2142 _bfd_mips_elf_generic_reloc, /* special_function */
2143 "R_MICROMIPS_SUB", /* name */
2144 TRUE, /* partial_inplace */
2145 MINUS_ONE, /* src_mask */
2146 MINUS_ONE, /* dst_mask */
2147 FALSE), /* pcrel_offset */
2149 /* We don't support these for REL relocations, because it means building
2150 the addend from a R_MICROMIPS_HIGHEST/R_MICROMIPS_HIGHER/
2151 R_MICROMIPS_HI16/R_MICROMIPS_LO16 sequence with varying ordering,
2152 using fallable heuristics. */
2153 EMPTY_HOWTO (R_MICROMIPS_HIGHER),
2154 EMPTY_HOWTO (R_MICROMIPS_HIGHEST),
2156 /* High 16 bits of displacement in global offset table. */
2157 HOWTO (R_MICROMIPS_CALL_HI16, /* type */
2159 2, /* size (0 = byte, 1 = short, 2 = long) */
2161 FALSE, /* pc_relative */
2163 complain_overflow_dont, /* complain_on_overflow */
2164 _bfd_mips_elf_generic_reloc, /* special_function */
2165 "R_MICROMIPS_CALL_HI16",/* name */
2166 TRUE, /* partial_inplace */
2167 0x0000ffff, /* src_mask */
2168 0x0000ffff, /* dst_mask */
2169 FALSE), /* pcrel_offset */
2171 /* Low 16 bits of displacement in global offset table. */
2172 HOWTO (R_MICROMIPS_CALL_LO16, /* type */
2174 2, /* size (0 = byte, 1 = short, 2 = long) */
2176 FALSE, /* pc_relative */
2178 complain_overflow_dont, /* complain_on_overflow */
2179 _bfd_mips_elf_generic_reloc, /* special_function */
2180 "R_MICROMIPS_CALL_LO16",/* name */
2181 TRUE, /* partial_inplace */
2182 0x0000ffff, /* src_mask */
2183 0x0000ffff, /* dst_mask */
2184 FALSE), /* pcrel_offset */
2186 /* Section displacement. */
2187 HOWTO (R_MICROMIPS_SCN_DISP, /* type */
2189 2, /* size (0 = byte, 1 = short, 2 = long) */
2191 FALSE, /* pc_relative */
2193 complain_overflow_dont, /* complain_on_overflow */
2194 _bfd_mips_elf_generic_reloc, /* special_function */
2195 "R_MICROMIPS_SCN_DISP", /* name */
2196 TRUE, /* partial_inplace */
2197 0xffffffff, /* src_mask */
2198 0xffffffff, /* dst_mask */
2199 FALSE), /* pcrel_offset */
2201 /* Protected jump conversion. This is an optimization hint. No
2202 relocation is required for correctness. */
2203 HOWTO (R_MICROMIPS_JALR, /* type */
2205 2, /* size (0 = byte, 1 = short, 2 = long) */
2207 FALSE, /* pc_relative */
2209 complain_overflow_dont, /* complain_on_overflow */
2210 _bfd_mips_elf_generic_reloc, /* special_function */
2211 "R_MICROMIPS_JALR", /* name */
2212 FALSE, /* partial_inplace */
2214 0x00000000, /* dst_mask */
2215 FALSE), /* pcrel_offset */
2218 static reloc_howto_type micromips_elf64_howto_table_rela[] =
2224 /* 26 bit jump address. */
2225 HOWTO (R_MICROMIPS_26_S1, /* type */
2227 2, /* size (0 = byte, 1 = short, 2 = long) */
2229 FALSE, /* pc_relative */
2231 complain_overflow_dont, /* complain_on_overflow */
2232 /* This needs complex overflow
2233 detection, because the upper four
2234 bits must match the PC. */
2235 _bfd_mips_elf_generic_reloc, /* special_function */
2236 "R_MICROMIPS_26_S1", /* name */
2237 FALSE, /* partial_inplace */
2239 0x3ffffff, /* dst_mask */
2240 FALSE), /* pcrel_offset */
2242 /* High 16 bits of symbol value. */
2243 HOWTO (R_MICROMIPS_HI16, /* type */
2244 16, /* rightshift */
2245 2, /* size (0 = byte, 1 = short, 2 = long) */
2247 FALSE, /* pc_relative */
2249 complain_overflow_dont, /* complain_on_overflow */
2250 _bfd_mips_elf_hi16_reloc, /* special_function */
2251 "R_MICROMIPS_HI16", /* name */
2252 FALSE, /* partial_inplace */
2254 0x0000ffff, /* dst_mask */
2255 FALSE), /* pcrel_offset */
2257 /* Low 16 bits of symbol value. */
2258 HOWTO (R_MICROMIPS_LO16, /* type */
2260 2, /* size (0 = byte, 1 = short, 2 = long) */
2262 FALSE, /* pc_relative */
2264 complain_overflow_dont, /* complain_on_overflow */
2265 _bfd_mips_elf_lo16_reloc, /* special_function */
2266 "R_MICROMIPS_LO16", /* name */
2267 FALSE, /* partial_inplace */
2269 0x0000ffff, /* dst_mask */
2270 FALSE), /* pcrel_offset */
2272 /* GP relative reference. */
2273 HOWTO (R_MICROMIPS_GPREL16, /* type */
2275 2, /* size (0 = byte, 1 = short, 2 = long) */
2277 FALSE, /* pc_relative */
2279 complain_overflow_signed, /* complain_on_overflow */
2280 _bfd_mips_elf32_gprel16_reloc, /* special_function */
2281 "R_MICROMIPS_GPREL16", /* name */
2282 FALSE, /* partial_inplace */
2284 0x0000ffff, /* dst_mask */
2285 FALSE), /* pcrel_offset */
2287 /* Reference to literal section. */
2288 HOWTO (R_MICROMIPS_LITERAL, /* type */
2290 2, /* size (0 = byte, 1 = short, 2 = long) */
2292 FALSE, /* pc_relative */
2294 complain_overflow_signed, /* complain_on_overflow */
2295 _bfd_mips_elf32_gprel16_reloc, /* special_function */
2296 "R_MICROMIPS_LITERAL", /* name */
2297 FALSE, /* partial_inplace */
2299 0x0000ffff, /* dst_mask */
2300 FALSE), /* pcrel_offset */
2302 /* Reference to global offset table. */
2303 HOWTO (R_MICROMIPS_GOT16, /* type */
2305 2, /* size (0 = byte, 1 = short, 2 = long) */
2307 FALSE, /* pc_relative */
2309 complain_overflow_signed, /* complain_on_overflow */
2310 _bfd_mips_elf_got16_reloc, /* special_function */
2311 "R_MICROMIPS_GOT16", /* name */
2312 FALSE, /* partial_inplace */
2314 0x0000ffff, /* dst_mask */
2315 FALSE), /* pcrel_offset */
2317 /* This is for microMIPS branches. */
2318 HOWTO (R_MICROMIPS_PC7_S1, /* type */
2320 1, /* size (0 = byte, 1 = short, 2 = long) */
2322 TRUE, /* pc_relative */
2324 complain_overflow_signed, /* complain_on_overflow */
2325 _bfd_mips_elf_generic_reloc, /* special_function */
2326 "R_MICROMIPS_PC7_S1", /* name */
2327 FALSE, /* partial_inplace */
2329 0x0000007f, /* dst_mask */
2330 TRUE), /* pcrel_offset */
2332 HOWTO (R_MICROMIPS_PC10_S1, /* type */
2334 1, /* size (0 = byte, 1 = short, 2 = long) */
2336 TRUE, /* pc_relative */
2338 complain_overflow_signed, /* complain_on_overflow */
2339 _bfd_mips_elf_generic_reloc, /* special_function */
2340 "R_MICROMIPS_PC10_S1", /* name */
2341 FALSE, /* partial_inplace */
2343 0x000003ff, /* dst_mask */
2344 TRUE), /* pcrel_offset */
2346 HOWTO (R_MICROMIPS_PC16_S1, /* type */
2348 2, /* size (0 = byte, 1 = short, 2 = long) */
2350 TRUE, /* pc_relative */
2352 complain_overflow_signed, /* complain_on_overflow */
2353 _bfd_mips_elf_generic_reloc, /* special_function */
2354 "R_MICROMIPS_PC16_S1", /* name */
2355 FALSE, /* partial_inplace */
2357 0x0000ffff, /* dst_mask */
2358 TRUE), /* pcrel_offset */
2360 /* 16 bit call through global offset table. */
2361 HOWTO (R_MICROMIPS_CALL16, /* type */
2363 2, /* size (0 = byte, 1 = short, 2 = long) */
2365 FALSE, /* pc_relative */
2367 complain_overflow_signed, /* complain_on_overflow */
2368 _bfd_mips_elf_generic_reloc, /* special_function */
2369 "R_MICROMIPS_CALL16", /* name */
2370 FALSE, /* partial_inplace */
2372 0x0000ffff, /* dst_mask */
2373 FALSE), /* pcrel_offset */
2378 /* Displacement in the global offset table. */
2379 HOWTO (R_MICROMIPS_GOT_DISP, /* type */
2381 2, /* size (0 = byte, 1 = short, 2 = long) */
2383 FALSE, /* pc_relative */
2385 complain_overflow_signed, /* complain_on_overflow */
2386 _bfd_mips_elf_generic_reloc, /* special_function */
2387 "R_MICROMIPS_GOT_DISP",/* name */
2388 FALSE, /* partial_inplace */
2390 0x0000ffff, /* dst_mask */
2391 FALSE), /* pcrel_offset */
2393 /* Displacement to page pointer in the global offset table. */
2394 HOWTO (R_MICROMIPS_GOT_PAGE, /* type */
2396 2, /* size (0 = byte, 1 = short, 2 = long) */
2398 FALSE, /* pc_relative */
2400 complain_overflow_signed, /* complain_on_overflow */
2401 _bfd_mips_elf_generic_reloc, /* special_function */
2402 "R_MICROMIPS_GOT_PAGE",/* name */
2403 FALSE, /* partial_inplace */
2405 0x0000ffff, /* dst_mask */
2406 FALSE), /* pcrel_offset */
2408 /* Offset from page pointer in the global offset table. */
2409 HOWTO (R_MICROMIPS_GOT_OFST, /* type */
2411 2, /* size (0 = byte, 1 = short, 2 = long) */
2413 FALSE, /* pc_relative */
2415 complain_overflow_signed, /* complain_on_overflow */
2416 _bfd_mips_elf_generic_reloc, /* special_function */
2417 "R_MICROMIPS_GOT_OFST",/* name */
2418 FALSE, /* partial_inplace */
2420 0x0000ffff, /* dst_mask */
2421 FALSE), /* pcrel_offset */
2423 /* High 16 bits of displacement in global offset table. */
2424 HOWTO (R_MICROMIPS_GOT_HI16, /* type */
2426 2, /* size (0 = byte, 1 = short, 2 = long) */
2428 FALSE, /* pc_relative */
2430 complain_overflow_dont, /* complain_on_overflow */
2431 _bfd_mips_elf_generic_reloc, /* special_function */
2432 "R_MICROMIPS_GOT_HI16",/* name */
2433 FALSE, /* partial_inplace */
2435 0x0000ffff, /* dst_mask */
2436 FALSE), /* pcrel_offset */
2438 /* Low 16 bits of displacement in global offset table. */
2439 HOWTO (R_MICROMIPS_GOT_LO16, /* type */
2441 2, /* size (0 = byte, 1 = short, 2 = long) */
2443 FALSE, /* pc_relative */
2445 complain_overflow_dont, /* complain_on_overflow */
2446 _bfd_mips_elf_generic_reloc, /* special_function */
2447 "R_MICROMIPS_GOT_LO16",/* name */
2448 FALSE, /* partial_inplace */
2450 0x0000ffff, /* dst_mask */
2451 FALSE), /* pcrel_offset */
2453 /* 64 bit subtraction. Used in the N32 ABI. */
2454 HOWTO (R_MICROMIPS_SUB, /* type */
2456 4, /* size (0 = byte, 1 = short, 2 = long) */
2458 FALSE, /* pc_relative */
2460 complain_overflow_dont, /* complain_on_overflow */
2461 _bfd_mips_elf_generic_reloc, /* special_function */
2462 "R_MICROMIPS_SUB", /* name */
2463 FALSE, /* partial_inplace */
2465 MINUS_ONE, /* dst_mask */
2466 FALSE), /* pcrel_offset */
2468 /* Get the higher value of a 64 bit addend. */
2469 HOWTO (R_MICROMIPS_HIGHER, /* type */
2471 2, /* size (0 = byte, 1 = short, 2 = long) */
2473 FALSE, /* pc_relative */
2475 complain_overflow_dont, /* complain_on_overflow */
2476 _bfd_mips_elf_generic_reloc, /* special_function */
2477 "R_MICROMIPS_HIGHER", /* name */
2478 FALSE, /* partial_inplace */
2480 0x0000ffff, /* dst_mask */
2481 FALSE), /* pcrel_offset */
2483 /* Get the highest value of a 64 bit addend. */
2484 HOWTO (R_MICROMIPS_HIGHEST, /* type */
2486 2, /* size (0 = byte, 1 = short, 2 = long) */
2488 FALSE, /* pc_relative */
2490 complain_overflow_dont, /* complain_on_overflow */
2491 _bfd_mips_elf_generic_reloc, /* special_function */
2492 "R_MICROMIPS_HIGHEST", /* name */
2493 FALSE, /* partial_inplace */
2495 0x0000ffff, /* dst_mask */
2496 FALSE), /* pcrel_offset */
2498 /* High 16 bits of displacement in global offset table. */
2499 HOWTO (R_MICROMIPS_CALL_HI16, /* type */
2501 2, /* size (0 = byte, 1 = short, 2 = long) */
2503 FALSE, /* pc_relative */
2505 complain_overflow_dont, /* complain_on_overflow */
2506 _bfd_mips_elf_generic_reloc, /* special_function */
2507 "R_MICROMIPS_CALL_HI16",/* name */
2508 FALSE, /* partial_inplace */
2510 0x0000ffff, /* dst_mask */
2511 FALSE), /* pcrel_offset */
2513 /* Low 16 bits of displacement in global offset table. */
2514 HOWTO (R_MICROMIPS_CALL_LO16, /* type */
2516 2, /* size (0 = byte, 1 = short, 2 = long) */
2518 FALSE, /* pc_relative */
2520 complain_overflow_dont, /* complain_on_overflow */
2521 _bfd_mips_elf_generic_reloc, /* special_function */
2522 "R_MICROMIPS_CALL_LO16",/* name */
2523 FALSE, /* partial_inplace */
2525 0x0000ffff, /* dst_mask */
2526 FALSE), /* pcrel_offset */
2528 /* Section displacement. */
2529 HOWTO (R_MICROMIPS_SCN_DISP, /* type */
2531 2, /* size (0 = byte, 1 = short, 2 = long) */
2533 FALSE, /* pc_relative */
2535 complain_overflow_dont, /* complain_on_overflow */
2536 _bfd_mips_elf_generic_reloc, /* special_function */
2537 "R_MICROMIPS_SCN_DISP", /* name */
2538 FALSE, /* partial_inplace */
2540 0xffffffff, /* dst_mask */
2541 FALSE), /* pcrel_offset */
2543 /* Protected jump conversion. This is an optimization hint. No
2544 relocation is required for correctness. */
2545 HOWTO (R_MICROMIPS_JALR, /* type */
2547 2, /* size (0 = byte, 1 = short, 2 = long) */
2549 FALSE, /* pc_relative */
2551 complain_overflow_dont, /* complain_on_overflow */
2552 _bfd_mips_elf_generic_reloc, /* special_function */
2553 "R_MICROMIPS_JALR", /* name */
2554 FALSE, /* partial_inplace */
2556 0x00000000, /* dst_mask */
2557 FALSE), /* pcrel_offset */
2560 /* GNU extension to record C++ vtable hierarchy */
2561 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
2562 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
2564 2, /* size (0 = byte, 1 = short, 2 = long) */
2566 FALSE, /* pc_relative */
2568 complain_overflow_dont, /* complain_on_overflow */
2569 NULL, /* special_function */
2570 "R_MIPS_GNU_VTINHERIT", /* name */
2571 FALSE, /* partial_inplace */
2574 FALSE); /* pcrel_offset */
2576 /* GNU extension to record C++ vtable member usage */
2577 static reloc_howto_type elf_mips_gnu_vtentry_howto =
2578 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
2580 2, /* size (0 = byte, 1 = short, 2 = long) */
2582 FALSE, /* pc_relative */
2584 complain_overflow_dont, /* complain_on_overflow */
2585 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
2586 "R_MIPS_GNU_VTENTRY", /* name */
2587 FALSE, /* partial_inplace */
2590 FALSE); /* pcrel_offset */
2592 /* 16 bit offset for pc-relative branches. */
2593 static reloc_howto_type elf_mips_gnu_rel16_s2 =
2594 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
2596 2, /* size (0 = byte, 1 = short, 2 = long) */
2598 TRUE, /* pc_relative */
2600 complain_overflow_signed, /* complain_on_overflow */
2601 _bfd_mips_elf_generic_reloc, /* special_function */
2602 "R_MIPS_GNU_REL16_S2", /* name */
2603 TRUE, /* partial_inplace */
2604 0x0000ffff, /* src_mask */
2605 0x0000ffff, /* dst_mask */
2606 TRUE); /* pcrel_offset */
2608 /* 16 bit offset for pc-relative branches. */
2609 static reloc_howto_type elf_mips_gnu_rela16_s2 =
2610 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
2612 2, /* size (0 = byte, 1 = short, 2 = long) */
2614 TRUE, /* pc_relative */
2616 complain_overflow_signed, /* complain_on_overflow */
2617 _bfd_mips_elf_generic_reloc, /* special_function */
2618 "R_MIPS_GNU_REL16_S2", /* name */
2619 FALSE, /* partial_inplace */
2621 0x0000ffff, /* dst_mask */
2622 TRUE); /* pcrel_offset */
2624 /* 32 bit pc-relative. Used for compact EH tables. */
2625 static reloc_howto_type elf_mips_gnu_pcrel32 =
2626 HOWTO (R_MIPS_PC32, /* type */
2628 2, /* size (0 = byte, 1 = short, 2 = long) */
2630 TRUE, /* pc_relative */
2632 complain_overflow_signed, /* complain_on_overflow */
2633 _bfd_mips_elf_generic_reloc, /* special_function */
2634 "R_MIPS_PC32", /* name */
2635 TRUE, /* partial_inplace */
2636 0xffffffff, /* src_mask */
2637 0xffffffff, /* dst_mask */
2638 TRUE); /* pcrel_offset */
2641 /* Originally a VxWorks extension, but now used for other systems too. */
2642 static reloc_howto_type elf_mips_copy_howto =
2643 HOWTO (R_MIPS_COPY, /* type */
2645 0, /* this one is variable size */
2647 FALSE, /* pc_relative */
2649 complain_overflow_bitfield, /* complain_on_overflow */
2650 _bfd_mips_elf_generic_reloc, /* special_function */
2651 "R_MIPS_COPY", /* name */
2652 FALSE, /* partial_inplace */
2655 FALSE); /* pcrel_offset */
2657 /* Originally a VxWorks extension, but now used for other systems too. */
2658 static reloc_howto_type elf_mips_jump_slot_howto =
2659 HOWTO (R_MIPS_JUMP_SLOT, /* type */
2661 4, /* size (0 = byte, 1 = short, 2 = long) */
2663 FALSE, /* pc_relative */
2665 complain_overflow_bitfield, /* complain_on_overflow */
2666 _bfd_mips_elf_generic_reloc, /* special_function */
2667 "R_MIPS_JUMP_SLOT", /* name */
2668 FALSE, /* partial_inplace */
2671 FALSE); /* pcrel_offset */
2673 /* Used in EH tables. */
2674 static reloc_howto_type elf_mips_eh_howto =
2675 HOWTO (R_MIPS_EH, /* type */
2677 2, /* size (0 = byte, 1 = short, 2 = long) */
2679 FALSE, /* pc_relative */
2681 complain_overflow_signed, /* complain_on_overflow */
2682 _bfd_mips_elf_generic_reloc, /* special_function */
2683 "R_MIPS_EH", /* name */
2684 TRUE, /* partial_inplace */
2685 0xffffffff, /* src_mask */
2686 0xffffffff, /* dst_mask */
2687 FALSE); /* pcrel_offset */
2690 /* Swap in a MIPS 64-bit Rel reloc. */
2693 mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src,
2694 Elf64_Mips_Internal_Rela *dst)
2696 dst->r_offset = H_GET_64 (abfd, src->r_offset);
2697 dst->r_sym = H_GET_32 (abfd, src->r_sym);
2698 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
2699 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
2700 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
2701 dst->r_type = H_GET_8 (abfd, src->r_type);
2705 /* Swap in a MIPS 64-bit Rela reloc. */
2708 mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src,
2709 Elf64_Mips_Internal_Rela *dst)
2711 dst->r_offset = H_GET_64 (abfd, src->r_offset);
2712 dst->r_sym = H_GET_32 (abfd, src->r_sym);
2713 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
2714 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
2715 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
2716 dst->r_type = H_GET_8 (abfd, src->r_type);
2717 dst->r_addend = H_GET_S64 (abfd, src->r_addend);
2720 /* Swap out a MIPS 64-bit Rel reloc. */
2723 mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
2724 Elf64_Mips_External_Rel *dst)
2726 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
2727 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
2728 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
2729 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
2730 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
2731 H_PUT_8 (abfd, src->r_type, dst->r_type);
2734 /* Swap out a MIPS 64-bit Rela reloc. */
2737 mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
2738 Elf64_Mips_External_Rela *dst)
2740 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
2741 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
2742 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
2743 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
2744 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
2745 H_PUT_8 (abfd, src->r_type, dst->r_type);
2746 H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
2749 /* Swap in a MIPS 64-bit Rel reloc. */
2752 mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src,
2753 Elf_Internal_Rela *dst)
2755 Elf64_Mips_Internal_Rela mirel;
2757 mips_elf64_swap_reloc_in (abfd,
2758 (const Elf64_Mips_External_Rel *) src,
2761 dst[0].r_offset = mirel.r_offset;
2762 dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
2763 dst[0].r_addend = 0;
2764 dst[1].r_offset = mirel.r_offset;
2765 dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
2766 dst[1].r_addend = 0;
2767 dst[2].r_offset = mirel.r_offset;
2768 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
2769 dst[2].r_addend = 0;
2772 /* Swap in a MIPS 64-bit Rela reloc. */
2775 mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src,
2776 Elf_Internal_Rela *dst)
2778 Elf64_Mips_Internal_Rela mirela;
2780 mips_elf64_swap_reloca_in (abfd,
2781 (const Elf64_Mips_External_Rela *) src,
2784 dst[0].r_offset = mirela.r_offset;
2785 dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
2786 dst[0].r_addend = mirela.r_addend;
2787 dst[1].r_offset = mirela.r_offset;
2788 dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
2789 dst[1].r_addend = 0;
2790 dst[2].r_offset = mirela.r_offset;
2791 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
2792 dst[2].r_addend = 0;
2795 /* Swap out a MIPS 64-bit Rel reloc. */
2798 mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src,
2801 Elf64_Mips_Internal_Rela mirel;
2803 mirel.r_offset = src[0].r_offset;
2804 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
2805 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
2807 mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
2808 mirel.r_sym = ELF64_R_SYM (src[0].r_info);
2809 mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
2810 mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
2811 mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
2813 mips_elf64_swap_reloc_out (abfd, &mirel,
2814 (Elf64_Mips_External_Rel *) dst);
2817 /* Swap out a MIPS 64-bit Rela reloc. */
2820 mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src,
2823 Elf64_Mips_Internal_Rela mirela;
2825 mirela.r_offset = src[0].r_offset;
2826 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
2827 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
2829 mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
2830 mirela.r_sym = ELF64_R_SYM (src[0].r_info);
2831 mirela.r_addend = src[0].r_addend;
2832 BFD_ASSERT(src[1].r_addend == 0);
2833 BFD_ASSERT(src[2].r_addend == 0);
2835 mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
2836 mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
2837 mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
2839 mips_elf64_swap_reloca_out (abfd, &mirela,
2840 (Elf64_Mips_External_Rela *) dst);
2843 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
2844 dangerous relocation. */
2847 mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp)
2853 /* If we've already figured out what GP will be, just return it. */
2854 *pgp = _bfd_get_gp_value (output_bfd);
2858 count = bfd_get_symcount (output_bfd);
2859 sym = bfd_get_outsymbols (output_bfd);
2861 /* The linker script will have created a symbol named `_gp' with the
2862 appropriate value. */
2867 for (i = 0; i < count; i++, sym++)
2869 register const char *name;
2871 name = bfd_asymbol_name (*sym);
2872 if (*name == '_' && strcmp (name, "_gp") == 0)
2874 *pgp = bfd_asymbol_value (*sym);
2875 _bfd_set_gp_value (output_bfd, *pgp);
2883 /* Only get the error once. */
2885 _bfd_set_gp_value (output_bfd, *pgp);
2892 /* We have to figure out the gp value, so that we can adjust the
2893 symbol value correctly. We look up the symbol _gp in the output
2894 BFD. If we can't find it, we're stuck. We cache it in the ELF
2895 target data. We don't need to adjust the symbol value for an
2896 external symbol if we are producing relocatable output. */
2898 static bfd_reloc_status_type
2899 mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
2900 char **error_message, bfd_vma *pgp)
2902 if (bfd_is_und_section (symbol->section)
2906 return bfd_reloc_undefined;
2909 *pgp = _bfd_get_gp_value (output_bfd);
2912 || (symbol->flags & BSF_SECTION_SYM) != 0))
2916 /* Make up a value. */
2917 *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
2918 _bfd_set_gp_value (output_bfd, *pgp);
2920 else if (!mips_elf64_assign_gp (output_bfd, pgp))
2923 (char *) _("GP relative relocation when _gp not defined");
2924 return bfd_reloc_dangerous;
2928 return bfd_reloc_ok;
2931 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
2932 become the offset from the gp register. */
2934 static bfd_reloc_status_type
2935 mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2936 void *data, asection *input_section, bfd *output_bfd,
2937 char **error_message)
2939 bfd_boolean relocatable;
2940 bfd_reloc_status_type ret;
2943 /* If we're relocating, and this is an external symbol, we don't want
2944 to change anything. */
2945 if (output_bfd != NULL
2946 && (symbol->flags & BSF_SECTION_SYM) == 0
2947 && (symbol->flags & BSF_LOCAL) != 0)
2949 reloc_entry->address += input_section->output_offset;
2950 return bfd_reloc_ok;
2953 if (output_bfd != NULL)
2957 relocatable = FALSE;
2958 output_bfd = symbol->section->output_section->owner;
2961 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
2963 if (ret != bfd_reloc_ok)
2966 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2967 input_section, relocatable,
2971 /* Do a R_MIPS_LITERAL relocation. */
2973 static bfd_reloc_status_type
2974 mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2975 void *data, asection *input_section, bfd *output_bfd,
2976 char **error_message)
2978 bfd_boolean relocatable;
2979 bfd_reloc_status_type ret;
2982 /* R_MIPS_LITERAL relocations are defined for local symbols only. */
2983 if (output_bfd != NULL
2984 && (symbol->flags & BSF_SECTION_SYM) == 0
2985 && (symbol->flags & BSF_LOCAL) != 0)
2987 *error_message = (char *)
2988 _("literal relocation occurs for an external symbol");
2989 return bfd_reloc_outofrange;
2992 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
2993 if (output_bfd != NULL)
2997 relocatable = FALSE;
2998 output_bfd = symbol->section->output_section->owner;
3001 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
3003 if (ret != bfd_reloc_ok)
3006 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
3007 input_section, relocatable,
3011 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
3012 become the offset from the gp register. */
3014 static bfd_reloc_status_type
3015 mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3016 void *data, asection *input_section, bfd *output_bfd,
3017 char **error_message)
3019 bfd_boolean relocatable;
3020 bfd_reloc_status_type ret;
3025 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
3026 if (output_bfd != NULL
3027 && (symbol->flags & BSF_SECTION_SYM) == 0
3028 && (symbol->flags & BSF_LOCAL) != 0)
3030 *error_message = (char *)
3031 _("32bits gp relative relocation occurs for an external symbol");
3032 return bfd_reloc_outofrange;
3035 if (output_bfd != NULL)
3039 relocatable = FALSE;
3040 output_bfd = symbol->section->output_section->owner;
3043 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable,
3044 error_message, &gp);
3045 if (ret != bfd_reloc_ok)
3048 if (bfd_is_com_section (symbol->section))
3051 relocation = symbol->value;
3053 relocation += symbol->section->output_section->vma;
3054 relocation += symbol->section->output_offset;
3056 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
3057 return bfd_reloc_outofrange;
3059 /* Set val to the offset into the section or symbol. */
3060 val = reloc_entry->addend;
3062 if (reloc_entry->howto->partial_inplace)
3063 val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
3065 /* Adjust val for the final section location and GP value. If we
3066 are producing relocatable output, we don't want to do this for
3067 an external symbol. */
3069 || (symbol->flags & BSF_SECTION_SYM) != 0)
3070 val += relocation - gp;
3072 if (reloc_entry->howto->partial_inplace)
3073 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
3075 reloc_entry->addend = val;
3078 reloc_entry->address += input_section->output_offset;
3080 return bfd_reloc_ok;
3083 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
3084 the rest is at bits 6-10. The bitpos already got right by the howto. */
3086 static bfd_reloc_status_type
3087 mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3088 void *data, asection *input_section, bfd *output_bfd,
3089 char **error_message)
3091 if (reloc_entry->howto->partial_inplace)
3093 reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
3094 | (reloc_entry->addend & 0x00000800) >> 9);
3097 return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
3098 input_section, output_bfd,
3102 /* Handle a mips16 GP relative reloc. */
3104 static bfd_reloc_status_type
3105 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3106 void *data, asection *input_section, bfd *output_bfd,
3107 char **error_message)
3109 bfd_boolean relocatable;
3110 bfd_reloc_status_type ret;
3114 /* If we're relocating, and this is an external symbol, we don't want
3115 to change anything. */
3116 if (output_bfd != NULL
3117 && (symbol->flags & BSF_SECTION_SYM) == 0
3118 && (symbol->flags & BSF_LOCAL) != 0)
3120 reloc_entry->address += input_section->output_offset;
3121 return bfd_reloc_ok;
3124 if (output_bfd != NULL)
3128 relocatable = FALSE;
3129 output_bfd = symbol->section->output_section->owner;
3132 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
3134 if (ret != bfd_reloc_ok)
3137 location = (bfd_byte *) data + reloc_entry->address;
3138 _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
3140 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
3141 input_section, relocatable,
3143 _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
3149 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
3151 struct elf_reloc_map {
3152 bfd_reloc_code_real_type bfd_val;
3153 enum elf_mips_reloc_type elf_val;
3156 static const struct elf_reloc_map mips_reloc_map[] =
3158 { BFD_RELOC_NONE, R_MIPS_NONE },
3159 { BFD_RELOC_16, R_MIPS_16 },
3160 { BFD_RELOC_32, R_MIPS_32 },
3161 /* There is no BFD reloc for R_MIPS_REL32. */
3162 { BFD_RELOC_64, R_MIPS_64 },
3163 { BFD_RELOC_CTOR, R_MIPS_64 },
3164 { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
3165 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
3166 { BFD_RELOC_LO16, R_MIPS_LO16 },
3167 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
3168 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
3169 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
3170 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
3171 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
3172 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
3173 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
3174 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
3175 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
3176 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
3177 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
3178 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
3179 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
3180 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
3181 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
3182 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
3183 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
3184 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
3185 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
3186 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
3187 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
3188 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
3189 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
3190 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
3191 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
3192 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
3193 { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
3194 { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
3195 { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
3196 { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
3197 { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
3198 { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
3199 { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
3200 { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
3201 { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
3202 { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
3203 { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
3204 { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
3205 { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
3208 static const struct elf_reloc_map mips16_reloc_map[] =
3210 { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
3211 { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
3212 { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
3213 { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
3214 { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
3215 { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
3216 { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
3217 { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
3218 { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
3219 R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
3220 { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
3221 R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
3222 { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
3223 { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
3224 { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
3227 static const struct elf_reloc_map micromips_reloc_map[] =
3229 { BFD_RELOC_MICROMIPS_JMP, R_MICROMIPS_26_S1 - R_MICROMIPS_min },
3230 { BFD_RELOC_MICROMIPS_HI16_S, R_MICROMIPS_HI16 - R_MICROMIPS_min },
3231 { BFD_RELOC_MICROMIPS_LO16, R_MICROMIPS_LO16 - R_MICROMIPS_min },
3232 { BFD_RELOC_MICROMIPS_GPREL16, R_MICROMIPS_GPREL16 - R_MICROMIPS_min },
3233 { BFD_RELOC_MICROMIPS_LITERAL, R_MICROMIPS_LITERAL - R_MICROMIPS_min },
3234 { BFD_RELOC_MICROMIPS_GOT16, R_MICROMIPS_GOT16 - R_MICROMIPS_min },
3235 { BFD_RELOC_MICROMIPS_7_PCREL_S1, R_MICROMIPS_PC7_S1 - R_MICROMIPS_min },
3236 { BFD_RELOC_MICROMIPS_10_PCREL_S1, R_MICROMIPS_PC10_S1 - R_MICROMIPS_min },
3237 { BFD_RELOC_MICROMIPS_16_PCREL_S1, R_MICROMIPS_PC16_S1 - R_MICROMIPS_min },
3238 { BFD_RELOC_MICROMIPS_CALL16, R_MICROMIPS_CALL16 - R_MICROMIPS_min },
3239 { BFD_RELOC_MICROMIPS_GOT_DISP, R_MICROMIPS_GOT_DISP - R_MICROMIPS_min },
3240 { BFD_RELOC_MICROMIPS_GOT_PAGE, R_MICROMIPS_GOT_PAGE - R_MICROMIPS_min },
3241 { BFD_RELOC_MICROMIPS_GOT_OFST, R_MICROMIPS_GOT_OFST - R_MICROMIPS_min },
3242 { BFD_RELOC_MICROMIPS_GOT_HI16, R_MICROMIPS_GOT_HI16 - R_MICROMIPS_min },
3243 { BFD_RELOC_MICROMIPS_GOT_LO16, R_MICROMIPS_GOT_LO16 - R_MICROMIPS_min },
3244 { BFD_RELOC_MICROMIPS_SUB, R_MICROMIPS_SUB - R_MICROMIPS_min },
3245 { BFD_RELOC_MICROMIPS_HIGHER, R_MICROMIPS_HIGHER - R_MICROMIPS_min },
3246 { BFD_RELOC_MICROMIPS_HIGHEST, R_MICROMIPS_HIGHEST - R_MICROMIPS_min },
3247 { BFD_RELOC_MICROMIPS_CALL_HI16, R_MICROMIPS_CALL_HI16 - R_MICROMIPS_min },
3248 { BFD_RELOC_MICROMIPS_CALL_LO16, R_MICROMIPS_CALL_LO16 - R_MICROMIPS_min },
3249 { BFD_RELOC_MICROMIPS_SCN_DISP, R_MICROMIPS_SCN_DISP - R_MICROMIPS_min },
3250 { BFD_RELOC_MICROMIPS_JALR, R_MICROMIPS_JALR - R_MICROMIPS_min },
3252 /* Given a BFD reloc type, return a howto structure. */
3254 static reloc_howto_type *
3255 bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3256 bfd_reloc_code_real_type code)
3259 /* FIXME: We default to RELA here instead of choosing the right
3260 relocation variant. */
3261 reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
3262 reloc_howto_type *howto16_table = mips16_elf64_howto_table_rela;
3263 reloc_howto_type *howto_micromips_table = micromips_elf64_howto_table_rela;
3265 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
3268 if (mips_reloc_map[i].bfd_val == code)
3269 return &howto_table[(int) mips_reloc_map[i].elf_val];
3272 for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
3275 if (mips16_reloc_map[i].bfd_val == code)
3276 return &howto16_table[(int) mips16_reloc_map[i].elf_val];
3279 for (i = 0; i < sizeof (micromips_reloc_map) / sizeof (struct elf_reloc_map);
3282 if (micromips_reloc_map[i].bfd_val == code)
3283 return &howto_micromips_table[(int) micromips_reloc_map[i].elf_val];
3288 case BFD_RELOC_VTABLE_INHERIT:
3289 return &elf_mips_gnu_vtinherit_howto;
3290 case BFD_RELOC_VTABLE_ENTRY:
3291 return &elf_mips_gnu_vtentry_howto;
3292 case BFD_RELOC_32_PCREL:
3293 return &elf_mips_gnu_pcrel32;
3294 case BFD_RELOC_MIPS_EH:
3295 return &elf_mips_eh_howto;
3296 case BFD_RELOC_MIPS_COPY:
3297 return &elf_mips_copy_howto;
3298 case BFD_RELOC_MIPS_JUMP_SLOT:
3299 return &elf_mips_jump_slot_howto;
3301 bfd_set_error (bfd_error_bad_value);
3306 static reloc_howto_type *
3307 bfd_elf64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3313 i < (sizeof (mips_elf64_howto_table_rela)
3314 / sizeof (mips_elf64_howto_table_rela[0])); i++)
3315 if (mips_elf64_howto_table_rela[i].name != NULL
3316 && strcasecmp (mips_elf64_howto_table_rela[i].name, r_name) == 0)
3317 return &mips_elf64_howto_table_rela[i];
3320 i < (sizeof (mips16_elf64_howto_table_rela)
3321 / sizeof (mips16_elf64_howto_table_rela[0]));
3323 if (mips16_elf64_howto_table_rela[i].name != NULL
3324 && strcasecmp (mips16_elf64_howto_table_rela[i].name, r_name) == 0)
3325 return &mips16_elf64_howto_table_rela[i];
3328 i < (sizeof (micromips_elf64_howto_table_rela)
3329 / sizeof (micromips_elf64_howto_table_rela[0]));
3331 if (micromips_elf64_howto_table_rela[i].name != NULL
3332 && strcasecmp (micromips_elf64_howto_table_rela[i].name, r_name) == 0)
3333 return µmips_elf64_howto_table_rela[i];
3335 if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
3336 return &elf_mips_gnu_vtinherit_howto;
3337 if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
3338 return &elf_mips_gnu_vtentry_howto;
3339 if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
3340 return &elf_mips_gnu_rel16_s2;
3341 if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
3342 return &elf_mips_gnu_rela16_s2;
3343 if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
3344 return &elf_mips_gnu_pcrel32;
3345 if (strcasecmp (elf_mips_eh_howto.name, r_name) == 0)
3346 return &elf_mips_eh_howto;
3347 if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
3348 return &elf_mips_copy_howto;
3349 if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
3350 return &elf_mips_jump_slot_howto;
3355 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
3357 static reloc_howto_type *
3358 mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
3362 case R_MIPS_GNU_VTINHERIT:
3363 return &elf_mips_gnu_vtinherit_howto;
3364 case R_MIPS_GNU_VTENTRY:
3365 return &elf_mips_gnu_vtentry_howto;
3366 case R_MIPS_GNU_REL16_S2:
3368 return &elf_mips_gnu_rela16_s2;
3370 return &elf_mips_gnu_rel16_s2;
3372 return &elf_mips_gnu_pcrel32;
3374 return &elf_mips_eh_howto;
3376 return &elf_mips_copy_howto;
3377 case R_MIPS_JUMP_SLOT:
3378 return &elf_mips_jump_slot_howto;
3380 if (r_type >= R_MICROMIPS_min && r_type < R_MICROMIPS_max)
3383 return µmips_elf64_howto_table_rela[r_type - R_MICROMIPS_min];
3385 return µmips_elf64_howto_table_rel[r_type - R_MICROMIPS_min];
3387 if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
3390 return &mips16_elf64_howto_table_rela[r_type - R_MIPS16_min];
3392 return &mips16_elf64_howto_table_rel[r_type - R_MIPS16_min];
3394 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
3396 return &mips_elf64_howto_table_rela[r_type];
3398 return &mips_elf64_howto_table_rel[r_type];
3403 /* Prevent relocation handling by bfd for MIPS ELF64. */
3406 mips_elf64_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
3407 arelent *cache_ptr ATTRIBUTE_UNUSED,
3408 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
3414 mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
3415 arelent *cache_ptr ATTRIBUTE_UNUSED,
3416 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
3421 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
3422 to three relocs, we must tell the user to allocate more space. */
3425 mips_elf64_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
3427 return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
3431 mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd)
3433 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
3436 /* We must also copy more relocations than the corresponding functions
3437 in elf.c would, so the two following functions are slightly
3438 modified from elf.c, that multiply the external relocation count by
3439 3 to obtain the internal relocation count. */
3442 mips_elf64_canonicalize_reloc (bfd *abfd, sec_ptr section,
3443 arelent **relptr, asymbol **symbols)
3447 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
3449 if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
3452 tblptr = section->relocation;
3453 for (i = 0; i < section->reloc_count * 3; i++)
3454 *relptr++ = tblptr++;
3458 return section->reloc_count * 3;
3462 mips_elf64_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
3465 bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
3469 if (elf_dynsymtab (abfd) == 0)
3471 bfd_set_error (bfd_error_invalid_operation);
3475 slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
3477 for (s = abfd->sections; s != NULL; s = s->next)
3479 if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
3480 && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
3481 || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
3486 if (! (*slurp_relocs) (abfd, s, syms, TRUE))
3488 count = s->size / elf_section_data (s)->this_hdr.sh_entsize * 3;
3490 for (i = 0; i < count; i++)
3501 /* Read the relocations from one reloc section. This is mostly copied
3502 from elfcode.h, except for the changes to expand one external
3503 relocation to 3 internal ones. We must unfortunately set
3504 reloc_count to the number of external relocations, because a lot of
3505 generic code seems to depend on this. */
3508 mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
3509 Elf_Internal_Shdr *rel_hdr,
3510 bfd_size_type reloc_count,
3511 arelent *relents, asymbol **symbols,
3512 bfd_boolean dynamic)
3515 bfd_byte *native_relocs;
3521 allocated = bfd_malloc (rel_hdr->sh_size);
3522 if (allocated == NULL)
3525 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
3526 || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
3527 != rel_hdr->sh_size))
3530 native_relocs = allocated;
3532 entsize = rel_hdr->sh_entsize;
3533 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
3534 || entsize == sizeof (Elf64_Mips_External_Rela));
3536 if (entsize == sizeof (Elf64_Mips_External_Rel))
3541 for (i = 0, relent = relents;
3543 i++, native_relocs += entsize)
3545 Elf64_Mips_Internal_Rela rela;
3546 bfd_boolean used_sym, used_ssym;
3549 if (entsize == sizeof (Elf64_Mips_External_Rela))
3550 mips_elf64_swap_reloca_in (abfd,
3551 (Elf64_Mips_External_Rela *) native_relocs,
3554 mips_elf64_swap_reloc_in (abfd,
3555 (Elf64_Mips_External_Rel *) native_relocs,
3558 /* Each entry represents exactly three actual relocations. */
3562 for (ir = 0; ir < 3; ir++)
3564 enum elf_mips_reloc_type type;
3571 type = (enum elf_mips_reloc_type) rela.r_type;
3574 type = (enum elf_mips_reloc_type) rela.r_type2;
3577 type = (enum elf_mips_reloc_type) rela.r_type3;
3581 /* Some types require symbols, whereas some do not. */
3585 case R_MIPS_LITERAL:
3586 case R_MIPS_INSERT_A:
3587 case R_MIPS_INSERT_B:
3589 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3595 if (rela.r_sym == STN_UNDEF)
3596 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3601 ps = symbols + rela.r_sym - 1;
3603 if ((s->flags & BSF_SECTION_SYM) == 0)
3604 relent->sym_ptr_ptr = ps;
3606 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
3611 else if (! used_ssym)
3613 switch (rela.r_ssym)
3616 relent->sym_ptr_ptr =
3617 bfd_abs_section_ptr->symbol_ptr_ptr;
3623 /* FIXME: I think these need to be handled using
3624 special howto structures. */
3636 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3641 /* The address of an ELF reloc is section relative for an
3642 object file, and absolute for an executable file or
3643 shared library. The address of a BFD reloc is always
3644 section relative. */
3645 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
3646 relent->address = rela.r_offset;
3648 relent->address = rela.r_offset - asect->vma;
3650 relent->addend = rela.r_addend;
3652 relent->howto = mips_elf64_rtype_to_howto (type, rela_p);
3658 asect->reloc_count += (relent - relents) / 3;
3660 if (allocated != NULL)
3666 if (allocated != NULL)
3671 /* Read the relocations. On Irix 6, there can be two reloc sections
3672 associated with a single data section. This is copied from
3673 elfcode.h as well, with changes as small as accounting for 3
3674 internal relocs per external reloc and resetting reloc_count to
3675 zero before processing the relocs of a section. */
3678 mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
3679 asymbol **symbols, bfd_boolean dynamic)
3681 struct bfd_elf_section_data * const d = elf_section_data (asect);
3682 Elf_Internal_Shdr *rel_hdr;
3683 Elf_Internal_Shdr *rel_hdr2;
3684 bfd_size_type reloc_count;
3685 bfd_size_type reloc_count2;
3689 if (asect->relocation != NULL)
3694 if ((asect->flags & SEC_RELOC) == 0
3695 || asect->reloc_count == 0)
3698 rel_hdr = d->rel.hdr;
3699 reloc_count = rel_hdr ? NUM_SHDR_ENTRIES (rel_hdr) : 0;
3700 rel_hdr2 = d->rela.hdr;
3701 reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
3703 BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
3704 BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
3705 || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
3710 /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
3711 case because relocations against this section may use the
3712 dynamic symbol table, and in that case bfd_section_from_shdr
3713 in elf.c does not update the RELOC_COUNT. */
3714 if (asect->size == 0)
3717 rel_hdr = &d->this_hdr;
3718 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
3723 /* Allocate space for 3 arelent structures for each Rel structure. */
3724 amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
3725 relents = bfd_alloc (abfd, amt);
3726 if (relents == NULL)
3729 /* The slurp_one_reloc_table routine increments reloc_count. */
3730 asect->reloc_count = 0;
3733 && ! mips_elf64_slurp_one_reloc_table (abfd, asect,
3734 rel_hdr, reloc_count,
3738 if (rel_hdr2 != NULL
3739 && ! mips_elf64_slurp_one_reloc_table (abfd, asect,
3740 rel_hdr2, reloc_count2,
3741 relents + reloc_count * 3,
3745 asect->relocation = relents;
3749 /* Write out the relocations. */
3752 mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
3754 bfd_boolean *failedp = data;
3756 Elf_Internal_Shdr *rel_hdr;
3759 /* If we have already failed, don't do anything. */
3763 if ((sec->flags & SEC_RELOC) == 0)
3766 /* The linker backend writes the relocs out itself, and sets the
3767 reloc_count field to zero to inhibit writing them here. Also,
3768 sometimes the SEC_RELOC flag gets set even when there aren't any
3770 if (sec->reloc_count == 0)
3773 /* We can combine up to three relocs that refer to the same address
3774 if the latter relocs have no associated symbol. */
3776 for (idx = 0; idx < sec->reloc_count; idx++)
3783 addr = sec->orelocation[idx]->address;
3784 for (i = 0; i < 2; i++)
3788 if (idx + 1 >= sec->reloc_count)
3790 r = sec->orelocation[idx + 1];
3791 if (r->address != addr
3792 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
3793 || (*r->sym_ptr_ptr)->value != 0)
3796 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
3802 rel_hdr = _bfd_elf_single_rel_hdr (sec);
3804 /* Do the actual relocation. */
3806 if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
3807 mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
3808 else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
3809 mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
3815 mips_elf64_write_rel (bfd *abfd, asection *sec,
3816 Elf_Internal_Shdr *rel_hdr,
3817 int *count, void *data)
3819 bfd_boolean *failedp = data;
3820 Elf64_Mips_External_Rel *ext_rel;
3822 asymbol *last_sym = 0;
3823 int last_sym_idx = 0;
3825 rel_hdr->sh_size = rel_hdr->sh_entsize * *count;
3826 rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size);
3827 if (rel_hdr->contents == NULL)
3833 ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
3834 for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
3837 Elf64_Mips_Internal_Rela int_rel;
3842 ptr = sec->orelocation[idx];
3844 /* The address of an ELF reloc is section relative for an object
3845 file, and absolute for an executable file or shared library.
3846 The address of a BFD reloc is always section relative. */
3847 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
3848 int_rel.r_offset = ptr->address;
3850 int_rel.r_offset = ptr->address + sec->vma;
3852 sym = *ptr->sym_ptr_ptr;
3853 if (sym == last_sym)
3855 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
3860 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
3870 int_rel.r_ssym = RSS_UNDEF;
3872 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
3873 && ! _bfd_elf_validate_reloc (abfd, ptr))
3879 int_rel.r_type = ptr->howto->type;
3880 int_rel.r_type2 = (int) R_MIPS_NONE;
3881 int_rel.r_type3 = (int) R_MIPS_NONE;
3883 for (i = 0; i < 2; i++)
3887 if (idx + 1 >= sec->reloc_count)
3889 r = sec->orelocation[idx + 1];
3890 if (r->address != ptr->address
3891 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
3892 || (*r->sym_ptr_ptr)->value != 0)
3895 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
3898 int_rel.r_type2 = r->howto->type;
3900 int_rel.r_type3 = r->howto->type;
3905 mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
3908 BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
3913 mips_elf64_write_rela (bfd *abfd, asection *sec,
3914 Elf_Internal_Shdr *rela_hdr,
3915 int *count, void *data)
3917 bfd_boolean *failedp = data;
3918 Elf64_Mips_External_Rela *ext_rela;
3920 asymbol *last_sym = 0;
3921 int last_sym_idx = 0;
3923 rela_hdr->sh_size = rela_hdr->sh_entsize * *count;
3924 rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
3925 if (rela_hdr->contents == NULL)
3931 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
3932 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
3935 Elf64_Mips_Internal_Rela int_rela;
3940 ptr = sec->orelocation[idx];
3942 /* The address of an ELF reloc is section relative for an object
3943 file, and absolute for an executable file or shared library.
3944 The address of a BFD reloc is always section relative. */
3945 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
3946 int_rela.r_offset = ptr->address;
3948 int_rela.r_offset = ptr->address + sec->vma;
3950 sym = *ptr->sym_ptr_ptr;
3951 if (sym == last_sym)
3953 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
3958 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
3968 int_rela.r_addend = ptr->addend;
3969 int_rela.r_ssym = RSS_UNDEF;
3971 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
3972 && ! _bfd_elf_validate_reloc (abfd, ptr))
3978 int_rela.r_type = ptr->howto->type;
3979 int_rela.r_type2 = (int) R_MIPS_NONE;
3980 int_rela.r_type3 = (int) R_MIPS_NONE;
3982 for (i = 0; i < 2; i++)
3986 if (idx + 1 >= sec->reloc_count)
3988 r = sec->orelocation[idx + 1];
3989 if (r->address != ptr->address
3990 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
3991 || (*r->sym_ptr_ptr)->value != 0)
3994 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
3997 int_rela.r_type2 = r->howto->type;
3999 int_rela.r_type3 = r->howto->type;
4004 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
4007 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
4011 /* Set the right machine number for a MIPS ELF file. */
4014 mips_elf64_object_p (bfd *abfd)
4018 /* Irix 6 is broken. Object file symbol tables are not always
4019 sorted correctly such that local symbols precede global symbols,
4020 and the sh_info field in the symbol table is not always right. */
4021 if (elf64_mips_irix_compat (abfd) != ict_none)
4022 elf_bad_symtab (abfd) = TRUE;
4024 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
4025 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
4029 /* Depending on the target vector we generate some version of Irix
4030 executables or "normal" MIPS ELF ABI executables. */
4031 static irix_compat_t
4032 elf64_mips_irix_compat (bfd *abfd)
4034 if ((abfd->xvec == &mips_elf64_be_vec)
4035 || (abfd->xvec == &mips_elf64_le_vec))
4041 /* Support for core dump NOTE sections. */
4043 elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
4048 switch (note->descsz)
4053 case 480: /* Linux/MIPS - N64 kernel */
4055 elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
4058 elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 32);
4067 /* Make a ".reg/999" section. */
4068 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
4069 size, note->descpos + offset);
4073 elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
4075 switch (note->descsz)
4080 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
4081 elf_tdata (abfd)->core->program
4082 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
4083 elf_tdata (abfd)->core->command
4084 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
4087 /* Note that for some reason, a spurious space is tacked
4088 onto the end of the args in some (at least one anyway)
4089 implementations, so strip it off if it exists. */
4092 char *command = elf_tdata (abfd)->core->command;
4093 int n = strlen (command);
4095 if (0 < n && command[n - 1] == ' ')
4096 command[n - 1] = '\0';
4102 /* ECOFF swapping routines. These are used when dealing with the
4103 .mdebug section, which is in the ECOFF debugging format. */
4104 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
4106 /* Symbol table magic number. */
4108 /* Alignment of debugging information. E.g., 4. */
4110 /* Sizes of external symbolic information. */
4111 sizeof (struct hdr_ext),
4112 sizeof (struct dnr_ext),
4113 sizeof (struct pdr_ext),
4114 sizeof (struct sym_ext),
4115 sizeof (struct opt_ext),
4116 sizeof (struct fdr_ext),
4117 sizeof (struct rfd_ext),
4118 sizeof (struct ext_ext),
4119 /* Functions to swap in external symbolic data. */
4128 _bfd_ecoff_swap_tir_in,
4129 _bfd_ecoff_swap_rndx_in,
4130 /* Functions to swap out external symbolic data. */
4139 _bfd_ecoff_swap_tir_out,
4140 _bfd_ecoff_swap_rndx_out,
4141 /* Function to read in symbolic data. */
4142 _bfd_mips_elf_read_ecoff_info
4145 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
4146 standard ELF. This structure is used to redirect the relocation
4147 handling routines. */
4149 const struct elf_size_info mips_elf64_size_info =
4151 sizeof (Elf64_External_Ehdr),
4152 sizeof (Elf64_External_Phdr),
4153 sizeof (Elf64_External_Shdr),
4154 sizeof (Elf64_Mips_External_Rel),
4155 sizeof (Elf64_Mips_External_Rela),
4156 sizeof (Elf64_External_Sym),
4157 sizeof (Elf64_External_Dyn),
4158 sizeof (Elf_External_Note),
4159 4, /* hash-table entry size */
4160 3, /* internal relocations per external relocations */
4162 3, /* log_file_align */
4165 bfd_elf64_write_out_phdrs,
4166 bfd_elf64_write_shdrs_and_ehdr,
4167 bfd_elf64_checksum_contents,
4168 mips_elf64_write_relocs,
4169 bfd_elf64_swap_symbol_in,
4170 bfd_elf64_swap_symbol_out,
4171 mips_elf64_slurp_reloc_table,
4172 bfd_elf64_slurp_symbol_table,
4173 bfd_elf64_swap_dyn_in,
4174 bfd_elf64_swap_dyn_out,
4175 mips_elf64_be_swap_reloc_in,
4176 mips_elf64_be_swap_reloc_out,
4177 mips_elf64_be_swap_reloca_in,
4178 mips_elf64_be_swap_reloca_out
4181 #define ELF_ARCH bfd_arch_mips
4182 #define ELF_TARGET_ID MIPS_ELF_DATA
4183 #define ELF_MACHINE_CODE EM_MIPS
4185 #define elf_backend_collect TRUE
4186 #define elf_backend_type_change_ok TRUE
4187 #define elf_backend_can_gc_sections TRUE
4188 #define elf_info_to_howto mips_elf64_info_to_howto_rela
4189 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
4190 #define elf_backend_object_p mips_elf64_object_p
4191 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
4192 #define elf_backend_section_processing _bfd_mips_elf_section_processing
4193 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
4194 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
4195 #define elf_backend_section_from_bfd_section \
4196 _bfd_mips_elf_section_from_bfd_section
4197 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
4198 #define elf_backend_link_output_symbol_hook \
4199 _bfd_mips_elf_link_output_symbol_hook
4200 #define elf_backend_create_dynamic_sections \
4201 _bfd_mips_elf_create_dynamic_sections
4202 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
4203 #define elf_backend_merge_symbol_attribute \
4204 _bfd_mips_elf_merge_symbol_attribute
4205 #define elf_backend_get_target_dtag _bfd_mips_elf_get_target_dtag
4206 #define elf_backend_adjust_dynamic_symbol \
4207 _bfd_mips_elf_adjust_dynamic_symbol
4208 #define elf_backend_always_size_sections \
4209 _bfd_mips_elf_always_size_sections
4210 #define elf_backend_size_dynamic_sections \
4211 _bfd_mips_elf_size_dynamic_sections
4212 #define elf_backend_init_index_section _bfd_elf_init_1_index_section
4213 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
4214 #define elf_backend_finish_dynamic_symbol \
4215 _bfd_mips_elf_finish_dynamic_symbol
4216 #define elf_backend_finish_dynamic_sections \
4217 _bfd_mips_elf_finish_dynamic_sections
4218 #define elf_backend_final_write_processing \
4219 _bfd_mips_elf_final_write_processing
4220 #define elf_backend_additional_program_headers \
4221 _bfd_mips_elf_additional_program_headers
4222 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
4223 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
4224 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
4225 #define elf_backend_copy_indirect_symbol \
4226 _bfd_mips_elf_copy_indirect_symbol
4227 #define elf_backend_ignore_discarded_relocs \
4228 _bfd_mips_elf_ignore_discarded_relocs
4229 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
4230 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
4231 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
4232 #define elf_backend_size_info mips_elf64_size_info
4234 #define elf_backend_grok_prstatus elf64_mips_grok_prstatus
4235 #define elf_backend_grok_psinfo elf64_mips_grok_psinfo
4237 #define elf_backend_got_header_size (8 * MIPS_RESERVED_GOTNO)
4239 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
4240 work better/work only in RELA, so we default to this. */
4241 #define elf_backend_may_use_rel_p 1
4242 #define elf_backend_may_use_rela_p 1
4243 #define elf_backend_default_use_rela_p 1
4244 #define elf_backend_rela_plts_and_copies_p 0
4245 #define elf_backend_plt_readonly 1
4246 #define elf_backend_plt_sym_val _bfd_mips_elf_plt_sym_val
4248 #define elf_backend_sign_extend_vma TRUE
4250 #define elf_backend_write_section _bfd_mips_elf_write_section
4252 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
4253 MIPS-specific function only applies to IRIX5, which had no 64-bit
4255 #define bfd_elf64_bfd_is_target_special_symbol \
4256 _bfd_mips_elf_is_target_special_symbol
4257 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
4258 #define bfd_elf64_find_inliner_info _bfd_mips_elf_find_inliner_info
4259 #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
4260 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
4261 #define bfd_elf64_bfd_get_relocated_section_contents \
4262 _bfd_elf_mips_get_relocated_section_contents
4263 #define bfd_elf64_bfd_link_hash_table_create \
4264 _bfd_mips_elf_link_hash_table_create
4265 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
4266 #define bfd_elf64_bfd_merge_private_bfd_data \
4267 _bfd_mips_elf_merge_private_bfd_data
4268 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
4269 #define bfd_elf64_bfd_print_private_bfd_data \
4270 _bfd_mips_elf_print_private_bfd_data
4272 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
4273 #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
4274 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
4275 #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
4276 #define bfd_elf64_bfd_relax_section _bfd_mips_relax_section
4277 #define bfd_elf64_mkobject _bfd_mips_elf_mkobject
4279 /* MIPS ELF64 archive functions. */
4280 #define bfd_elf64_archive_functions
4281 extern bfd_boolean bfd_elf64_archive_slurp_armap
4283 extern bfd_boolean bfd_elf64_archive_write_armap
4284 (bfd *, unsigned int, struct orl *, unsigned int, int);
4285 #define bfd_elf64_archive_slurp_extended_name_table \
4286 _bfd_archive_coff_slurp_extended_name_table
4287 #define bfd_elf64_archive_construct_extended_name_table \
4288 _bfd_archive_coff_construct_extended_name_table
4289 #define bfd_elf64_archive_truncate_arname \
4290 _bfd_archive_coff_truncate_arname
4291 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
4292 #define bfd_elf64_archive_write_ar_hdr _bfd_archive_coff_write_ar_hdr
4293 #define bfd_elf64_archive_openr_next_archived_file \
4294 _bfd_archive_coff_openr_next_archived_file
4295 #define bfd_elf64_archive_get_elt_at_index \
4296 _bfd_archive_coff_get_elt_at_index
4297 #define bfd_elf64_archive_generic_stat_arch_elt \
4298 _bfd_archive_coff_generic_stat_arch_elt
4299 #define bfd_elf64_archive_update_armap_timestamp \
4300 _bfd_archive_coff_update_armap_timestamp
4302 /* The SGI style (n)64 NewABI. */
4303 #define TARGET_LITTLE_SYM mips_elf64_le_vec
4304 #define TARGET_LITTLE_NAME "elf64-littlemips"
4305 #define TARGET_BIG_SYM mips_elf64_be_vec
4306 #define TARGET_BIG_NAME "elf64-bigmips"
4308 #define ELF_MAXPAGESIZE 0x10000
4309 #define ELF_COMMONPAGESIZE 0x1000
4311 #include "elf64-target.h"
4313 /* The SYSV-style 'traditional' (n)64 NewABI. */
4314 #undef TARGET_LITTLE_SYM
4315 #undef TARGET_LITTLE_NAME
4316 #undef TARGET_BIG_SYM
4317 #undef TARGET_BIG_NAME
4319 #undef ELF_MAXPAGESIZE
4320 #undef ELF_COMMONPAGESIZE
4322 #define TARGET_LITTLE_SYM mips_elf64_trad_le_vec
4323 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
4324 #define TARGET_BIG_SYM mips_elf64_trad_be_vec
4325 #define TARGET_BIG_NAME "elf64-tradbigmips"
4327 #define ELF_MAXPAGESIZE 0x10000
4328 #define ELF_COMMONPAGESIZE 0x1000
4329 #define elf64_bed elf64_tradbed
4331 /* Include the target file again for this target. */
4332 #include "elf64-target.h"
4335 /* FreeBSD support. */
4337 #undef TARGET_LITTLE_SYM
4338 #undef TARGET_LITTLE_NAME
4339 #undef TARGET_BIG_SYM
4340 #undef TARGET_BIG_NAME
4342 #define TARGET_LITTLE_SYM mips_elf64_tradfbsd_le_vec
4343 #define TARGET_LITTLE_NAME "elf64-tradlittlemips-freebsd"
4344 #define TARGET_BIG_SYM mips_elf64_tradfbsd_be_vec
4345 #define TARGET_BIG_NAME "elf64-tradbigmips-freebsd"
4348 #define ELF_OSABI ELFOSABI_FREEBSD
4351 #define elf64_bed elf64_fbsd_tradbed
4353 #include "elf64-target.h"