1 /* MIPS-specific support for 32-bit ELF
2 Copyright (C) 1993-2016 Free Software Foundation, Inc.
4 Most of the information added by Ian Lance Taylor, Cygnus Support,
6 N32/64 ABI support added by Mark Mitchell, CodeSourcery, LLC.
7 <mark@codesourcery.com>
8 Traditional MIPS targets support added by Koundinya.K, Dansk Data
9 Elektronik & Operations Research Group. <kk@ddeorg.soft.net>
11 This file is part of BFD, the Binary File Descriptor library.
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 3 of the License, or
16 (at your option) any later version.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
26 MA 02110-1301, USA. */
29 /* This file handles MIPS ELF targets. SGI Irix 5 uses a slightly
30 different MIPS ELF from other targets. This matters when linking.
31 This file supports both, switching at runtime. */
39 #include "elfxx-mips.h"
42 /* Get the ECOFF swapping routines. */
44 #include "coff/symconst.h"
45 #include "coff/internal.h"
46 #include "coff/ecoff.h"
47 #include "coff/mips.h"
48 #define ECOFF_SIGNED_32
49 #include "ecoffswap.h"
51 static bfd_boolean mips_elf_assign_gp
53 static bfd_reloc_status_type mips_elf_final_gp
54 (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
55 static bfd_reloc_status_type mips_elf_gprel16_reloc
56 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
57 static bfd_reloc_status_type mips_elf_literal_reloc
58 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
59 static bfd_reloc_status_type mips_elf_gprel32_reloc
60 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
61 static bfd_reloc_status_type gprel32_with_gp
62 (bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma);
63 static bfd_reloc_status_type mips_elf_shift6_reloc
64 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
65 static bfd_reloc_status_type mips16_gprel_reloc
66 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
67 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
68 (bfd *, bfd_reloc_code_real_type);
69 static reloc_howto_type *mips_elf_n32_rtype_to_howto
70 (unsigned int, bfd_boolean);
71 static void mips_info_to_howto_rel
72 (bfd *, arelent *, Elf_Internal_Rela *);
73 static void mips_info_to_howto_rela
74 (bfd *, arelent *, Elf_Internal_Rela *);
75 static bfd_boolean mips_elf_sym_is_global
77 static bfd_boolean mips_elf_n32_object_p
79 static bfd_boolean elf32_mips_grok_prstatus
80 (bfd *, Elf_Internal_Note *);
81 static bfd_boolean elf32_mips_grok_psinfo
82 (bfd *, Elf_Internal_Note *);
83 static irix_compat_t elf_n32_mips_irix_compat
86 extern const bfd_target mips_elf32_n_be_vec;
87 extern const bfd_target mips_elf32_n_le_vec;
89 /* Nonzero if ABFD is using the N32 ABI. */
90 #define ABI_N32_P(abfd) \
91 ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
93 /* Whether we are trying to be compatible with IRIX at all. */
94 #define SGI_COMPAT(abfd) \
95 (elf_n32_mips_irix_compat (abfd) != ict_none)
97 /* The number of local .got entries we reserve. */
98 #define MIPS_RESERVED_GOTNO (2)
100 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
101 from smaller values. Start with zero, widen, *then* decrement. */
102 #define MINUS_ONE (((bfd_vma)0) - 1)
104 /* The relocation table used for SHT_REL sections. */
106 static reloc_howto_type elf_mips_howto_table_rel[] =
109 HOWTO (R_MIPS_NONE, /* type */
111 3, /* size (0 = byte, 1 = short, 2 = long) */
113 FALSE, /* pc_relative */
115 complain_overflow_dont, /* complain_on_overflow */
116 _bfd_mips_elf_generic_reloc, /* special_function */
117 "R_MIPS_NONE", /* name */
118 FALSE, /* partial_inplace */
121 FALSE), /* pcrel_offset */
123 /* 16 bit relocation. */
124 HOWTO (R_MIPS_16, /* type */
126 2, /* size (0 = byte, 1 = short, 2 = long) */
128 FALSE, /* pc_relative */
130 complain_overflow_signed, /* complain_on_overflow */
131 _bfd_mips_elf_generic_reloc, /* special_function */
132 "R_MIPS_16", /* name */
133 TRUE, /* partial_inplace */
134 0x0000ffff, /* src_mask */
135 0x0000ffff, /* dst_mask */
136 FALSE), /* pcrel_offset */
138 /* 32 bit relocation. */
139 HOWTO (R_MIPS_32, /* type */
141 2, /* size (0 = byte, 1 = short, 2 = long) */
143 FALSE, /* pc_relative */
145 complain_overflow_dont, /* complain_on_overflow */
146 _bfd_mips_elf_generic_reloc, /* special_function */
147 "R_MIPS_32", /* name */
148 TRUE, /* partial_inplace */
149 0xffffffff, /* src_mask */
150 0xffffffff, /* dst_mask */
151 FALSE), /* pcrel_offset */
153 /* 32 bit symbol relative relocation. */
154 HOWTO (R_MIPS_REL32, /* type */
156 2, /* size (0 = byte, 1 = short, 2 = long) */
158 FALSE, /* pc_relative */
160 complain_overflow_dont, /* complain_on_overflow */
161 _bfd_mips_elf_generic_reloc, /* special_function */
162 "R_MIPS_REL32", /* name */
163 TRUE, /* partial_inplace */
164 0xffffffff, /* src_mask */
165 0xffffffff, /* dst_mask */
166 FALSE), /* pcrel_offset */
168 /* 26 bit jump address. */
169 HOWTO (R_MIPS_26, /* type */
171 2, /* size (0 = byte, 1 = short, 2 = long) */
173 FALSE, /* pc_relative */
175 complain_overflow_dont, /* complain_on_overflow */
176 /* This needs complex overflow
177 detection, because the upper four
178 bits must match the PC + 4. */
179 _bfd_mips_elf_generic_reloc, /* special_function */
180 "R_MIPS_26", /* name */
181 TRUE, /* partial_inplace */
182 0x03ffffff, /* src_mask */
183 0x03ffffff, /* dst_mask */
184 FALSE), /* pcrel_offset */
186 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
187 However, the native IRIX6 tools use them, so we try our best. */
189 /* High 16 bits of symbol value. */
190 HOWTO (R_MIPS_HI16, /* type */
192 2, /* size (0 = byte, 1 = short, 2 = long) */
194 FALSE, /* pc_relative */
196 complain_overflow_dont, /* complain_on_overflow */
197 _bfd_mips_elf_hi16_reloc, /* special_function */
198 "R_MIPS_HI16", /* name */
199 TRUE, /* partial_inplace */
200 0x0000ffff, /* src_mask */
201 0x0000ffff, /* dst_mask */
202 FALSE), /* pcrel_offset */
204 /* Low 16 bits of symbol value. */
205 HOWTO (R_MIPS_LO16, /* type */
207 2, /* size (0 = byte, 1 = short, 2 = long) */
209 FALSE, /* pc_relative */
211 complain_overflow_dont, /* complain_on_overflow */
212 _bfd_mips_elf_lo16_reloc, /* special_function */
213 "R_MIPS_LO16", /* name */
214 TRUE, /* partial_inplace */
215 0x0000ffff, /* src_mask */
216 0x0000ffff, /* dst_mask */
217 FALSE), /* pcrel_offset */
219 /* GP relative reference. */
220 HOWTO (R_MIPS_GPREL16, /* type */
222 2, /* size (0 = byte, 1 = short, 2 = long) */
224 FALSE, /* pc_relative */
226 complain_overflow_signed, /* complain_on_overflow */
227 mips_elf_gprel16_reloc, /* special_function */
228 "R_MIPS_GPREL16", /* name */
229 TRUE, /* partial_inplace */
230 0x0000ffff, /* src_mask */
231 0x0000ffff, /* dst_mask */
232 FALSE), /* pcrel_offset */
234 /* Reference to literal section. */
235 HOWTO (R_MIPS_LITERAL, /* type */
237 2, /* size (0 = byte, 1 = short, 2 = long) */
239 FALSE, /* pc_relative */
241 complain_overflow_signed, /* complain_on_overflow */
242 mips_elf_literal_reloc, /* special_function */
243 "R_MIPS_LITERAL", /* name */
244 TRUE, /* partial_inplace */
245 0x0000ffff, /* src_mask */
246 0x0000ffff, /* dst_mask */
247 FALSE), /* pcrel_offset */
249 /* Reference to global offset table. */
250 HOWTO (R_MIPS_GOT16, /* type */
252 2, /* size (0 = byte, 1 = short, 2 = long) */
254 FALSE, /* pc_relative */
256 complain_overflow_signed, /* complain_on_overflow */
257 _bfd_mips_elf_got16_reloc, /* special_function */
258 "R_MIPS_GOT16", /* name */
259 TRUE, /* partial_inplace */
260 0x0000ffff, /* src_mask */
261 0x0000ffff, /* dst_mask */
262 FALSE), /* pcrel_offset */
264 /* 16 bit PC relative reference. Note that the ABI document has a typo
265 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
266 We do the right thing here. */
267 HOWTO (R_MIPS_PC16, /* type */
269 2, /* size (0 = byte, 1 = short, 2 = long) */
271 TRUE, /* pc_relative */
273 complain_overflow_signed, /* complain_on_overflow */
274 _bfd_mips_elf_generic_reloc, /* special_function */
275 "R_MIPS_PC16", /* name */
276 TRUE, /* partial_inplace */
277 0x0000ffff, /* src_mask */
278 0x0000ffff, /* dst_mask */
279 TRUE), /* pcrel_offset */
281 /* 16 bit call through global offset table. */
282 HOWTO (R_MIPS_CALL16, /* type */
284 2, /* size (0 = byte, 1 = short, 2 = long) */
286 FALSE, /* pc_relative */
288 complain_overflow_signed, /* complain_on_overflow */
289 _bfd_mips_elf_generic_reloc, /* special_function */
290 "R_MIPS_CALL16", /* name */
291 TRUE, /* partial_inplace */
292 0x0000ffff, /* src_mask */
293 0x0000ffff, /* dst_mask */
294 FALSE), /* pcrel_offset */
296 /* 32 bit GP relative reference. */
297 HOWTO (R_MIPS_GPREL32, /* type */
299 2, /* size (0 = byte, 1 = short, 2 = long) */
301 FALSE, /* pc_relative */
303 complain_overflow_dont, /* complain_on_overflow */
304 mips_elf_gprel32_reloc, /* special_function */
305 "R_MIPS_GPREL32", /* name */
306 TRUE, /* partial_inplace */
307 0xffffffff, /* src_mask */
308 0xffffffff, /* dst_mask */
309 FALSE), /* pcrel_offset */
311 /* The remaining relocs are defined on Irix 5, although they are
312 not defined by the ABI. */
317 /* A 5 bit shift field. */
318 HOWTO (R_MIPS_SHIFT5, /* type */
320 2, /* size (0 = byte, 1 = short, 2 = long) */
322 FALSE, /* pc_relative */
324 complain_overflow_bitfield, /* complain_on_overflow */
325 _bfd_mips_elf_generic_reloc, /* special_function */
326 "R_MIPS_SHIFT5", /* name */
327 TRUE, /* partial_inplace */
328 0x000007c0, /* src_mask */
329 0x000007c0, /* dst_mask */
330 FALSE), /* pcrel_offset */
332 /* A 6 bit shift field. */
333 HOWTO (R_MIPS_SHIFT6, /* type */
335 2, /* size (0 = byte, 1 = short, 2 = long) */
337 FALSE, /* pc_relative */
339 complain_overflow_bitfield, /* complain_on_overflow */
340 mips_elf_shift6_reloc, /* special_function */
341 "R_MIPS_SHIFT6", /* name */
342 TRUE, /* partial_inplace */
343 0x000007c4, /* src_mask */
344 0x000007c4, /* dst_mask */
345 FALSE), /* pcrel_offset */
347 /* A 64 bit relocation. */
348 HOWTO (R_MIPS_64, /* type */
350 4, /* size (0 = byte, 1 = short, 2 = long) */
352 FALSE, /* pc_relative */
354 complain_overflow_dont, /* complain_on_overflow */
355 _bfd_mips_elf_generic_reloc, /* special_function */
356 "R_MIPS_64", /* name */
357 TRUE, /* partial_inplace */
358 MINUS_ONE, /* src_mask */
359 MINUS_ONE, /* dst_mask */
360 FALSE), /* pcrel_offset */
362 /* Displacement in the global offset table. */
363 HOWTO (R_MIPS_GOT_DISP, /* type */
365 2, /* size (0 = byte, 1 = short, 2 = long) */
367 FALSE, /* pc_relative */
369 complain_overflow_signed, /* complain_on_overflow */
370 _bfd_mips_elf_generic_reloc, /* special_function */
371 "R_MIPS_GOT_DISP", /* name */
372 TRUE, /* partial_inplace */
373 0x0000ffff, /* src_mask */
374 0x0000ffff, /* dst_mask */
375 FALSE), /* pcrel_offset */
377 /* Displacement to page pointer in the global offset table. */
378 HOWTO (R_MIPS_GOT_PAGE, /* type */
380 2, /* size (0 = byte, 1 = short, 2 = long) */
382 FALSE, /* pc_relative */
384 complain_overflow_signed, /* complain_on_overflow */
385 _bfd_mips_elf_generic_reloc, /* special_function */
386 "R_MIPS_GOT_PAGE", /* name */
387 TRUE, /* partial_inplace */
388 0x0000ffff, /* src_mask */
389 0x0000ffff, /* dst_mask */
390 FALSE), /* pcrel_offset */
392 /* Offset from page pointer in the global offset table. */
393 HOWTO (R_MIPS_GOT_OFST, /* type */
395 2, /* size (0 = byte, 1 = short, 2 = long) */
397 FALSE, /* pc_relative */
399 complain_overflow_signed, /* complain_on_overflow */
400 _bfd_mips_elf_generic_reloc, /* special_function */
401 "R_MIPS_GOT_OFST", /* name */
402 TRUE, /* partial_inplace */
403 0x0000ffff, /* src_mask */
404 0x0000ffff, /* dst_mask */
405 FALSE), /* pcrel_offset */
407 /* High 16 bits of displacement in global offset table. */
408 HOWTO (R_MIPS_GOT_HI16, /* type */
410 2, /* size (0 = byte, 1 = short, 2 = long) */
412 FALSE, /* pc_relative */
414 complain_overflow_dont, /* complain_on_overflow */
415 _bfd_mips_elf_generic_reloc, /* special_function */
416 "R_MIPS_GOT_HI16", /* name */
417 TRUE, /* partial_inplace */
418 0x0000ffff, /* src_mask */
419 0x0000ffff, /* dst_mask */
420 FALSE), /* pcrel_offset */
422 /* Low 16 bits of displacement in global offset table. */
423 HOWTO (R_MIPS_GOT_LO16, /* type */
425 2, /* size (0 = byte, 1 = short, 2 = long) */
427 FALSE, /* pc_relative */
429 complain_overflow_dont, /* complain_on_overflow */
430 _bfd_mips_elf_generic_reloc, /* special_function */
431 "R_MIPS_GOT_LO16", /* name */
432 TRUE, /* partial_inplace */
433 0x0000ffff, /* src_mask */
434 0x0000ffff, /* dst_mask */
435 FALSE), /* pcrel_offset */
437 /* 64 bit subtraction. */
438 HOWTO (R_MIPS_SUB, /* type */
440 4, /* size (0 = byte, 1 = short, 2 = long) */
442 FALSE, /* pc_relative */
444 complain_overflow_dont, /* complain_on_overflow */
445 _bfd_mips_elf_generic_reloc, /* special_function */
446 "R_MIPS_SUB", /* name */
447 TRUE, /* partial_inplace */
448 MINUS_ONE, /* src_mask */
449 MINUS_ONE, /* dst_mask */
450 FALSE), /* pcrel_offset */
452 /* Insert the addend as an instruction. */
453 /* FIXME: Not handled correctly. */
454 HOWTO (R_MIPS_INSERT_A, /* type */
456 2, /* size (0 = byte, 1 = short, 2 = long) */
458 FALSE, /* pc_relative */
460 complain_overflow_dont, /* complain_on_overflow */
461 _bfd_mips_elf_generic_reloc, /* special_function */
462 "R_MIPS_INSERT_A", /* name */
463 TRUE, /* partial_inplace */
464 0xffffffff, /* src_mask */
465 0xffffffff, /* dst_mask */
466 FALSE), /* pcrel_offset */
468 /* Insert the addend as an instruction, and change all relocations
469 to refer to the old instruction at the address. */
470 /* FIXME: Not handled correctly. */
471 HOWTO (R_MIPS_INSERT_B, /* type */
473 2, /* size (0 = byte, 1 = short, 2 = long) */
475 FALSE, /* pc_relative */
477 complain_overflow_dont, /* complain_on_overflow */
478 _bfd_mips_elf_generic_reloc, /* special_function */
479 "R_MIPS_INSERT_B", /* name */
480 TRUE, /* partial_inplace */
481 0xffffffff, /* src_mask */
482 0xffffffff, /* dst_mask */
483 FALSE), /* pcrel_offset */
485 /* Delete a 32 bit instruction. */
486 /* FIXME: Not handled correctly. */
487 HOWTO (R_MIPS_DELETE, /* type */
489 2, /* size (0 = byte, 1 = short, 2 = long) */
491 FALSE, /* pc_relative */
493 complain_overflow_dont, /* complain_on_overflow */
494 _bfd_mips_elf_generic_reloc, /* special_function */
495 "R_MIPS_DELETE", /* name */
496 TRUE, /* partial_inplace */
497 0xffffffff, /* src_mask */
498 0xffffffff, /* dst_mask */
499 FALSE), /* pcrel_offset */
501 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
503 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
504 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
506 b) No other NewABI toolchain actually emits such relocations. */
507 EMPTY_HOWTO (R_MIPS_HIGHER),
508 EMPTY_HOWTO (R_MIPS_HIGHEST),
510 /* High 16 bits of displacement in global offset table. */
511 HOWTO (R_MIPS_CALL_HI16, /* type */
513 2, /* size (0 = byte, 1 = short, 2 = long) */
515 FALSE, /* pc_relative */
517 complain_overflow_dont, /* complain_on_overflow */
518 _bfd_mips_elf_generic_reloc, /* special_function */
519 "R_MIPS_CALL_HI16", /* name */
520 TRUE, /* partial_inplace */
521 0x0000ffff, /* src_mask */
522 0x0000ffff, /* dst_mask */
523 FALSE), /* pcrel_offset */
525 /* Low 16 bits of displacement in global offset table. */
526 HOWTO (R_MIPS_CALL_LO16, /* type */
528 2, /* size (0 = byte, 1 = short, 2 = long) */
530 FALSE, /* pc_relative */
532 complain_overflow_dont, /* complain_on_overflow */
533 _bfd_mips_elf_generic_reloc, /* special_function */
534 "R_MIPS_CALL_LO16", /* name */
535 TRUE, /* partial_inplace */
536 0x0000ffff, /* src_mask */
537 0x0000ffff, /* dst_mask */
538 FALSE), /* pcrel_offset */
540 /* Section displacement. */
541 HOWTO (R_MIPS_SCN_DISP, /* type */
543 2, /* size (0 = byte, 1 = short, 2 = long) */
545 FALSE, /* pc_relative */
547 complain_overflow_dont, /* complain_on_overflow */
548 _bfd_mips_elf_generic_reloc, /* special_function */
549 "R_MIPS_SCN_DISP", /* name */
550 TRUE, /* partial_inplace */
551 0xffffffff, /* src_mask */
552 0xffffffff, /* dst_mask */
553 FALSE), /* pcrel_offset */
555 HOWTO (R_MIPS_REL16, /* type */
557 1, /* size (0 = byte, 1 = short, 2 = long) */
559 FALSE, /* pc_relative */
561 complain_overflow_signed, /* complain_on_overflow */
562 _bfd_mips_elf_generic_reloc, /* special_function */
563 "R_MIPS_REL16", /* name */
564 TRUE, /* partial_inplace */
565 0xffff, /* src_mask */
566 0xffff, /* dst_mask */
567 FALSE), /* pcrel_offset */
569 /* These two are obsolete. */
570 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
571 EMPTY_HOWTO (R_MIPS_PJUMP),
573 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
574 It must be used for multigot GOT's (and only there). */
575 HOWTO (R_MIPS_RELGOT, /* type */
577 2, /* size (0 = byte, 1 = short, 2 = long) */
579 FALSE, /* pc_relative */
581 complain_overflow_dont, /* complain_on_overflow */
582 _bfd_mips_elf_generic_reloc, /* special_function */
583 "R_MIPS_RELGOT", /* name */
584 TRUE, /* partial_inplace */
585 0xffffffff, /* src_mask */
586 0xffffffff, /* dst_mask */
587 FALSE), /* pcrel_offset */
589 /* Protected jump conversion. This is an optimization hint. No
590 relocation is required for correctness. */
591 HOWTO (R_MIPS_JALR, /* type */
593 2, /* size (0 = byte, 1 = short, 2 = long) */
595 FALSE, /* pc_relative */
597 complain_overflow_dont, /* complain_on_overflow */
598 _bfd_mips_elf_generic_reloc, /* special_function */
599 "R_MIPS_JALR", /* name */
600 FALSE, /* partial_inplace */
601 0x00000000, /* src_mask */
602 0x00000000, /* dst_mask */
603 FALSE), /* pcrel_offset */
605 /* TLS GD/LD dynamic relocations. */
606 HOWTO (R_MIPS_TLS_DTPMOD32, /* type */
608 2, /* size (0 = byte, 1 = short, 2 = long) */
610 FALSE, /* pc_relative */
612 complain_overflow_dont, /* complain_on_overflow */
613 _bfd_mips_elf_generic_reloc, /* special_function */
614 "R_MIPS_TLS_DTPMOD32", /* name */
615 TRUE, /* partial_inplace */
616 0xffffffff, /* src_mask */
617 0xffffffff, /* dst_mask */
618 FALSE), /* pcrel_offset */
620 HOWTO (R_MIPS_TLS_DTPREL32, /* type */
622 2, /* size (0 = byte, 1 = short, 2 = long) */
624 FALSE, /* pc_relative */
626 complain_overflow_dont, /* complain_on_overflow */
627 _bfd_mips_elf_generic_reloc, /* special_function */
628 "R_MIPS_TLS_DTPREL32", /* name */
629 TRUE, /* partial_inplace */
630 0xffffffff, /* src_mask */
631 0xffffffff, /* dst_mask */
632 FALSE), /* pcrel_offset */
634 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
635 EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
637 /* TLS general dynamic variable reference. */
638 HOWTO (R_MIPS_TLS_GD, /* type */
640 2, /* size (0 = byte, 1 = short, 2 = long) */
642 FALSE, /* pc_relative */
644 complain_overflow_signed, /* complain_on_overflow */
645 _bfd_mips_elf_generic_reloc, /* special_function */
646 "R_MIPS_TLS_GD", /* name */
647 TRUE, /* partial_inplace */
648 0x0000ffff, /* src_mask */
649 0x0000ffff, /* dst_mask */
650 FALSE), /* pcrel_offset */
652 /* TLS local dynamic variable reference. */
653 HOWTO (R_MIPS_TLS_LDM, /* type */
655 2, /* size (0 = byte, 1 = short, 2 = long) */
657 FALSE, /* pc_relative */
659 complain_overflow_signed, /* complain_on_overflow */
660 _bfd_mips_elf_generic_reloc, /* special_function */
661 "R_MIPS_TLS_LDM", /* name */
662 TRUE, /* partial_inplace */
663 0x0000ffff, /* src_mask */
664 0x0000ffff, /* dst_mask */
665 FALSE), /* pcrel_offset */
667 /* TLS local dynamic offset. */
668 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
670 2, /* size (0 = byte, 1 = short, 2 = long) */
672 FALSE, /* pc_relative */
674 complain_overflow_signed, /* complain_on_overflow */
675 _bfd_mips_elf_generic_reloc, /* special_function */
676 "R_MIPS_TLS_DTPREL_HI16", /* name */
677 TRUE, /* partial_inplace */
678 0x0000ffff, /* src_mask */
679 0x0000ffff, /* dst_mask */
680 FALSE), /* pcrel_offset */
682 /* TLS local dynamic offset. */
683 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
685 2, /* size (0 = byte, 1 = short, 2 = long) */
687 FALSE, /* pc_relative */
689 complain_overflow_signed, /* complain_on_overflow */
690 _bfd_mips_elf_generic_reloc, /* special_function */
691 "R_MIPS_TLS_DTPREL_LO16", /* name */
692 TRUE, /* partial_inplace */
693 0x0000ffff, /* src_mask */
694 0x0000ffff, /* dst_mask */
695 FALSE), /* pcrel_offset */
697 /* TLS thread pointer offset. */
698 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
700 2, /* size (0 = byte, 1 = short, 2 = long) */
702 FALSE, /* pc_relative */
704 complain_overflow_signed, /* complain_on_overflow */
705 _bfd_mips_elf_generic_reloc, /* special_function */
706 "R_MIPS_TLS_GOTTPREL", /* name */
707 TRUE, /* partial_inplace */
708 0x0000ffff, /* src_mask */
709 0x0000ffff, /* dst_mask */
710 FALSE), /* pcrel_offset */
712 /* TLS IE dynamic relocations. */
713 HOWTO (R_MIPS_TLS_TPREL32, /* type */
715 2, /* size (0 = byte, 1 = short, 2 = long) */
717 FALSE, /* pc_relative */
719 complain_overflow_dont, /* complain_on_overflow */
720 _bfd_mips_elf_generic_reloc, /* special_function */
721 "R_MIPS_TLS_TPREL32", /* name */
722 TRUE, /* partial_inplace */
723 0xffffffff, /* src_mask */
724 0xffffffff, /* dst_mask */
725 FALSE), /* pcrel_offset */
727 EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
729 /* TLS thread pointer offset. */
730 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
732 2, /* size (0 = byte, 1 = short, 2 = long) */
734 FALSE, /* pc_relative */
736 complain_overflow_signed, /* complain_on_overflow */
737 _bfd_mips_elf_generic_reloc, /* special_function */
738 "R_MIPS_TLS_TPREL_HI16", /* name */
739 TRUE, /* partial_inplace */
740 0x0000ffff, /* src_mask */
741 0x0000ffff, /* dst_mask */
742 FALSE), /* pcrel_offset */
744 /* TLS thread pointer offset. */
745 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
747 2, /* size (0 = byte, 1 = short, 2 = long) */
749 FALSE, /* pc_relative */
751 complain_overflow_signed, /* complain_on_overflow */
752 _bfd_mips_elf_generic_reloc, /* special_function */
753 "R_MIPS_TLS_TPREL_LO16", /* name */
754 TRUE, /* partial_inplace */
755 0x0000ffff, /* src_mask */
756 0x0000ffff, /* dst_mask */
757 FALSE), /* pcrel_offset */
759 /* 32 bit relocation with no addend. */
760 HOWTO (R_MIPS_GLOB_DAT, /* type */
762 2, /* size (0 = byte, 1 = short, 2 = long) */
764 FALSE, /* pc_relative */
766 complain_overflow_dont, /* complain_on_overflow */
767 _bfd_mips_elf_generic_reloc, /* special_function */
768 "R_MIPS_GLOB_DAT", /* name */
769 FALSE, /* partial_inplace */
771 0xffffffff, /* dst_mask */
772 FALSE), /* pcrel_offset */
783 HOWTO (R_MIPS_PC21_S2, /* type */
785 2, /* size (0 = byte, 1 = short, 2 = long) */
787 TRUE, /* pc_relative */
789 complain_overflow_signed, /* complain_on_overflow */
790 _bfd_mips_elf_generic_reloc, /* special_function */
791 "R_MIPS_PC21_S2", /* name */
792 TRUE, /* partial_inplace */
793 0x001fffff, /* src_mask */
794 0x001fffff, /* dst_mask */
795 TRUE), /* pcrel_offset */
797 HOWTO (R_MIPS_PC26_S2, /* type */
799 2, /* size (0 = byte, 1 = short, 2 = long) */
801 TRUE, /* pc_relative */
803 complain_overflow_signed, /* complain_on_overflow */
804 _bfd_mips_elf_generic_reloc, /* special_function */
805 "R_MIPS_PC26_S2", /* name */
806 TRUE, /* partial_inplace */
807 0x03ffffff, /* src_mask */
808 0x03ffffff, /* dst_mask */
809 TRUE), /* pcrel_offset */
811 HOWTO (R_MIPS_PC18_S3, /* type */
813 2, /* size (0 = byte, 1 = short, 2 = long) */
815 TRUE, /* pc_relative */
817 complain_overflow_signed, /* complain_on_overflow */
818 _bfd_mips_elf_generic_reloc, /* special_function */
819 "R_MIPS_PC18_S3", /* name */
820 TRUE, /* partial_inplace */
821 0x0003ffff, /* src_mask */
822 0x0003ffff, /* dst_mask */
823 TRUE), /* pcrel_offset */
825 HOWTO (R_MIPS_PC19_S2, /* type */
827 2, /* size (0 = byte, 1 = short, 2 = long) */
829 TRUE, /* pc_relative */
831 complain_overflow_signed, /* complain_on_overflow */
832 _bfd_mips_elf_generic_reloc, /* special_function */
833 "R_MIPS_PC19_S2", /* name */
834 TRUE, /* partial_inplace */
835 0x0007ffff, /* src_mask */
836 0x0007ffff, /* dst_mask */
837 TRUE), /* pcrel_offset */
839 HOWTO (R_MIPS_PCHI16, /* type */
841 2, /* size (0 = byte, 1 = short, 2 = long) */
843 TRUE, /* pc_relative */
845 complain_overflow_signed, /* complain_on_overflow */
846 _bfd_mips_elf_generic_reloc, /* special_function */
847 "R_MIPS_PCHI16", /* name */
848 TRUE, /* partial_inplace */
849 0x0000ffff, /* src_mask */
850 0x0000ffff, /* dst_mask */
851 TRUE), /* pcrel_offset */
853 HOWTO (R_MIPS_PCLO16, /* type */
855 2, /* size (0 = byte, 1 = short, 2 = long) */
857 TRUE, /* pc_relative */
859 complain_overflow_dont, /* complain_on_overflow */
860 _bfd_mips_elf_generic_reloc, /* special_function */
861 "R_MIPS_PCLO16", /* name */
862 TRUE, /* partial_inplace */
863 0x0000ffff, /* src_mask */
864 0x0000ffff, /* dst_mask */
865 TRUE), /* pcrel_offset */
869 /* The relocation table used for SHT_RELA sections. */
871 static reloc_howto_type elf_mips_howto_table_rela[] =
874 HOWTO (R_MIPS_NONE, /* type */
876 0, /* size (0 = byte, 1 = short, 2 = long) */
878 FALSE, /* pc_relative */
880 complain_overflow_dont, /* complain_on_overflow */
881 _bfd_mips_elf_generic_reloc, /* special_function */
882 "R_MIPS_NONE", /* name */
883 FALSE, /* partial_inplace */
886 FALSE), /* pcrel_offset */
888 /* 16 bit relocation. */
889 HOWTO (R_MIPS_16, /* type */
891 2, /* size (0 = byte, 1 = short, 2 = long) */
893 FALSE, /* pc_relative */
895 complain_overflow_signed, /* complain_on_overflow */
896 _bfd_mips_elf_generic_reloc, /* special_function */
897 "R_MIPS_16", /* name */
898 FALSE, /* partial_inplace */
900 0x0000, /* dst_mask */
901 FALSE), /* pcrel_offset */
903 /* 32 bit relocation. */
904 HOWTO (R_MIPS_32, /* type */
906 2, /* size (0 = byte, 1 = short, 2 = long) */
908 FALSE, /* pc_relative */
910 complain_overflow_dont, /* complain_on_overflow */
911 _bfd_mips_elf_generic_reloc, /* special_function */
912 "R_MIPS_32", /* name */
913 FALSE, /* partial_inplace */
915 0xffffffff, /* dst_mask */
916 FALSE), /* pcrel_offset */
918 /* 32 bit symbol relative relocation. */
919 HOWTO (R_MIPS_REL32, /* type */
921 2, /* size (0 = byte, 1 = short, 2 = long) */
923 FALSE, /* pc_relative */
925 complain_overflow_dont, /* complain_on_overflow */
926 _bfd_mips_elf_generic_reloc, /* special_function */
927 "R_MIPS_REL32", /* name */
928 FALSE, /* partial_inplace */
930 0xffffffff, /* dst_mask */
931 FALSE), /* pcrel_offset */
933 /* 26 bit jump address. */
934 HOWTO (R_MIPS_26, /* type */
936 2, /* size (0 = byte, 1 = short, 2 = long) */
938 FALSE, /* pc_relative */
940 complain_overflow_dont, /* complain_on_overflow */
941 /* This needs complex overflow
942 detection, because the upper 36
943 bits must match the PC + 4. */
944 _bfd_mips_elf_generic_reloc, /* special_function */
945 "R_MIPS_26", /* name */
946 FALSE, /* partial_inplace */
948 0x03ffffff, /* dst_mask */
949 FALSE), /* pcrel_offset */
951 /* High 16 bits of symbol value. */
952 HOWTO (R_MIPS_HI16, /* type */
954 2, /* size (0 = byte, 1 = short, 2 = long) */
956 FALSE, /* pc_relative */
958 complain_overflow_dont, /* complain_on_overflow */
959 _bfd_mips_elf_generic_reloc, /* special_function */
960 "R_MIPS_HI16", /* name */
961 FALSE, /* partial_inplace */
963 0x0000ffff, /* dst_mask */
964 FALSE), /* pcrel_offset */
966 /* Low 16 bits of symbol value. */
967 HOWTO (R_MIPS_LO16, /* type */
969 2, /* size (0 = byte, 1 = short, 2 = long) */
971 FALSE, /* pc_relative */
973 complain_overflow_dont, /* complain_on_overflow */
974 _bfd_mips_elf_generic_reloc, /* special_function */
975 "R_MIPS_LO16", /* name */
976 FALSE, /* partial_inplace */
978 0x0000ffff, /* dst_mask */
979 FALSE), /* pcrel_offset */
981 /* GP relative reference. */
982 HOWTO (R_MIPS_GPREL16, /* type */
984 2, /* size (0 = byte, 1 = short, 2 = long) */
986 FALSE, /* pc_relative */
988 complain_overflow_signed, /* complain_on_overflow */
989 mips_elf_gprel16_reloc, /* special_function */
990 "R_MIPS_GPREL16", /* name */
991 FALSE, /* partial_inplace */
993 0x0000ffff, /* dst_mask */
994 FALSE), /* pcrel_offset */
996 /* Reference to literal section. */
997 HOWTO (R_MIPS_LITERAL, /* type */
999 2, /* size (0 = byte, 1 = short, 2 = long) */
1001 FALSE, /* pc_relative */
1003 complain_overflow_signed, /* complain_on_overflow */
1004 mips_elf_literal_reloc, /* special_function */
1005 "R_MIPS_LITERAL", /* name */
1006 FALSE, /* partial_inplace */
1008 0x0000ffff, /* dst_mask */
1009 FALSE), /* pcrel_offset */
1011 /* Reference to global offset table. */
1012 HOWTO (R_MIPS_GOT16, /* type */
1014 2, /* size (0 = byte, 1 = short, 2 = long) */
1016 FALSE, /* pc_relative */
1018 complain_overflow_signed, /* complain_on_overflow */
1019 _bfd_mips_elf_generic_reloc, /* special_function */
1020 "R_MIPS_GOT16", /* name */
1021 FALSE, /* partial_inplace */
1023 0x0000ffff, /* dst_mask */
1024 FALSE), /* pcrel_offset */
1026 /* 16 bit PC relative reference. Note that the ABI document has a typo
1027 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
1028 We do the right thing here. */
1029 HOWTO (R_MIPS_PC16, /* type */
1031 2, /* size (0 = byte, 1 = short, 2 = long) */
1033 TRUE, /* pc_relative */
1035 complain_overflow_signed, /* complain_on_overflow */
1036 _bfd_mips_elf_generic_reloc, /* special_function */
1037 "R_MIPS_PC16", /* name */
1038 FALSE, /* partial_inplace */
1040 0x0000ffff, /* dst_mask */
1041 TRUE), /* pcrel_offset */
1043 /* 16 bit call through global offset table. */
1044 HOWTO (R_MIPS_CALL16, /* type */
1046 2, /* size (0 = byte, 1 = short, 2 = long) */
1048 FALSE, /* pc_relative */
1050 complain_overflow_signed, /* complain_on_overflow */
1051 _bfd_mips_elf_generic_reloc, /* special_function */
1052 "R_MIPS_CALL16", /* name */
1053 FALSE, /* partial_inplace */
1055 0x0000ffff, /* dst_mask */
1056 FALSE), /* pcrel_offset */
1058 /* 32 bit GP relative reference. */
1059 HOWTO (R_MIPS_GPREL32, /* type */
1061 2, /* size (0 = byte, 1 = short, 2 = long) */
1063 FALSE, /* pc_relative */
1065 complain_overflow_dont, /* complain_on_overflow */
1066 mips_elf_gprel32_reloc, /* special_function */
1067 "R_MIPS_GPREL32", /* name */
1068 FALSE, /* partial_inplace */
1070 0xffffffff, /* dst_mask */
1071 FALSE), /* pcrel_offset */
1077 /* A 5 bit shift field. */
1078 HOWTO (R_MIPS_SHIFT5, /* type */
1080 2, /* size (0 = byte, 1 = short, 2 = long) */
1082 FALSE, /* pc_relative */
1084 complain_overflow_bitfield, /* complain_on_overflow */
1085 _bfd_mips_elf_generic_reloc, /* special_function */
1086 "R_MIPS_SHIFT5", /* name */
1087 FALSE, /* partial_inplace */
1089 0x000007c0, /* dst_mask */
1090 FALSE), /* pcrel_offset */
1092 /* A 6 bit shift field. */
1093 HOWTO (R_MIPS_SHIFT6, /* type */
1095 2, /* size (0 = byte, 1 = short, 2 = long) */
1097 FALSE, /* pc_relative */
1099 complain_overflow_bitfield, /* complain_on_overflow */
1100 mips_elf_shift6_reloc, /* special_function */
1101 "R_MIPS_SHIFT6", /* name */
1102 FALSE, /* partial_inplace */
1104 0x000007c4, /* dst_mask */
1105 FALSE), /* pcrel_offset */
1107 /* 64 bit relocation. */
1108 HOWTO (R_MIPS_64, /* type */
1110 4, /* size (0 = byte, 1 = short, 2 = long) */
1112 FALSE, /* pc_relative */
1114 complain_overflow_dont, /* complain_on_overflow */
1115 _bfd_mips_elf_generic_reloc, /* special_function */
1116 "R_MIPS_64", /* name */
1117 FALSE, /* partial_inplace */
1119 MINUS_ONE, /* dst_mask */
1120 FALSE), /* pcrel_offset */
1122 /* Displacement in the global offset table. */
1123 HOWTO (R_MIPS_GOT_DISP, /* type */
1125 2, /* size (0 = byte, 1 = short, 2 = long) */
1127 FALSE, /* pc_relative */
1129 complain_overflow_signed, /* complain_on_overflow */
1130 _bfd_mips_elf_generic_reloc, /* special_function */
1131 "R_MIPS_GOT_DISP", /* name */
1132 FALSE, /* partial_inplace */
1134 0x0000ffff, /* dst_mask */
1135 FALSE), /* pcrel_offset */
1137 /* Displacement to page pointer in the global offset table. */
1138 HOWTO (R_MIPS_GOT_PAGE, /* type */
1140 2, /* size (0 = byte, 1 = short, 2 = long) */
1142 FALSE, /* pc_relative */
1144 complain_overflow_signed, /* complain_on_overflow */
1145 _bfd_mips_elf_generic_reloc, /* special_function */
1146 "R_MIPS_GOT_PAGE", /* name */
1147 FALSE, /* partial_inplace */
1149 0x0000ffff, /* dst_mask */
1150 FALSE), /* pcrel_offset */
1152 /* Offset from page pointer in the global offset table. */
1153 HOWTO (R_MIPS_GOT_OFST, /* type */
1155 2, /* size (0 = byte, 1 = short, 2 = long) */
1157 FALSE, /* pc_relative */
1159 complain_overflow_signed, /* complain_on_overflow */
1160 _bfd_mips_elf_generic_reloc, /* special_function */
1161 "R_MIPS_GOT_OFST", /* name */
1162 FALSE, /* partial_inplace */
1164 0x0000ffff, /* dst_mask */
1165 FALSE), /* pcrel_offset */
1167 /* High 16 bits of displacement in global offset table. */
1168 HOWTO (R_MIPS_GOT_HI16, /* type */
1170 2, /* size (0 = byte, 1 = short, 2 = long) */
1172 FALSE, /* pc_relative */
1174 complain_overflow_dont, /* complain_on_overflow */
1175 _bfd_mips_elf_generic_reloc, /* special_function */
1176 "R_MIPS_GOT_HI16", /* name */
1177 FALSE, /* partial_inplace */
1179 0x0000ffff, /* dst_mask */
1180 FALSE), /* pcrel_offset */
1182 /* Low 16 bits of displacement in global offset table. */
1183 HOWTO (R_MIPS_GOT_LO16, /* type */
1185 2, /* size (0 = byte, 1 = short, 2 = long) */
1187 FALSE, /* pc_relative */
1189 complain_overflow_dont, /* complain_on_overflow */
1190 _bfd_mips_elf_generic_reloc, /* special_function */
1191 "R_MIPS_GOT_LO16", /* name */
1192 FALSE, /* partial_inplace */
1194 0x0000ffff, /* dst_mask */
1195 FALSE), /* pcrel_offset */
1197 /* 64 bit subtraction. */
1198 HOWTO (R_MIPS_SUB, /* type */
1200 4, /* size (0 = byte, 1 = short, 2 = long) */
1202 FALSE, /* pc_relative */
1204 complain_overflow_dont, /* complain_on_overflow */
1205 _bfd_mips_elf_generic_reloc, /* special_function */
1206 "R_MIPS_SUB", /* name */
1207 FALSE, /* partial_inplace */
1209 MINUS_ONE, /* dst_mask */
1210 FALSE), /* pcrel_offset */
1212 /* Insert the addend as an instruction. */
1213 /* FIXME: Not handled correctly. */
1214 HOWTO (R_MIPS_INSERT_A, /* type */
1216 2, /* size (0 = byte, 1 = short, 2 = long) */
1218 FALSE, /* pc_relative */
1220 complain_overflow_dont, /* complain_on_overflow */
1221 _bfd_mips_elf_generic_reloc, /* special_function */
1222 "R_MIPS_INSERT_A", /* name */
1223 FALSE, /* partial_inplace */
1225 0xffffffff, /* dst_mask */
1226 FALSE), /* pcrel_offset */
1228 /* Insert the addend as an instruction, and change all relocations
1229 to refer to the old instruction at the address. */
1230 /* FIXME: Not handled correctly. */
1231 HOWTO (R_MIPS_INSERT_B, /* type */
1233 2, /* size (0 = byte, 1 = short, 2 = long) */
1235 FALSE, /* pc_relative */
1237 complain_overflow_dont, /* complain_on_overflow */
1238 _bfd_mips_elf_generic_reloc, /* special_function */
1239 "R_MIPS_INSERT_B", /* name */
1240 FALSE, /* partial_inplace */
1242 0xffffffff, /* dst_mask */
1243 FALSE), /* pcrel_offset */
1245 /* Delete a 32 bit instruction. */
1246 /* FIXME: Not handled correctly. */
1247 HOWTO (R_MIPS_DELETE, /* type */
1249 2, /* size (0 = byte, 1 = short, 2 = long) */
1251 FALSE, /* pc_relative */
1253 complain_overflow_dont, /* complain_on_overflow */
1254 _bfd_mips_elf_generic_reloc, /* special_function */
1255 "R_MIPS_DELETE", /* name */
1256 FALSE, /* partial_inplace */
1258 0xffffffff, /* dst_mask */
1259 FALSE), /* pcrel_offset */
1261 /* Get the higher value of a 64 bit addend. */
1262 HOWTO (R_MIPS_HIGHER, /* type */
1264 2, /* size (0 = byte, 1 = short, 2 = long) */
1266 FALSE, /* pc_relative */
1268 complain_overflow_dont, /* complain_on_overflow */
1269 _bfd_mips_elf_generic_reloc, /* special_function */
1270 "R_MIPS_HIGHER", /* name */
1271 FALSE, /* partial_inplace */
1273 0x0000ffff, /* dst_mask */
1274 FALSE), /* pcrel_offset */
1276 /* Get the highest value of a 64 bit addend. */
1277 HOWTO (R_MIPS_HIGHEST, /* type */
1279 2, /* size (0 = byte, 1 = short, 2 = long) */
1281 FALSE, /* pc_relative */
1283 complain_overflow_dont, /* complain_on_overflow */
1284 _bfd_mips_elf_generic_reloc, /* special_function */
1285 "R_MIPS_HIGHEST", /* name */
1286 FALSE, /* partial_inplace */
1288 0x0000ffff, /* dst_mask */
1289 FALSE), /* pcrel_offset */
1291 /* High 16 bits of displacement in global offset table. */
1292 HOWTO (R_MIPS_CALL_HI16, /* type */
1294 2, /* size (0 = byte, 1 = short, 2 = long) */
1296 FALSE, /* pc_relative */
1298 complain_overflow_dont, /* complain_on_overflow */
1299 _bfd_mips_elf_generic_reloc, /* special_function */
1300 "R_MIPS_CALL_HI16", /* name */
1301 FALSE, /* partial_inplace */
1303 0x0000ffff, /* dst_mask */
1304 FALSE), /* pcrel_offset */
1306 /* Low 16 bits of displacement in global offset table. */
1307 HOWTO (R_MIPS_CALL_LO16, /* type */
1309 2, /* size (0 = byte, 1 = short, 2 = long) */
1311 FALSE, /* pc_relative */
1313 complain_overflow_dont, /* complain_on_overflow */
1314 _bfd_mips_elf_generic_reloc, /* special_function */
1315 "R_MIPS_CALL_LO16", /* name */
1316 FALSE, /* partial_inplace */
1318 0x0000ffff, /* dst_mask */
1319 FALSE), /* pcrel_offset */
1321 /* Section displacement, used by an associated event location section. */
1322 HOWTO (R_MIPS_SCN_DISP, /* type */
1324 2, /* size (0 = byte, 1 = short, 2 = long) */
1326 FALSE, /* pc_relative */
1328 complain_overflow_dont, /* complain_on_overflow */
1329 _bfd_mips_elf_generic_reloc, /* special_function */
1330 "R_MIPS_SCN_DISP", /* name */
1331 FALSE, /* partial_inplace */
1333 0xffffffff, /* dst_mask */
1334 FALSE), /* pcrel_offset */
1336 /* 16 bit relocation. */
1337 HOWTO (R_MIPS_REL16, /* type */
1339 1, /* size (0 = byte, 1 = short, 2 = long) */
1341 FALSE, /* pc_relative */
1343 complain_overflow_signed, /* complain_on_overflow */
1344 _bfd_mips_elf_generic_reloc, /* special_function */
1345 "R_MIPS_REL16", /* name */
1346 FALSE, /* partial_inplace */
1348 0xffff, /* dst_mask */
1349 FALSE), /* pcrel_offset */
1351 /* These two are obsolete. */
1352 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1353 EMPTY_HOWTO (R_MIPS_PJUMP),
1355 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1356 It must be used for multigot GOT's (and only there). */
1357 HOWTO (R_MIPS_RELGOT, /* type */
1359 2, /* size (0 = byte, 1 = short, 2 = long) */
1361 FALSE, /* pc_relative */
1363 complain_overflow_dont, /* complain_on_overflow */
1364 _bfd_mips_elf_generic_reloc, /* special_function */
1365 "R_MIPS_RELGOT", /* name */
1366 FALSE, /* partial_inplace */
1368 0xffffffff, /* dst_mask */
1369 FALSE), /* pcrel_offset */
1371 /* Protected jump conversion. This is an optimization hint. No
1372 relocation is required for correctness. */
1373 HOWTO (R_MIPS_JALR, /* type */
1375 2, /* size (0 = byte, 1 = short, 2 = long) */
1377 FALSE, /* pc_relative */
1379 complain_overflow_dont, /* complain_on_overflow */
1380 _bfd_mips_elf_generic_reloc, /* special_function */
1381 "R_MIPS_JALR", /* name */
1382 FALSE, /* partial_inplace */
1385 FALSE), /* pcrel_offset */
1387 /* TLS GD/LD dynamic relocations. */
1388 HOWTO (R_MIPS_TLS_DTPMOD32, /* type */
1390 2, /* size (0 = byte, 1 = short, 2 = long) */
1392 FALSE, /* pc_relative */
1394 complain_overflow_dont, /* complain_on_overflow */
1395 _bfd_mips_elf_generic_reloc, /* special_function */
1396 "R_MIPS_TLS_DTPMOD32", /* name */
1397 FALSE, /* partial_inplace */
1399 0xffffffff, /* dst_mask */
1400 FALSE), /* pcrel_offset */
1402 HOWTO (R_MIPS_TLS_DTPREL32, /* type */
1404 2, /* size (0 = byte, 1 = short, 2 = long) */
1406 FALSE, /* pc_relative */
1408 complain_overflow_dont, /* complain_on_overflow */
1409 _bfd_mips_elf_generic_reloc, /* special_function */
1410 "R_MIPS_TLS_DTPREL32", /* name */
1411 FALSE, /* partial_inplace */
1413 0xffffffff, /* dst_mask */
1414 FALSE), /* pcrel_offset */
1416 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
1417 EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
1419 /* TLS general dynamic variable reference. */
1420 HOWTO (R_MIPS_TLS_GD, /* 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_GD", /* name */
1429 FALSE, /* partial_inplace */
1431 0x0000ffff, /* dst_mask */
1432 FALSE), /* pcrel_offset */
1434 /* TLS local dynamic variable reference. */
1435 HOWTO (R_MIPS_TLS_LDM, /* type */
1437 2, /* size (0 = byte, 1 = short, 2 = long) */
1439 FALSE, /* pc_relative */
1441 complain_overflow_signed, /* complain_on_overflow */
1442 _bfd_mips_elf_generic_reloc, /* special_function */
1443 "R_MIPS_TLS_LDM", /* name */
1444 FALSE, /* partial_inplace */
1446 0x0000ffff, /* dst_mask */
1447 FALSE), /* pcrel_offset */
1449 /* TLS local dynamic offset. */
1450 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
1452 2, /* size (0 = byte, 1 = short, 2 = long) */
1454 FALSE, /* pc_relative */
1456 complain_overflow_signed, /* complain_on_overflow */
1457 _bfd_mips_elf_generic_reloc, /* special_function */
1458 "R_MIPS_TLS_DTPREL_HI16", /* name */
1459 FALSE, /* partial_inplace */
1461 0x0000ffff, /* dst_mask */
1462 FALSE), /* pcrel_offset */
1464 /* TLS local dynamic offset. */
1465 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
1467 2, /* size (0 = byte, 1 = short, 2 = long) */
1469 FALSE, /* pc_relative */
1471 complain_overflow_signed, /* complain_on_overflow */
1472 _bfd_mips_elf_generic_reloc, /* special_function */
1473 "R_MIPS_TLS_DTPREL_LO16", /* name */
1474 FALSE, /* partial_inplace */
1476 0x0000ffff, /* dst_mask */
1477 FALSE), /* pcrel_offset */
1479 /* TLS thread pointer offset. */
1480 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
1482 2, /* size (0 = byte, 1 = short, 2 = long) */
1484 FALSE, /* pc_relative */
1486 complain_overflow_signed, /* complain_on_overflow */
1487 _bfd_mips_elf_generic_reloc, /* special_function */
1488 "R_MIPS_TLS_GOTTPREL", /* name */
1489 FALSE, /* partial_inplace */
1491 0x0000ffff, /* dst_mask */
1492 FALSE), /* pcrel_offset */
1494 /* TLS IE dynamic relocations. */
1495 HOWTO (R_MIPS_TLS_TPREL32, /* type */
1497 2, /* size (0 = byte, 1 = short, 2 = long) */
1499 FALSE, /* pc_relative */
1501 complain_overflow_dont, /* complain_on_overflow */
1502 _bfd_mips_elf_generic_reloc, /* special_function */
1503 "R_MIPS_TLS_TPREL32", /* name */
1504 FALSE, /* partial_inplace */
1506 0xffffffff, /* dst_mask */
1507 FALSE), /* pcrel_offset */
1509 EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
1511 /* TLS thread pointer offset. */
1512 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
1514 2, /* size (0 = byte, 1 = short, 2 = long) */
1516 FALSE, /* pc_relative */
1518 complain_overflow_signed, /* complain_on_overflow */
1519 _bfd_mips_elf_generic_reloc, /* special_function */
1520 "R_MIPS_TLS_TPREL_HI16", /* name */
1521 FALSE, /* partial_inplace */
1523 0x0000ffff, /* dst_mask */
1524 FALSE), /* pcrel_offset */
1526 /* TLS thread pointer offset. */
1527 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
1529 2, /* size (0 = byte, 1 = short, 2 = long) */
1531 FALSE, /* pc_relative */
1533 complain_overflow_signed, /* complain_on_overflow */
1534 _bfd_mips_elf_generic_reloc, /* special_function */
1535 "R_MIPS_TLS_TPREL_LO16", /* name */
1536 FALSE, /* partial_inplace */
1538 0x0000ffff, /* dst_mask */
1539 FALSE), /* pcrel_offset */
1541 /* 32 bit relocation with no addend. */
1542 HOWTO (R_MIPS_GLOB_DAT, /* type */
1544 2, /* size (0 = byte, 1 = short, 2 = long) */
1546 FALSE, /* pc_relative */
1548 complain_overflow_dont, /* complain_on_overflow */
1549 _bfd_mips_elf_generic_reloc, /* special_function */
1550 "R_MIPS_GLOB_DAT", /* name */
1551 FALSE, /* partial_inplace */
1553 0xffffffff, /* dst_mask */
1554 FALSE), /* pcrel_offset */
1565 HOWTO (R_MIPS_PC21_S2, /* type */
1567 2, /* size (0 = byte, 1 = short, 2 = long) */
1569 TRUE, /* pc_relative */
1571 complain_overflow_signed, /* complain_on_overflow */
1572 _bfd_mips_elf_generic_reloc, /* special_function */
1573 "R_MIPS_PC21_S2", /* name */
1574 FALSE, /* partial_inplace */
1576 0x001fffff, /* dst_mask */
1577 TRUE), /* pcrel_offset */
1579 HOWTO (R_MIPS_PC26_S2, /* type */
1581 2, /* size (0 = byte, 1 = short, 2 = long) */
1583 TRUE, /* pc_relative */
1585 complain_overflow_signed, /* complain_on_overflow */
1586 _bfd_mips_elf_generic_reloc, /* special_function */
1587 "R_MIPS_PC26_S2", /* name */
1588 FALSE, /* partial_inplace */
1590 0x03ffffff, /* dst_mask */
1591 TRUE), /* pcrel_offset */
1593 HOWTO (R_MIPS_PC18_S3, /* type */
1595 2, /* size (0 = byte, 1 = short, 2 = long) */
1597 TRUE, /* pc_relative */
1599 complain_overflow_signed, /* complain_on_overflow */
1600 _bfd_mips_elf_generic_reloc, /* special_function */
1601 "R_MIPS_PC18_S3", /* name */
1602 FALSE, /* partial_inplace */
1604 0x0003ffff, /* dst_mask */
1605 TRUE), /* pcrel_offset */
1607 HOWTO (R_MIPS_PC19_S2, /* type */
1609 2, /* size (0 = byte, 1 = short, 2 = long) */
1611 TRUE, /* pc_relative */
1613 complain_overflow_signed, /* complain_on_overflow */
1614 _bfd_mips_elf_generic_reloc, /* special_function */
1615 "R_MIPS_PC19_S2", /* name */
1616 FALSE, /* partial_inplace */
1618 0x0007ffff, /* dst_mask */
1619 TRUE), /* pcrel_offset */
1621 HOWTO (R_MIPS_PCHI16, /* type */
1622 16, /* rightshift */
1623 2, /* size (0 = byte, 1 = short, 2 = long) */
1625 TRUE, /* pc_relative */
1627 complain_overflow_signed, /* complain_on_overflow */
1628 _bfd_mips_elf_generic_reloc, /* special_function */
1629 "R_MIPS_PCHI16", /* name */
1630 FALSE, /* partial_inplace */
1632 0x0000ffff, /* dst_mask */
1633 TRUE), /* pcrel_offset */
1635 HOWTO (R_MIPS_PCLO16, /* type */
1637 2, /* size (0 = byte, 1 = short, 2 = long) */
1639 TRUE, /* pc_relative */
1641 complain_overflow_dont, /* complain_on_overflow */
1642 _bfd_mips_elf_generic_reloc, /* special_function */
1643 "R_MIPS_PCLO16", /* name */
1644 FALSE, /* partial_inplace */
1646 0x0000ffff, /* dst_mask */
1647 TRUE), /* pcrel_offset */
1651 static reloc_howto_type elf_mips16_howto_table_rel[] =
1653 /* The reloc used for the mips16 jump instruction. */
1654 HOWTO (R_MIPS16_26, /* type */
1656 2, /* size (0 = byte, 1 = short, 2 = long) */
1658 FALSE, /* pc_relative */
1660 complain_overflow_dont, /* complain_on_overflow */
1661 /* This needs complex overflow
1662 detection, because the upper four
1663 bits must match the PC. */
1664 _bfd_mips_elf_generic_reloc, /* special_function */
1665 "R_MIPS16_26", /* name */
1666 TRUE, /* partial_inplace */
1667 0x3ffffff, /* src_mask */
1668 0x3ffffff, /* dst_mask */
1669 FALSE), /* pcrel_offset */
1671 /* The reloc used for the mips16 gprel instruction. */
1672 HOWTO (R_MIPS16_GPREL, /* type */
1674 2, /* size (0 = byte, 1 = short, 2 = long) */
1676 FALSE, /* pc_relative */
1678 complain_overflow_signed, /* complain_on_overflow */
1679 mips16_gprel_reloc, /* special_function */
1680 "R_MIPS16_GPREL", /* name */
1681 TRUE, /* partial_inplace */
1682 0x0000ffff, /* src_mask */
1683 0x0000ffff, /* dst_mask */
1684 FALSE), /* pcrel_offset */
1686 /* A MIPS16 reference to the global offset table. */
1687 HOWTO (R_MIPS16_GOT16, /* type */
1689 2, /* size (0 = byte, 1 = short, 2 = long) */
1691 FALSE, /* pc_relative */
1693 complain_overflow_dont, /* complain_on_overflow */
1694 _bfd_mips_elf_got16_reloc, /* special_function */
1695 "R_MIPS16_GOT16", /* name */
1696 TRUE, /* partial_inplace */
1697 0x0000ffff, /* src_mask */
1698 0x0000ffff, /* dst_mask */
1699 FALSE), /* pcrel_offset */
1701 /* A MIPS16 call through the global offset table. */
1702 HOWTO (R_MIPS16_CALL16, /* type */
1704 2, /* size (0 = byte, 1 = short, 2 = long) */
1706 FALSE, /* pc_relative */
1708 complain_overflow_dont, /* complain_on_overflow */
1709 _bfd_mips_elf_generic_reloc, /* special_function */
1710 "R_MIPS16_CALL16", /* name */
1711 TRUE, /* partial_inplace */
1712 0x0000ffff, /* src_mask */
1713 0x0000ffff, /* dst_mask */
1714 FALSE), /* pcrel_offset */
1716 /* MIPS16 high 16 bits of symbol value. */
1717 HOWTO (R_MIPS16_HI16, /* type */
1718 16, /* rightshift */
1719 2, /* size (0 = byte, 1 = short, 2 = long) */
1721 FALSE, /* pc_relative */
1723 complain_overflow_dont, /* complain_on_overflow */
1724 _bfd_mips_elf_hi16_reloc, /* special_function */
1725 "R_MIPS16_HI16", /* name */
1726 TRUE, /* partial_inplace */
1727 0x0000ffff, /* src_mask */
1728 0x0000ffff, /* dst_mask */
1729 FALSE), /* pcrel_offset */
1731 /* MIPS16 low 16 bits of symbol value. */
1732 HOWTO (R_MIPS16_LO16, /* type */
1734 2, /* size (0 = byte, 1 = short, 2 = long) */
1736 FALSE, /* pc_relative */
1738 complain_overflow_dont, /* complain_on_overflow */
1739 _bfd_mips_elf_lo16_reloc, /* special_function */
1740 "R_MIPS16_LO16", /* name */
1741 TRUE, /* partial_inplace */
1742 0x0000ffff, /* src_mask */
1743 0x0000ffff, /* dst_mask */
1744 FALSE), /* pcrel_offset */
1746 /* MIPS16 TLS general dynamic variable reference. */
1747 HOWTO (R_MIPS16_TLS_GD, /* type */
1749 2, /* size (0 = byte, 1 = short, 2 = long) */
1751 FALSE, /* pc_relative */
1753 complain_overflow_signed, /* complain_on_overflow */
1754 _bfd_mips_elf_generic_reloc, /* special_function */
1755 "R_MIPS16_TLS_GD", /* name */
1756 TRUE, /* partial_inplace */
1757 0x0000ffff, /* src_mask */
1758 0x0000ffff, /* dst_mask */
1759 FALSE), /* pcrel_offset */
1761 /* MIPS16 TLS local dynamic variable reference. */
1762 HOWTO (R_MIPS16_TLS_LDM, /* type */
1764 2, /* size (0 = byte, 1 = short, 2 = long) */
1766 FALSE, /* pc_relative */
1768 complain_overflow_signed, /* complain_on_overflow */
1769 _bfd_mips_elf_generic_reloc, /* special_function */
1770 "R_MIPS16_TLS_LDM", /* name */
1771 TRUE, /* partial_inplace */
1772 0x0000ffff, /* src_mask */
1773 0x0000ffff, /* dst_mask */
1774 FALSE), /* pcrel_offset */
1776 /* MIPS16 TLS local dynamic offset. */
1777 HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */
1779 2, /* size (0 = byte, 1 = short, 2 = long) */
1781 FALSE, /* pc_relative */
1783 complain_overflow_signed, /* complain_on_overflow */
1784 _bfd_mips_elf_generic_reloc, /* special_function */
1785 "R_MIPS16_TLS_DTPREL_HI16", /* name */
1786 TRUE, /* partial_inplace */
1787 0x0000ffff, /* src_mask */
1788 0x0000ffff, /* dst_mask */
1789 FALSE), /* pcrel_offset */
1791 /* MIPS16 TLS local dynamic offset. */
1792 HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */
1794 2, /* size (0 = byte, 1 = short, 2 = long) */
1796 FALSE, /* pc_relative */
1798 complain_overflow_signed, /* complain_on_overflow */
1799 _bfd_mips_elf_generic_reloc, /* special_function */
1800 "R_MIPS16_TLS_DTPREL_LO16", /* name */
1801 TRUE, /* partial_inplace */
1802 0x0000ffff, /* src_mask */
1803 0x0000ffff, /* dst_mask */
1804 FALSE), /* pcrel_offset */
1806 /* MIPS16 TLS thread pointer offset. */
1807 HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */
1809 2, /* size (0 = byte, 1 = short, 2 = long) */
1811 FALSE, /* pc_relative */
1813 complain_overflow_signed, /* complain_on_overflow */
1814 _bfd_mips_elf_generic_reloc, /* special_function */
1815 "R_MIPS16_TLS_GOTTPREL", /* name */
1816 TRUE, /* partial_inplace */
1817 0x0000ffff, /* src_mask */
1818 0x0000ffff, /* dst_mask */
1819 FALSE), /* pcrel_offset */
1821 /* MIPS16 TLS thread pointer offset. */
1822 HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */
1824 2, /* size (0 = byte, 1 = short, 2 = long) */
1826 FALSE, /* pc_relative */
1828 complain_overflow_signed, /* complain_on_overflow */
1829 _bfd_mips_elf_generic_reloc, /* special_function */
1830 "R_MIPS16_TLS_TPREL_HI16", /* name */
1831 TRUE, /* partial_inplace */
1832 0x0000ffff, /* src_mask */
1833 0x0000ffff, /* dst_mask */
1834 FALSE), /* pcrel_offset */
1836 /* MIPS16 TLS thread pointer offset. */
1837 HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */
1839 2, /* size (0 = byte, 1 = short, 2 = long) */
1841 FALSE, /* pc_relative */
1843 complain_overflow_signed, /* complain_on_overflow */
1844 _bfd_mips_elf_generic_reloc, /* special_function */
1845 "R_MIPS16_TLS_TPREL_LO16", /* name */
1846 TRUE, /* partial_inplace */
1847 0x0000ffff, /* src_mask */
1848 0x0000ffff, /* dst_mask */
1849 FALSE), /* pcrel_offset */
1852 static reloc_howto_type elf_mips16_howto_table_rela[] =
1854 /* The reloc used for the mips16 jump instruction. */
1855 HOWTO (R_MIPS16_26, /* type */
1857 2, /* size (0 = byte, 1 = short, 2 = long) */
1859 FALSE, /* pc_relative */
1861 complain_overflow_dont, /* complain_on_overflow */
1862 /* This needs complex overflow
1863 detection, because the upper four
1864 bits must match the PC. */
1865 _bfd_mips_elf_generic_reloc, /* special_function */
1866 "R_MIPS16_26", /* name */
1867 FALSE, /* partial_inplace */
1869 0x3ffffff, /* dst_mask */
1870 FALSE), /* pcrel_offset */
1872 /* The reloc used for the mips16 gprel instruction. */
1873 HOWTO (R_MIPS16_GPREL, /* type */
1875 2, /* size (0 = byte, 1 = short, 2 = long) */
1877 FALSE, /* pc_relative */
1879 complain_overflow_signed, /* complain_on_overflow */
1880 mips16_gprel_reloc, /* special_function */
1881 "R_MIPS16_GPREL", /* name */
1882 FALSE, /* partial_inplace */
1884 0x0000ffff, /* dst_mask */
1885 FALSE), /* pcrel_offset */
1887 /* A MIPS16 reference to the global offset table. */
1888 HOWTO (R_MIPS16_GOT16, /* type */
1890 2, /* size (0 = byte, 1 = short, 2 = long) */
1892 FALSE, /* pc_relative */
1894 complain_overflow_dont, /* complain_on_overflow */
1895 _bfd_mips_elf_got16_reloc, /* special_function */
1896 "R_MIPS16_GOT16", /* name */
1897 FALSE, /* partial_inplace */
1899 0x0000ffff, /* dst_mask */
1900 FALSE), /* pcrel_offset */
1902 /* A MIPS16 call through the global offset table. */
1903 HOWTO (R_MIPS16_CALL16, /* type */
1905 2, /* size (0 = byte, 1 = short, 2 = long) */
1907 FALSE, /* pc_relative */
1909 complain_overflow_dont, /* complain_on_overflow */
1910 _bfd_mips_elf_generic_reloc, /* special_function */
1911 "R_MIPS16_CALL16", /* name */
1912 FALSE, /* partial_inplace */
1914 0x0000ffff, /* dst_mask */
1915 FALSE), /* pcrel_offset */
1917 /* MIPS16 high 16 bits of symbol value. */
1918 HOWTO (R_MIPS16_HI16, /* type */
1919 16, /* rightshift */
1920 2, /* size (0 = byte, 1 = short, 2 = long) */
1922 FALSE, /* pc_relative */
1924 complain_overflow_dont, /* complain_on_overflow */
1925 _bfd_mips_elf_hi16_reloc, /* special_function */
1926 "R_MIPS16_HI16", /* name */
1927 FALSE, /* partial_inplace */
1929 0x0000ffff, /* dst_mask */
1930 FALSE), /* pcrel_offset */
1932 /* MIPS16 low 16 bits of symbol value. */
1933 HOWTO (R_MIPS16_LO16, /* type */
1935 2, /* size (0 = byte, 1 = short, 2 = long) */
1937 FALSE, /* pc_relative */
1939 complain_overflow_dont, /* complain_on_overflow */
1940 _bfd_mips_elf_lo16_reloc, /* special_function */
1941 "R_MIPS16_LO16", /* name */
1942 FALSE, /* partial_inplace */
1944 0x0000ffff, /* dst_mask */
1945 FALSE), /* pcrel_offset */
1947 /* MIPS16 TLS general dynamic variable reference. */
1948 HOWTO (R_MIPS16_TLS_GD, /* type */
1950 2, /* size (0 = byte, 1 = short, 2 = long) */
1952 FALSE, /* pc_relative */
1954 complain_overflow_signed, /* complain_on_overflow */
1955 _bfd_mips_elf_generic_reloc, /* special_function */
1956 "R_MIPS16_TLS_GD", /* name */
1957 FALSE, /* partial_inplace */
1959 0x0000ffff, /* dst_mask */
1960 FALSE), /* pcrel_offset */
1962 /* MIPS16 TLS local dynamic variable reference. */
1963 HOWTO (R_MIPS16_TLS_LDM, /* type */
1965 2, /* size (0 = byte, 1 = short, 2 = long) */
1967 FALSE, /* pc_relative */
1969 complain_overflow_signed, /* complain_on_overflow */
1970 _bfd_mips_elf_generic_reloc, /* special_function */
1971 "R_MIPS16_TLS_LDM", /* name */
1972 FALSE, /* partial_inplace */
1974 0x0000ffff, /* dst_mask */
1975 FALSE), /* pcrel_offset */
1977 /* MIPS16 TLS local dynamic offset. */
1978 HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */
1980 2, /* size (0 = byte, 1 = short, 2 = long) */
1982 FALSE, /* pc_relative */
1984 complain_overflow_signed, /* complain_on_overflow */
1985 _bfd_mips_elf_generic_reloc, /* special_function */
1986 "R_MIPS16_TLS_DTPREL_HI16", /* name */
1987 FALSE, /* partial_inplace */
1989 0x0000ffff, /* dst_mask */
1990 FALSE), /* pcrel_offset */
1992 /* MIPS16 TLS local dynamic offset. */
1993 HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */
1995 2, /* size (0 = byte, 1 = short, 2 = long) */
1997 FALSE, /* pc_relative */
1999 complain_overflow_signed, /* complain_on_overflow */
2000 _bfd_mips_elf_generic_reloc, /* special_function */
2001 "R_MIPS16_TLS_DTPREL_LO16", /* name */
2002 FALSE, /* partial_inplace */
2004 0x0000ffff, /* dst_mask */
2005 FALSE), /* pcrel_offset */
2007 /* MIPS16 TLS thread pointer offset. */
2008 HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */
2010 2, /* size (0 = byte, 1 = short, 2 = long) */
2012 FALSE, /* pc_relative */
2014 complain_overflow_signed, /* complain_on_overflow */
2015 _bfd_mips_elf_generic_reloc, /* special_function */
2016 "R_MIPS16_TLS_GOTTPREL", /* name */
2017 FALSE, /* partial_inplace */
2019 0x0000ffff, /* dst_mask */
2020 FALSE), /* pcrel_offset */
2022 /* MIPS16 TLS thread pointer offset. */
2023 HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */
2025 2, /* size (0 = byte, 1 = short, 2 = long) */
2027 FALSE, /* pc_relative */
2029 complain_overflow_signed, /* complain_on_overflow */
2030 _bfd_mips_elf_generic_reloc, /* special_function */
2031 "R_MIPS16_TLS_TPREL_HI16", /* name */
2032 FALSE, /* partial_inplace */
2034 0x0000ffff, /* dst_mask */
2035 FALSE), /* pcrel_offset */
2037 /* MIPS16 TLS thread pointer offset. */
2038 HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */
2040 2, /* size (0 = byte, 1 = short, 2 = long) */
2042 FALSE, /* pc_relative */
2044 complain_overflow_signed, /* complain_on_overflow */
2045 _bfd_mips_elf_generic_reloc, /* special_function */
2046 "R_MIPS16_TLS_TPREL_LO16", /* name */
2047 FALSE, /* partial_inplace */
2049 0x0000ffff, /* dst_mask */
2050 FALSE), /* pcrel_offset */
2053 static reloc_howto_type elf_micromips_howto_table_rel[] =
2059 /* 26 bit jump address. */
2060 HOWTO (R_MICROMIPS_26_S1, /* type */
2062 2, /* size (0 = byte, 1 = short, 2 = long) */
2064 FALSE, /* pc_relative */
2066 complain_overflow_dont, /* complain_on_overflow */
2067 /* This needs complex overflow
2068 detection, because the upper four
2069 bits must match the PC. */
2070 _bfd_mips_elf_generic_reloc, /* special_function */
2071 "R_MICROMIPS_26_S1", /* name */
2072 TRUE, /* partial_inplace */
2073 0x3ffffff, /* src_mask */
2074 0x3ffffff, /* dst_mask */
2075 FALSE), /* pcrel_offset */
2077 /* High 16 bits of symbol value. */
2078 HOWTO (R_MICROMIPS_HI16, /* type */
2079 16, /* rightshift */
2080 2, /* size (0 = byte, 1 = short, 2 = long) */
2082 FALSE, /* pc_relative */
2084 complain_overflow_dont, /* complain_on_overflow */
2085 _bfd_mips_elf_hi16_reloc, /* special_function */
2086 "R_MICROMIPS_HI16", /* name */
2087 TRUE, /* partial_inplace */
2088 0x0000ffff, /* src_mask */
2089 0x0000ffff, /* dst_mask */
2090 FALSE), /* pcrel_offset */
2092 /* Low 16 bits of symbol value. */
2093 HOWTO (R_MICROMIPS_LO16, /* type */
2095 2, /* size (0 = byte, 1 = short, 2 = long) */
2097 FALSE, /* pc_relative */
2099 complain_overflow_dont, /* complain_on_overflow */
2100 _bfd_mips_elf_lo16_reloc, /* special_function */
2101 "R_MICROMIPS_LO16", /* name */
2102 TRUE, /* partial_inplace */
2103 0x0000ffff, /* src_mask */
2104 0x0000ffff, /* dst_mask */
2105 FALSE), /* pcrel_offset */
2107 /* GP relative reference. */
2108 HOWTO (R_MICROMIPS_GPREL16, /* type */
2110 2, /* size (0 = byte, 1 = short, 2 = long) */
2112 FALSE, /* pc_relative */
2114 complain_overflow_signed, /* complain_on_overflow */
2115 _bfd_mips_elf32_gprel16_reloc, /* special_function */
2116 "R_MICROMIPS_GPREL16", /* name */
2117 TRUE, /* partial_inplace */
2118 0x0000ffff, /* src_mask */
2119 0x0000ffff, /* dst_mask */
2120 FALSE), /* pcrel_offset */
2122 /* Reference to literal section. */
2123 HOWTO (R_MICROMIPS_LITERAL, /* type */
2125 2, /* size (0 = byte, 1 = short, 2 = long) */
2127 FALSE, /* pc_relative */
2129 complain_overflow_signed, /* complain_on_overflow */
2130 _bfd_mips_elf32_gprel16_reloc, /* special_function */
2131 "R_MICROMIPS_LITERAL", /* name */
2132 TRUE, /* partial_inplace */
2133 0x0000ffff, /* src_mask */
2134 0x0000ffff, /* dst_mask */
2135 FALSE), /* pcrel_offset */
2137 /* Reference to global offset table. */
2138 HOWTO (R_MICROMIPS_GOT16, /* type */
2140 2, /* size (0 = byte, 1 = short, 2 = long) */
2142 FALSE, /* pc_relative */
2144 complain_overflow_signed, /* complain_on_overflow */
2145 _bfd_mips_elf_got16_reloc, /* special_function */
2146 "R_MICROMIPS_GOT16", /* name */
2147 TRUE, /* partial_inplace */
2148 0x0000ffff, /* src_mask */
2149 0x0000ffff, /* dst_mask */
2150 FALSE), /* pcrel_offset */
2152 /* This is for microMIPS branches. */
2153 HOWTO (R_MICROMIPS_PC7_S1, /* type */
2155 1, /* size (0 = byte, 1 = short, 2 = long) */
2157 TRUE, /* pc_relative */
2159 complain_overflow_signed, /* complain_on_overflow */
2160 _bfd_mips_elf_generic_reloc, /* special_function */
2161 "R_MICROMIPS_PC7_S1", /* name */
2162 TRUE, /* partial_inplace */
2163 0x0000007f, /* src_mask */
2164 0x0000007f, /* dst_mask */
2165 TRUE), /* pcrel_offset */
2167 HOWTO (R_MICROMIPS_PC10_S1, /* type */
2169 1, /* size (0 = byte, 1 = short, 2 = long) */
2171 TRUE, /* pc_relative */
2173 complain_overflow_signed, /* complain_on_overflow */
2174 _bfd_mips_elf_generic_reloc, /* special_function */
2175 "R_MICROMIPS_PC10_S1", /* name */
2176 TRUE, /* partial_inplace */
2177 0x000003ff, /* src_mask */
2178 0x000003ff, /* dst_mask */
2179 TRUE), /* pcrel_offset */
2181 HOWTO (R_MICROMIPS_PC16_S1, /* type */
2183 2, /* size (0 = byte, 1 = short, 2 = long) */
2185 TRUE, /* pc_relative */
2187 complain_overflow_signed, /* complain_on_overflow */
2188 _bfd_mips_elf_generic_reloc, /* special_function */
2189 "R_MICROMIPS_PC16_S1", /* name */
2190 TRUE, /* partial_inplace */
2191 0x0000ffff, /* src_mask */
2192 0x0000ffff, /* dst_mask */
2193 TRUE), /* pcrel_offset */
2195 /* 16 bit call through global offset table. */
2196 HOWTO (R_MICROMIPS_CALL16, /* type */
2198 2, /* size (0 = byte, 1 = short, 2 = long) */
2200 FALSE, /* pc_relative */
2202 complain_overflow_signed, /* complain_on_overflow */
2203 _bfd_mips_elf_generic_reloc, /* special_function */
2204 "R_MICROMIPS_CALL16", /* name */
2205 TRUE, /* partial_inplace */
2206 0x0000ffff, /* src_mask */
2207 0x0000ffff, /* dst_mask */
2208 FALSE), /* pcrel_offset */
2213 /* Displacement in the global offset table. */
2214 HOWTO (R_MICROMIPS_GOT_DISP, /* type */
2216 2, /* size (0 = byte, 1 = short, 2 = long) */
2218 FALSE, /* pc_relative */
2220 complain_overflow_signed, /* complain_on_overflow */
2221 _bfd_mips_elf_generic_reloc, /* special_function */
2222 "R_MICROMIPS_GOT_DISP",/* name */
2223 TRUE, /* partial_inplace */
2224 0x0000ffff, /* src_mask */
2225 0x0000ffff, /* dst_mask */
2226 FALSE), /* pcrel_offset */
2228 /* Displacement to page pointer in the global offset table. */
2229 HOWTO (R_MICROMIPS_GOT_PAGE, /* type */
2231 2, /* size (0 = byte, 1 = short, 2 = long) */
2233 FALSE, /* pc_relative */
2235 complain_overflow_signed, /* complain_on_overflow */
2236 _bfd_mips_elf_generic_reloc, /* special_function */
2237 "R_MICROMIPS_GOT_PAGE",/* name */
2238 TRUE, /* partial_inplace */
2239 0x0000ffff, /* src_mask */
2240 0x0000ffff, /* dst_mask */
2241 FALSE), /* pcrel_offset */
2243 /* Offset from page pointer in the global offset table. */
2244 HOWTO (R_MICROMIPS_GOT_OFST, /* type */
2246 2, /* size (0 = byte, 1 = short, 2 = long) */
2248 FALSE, /* pc_relative */
2250 complain_overflow_signed, /* complain_on_overflow */
2251 _bfd_mips_elf_generic_reloc, /* special_function */
2252 "R_MICROMIPS_GOT_OFST",/* name */
2253 TRUE, /* partial_inplace */
2254 0x0000ffff, /* src_mask */
2255 0x0000ffff, /* dst_mask */
2256 FALSE), /* pcrel_offset */
2258 /* High 16 bits of displacement in global offset table. */
2259 HOWTO (R_MICROMIPS_GOT_HI16, /* type */
2261 2, /* size (0 = byte, 1 = short, 2 = long) */
2263 FALSE, /* pc_relative */
2265 complain_overflow_dont, /* complain_on_overflow */
2266 _bfd_mips_elf_generic_reloc, /* special_function */
2267 "R_MICROMIPS_GOT_HI16",/* name */
2268 TRUE, /* partial_inplace */
2269 0x0000ffff, /* src_mask */
2270 0x0000ffff, /* dst_mask */
2271 FALSE), /* pcrel_offset */
2273 /* Low 16 bits of displacement in global offset table. */
2274 HOWTO (R_MICROMIPS_GOT_LO16, /* type */
2276 2, /* size (0 = byte, 1 = short, 2 = long) */
2278 FALSE, /* pc_relative */
2280 complain_overflow_dont, /* complain_on_overflow */
2281 _bfd_mips_elf_generic_reloc, /* special_function */
2282 "R_MICROMIPS_GOT_LO16",/* name */
2283 TRUE, /* partial_inplace */
2284 0x0000ffff, /* src_mask */
2285 0x0000ffff, /* dst_mask */
2286 FALSE), /* pcrel_offset */
2288 /* 64 bit subtraction. Used in the N32 ABI. */
2289 HOWTO (R_MICROMIPS_SUB, /* type */
2291 4, /* size (0 = byte, 1 = short, 2 = long) */
2293 FALSE, /* pc_relative */
2295 complain_overflow_dont, /* complain_on_overflow */
2296 _bfd_mips_elf_generic_reloc, /* special_function */
2297 "R_MICROMIPS_SUB", /* name */
2298 TRUE, /* partial_inplace */
2299 MINUS_ONE, /* src_mask */
2300 MINUS_ONE, /* dst_mask */
2301 FALSE), /* pcrel_offset */
2303 /* We don't support these for REL relocations, because it means building
2304 the addend from a R_MICROMIPS_HIGHEST/R_MICROMIPS_HIGHER/
2305 R_MICROMIPS_HI16/R_MICROMIPS_LO16 sequence with varying ordering,
2306 using fallable heuristics. */
2307 EMPTY_HOWTO (R_MICROMIPS_HIGHER),
2308 EMPTY_HOWTO (R_MICROMIPS_HIGHEST),
2310 /* High 16 bits of displacement in global offset table. */
2311 HOWTO (R_MICROMIPS_CALL_HI16, /* type */
2313 2, /* size (0 = byte, 1 = short, 2 = long) */
2315 FALSE, /* pc_relative */
2317 complain_overflow_dont, /* complain_on_overflow */
2318 _bfd_mips_elf_generic_reloc, /* special_function */
2319 "R_MICROMIPS_CALL_HI16",/* name */
2320 TRUE, /* partial_inplace */
2321 0x0000ffff, /* src_mask */
2322 0x0000ffff, /* dst_mask */
2323 FALSE), /* pcrel_offset */
2325 /* Low 16 bits of displacement in global offset table. */
2326 HOWTO (R_MICROMIPS_CALL_LO16, /* type */
2328 2, /* size (0 = byte, 1 = short, 2 = long) */
2330 FALSE, /* pc_relative */
2332 complain_overflow_dont, /* complain_on_overflow */
2333 _bfd_mips_elf_generic_reloc, /* special_function */
2334 "R_MICROMIPS_CALL_LO16",/* name */
2335 TRUE, /* partial_inplace */
2336 0x0000ffff, /* src_mask */
2337 0x0000ffff, /* dst_mask */
2338 FALSE), /* pcrel_offset */
2340 /* Section displacement. */
2341 HOWTO (R_MICROMIPS_SCN_DISP, /* type */
2343 2, /* size (0 = byte, 1 = short, 2 = long) */
2345 FALSE, /* pc_relative */
2347 complain_overflow_dont, /* complain_on_overflow */
2348 _bfd_mips_elf_generic_reloc, /* special_function */
2349 "R_MICROMIPS_SCN_DISP", /* name */
2350 TRUE, /* partial_inplace */
2351 0xffffffff, /* src_mask */
2352 0xffffffff, /* dst_mask */
2353 FALSE), /* pcrel_offset */
2355 /* Protected jump conversion. This is an optimization hint. No
2356 relocation is required for correctness. */
2357 HOWTO (R_MICROMIPS_JALR, /* type */
2359 2, /* size (0 = byte, 1 = short, 2 = long) */
2361 FALSE, /* pc_relative */
2363 complain_overflow_dont, /* complain_on_overflow */
2364 _bfd_mips_elf_generic_reloc, /* special_function */
2365 "R_MICROMIPS_JALR", /* name */
2366 FALSE, /* partial_inplace */
2368 0x00000000, /* dst_mask */
2369 FALSE), /* pcrel_offset */
2372 static reloc_howto_type elf_micromips_howto_table_rela[] =
2378 /* 26 bit jump address. */
2379 HOWTO (R_MICROMIPS_26_S1, /* type */
2381 2, /* size (0 = byte, 1 = short, 2 = long) */
2383 FALSE, /* pc_relative */
2385 complain_overflow_dont, /* complain_on_overflow */
2386 /* This needs complex overflow
2387 detection, because the upper four
2388 bits must match the PC. */
2389 _bfd_mips_elf_generic_reloc, /* special_function */
2390 "R_MICROMIPS_26_S1", /* name */
2391 FALSE, /* partial_inplace */
2393 0x3ffffff, /* dst_mask */
2394 FALSE), /* pcrel_offset */
2396 /* High 16 bits of symbol value. */
2397 HOWTO (R_MICROMIPS_HI16, /* type */
2398 16, /* rightshift */
2399 2, /* size (0 = byte, 1 = short, 2 = long) */
2401 FALSE, /* pc_relative */
2403 complain_overflow_dont, /* complain_on_overflow */
2404 _bfd_mips_elf_hi16_reloc, /* special_function */
2405 "R_MICROMIPS_HI16", /* name */
2406 FALSE, /* partial_inplace */
2408 0x0000ffff, /* dst_mask */
2409 FALSE), /* pcrel_offset */
2411 /* Low 16 bits of symbol value. */
2412 HOWTO (R_MICROMIPS_LO16, /* type */
2414 2, /* size (0 = byte, 1 = short, 2 = long) */
2416 FALSE, /* pc_relative */
2418 complain_overflow_dont, /* complain_on_overflow */
2419 _bfd_mips_elf_lo16_reloc, /* special_function */
2420 "R_MICROMIPS_LO16", /* name */
2421 FALSE, /* partial_inplace */
2423 0x0000ffff, /* dst_mask */
2424 FALSE), /* pcrel_offset */
2426 /* GP relative reference. */
2427 HOWTO (R_MICROMIPS_GPREL16, /* type */
2429 2, /* size (0 = byte, 1 = short, 2 = long) */
2431 FALSE, /* pc_relative */
2433 complain_overflow_signed, /* complain_on_overflow */
2434 _bfd_mips_elf32_gprel16_reloc, /* special_function */
2435 "R_MICROMIPS_GPREL16", /* name */
2436 FALSE, /* partial_inplace */
2438 0x0000ffff, /* dst_mask */
2439 FALSE), /* pcrel_offset */
2441 /* Reference to literal section. */
2442 HOWTO (R_MICROMIPS_LITERAL, /* type */
2444 2, /* size (0 = byte, 1 = short, 2 = long) */
2446 FALSE, /* pc_relative */
2448 complain_overflow_signed, /* complain_on_overflow */
2449 _bfd_mips_elf32_gprel16_reloc, /* special_function */
2450 "R_MICROMIPS_LITERAL", /* name */
2451 FALSE, /* partial_inplace */
2453 0x0000ffff, /* dst_mask */
2454 FALSE), /* pcrel_offset */
2456 /* Reference to global offset table. */
2457 HOWTO (R_MICROMIPS_GOT16, /* type */
2459 2, /* size (0 = byte, 1 = short, 2 = long) */
2461 FALSE, /* pc_relative */
2463 complain_overflow_signed, /* complain_on_overflow */
2464 _bfd_mips_elf_got16_reloc, /* special_function */
2465 "R_MICROMIPS_GOT16", /* name */
2466 FALSE, /* partial_inplace */
2468 0x0000ffff, /* dst_mask */
2469 FALSE), /* pcrel_offset */
2471 /* This is for microMIPS branches. */
2472 HOWTO (R_MICROMIPS_PC7_S1, /* type */
2474 1, /* size (0 = byte, 1 = short, 2 = long) */
2476 TRUE, /* pc_relative */
2478 complain_overflow_signed, /* complain_on_overflow */
2479 _bfd_mips_elf_generic_reloc, /* special_function */
2480 "R_MICROMIPS_PC7_S1", /* name */
2481 FALSE, /* partial_inplace */
2483 0x0000007f, /* dst_mask */
2484 TRUE), /* pcrel_offset */
2486 HOWTO (R_MICROMIPS_PC10_S1, /* type */
2488 1, /* size (0 = byte, 1 = short, 2 = long) */
2490 TRUE, /* pc_relative */
2492 complain_overflow_signed, /* complain_on_overflow */
2493 _bfd_mips_elf_generic_reloc, /* special_function */
2494 "R_MICROMIPS_PC10_S1", /* name */
2495 FALSE, /* partial_inplace */
2497 0x000003ff, /* dst_mask */
2498 TRUE), /* pcrel_offset */
2500 HOWTO (R_MICROMIPS_PC16_S1, /* type */
2502 2, /* size (0 = byte, 1 = short, 2 = long) */
2504 TRUE, /* pc_relative */
2506 complain_overflow_signed, /* complain_on_overflow */
2507 _bfd_mips_elf_generic_reloc, /* special_function */
2508 "R_MICROMIPS_PC16_S1", /* name */
2509 FALSE, /* partial_inplace */
2511 0x0000ffff, /* dst_mask */
2512 TRUE), /* pcrel_offset */
2514 /* 16 bit call through global offset table. */
2515 HOWTO (R_MICROMIPS_CALL16, /* type */
2517 2, /* size (0 = byte, 1 = short, 2 = long) */
2519 FALSE, /* pc_relative */
2521 complain_overflow_signed, /* complain_on_overflow */
2522 _bfd_mips_elf_generic_reloc, /* special_function */
2523 "R_MICROMIPS_CALL16", /* name */
2524 FALSE, /* partial_inplace */
2526 0x0000ffff, /* dst_mask */
2527 FALSE), /* pcrel_offset */
2532 /* Displacement in the global offset table. */
2533 HOWTO (R_MICROMIPS_GOT_DISP, /* type */
2535 2, /* size (0 = byte, 1 = short, 2 = long) */
2537 FALSE, /* pc_relative */
2539 complain_overflow_signed, /* complain_on_overflow */
2540 _bfd_mips_elf_generic_reloc, /* special_function */
2541 "R_MICROMIPS_GOT_DISP",/* name */
2542 FALSE, /* partial_inplace */
2544 0x0000ffff, /* dst_mask */
2545 FALSE), /* pcrel_offset */
2547 /* Displacement to page pointer in the global offset table. */
2548 HOWTO (R_MICROMIPS_GOT_PAGE, /* type */
2550 2, /* size (0 = byte, 1 = short, 2 = long) */
2552 FALSE, /* pc_relative */
2554 complain_overflow_signed, /* complain_on_overflow */
2555 _bfd_mips_elf_generic_reloc, /* special_function */
2556 "R_MICROMIPS_GOT_PAGE",/* name */
2557 FALSE, /* partial_inplace */
2559 0x0000ffff, /* dst_mask */
2560 FALSE), /* pcrel_offset */
2562 /* Offset from page pointer in the global offset table. */
2563 HOWTO (R_MICROMIPS_GOT_OFST, /* type */
2565 2, /* size (0 = byte, 1 = short, 2 = long) */
2567 FALSE, /* pc_relative */
2569 complain_overflow_signed, /* complain_on_overflow */
2570 _bfd_mips_elf_generic_reloc, /* special_function */
2571 "R_MICROMIPS_GOT_OFST",/* name */
2572 FALSE, /* partial_inplace */
2574 0x0000ffff, /* dst_mask */
2575 FALSE), /* pcrel_offset */
2577 /* High 16 bits of displacement in global offset table. */
2578 HOWTO (R_MICROMIPS_GOT_HI16, /* type */
2580 2, /* size (0 = byte, 1 = short, 2 = long) */
2582 FALSE, /* pc_relative */
2584 complain_overflow_dont, /* complain_on_overflow */
2585 _bfd_mips_elf_generic_reloc, /* special_function */
2586 "R_MICROMIPS_GOT_HI16",/* name */
2587 FALSE, /* partial_inplace */
2589 0x0000ffff, /* dst_mask */
2590 FALSE), /* pcrel_offset */
2592 /* Low 16 bits of displacement in global offset table. */
2593 HOWTO (R_MICROMIPS_GOT_LO16, /* type */
2595 2, /* size (0 = byte, 1 = short, 2 = long) */
2597 FALSE, /* pc_relative */
2599 complain_overflow_dont, /* complain_on_overflow */
2600 _bfd_mips_elf_generic_reloc, /* special_function */
2601 "R_MICROMIPS_GOT_LO16",/* name */
2602 FALSE, /* partial_inplace */
2604 0x0000ffff, /* dst_mask */
2605 FALSE), /* pcrel_offset */
2607 /* 64 bit subtraction. Used in the N32 ABI. */
2608 HOWTO (R_MICROMIPS_SUB, /* type */
2610 4, /* size (0 = byte, 1 = short, 2 = long) */
2612 FALSE, /* pc_relative */
2614 complain_overflow_dont, /* complain_on_overflow */
2615 _bfd_mips_elf_generic_reloc, /* special_function */
2616 "R_MICROMIPS_SUB", /* name */
2617 FALSE, /* partial_inplace */
2619 MINUS_ONE, /* dst_mask */
2620 FALSE), /* pcrel_offset */
2622 /* Get the higher value of a 64 bit addend. */
2623 HOWTO (R_MICROMIPS_HIGHER, /* type */
2625 2, /* size (0 = byte, 1 = short, 2 = long) */
2627 FALSE, /* pc_relative */
2629 complain_overflow_dont, /* complain_on_overflow */
2630 _bfd_mips_elf_generic_reloc, /* special_function */
2631 "R_MICROMIPS_HIGHER", /* name */
2632 FALSE, /* partial_inplace */
2634 0x0000ffff, /* dst_mask */
2635 FALSE), /* pcrel_offset */
2637 /* Get the highest value of a 64 bit addend. */
2638 HOWTO (R_MICROMIPS_HIGHEST, /* type */
2640 2, /* size (0 = byte, 1 = short, 2 = long) */
2642 FALSE, /* pc_relative */
2644 complain_overflow_dont, /* complain_on_overflow */
2645 _bfd_mips_elf_generic_reloc, /* special_function */
2646 "R_MICROMIPS_HIGHEST", /* name */
2647 FALSE, /* partial_inplace */
2649 0x0000ffff, /* dst_mask */
2650 FALSE), /* pcrel_offset */
2652 /* High 16 bits of displacement in global offset table. */
2653 HOWTO (R_MICROMIPS_CALL_HI16, /* type */
2655 2, /* size (0 = byte, 1 = short, 2 = long) */
2657 FALSE, /* pc_relative */
2659 complain_overflow_dont, /* complain_on_overflow */
2660 _bfd_mips_elf_generic_reloc, /* special_function */
2661 "R_MICROMIPS_CALL_HI16",/* name */
2662 FALSE, /* partial_inplace */
2664 0x0000ffff, /* dst_mask */
2665 FALSE), /* pcrel_offset */
2667 /* Low 16 bits of displacement in global offset table. */
2668 HOWTO (R_MICROMIPS_CALL_LO16, /* type */
2670 2, /* size (0 = byte, 1 = short, 2 = long) */
2672 FALSE, /* pc_relative */
2674 complain_overflow_dont, /* complain_on_overflow */
2675 _bfd_mips_elf_generic_reloc, /* special_function */
2676 "R_MICROMIPS_CALL_LO16",/* name */
2677 FALSE, /* partial_inplace */
2679 0x0000ffff, /* dst_mask */
2680 FALSE), /* pcrel_offset */
2682 /* Section displacement. */
2683 HOWTO (R_MICROMIPS_SCN_DISP, /* type */
2685 2, /* size (0 = byte, 1 = short, 2 = long) */
2687 FALSE, /* pc_relative */
2689 complain_overflow_dont, /* complain_on_overflow */
2690 _bfd_mips_elf_generic_reloc, /* special_function */
2691 "R_MICROMIPS_SCN_DISP", /* name */
2692 FALSE, /* partial_inplace */
2694 0xffffffff, /* dst_mask */
2695 FALSE), /* pcrel_offset */
2697 /* Protected jump conversion. This is an optimization hint. No
2698 relocation is required for correctness. */
2699 HOWTO (R_MICROMIPS_JALR, /* type */
2701 2, /* size (0 = byte, 1 = short, 2 = long) */
2703 FALSE, /* pc_relative */
2705 complain_overflow_dont, /* complain_on_overflow */
2706 _bfd_mips_elf_generic_reloc, /* special_function */
2707 "R_MICROMIPS_JALR", /* name */
2708 FALSE, /* partial_inplace */
2710 0x00000000, /* dst_mask */
2711 FALSE), /* pcrel_offset */
2714 /* GNU extension to record C++ vtable hierarchy */
2715 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
2716 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
2718 2, /* size (0 = byte, 1 = short, 2 = long) */
2720 FALSE, /* pc_relative */
2722 complain_overflow_dont, /* complain_on_overflow */
2723 NULL, /* special_function */
2724 "R_MIPS_GNU_VTINHERIT", /* name */
2725 FALSE, /* partial_inplace */
2728 FALSE); /* pcrel_offset */
2730 /* GNU extension to record C++ vtable member usage */
2731 static reloc_howto_type elf_mips_gnu_vtentry_howto =
2732 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
2734 2, /* size (0 = byte, 1 = short, 2 = long) */
2736 FALSE, /* pc_relative */
2738 complain_overflow_dont, /* complain_on_overflow */
2739 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
2740 "R_MIPS_GNU_VTENTRY", /* name */
2741 FALSE, /* partial_inplace */
2744 FALSE); /* pcrel_offset */
2746 /* 16 bit offset for pc-relative branches. */
2747 static reloc_howto_type elf_mips_gnu_rel16_s2 =
2748 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
2750 2, /* size (0 = byte, 1 = short, 2 = long) */
2752 TRUE, /* pc_relative */
2754 complain_overflow_signed, /* complain_on_overflow */
2755 _bfd_mips_elf_generic_reloc, /* special_function */
2756 "R_MIPS_GNU_REL16_S2", /* name */
2757 TRUE, /* partial_inplace */
2758 0x0000ffff, /* src_mask */
2759 0x0000ffff, /* dst_mask */
2760 TRUE); /* pcrel_offset */
2762 /* 16 bit offset for pc-relative branches. */
2763 static reloc_howto_type elf_mips_gnu_rela16_s2 =
2764 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
2766 2, /* size (0 = byte, 1 = short, 2 = long) */
2768 TRUE, /* pc_relative */
2770 complain_overflow_signed, /* complain_on_overflow */
2771 _bfd_mips_elf_generic_reloc, /* special_function */
2772 "R_MIPS_GNU_REL16_S2", /* name */
2773 FALSE, /* partial_inplace */
2775 0x0000ffff, /* dst_mask */
2776 TRUE); /* pcrel_offset */
2778 /* 32 bit pc-relative. Used for compact EH tables. */
2779 static reloc_howto_type elf_mips_gnu_pcrel32 =
2780 HOWTO (R_MIPS_PC32, /* type */
2782 2, /* size (0 = byte, 1 = short, 2 = long) */
2784 TRUE, /* pc_relative */
2786 complain_overflow_signed, /* complain_on_overflow */
2787 _bfd_mips_elf_generic_reloc, /* special_function */
2788 "R_MIPS_PC32", /* name */
2789 TRUE, /* partial_inplace */
2790 0xffffffff, /* src_mask */
2791 0xffffffff, /* dst_mask */
2792 TRUE); /* pcrel_offset */
2795 /* Originally a VxWorks extension, but now used for other systems too. */
2796 static reloc_howto_type elf_mips_copy_howto =
2797 HOWTO (R_MIPS_COPY, /* type */
2799 0, /* this one is variable size */
2801 FALSE, /* pc_relative */
2803 complain_overflow_bitfield, /* complain_on_overflow */
2804 _bfd_mips_elf_generic_reloc, /* special_function */
2805 "R_MIPS_COPY", /* name */
2806 FALSE, /* partial_inplace */
2809 FALSE); /* pcrel_offset */
2811 /* Originally a VxWorks extension, but now used for other systems too. */
2812 static reloc_howto_type elf_mips_jump_slot_howto =
2813 HOWTO (R_MIPS_JUMP_SLOT, /* type */
2815 2, /* size (0 = byte, 1 = short, 2 = long) */
2817 FALSE, /* pc_relative */
2819 complain_overflow_bitfield, /* complain_on_overflow */
2820 _bfd_mips_elf_generic_reloc, /* special_function */
2821 "R_MIPS_JUMP_SLOT", /* name */
2822 FALSE, /* partial_inplace */
2825 FALSE); /* pcrel_offset */
2827 /* Used in EH tables. */
2828 static reloc_howto_type elf_mips_eh_howto =
2829 HOWTO (R_MIPS_EH, /* type */
2831 2, /* size (0 = byte, 1 = short, 2 = long) */
2833 FALSE, /* pc_relative */
2835 complain_overflow_signed, /* complain_on_overflow */
2836 _bfd_mips_elf_generic_reloc, /* special_function */
2837 "R_MIPS_EH", /* name */
2838 TRUE, /* partial_inplace */
2839 0xffffffff, /* src_mask */
2840 0xffffffff, /* dst_mask */
2841 FALSE); /* pcrel_offset */
2844 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
2845 dangerous relocation. */
2848 mips_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
2854 /* If we've already figured out what GP will be, just return it. */
2855 *pgp = _bfd_get_gp_value (output_bfd);
2859 count = bfd_get_symcount (output_bfd);
2860 sym = bfd_get_outsymbols (output_bfd);
2862 /* The linker script will have created a symbol named `_gp' with the
2863 appropriate value. */
2868 for (i = 0; i < count; i++, sym++)
2870 register const char *name;
2872 name = bfd_asymbol_name (*sym);
2873 if (*name == '_' && strcmp (name, "_gp") == 0)
2875 *pgp = bfd_asymbol_value (*sym);
2876 _bfd_set_gp_value (output_bfd, *pgp);
2884 /* Only get the error once. */
2886 _bfd_set_gp_value (output_bfd, *pgp);
2893 /* We have to figure out the gp value, so that we can adjust the
2894 symbol value correctly. We look up the symbol _gp in the output
2895 BFD. If we can't find it, we're stuck. We cache it in the ELF
2896 target data. We don't need to adjust the symbol value for an
2897 external symbol if we are producing relocatable output. */
2899 static bfd_reloc_status_type
2900 mips_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
2901 char **error_message, bfd_vma *pgp)
2903 if (bfd_is_und_section (symbol->section)
2907 return bfd_reloc_undefined;
2910 *pgp = _bfd_get_gp_value (output_bfd);
2913 || (symbol->flags & BSF_SECTION_SYM) != 0))
2917 /* Make up a value. */
2918 *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
2919 _bfd_set_gp_value (output_bfd, *pgp);
2921 else if (!mips_elf_assign_gp (output_bfd, pgp))
2924 (char *) _("GP relative relocation when _gp not defined");
2925 return bfd_reloc_dangerous;
2929 return bfd_reloc_ok;
2932 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
2933 become the offset from the gp register. */
2935 static bfd_reloc_status_type
2936 mips_elf_gprel16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
2937 asymbol *symbol, void *data ATTRIBUTE_UNUSED,
2938 asection *input_section, bfd *output_bfd,
2939 char **error_message ATTRIBUTE_UNUSED)
2941 bfd_boolean relocatable;
2942 bfd_reloc_status_type ret;
2945 if (output_bfd != NULL)
2949 relocatable = FALSE;
2950 output_bfd = symbol->section->output_section->owner;
2953 ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
2955 if (ret != bfd_reloc_ok)
2958 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2959 input_section, relocatable,
2963 /* Do a R_MIPS_LITERAL relocation. */
2965 static bfd_reloc_status_type
2966 mips_elf_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2967 void *data, asection *input_section, bfd *output_bfd,
2968 char **error_message)
2970 bfd_boolean relocatable;
2971 bfd_reloc_status_type ret;
2974 /* R_MIPS_LITERAL relocations are defined for local symbols only. */
2975 if (output_bfd != NULL
2976 && (symbol->flags & BSF_SECTION_SYM) == 0
2977 && (symbol->flags & BSF_LOCAL) != 0)
2979 *error_message = (char *)
2980 _("literal relocation occurs for an external symbol");
2981 return bfd_reloc_outofrange;
2984 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
2985 if (output_bfd != NULL)
2989 relocatable = FALSE;
2990 output_bfd = symbol->section->output_section->owner;
2993 ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
2995 if (ret != bfd_reloc_ok)
2998 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2999 input_section, relocatable,
3003 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
3004 become the offset from the gp register. */
3006 static bfd_reloc_status_type
3007 mips_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3008 void *data, asection *input_section, bfd *output_bfd,
3009 char **error_message)
3011 bfd_boolean relocatable;
3012 bfd_reloc_status_type ret;
3015 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
3016 if (output_bfd != NULL
3017 && (symbol->flags & BSF_SECTION_SYM) == 0
3018 && (symbol->flags & BSF_LOCAL) != 0)
3020 *error_message = (char *)
3021 _("32bits gp relative relocation occurs for an external symbol");
3022 return bfd_reloc_outofrange;
3025 if (output_bfd != NULL)
3028 gp = _bfd_get_gp_value (output_bfd);
3032 relocatable = FALSE;
3033 output_bfd = symbol->section->output_section->owner;
3035 ret = mips_elf_final_gp (output_bfd, symbol, relocatable,
3036 error_message, &gp);
3037 if (ret != bfd_reloc_ok)
3041 return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
3042 relocatable, data, gp);
3045 static bfd_reloc_status_type
3046 gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
3047 asection *input_section, bfd_boolean relocatable,
3048 void *data, bfd_vma gp)
3053 if (bfd_is_com_section (symbol->section))
3056 relocation = symbol->value;
3058 relocation += symbol->section->output_section->vma;
3059 relocation += symbol->section->output_offset;
3061 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
3062 return bfd_reloc_outofrange;
3064 if (reloc_entry->howto->src_mask == 0)
3067 val = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
3069 /* Set val to the offset into the section or symbol. */
3070 val += reloc_entry->addend;
3072 /* Adjust val for the final section location and GP value. If we
3073 are producing relocatable output, we don't want to do this for
3074 an external symbol. */
3076 || (symbol->flags & BSF_SECTION_SYM) != 0)
3077 val += relocation - gp;
3079 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
3082 reloc_entry->address += input_section->output_offset;
3084 return bfd_reloc_ok;
3087 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
3088 the rest is at bits 6-10. The bitpos already got right by the howto. */
3090 static bfd_reloc_status_type
3091 mips_elf_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3092 void *data, asection *input_section, bfd *output_bfd,
3093 char **error_message)
3095 if (reloc_entry->howto->partial_inplace)
3097 reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
3098 | (reloc_entry->addend & 0x00000800) >> 9);
3101 return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
3102 input_section, output_bfd,
3106 /* Handle a mips16 GP relative reloc. */
3108 static bfd_reloc_status_type
3109 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3110 void *data, asection *input_section, bfd *output_bfd,
3111 char **error_message)
3113 bfd_boolean relocatable;
3114 bfd_reloc_status_type ret;
3118 /* If we're relocating, and this is an external symbol, we don't want
3119 to change anything. */
3120 if (output_bfd != NULL
3121 && (symbol->flags & BSF_SECTION_SYM) == 0
3122 && (symbol->flags & BSF_LOCAL) != 0)
3124 reloc_entry->address += input_section->output_offset;
3125 return bfd_reloc_ok;
3128 if (output_bfd != NULL)
3132 relocatable = FALSE;
3133 output_bfd = symbol->section->output_section->owner;
3136 ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
3138 if (ret != bfd_reloc_ok)
3141 location = (bfd_byte *) data + reloc_entry->address;
3142 _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
3144 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
3145 input_section, relocatable,
3147 _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
3153 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
3155 struct elf_reloc_map {
3156 bfd_reloc_code_real_type bfd_val;
3157 enum elf_mips_reloc_type elf_val;
3160 static const struct elf_reloc_map mips_reloc_map[] =
3162 { BFD_RELOC_NONE, R_MIPS_NONE },
3163 { BFD_RELOC_16, R_MIPS_16 },
3164 { BFD_RELOC_32, R_MIPS_32 },
3165 /* There is no BFD reloc for R_MIPS_REL32. */
3166 { BFD_RELOC_CTOR, R_MIPS_32 },
3167 { BFD_RELOC_64, R_MIPS_64 },
3168 { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
3169 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
3170 { BFD_RELOC_LO16, R_MIPS_LO16 },
3171 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
3172 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
3173 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
3174 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
3175 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
3176 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
3177 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
3178 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
3179 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
3180 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
3181 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
3182 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
3183 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
3184 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
3185 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
3186 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
3187 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
3188 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
3189 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
3190 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
3191 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
3192 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
3193 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
3194 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
3195 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
3196 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
3197 { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
3198 { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
3199 { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
3200 { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
3201 { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
3202 { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
3203 { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
3204 { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
3205 { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
3206 { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
3207 { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
3208 { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
3209 { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 },
3210 { BFD_RELOC_MIPS_21_PCREL_S2, R_MIPS_PC21_S2 },
3211 { BFD_RELOC_MIPS_26_PCREL_S2, R_MIPS_PC26_S2 },
3212 { BFD_RELOC_MIPS_18_PCREL_S3, R_MIPS_PC18_S3 },
3213 { BFD_RELOC_MIPS_19_PCREL_S2, R_MIPS_PC19_S2 },
3214 { BFD_RELOC_HI16_S_PCREL, R_MIPS_PCHI16 },
3215 { BFD_RELOC_LO16_PCREL, R_MIPS_PCLO16 }
3218 static const struct elf_reloc_map mips16_reloc_map[] =
3220 { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
3221 { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
3222 { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
3223 { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
3224 { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
3225 { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
3226 { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
3227 { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
3228 { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
3229 R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
3230 { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
3231 R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
3232 { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
3233 { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
3234 { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
3237 static const struct elf_reloc_map micromips_reloc_map[] =
3239 { BFD_RELOC_MICROMIPS_JMP, R_MICROMIPS_26_S1 - R_MICROMIPS_min },
3240 { BFD_RELOC_MICROMIPS_HI16_S, R_MICROMIPS_HI16 - R_MICROMIPS_min },
3241 { BFD_RELOC_MICROMIPS_LO16, R_MICROMIPS_LO16 - R_MICROMIPS_min },
3242 { BFD_RELOC_MICROMIPS_GPREL16, R_MICROMIPS_GPREL16 - R_MICROMIPS_min },
3243 { BFD_RELOC_MICROMIPS_LITERAL, R_MICROMIPS_LITERAL - R_MICROMIPS_min },
3244 { BFD_RELOC_MICROMIPS_GOT16, R_MICROMIPS_GOT16 - R_MICROMIPS_min },
3245 { BFD_RELOC_MICROMIPS_7_PCREL_S1, R_MICROMIPS_PC7_S1 - R_MICROMIPS_min },
3246 { BFD_RELOC_MICROMIPS_10_PCREL_S1, R_MICROMIPS_PC10_S1 - R_MICROMIPS_min },
3247 { BFD_RELOC_MICROMIPS_16_PCREL_S1, R_MICROMIPS_PC16_S1 - R_MICROMIPS_min },
3248 { BFD_RELOC_MICROMIPS_CALL16, R_MICROMIPS_CALL16 - R_MICROMIPS_min },
3249 { BFD_RELOC_MICROMIPS_GOT_DISP, R_MICROMIPS_GOT_DISP - R_MICROMIPS_min },
3250 { BFD_RELOC_MICROMIPS_GOT_PAGE, R_MICROMIPS_GOT_PAGE - R_MICROMIPS_min },
3251 { BFD_RELOC_MICROMIPS_GOT_OFST, R_MICROMIPS_GOT_OFST - R_MICROMIPS_min },
3252 { BFD_RELOC_MICROMIPS_GOT_HI16, R_MICROMIPS_GOT_HI16 - R_MICROMIPS_min },
3253 { BFD_RELOC_MICROMIPS_GOT_LO16, R_MICROMIPS_GOT_LO16 - R_MICROMIPS_min },
3254 { BFD_RELOC_MICROMIPS_SUB, R_MICROMIPS_SUB - R_MICROMIPS_min },
3255 { BFD_RELOC_MICROMIPS_HIGHER, R_MICROMIPS_HIGHER - R_MICROMIPS_min },
3256 { BFD_RELOC_MICROMIPS_HIGHEST, R_MICROMIPS_HIGHEST - R_MICROMIPS_min },
3257 { BFD_RELOC_MICROMIPS_CALL_HI16, R_MICROMIPS_CALL_HI16 - R_MICROMIPS_min },
3258 { BFD_RELOC_MICROMIPS_CALL_LO16, R_MICROMIPS_CALL_LO16 - R_MICROMIPS_min },
3259 { BFD_RELOC_MICROMIPS_SCN_DISP, R_MICROMIPS_SCN_DISP - R_MICROMIPS_min },
3260 { BFD_RELOC_MICROMIPS_JALR, R_MICROMIPS_JALR - R_MICROMIPS_min },
3263 /* Given a BFD reloc type, return a howto structure. */
3265 static reloc_howto_type *
3266 bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3267 bfd_reloc_code_real_type code)
3270 /* FIXME: We default to RELA here instead of choosing the right
3271 relocation variant. */
3272 reloc_howto_type *howto_table = elf_mips_howto_table_rela;
3273 reloc_howto_type *howto16_table = elf_mips16_howto_table_rela;
3274 reloc_howto_type *howto_micromips_table = elf_micromips_howto_table_rela;
3276 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
3279 if (mips_reloc_map[i].bfd_val == code)
3280 return &howto_table[(int) mips_reloc_map[i].elf_val];
3283 for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
3286 if (mips16_reloc_map[i].bfd_val == code)
3287 return &howto16_table[(int) mips16_reloc_map[i].elf_val];
3290 for (i = 0; i < sizeof (micromips_reloc_map) / sizeof (struct elf_reloc_map);
3293 if (micromips_reloc_map[i].bfd_val == code)
3294 return &howto_micromips_table[(int) micromips_reloc_map[i].elf_val];
3299 case BFD_RELOC_VTABLE_INHERIT:
3300 return &elf_mips_gnu_vtinherit_howto;
3301 case BFD_RELOC_VTABLE_ENTRY:
3302 return &elf_mips_gnu_vtentry_howto;
3303 case BFD_RELOC_32_PCREL:
3304 return &elf_mips_gnu_pcrel32;
3305 case BFD_RELOC_MIPS_EH:
3306 return &elf_mips_eh_howto;
3307 case BFD_RELOC_MIPS_COPY:
3308 return &elf_mips_copy_howto;
3309 case BFD_RELOC_MIPS_JUMP_SLOT:
3310 return &elf_mips_jump_slot_howto;
3312 bfd_set_error (bfd_error_bad_value);
3317 static reloc_howto_type *
3318 bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3324 i < (sizeof (elf_mips_howto_table_rela)
3325 / sizeof (elf_mips_howto_table_rela[0]));
3327 if (elf_mips_howto_table_rela[i].name != NULL
3328 && strcasecmp (elf_mips_howto_table_rela[i].name, r_name) == 0)
3329 return &elf_mips_howto_table_rela[i];
3332 i < (sizeof (elf_mips16_howto_table_rela)
3333 / sizeof (elf_mips16_howto_table_rela[0]));
3335 if (elf_mips16_howto_table_rela[i].name != NULL
3336 && strcasecmp (elf_mips16_howto_table_rela[i].name, r_name) == 0)
3337 return &elf_mips16_howto_table_rela[i];
3340 i < (sizeof (elf_micromips_howto_table_rela)
3341 / sizeof (elf_micromips_howto_table_rela[0]));
3343 if (elf_micromips_howto_table_rela[i].name != NULL
3344 && strcasecmp (elf_micromips_howto_table_rela[i].name, r_name) == 0)
3345 return &elf_micromips_howto_table_rela[i];
3347 if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
3348 return &elf_mips_gnu_vtinherit_howto;
3349 if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
3350 return &elf_mips_gnu_vtentry_howto;
3351 if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
3352 return &elf_mips_gnu_rel16_s2;
3353 if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
3354 return &elf_mips_gnu_rela16_s2;
3355 if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
3356 return &elf_mips_gnu_pcrel32;
3357 if (strcasecmp (elf_mips_eh_howto.name, r_name) == 0)
3358 return &elf_mips_eh_howto;
3359 if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
3360 return &elf_mips_copy_howto;
3361 if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
3362 return &elf_mips_jump_slot_howto;
3367 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
3369 static reloc_howto_type *
3370 mips_elf_n32_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
3374 case R_MIPS_GNU_VTINHERIT:
3375 return &elf_mips_gnu_vtinherit_howto;
3376 case R_MIPS_GNU_VTENTRY:
3377 return &elf_mips_gnu_vtentry_howto;
3378 case R_MIPS_GNU_REL16_S2:
3380 return &elf_mips_gnu_rela16_s2;
3382 return &elf_mips_gnu_rel16_s2;
3384 return &elf_mips_gnu_pcrel32;
3386 return &elf_mips_eh_howto;
3388 return &elf_mips_copy_howto;
3389 case R_MIPS_JUMP_SLOT:
3390 return &elf_mips_jump_slot_howto;
3392 if (r_type >= R_MICROMIPS_min && r_type < R_MICROMIPS_max)
3395 return &elf_micromips_howto_table_rela[r_type - R_MICROMIPS_min];
3397 return &elf_micromips_howto_table_rel[r_type - R_MICROMIPS_min];
3399 if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
3402 return &elf_mips16_howto_table_rela[r_type - R_MIPS16_min];
3404 return &elf_mips16_howto_table_rel[r_type - R_MIPS16_min];
3406 if (r_type >= R_MIPS_max)
3408 (*_bfd_error_handler) (_("unrecognised MIPS reloc number: %d"), r_type);
3409 bfd_set_error (bfd_error_bad_value);
3410 r_type = R_MIPS_NONE;
3413 return &elf_mips_howto_table_rela[r_type];
3415 return &elf_mips_howto_table_rel[r_type];
3420 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
3423 mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
3425 unsigned int r_type;
3427 r_type = ELF32_R_TYPE (dst->r_info);
3428 cache_ptr->howto = mips_elf_n32_rtype_to_howto (r_type, FALSE);
3430 /* The addend for a GPREL16 or LITERAL relocation comes from the GP
3431 value for the object file. We get the addend now, rather than
3432 when we do the relocation, because the symbol manipulations done
3433 by the linker may cause us to lose track of the input BFD. */
3434 if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
3435 && (gprel16_reloc_p (r_type) || r_type == (unsigned int) R_MIPS_LITERAL))
3436 cache_ptr->addend = elf_gp (abfd);
3439 /* Given a MIPS Elf_Internal_Rela, fill in an arelent structure. */
3442 mips_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
3443 arelent *cache_ptr, Elf_Internal_Rela *dst)
3445 unsigned int r_type;
3447 r_type = ELF32_R_TYPE (dst->r_info);
3448 cache_ptr->howto = mips_elf_n32_rtype_to_howto (r_type, TRUE);
3449 cache_ptr->addend = dst->r_addend;
3452 /* Determine whether a symbol is global for the purposes of splitting
3453 the symbol table into global symbols and local symbols. At least
3454 on Irix 5, this split must be between section symbols and all other
3455 symbols. On most ELF targets the split is between static symbols
3456 and externally visible symbols. */
3459 mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
3461 if (SGI_COMPAT (abfd))
3462 return (sym->flags & BSF_SECTION_SYM) == 0;
3464 return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0
3465 || bfd_is_und_section (bfd_get_section (sym))
3466 || bfd_is_com_section (bfd_get_section (sym)));
3469 /* Set the right machine number for a MIPS ELF file. */
3472 mips_elf_n32_object_p (bfd *abfd)
3476 if (!ABI_N32_P (abfd))
3479 /* Irix 5 and 6 are broken. Object file symbol tables are not always
3480 sorted correctly such that local symbols precede global symbols,
3481 and the sh_info field in the symbol table is not always right. */
3482 if (SGI_COMPAT (abfd))
3483 elf_bad_symtab (abfd) = TRUE;
3485 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
3486 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
3490 /* Support for core dump NOTE sections. */
3492 elf32_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3497 switch (note->descsz)
3502 case 440: /* Linux/MIPS N32 */
3504 elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
3507 elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
3516 /* Make a ".reg/999" section. */
3517 return _bfd_elfcore_make_pseudosection (abfd, ".reg", size,
3518 note->descpos + offset);
3522 elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3524 switch (note->descsz)
3529 case 128: /* Linux/MIPS elf_prpsinfo */
3530 elf_tdata (abfd)->core->program
3531 = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
3532 elf_tdata (abfd)->core->command
3533 = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
3536 /* Note that for some reason, a spurious space is tacked
3537 onto the end of the args in some (at least one anyway)
3538 implementations, so strip it off if it exists. */
3541 char *command = elf_tdata (abfd)->core->command;
3542 int n = strlen (command);
3544 if (0 < n && command[n - 1] == ' ')
3545 command[n - 1] = '\0';
3551 /* Depending on the target vector we generate some version of Irix
3552 executables or "normal" MIPS ELF ABI executables. */
3553 static irix_compat_t
3554 elf_n32_mips_irix_compat (bfd *abfd)
3556 if ((abfd->xvec == &mips_elf32_n_be_vec)
3557 || (abfd->xvec == &mips_elf32_n_le_vec))
3563 /* ECOFF swapping routines. These are used when dealing with the
3564 .mdebug section, which is in the ECOFF debugging format. */
3565 static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
3566 /* Symbol table magic number. */
3568 /* Alignment of debugging information. E.g., 4. */
3570 /* Sizes of external symbolic information. */
3571 sizeof (struct hdr_ext),
3572 sizeof (struct dnr_ext),
3573 sizeof (struct pdr_ext),
3574 sizeof (struct sym_ext),
3575 sizeof (struct opt_ext),
3576 sizeof (struct fdr_ext),
3577 sizeof (struct rfd_ext),
3578 sizeof (struct ext_ext),
3579 /* Functions to swap in external symbolic data. */
3588 _bfd_ecoff_swap_tir_in,
3589 _bfd_ecoff_swap_rndx_in,
3590 /* Functions to swap out external symbolic data. */
3599 _bfd_ecoff_swap_tir_out,
3600 _bfd_ecoff_swap_rndx_out,
3601 /* Function to read in symbolic data. */
3602 _bfd_mips_elf_read_ecoff_info
3605 #define ELF_ARCH bfd_arch_mips
3606 #define ELF_TARGET_ID MIPS_ELF_DATA
3607 #define ELF_MACHINE_CODE EM_MIPS
3609 #define elf_backend_collect TRUE
3610 #define elf_backend_type_change_ok TRUE
3611 #define elf_backend_can_gc_sections TRUE
3612 #define elf_backend_gc_mark_extra_sections \
3613 _bfd_mips_elf_gc_mark_extra_sections
3614 #define elf_info_to_howto mips_info_to_howto_rela
3615 #define elf_info_to_howto_rel mips_info_to_howto_rel
3616 #define elf_backend_sym_is_global mips_elf_sym_is_global
3617 #define elf_backend_object_p mips_elf_n32_object_p
3618 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
3619 #define elf_backend_section_processing _bfd_mips_elf_section_processing
3620 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
3621 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
3622 #define elf_backend_section_from_bfd_section \
3623 _bfd_mips_elf_section_from_bfd_section
3624 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
3625 #define elf_backend_link_output_symbol_hook \
3626 _bfd_mips_elf_link_output_symbol_hook
3627 #define elf_backend_create_dynamic_sections \
3628 _bfd_mips_elf_create_dynamic_sections
3629 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
3630 #define elf_backend_merge_symbol_attribute \
3631 _bfd_mips_elf_merge_symbol_attribute
3632 #define elf_backend_get_target_dtag _bfd_mips_elf_get_target_dtag
3633 #define elf_backend_adjust_dynamic_symbol \
3634 _bfd_mips_elf_adjust_dynamic_symbol
3635 #define elf_backend_always_size_sections \
3636 _bfd_mips_elf_always_size_sections
3637 #define elf_backend_size_dynamic_sections \
3638 _bfd_mips_elf_size_dynamic_sections
3639 #define elf_backend_init_index_section _bfd_elf_init_1_index_section
3640 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
3641 #define elf_backend_finish_dynamic_symbol \
3642 _bfd_mips_elf_finish_dynamic_symbol
3643 #define elf_backend_finish_dynamic_sections \
3644 _bfd_mips_elf_finish_dynamic_sections
3645 #define elf_backend_final_write_processing \
3646 _bfd_mips_elf_final_write_processing
3647 #define elf_backend_additional_program_headers \
3648 _bfd_mips_elf_additional_program_headers
3649 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
3650 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
3651 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
3652 #define elf_backend_copy_indirect_symbol \
3653 _bfd_mips_elf_copy_indirect_symbol
3654 #define elf_backend_grok_prstatus elf32_mips_grok_prstatus
3655 #define elf_backend_grok_psinfo elf32_mips_grok_psinfo
3656 #define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap
3658 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
3660 /* MIPS n32 ELF can use a mixture of REL and RELA, but some Relocations
3661 work better/work only in RELA, so we default to this. */
3662 #define elf_backend_may_use_rel_p 1
3663 #define elf_backend_may_use_rela_p 1
3664 #define elf_backend_default_use_rela_p 1
3665 #define elf_backend_rela_plts_and_copies_p 0
3666 #define elf_backend_sign_extend_vma TRUE
3667 #define elf_backend_plt_readonly 1
3668 #define elf_backend_plt_sym_val _bfd_mips_elf_plt_sym_val
3670 #define elf_backend_discard_info _bfd_mips_elf_discard_info
3671 #define elf_backend_ignore_discarded_relocs \
3672 _bfd_mips_elf_ignore_discarded_relocs
3673 #define elf_backend_write_section _bfd_mips_elf_write_section
3674 #define elf_backend_mips_irix_compat elf_n32_mips_irix_compat
3675 #define elf_backend_mips_rtype_to_howto mips_elf_n32_rtype_to_howto
3676 #define bfd_elf32_bfd_is_target_special_symbol \
3677 _bfd_mips_elf_is_target_special_symbol
3678 #define bfd_elf32_find_nearest_line _bfd_mips_elf_find_nearest_line
3679 #define bfd_elf32_find_inliner_info _bfd_mips_elf_find_inliner_info
3680 #define bfd_elf32_new_section_hook _bfd_mips_elf_new_section_hook
3681 #define bfd_elf32_set_section_contents _bfd_mips_elf_set_section_contents
3682 #define bfd_elf32_bfd_get_relocated_section_contents \
3683 _bfd_elf_mips_get_relocated_section_contents
3684 #define bfd_elf32_bfd_link_hash_table_create \
3685 _bfd_mips_elf_link_hash_table_create
3686 #define bfd_elf32_bfd_final_link _bfd_mips_elf_final_link
3687 #define bfd_elf32_bfd_merge_private_bfd_data \
3688 _bfd_mips_elf_merge_private_bfd_data
3689 #define bfd_elf32_bfd_set_private_flags _bfd_mips_elf_set_private_flags
3690 #define bfd_elf32_bfd_print_private_bfd_data \
3691 _bfd_mips_elf_print_private_bfd_data
3692 #define bfd_elf32_bfd_relax_section _bfd_mips_relax_section
3693 #define bfd_elf32_mkobject _bfd_mips_elf_mkobject
3695 /* Support for SGI-ish mips targets using n32 ABI. */
3697 #define TARGET_LITTLE_SYM mips_elf32_n_le_vec
3698 #define TARGET_LITTLE_NAME "elf32-nlittlemips"
3699 #define TARGET_BIG_SYM mips_elf32_n_be_vec
3700 #define TARGET_BIG_NAME "elf32-nbigmips"
3702 #define ELF_MAXPAGESIZE 0x10000
3703 #define ELF_COMMONPAGESIZE 0x1000
3705 #include "elf32-target.h"
3707 /* Support for traditional mips targets using n32 ABI. */
3708 #undef TARGET_LITTLE_SYM
3709 #undef TARGET_LITTLE_NAME
3710 #undef TARGET_BIG_SYM
3711 #undef TARGET_BIG_NAME
3713 #undef ELF_MAXPAGESIZE
3714 #undef ELF_COMMONPAGESIZE
3716 #define TARGET_LITTLE_SYM mips_elf32_ntrad_le_vec
3717 #define TARGET_LITTLE_NAME "elf32-ntradlittlemips"
3718 #define TARGET_BIG_SYM mips_elf32_ntrad_be_vec
3719 #define TARGET_BIG_NAME "elf32-ntradbigmips"
3721 #define ELF_MAXPAGESIZE 0x10000
3722 #define ELF_COMMONPAGESIZE 0x1000
3723 #define elf32_bed elf32_tradbed
3725 /* Include the target file again for this target. */
3726 #include "elf32-target.h"
3729 /* FreeBSD support. */
3731 #undef TARGET_LITTLE_SYM
3732 #undef TARGET_LITTLE_NAME
3733 #undef TARGET_BIG_SYM
3734 #undef TARGET_BIG_NAME
3736 #define TARGET_LITTLE_SYM mips_elf32_ntradfbsd_le_vec
3737 #define TARGET_LITTLE_NAME "elf32-ntradlittlemips-freebsd"
3738 #define TARGET_BIG_SYM mips_elf32_ntradfbsd_be_vec
3739 #define TARGET_BIG_NAME "elf32-ntradbigmips-freebsd"
3742 #define ELF_OSABI ELFOSABI_FREEBSD
3745 #define elf32_bed elf32_fbsd_tradbed
3747 #include "elf32-target.h"