1 /* MIPS-specific support for 32-bit ELF
2 Copyright (C) 1993-2014 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 0, /* 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 */
775 /* The relocation table used for SHT_RELA sections. */
777 static reloc_howto_type elf_mips_howto_table_rela[] =
780 HOWTO (R_MIPS_NONE, /* type */
782 0, /* size (0 = byte, 1 = short, 2 = long) */
784 FALSE, /* pc_relative */
786 complain_overflow_dont, /* complain_on_overflow */
787 _bfd_mips_elf_generic_reloc, /* special_function */
788 "R_MIPS_NONE", /* name */
789 FALSE, /* partial_inplace */
792 FALSE), /* pcrel_offset */
794 /* 16 bit relocation. */
795 HOWTO (R_MIPS_16, /* type */
797 2, /* size (0 = byte, 1 = short, 2 = long) */
799 FALSE, /* pc_relative */
801 complain_overflow_signed, /* complain_on_overflow */
802 _bfd_mips_elf_generic_reloc, /* special_function */
803 "R_MIPS_16", /* name */
804 FALSE, /* partial_inplace */
806 0x0000, /* dst_mask */
807 FALSE), /* pcrel_offset */
809 /* 32 bit relocation. */
810 HOWTO (R_MIPS_32, /* type */
812 2, /* size (0 = byte, 1 = short, 2 = long) */
814 FALSE, /* pc_relative */
816 complain_overflow_dont, /* complain_on_overflow */
817 _bfd_mips_elf_generic_reloc, /* special_function */
818 "R_MIPS_32", /* name */
819 FALSE, /* partial_inplace */
821 0xffffffff, /* dst_mask */
822 FALSE), /* pcrel_offset */
824 /* 32 bit symbol relative relocation. */
825 HOWTO (R_MIPS_REL32, /* type */
827 2, /* size (0 = byte, 1 = short, 2 = long) */
829 FALSE, /* pc_relative */
831 complain_overflow_dont, /* complain_on_overflow */
832 _bfd_mips_elf_generic_reloc, /* special_function */
833 "R_MIPS_REL32", /* name */
834 FALSE, /* partial_inplace */
836 0xffffffff, /* dst_mask */
837 FALSE), /* pcrel_offset */
839 /* 26 bit jump address. */
840 HOWTO (R_MIPS_26, /* type */
842 2, /* size (0 = byte, 1 = short, 2 = long) */
844 FALSE, /* pc_relative */
846 complain_overflow_dont, /* complain_on_overflow */
847 /* This needs complex overflow
848 detection, because the upper 36
849 bits must match the PC + 4. */
850 _bfd_mips_elf_generic_reloc, /* special_function */
851 "R_MIPS_26", /* name */
852 FALSE, /* partial_inplace */
854 0x03ffffff, /* dst_mask */
855 FALSE), /* pcrel_offset */
857 /* High 16 bits of symbol value. */
858 HOWTO (R_MIPS_HI16, /* type */
860 2, /* size (0 = byte, 1 = short, 2 = long) */
862 FALSE, /* pc_relative */
864 complain_overflow_dont, /* complain_on_overflow */
865 _bfd_mips_elf_generic_reloc, /* special_function */
866 "R_MIPS_HI16", /* name */
867 FALSE, /* partial_inplace */
869 0x0000ffff, /* dst_mask */
870 FALSE), /* pcrel_offset */
872 /* Low 16 bits of symbol value. */
873 HOWTO (R_MIPS_LO16, /* type */
875 2, /* size (0 = byte, 1 = short, 2 = long) */
877 FALSE, /* pc_relative */
879 complain_overflow_dont, /* complain_on_overflow */
880 _bfd_mips_elf_generic_reloc, /* special_function */
881 "R_MIPS_LO16", /* name */
882 FALSE, /* partial_inplace */
884 0x0000ffff, /* dst_mask */
885 FALSE), /* pcrel_offset */
887 /* GP relative reference. */
888 HOWTO (R_MIPS_GPREL16, /* type */
890 2, /* size (0 = byte, 1 = short, 2 = long) */
892 FALSE, /* pc_relative */
894 complain_overflow_signed, /* complain_on_overflow */
895 mips_elf_gprel16_reloc, /* special_function */
896 "R_MIPS_GPREL16", /* name */
897 FALSE, /* partial_inplace */
899 0x0000ffff, /* dst_mask */
900 FALSE), /* pcrel_offset */
902 /* Reference to literal section. */
903 HOWTO (R_MIPS_LITERAL, /* type */
905 2, /* size (0 = byte, 1 = short, 2 = long) */
907 FALSE, /* pc_relative */
909 complain_overflow_signed, /* complain_on_overflow */
910 mips_elf_literal_reloc, /* special_function */
911 "R_MIPS_LITERAL", /* name */
912 FALSE, /* partial_inplace */
914 0x0000ffff, /* dst_mask */
915 FALSE), /* pcrel_offset */
917 /* Reference to global offset table. */
918 HOWTO (R_MIPS_GOT16, /* type */
920 2, /* size (0 = byte, 1 = short, 2 = long) */
922 FALSE, /* pc_relative */
924 complain_overflow_signed, /* complain_on_overflow */
925 _bfd_mips_elf_generic_reloc, /* special_function */
926 "R_MIPS_GOT16", /* name */
927 FALSE, /* partial_inplace */
929 0x0000ffff, /* dst_mask */
930 FALSE), /* pcrel_offset */
932 /* 16 bit PC relative reference. Note that the ABI document has a typo
933 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
934 We do the right thing here. */
935 HOWTO (R_MIPS_PC16, /* type */
937 2, /* size (0 = byte, 1 = short, 2 = long) */
939 TRUE, /* pc_relative */
941 complain_overflow_signed, /* complain_on_overflow */
942 _bfd_mips_elf_generic_reloc, /* special_function */
943 "R_MIPS_PC16", /* name */
944 FALSE, /* partial_inplace */
946 0x0000ffff, /* dst_mask */
947 TRUE), /* pcrel_offset */
949 /* 16 bit call through global offset table. */
950 HOWTO (R_MIPS_CALL16, /* type */
952 2, /* size (0 = byte, 1 = short, 2 = long) */
954 FALSE, /* pc_relative */
956 complain_overflow_signed, /* complain_on_overflow */
957 _bfd_mips_elf_generic_reloc, /* special_function */
958 "R_MIPS_CALL16", /* name */
959 FALSE, /* partial_inplace */
961 0x0000ffff, /* dst_mask */
962 FALSE), /* pcrel_offset */
964 /* 32 bit GP relative reference. */
965 HOWTO (R_MIPS_GPREL32, /* type */
967 2, /* size (0 = byte, 1 = short, 2 = long) */
969 FALSE, /* pc_relative */
971 complain_overflow_dont, /* complain_on_overflow */
972 mips_elf_gprel32_reloc, /* special_function */
973 "R_MIPS_GPREL32", /* name */
974 FALSE, /* partial_inplace */
976 0xffffffff, /* dst_mask */
977 FALSE), /* pcrel_offset */
983 /* A 5 bit shift field. */
984 HOWTO (R_MIPS_SHIFT5, /* type */
986 2, /* size (0 = byte, 1 = short, 2 = long) */
988 FALSE, /* pc_relative */
990 complain_overflow_bitfield, /* complain_on_overflow */
991 _bfd_mips_elf_generic_reloc, /* special_function */
992 "R_MIPS_SHIFT5", /* name */
993 FALSE, /* partial_inplace */
995 0x000007c0, /* dst_mask */
996 FALSE), /* pcrel_offset */
998 /* A 6 bit shift field. */
999 HOWTO (R_MIPS_SHIFT6, /* type */
1001 2, /* size (0 = byte, 1 = short, 2 = long) */
1003 FALSE, /* pc_relative */
1005 complain_overflow_bitfield, /* complain_on_overflow */
1006 mips_elf_shift6_reloc, /* special_function */
1007 "R_MIPS_SHIFT6", /* name */
1008 FALSE, /* partial_inplace */
1010 0x000007c4, /* dst_mask */
1011 FALSE), /* pcrel_offset */
1013 /* 64 bit relocation. */
1014 HOWTO (R_MIPS_64, /* type */
1016 4, /* size (0 = byte, 1 = short, 2 = long) */
1018 FALSE, /* pc_relative */
1020 complain_overflow_dont, /* complain_on_overflow */
1021 _bfd_mips_elf_generic_reloc, /* special_function */
1022 "R_MIPS_64", /* name */
1023 FALSE, /* partial_inplace */
1025 MINUS_ONE, /* dst_mask */
1026 FALSE), /* pcrel_offset */
1028 /* Displacement in the global offset table. */
1029 HOWTO (R_MIPS_GOT_DISP, /* type */
1031 2, /* size (0 = byte, 1 = short, 2 = long) */
1033 FALSE, /* pc_relative */
1035 complain_overflow_signed, /* complain_on_overflow */
1036 _bfd_mips_elf_generic_reloc, /* special_function */
1037 "R_MIPS_GOT_DISP", /* name */
1038 FALSE, /* partial_inplace */
1040 0x0000ffff, /* dst_mask */
1041 FALSE), /* pcrel_offset */
1043 /* Displacement to page pointer in the global offset table. */
1044 HOWTO (R_MIPS_GOT_PAGE, /* 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_GOT_PAGE", /* name */
1053 FALSE, /* partial_inplace */
1055 0x0000ffff, /* dst_mask */
1056 FALSE), /* pcrel_offset */
1058 /* Offset from page pointer in the global offset table. */
1059 HOWTO (R_MIPS_GOT_OFST, /* type */
1061 2, /* size (0 = byte, 1 = short, 2 = long) */
1063 FALSE, /* pc_relative */
1065 complain_overflow_signed, /* complain_on_overflow */
1066 _bfd_mips_elf_generic_reloc, /* special_function */
1067 "R_MIPS_GOT_OFST", /* name */
1068 FALSE, /* partial_inplace */
1070 0x0000ffff, /* dst_mask */
1071 FALSE), /* pcrel_offset */
1073 /* High 16 bits of displacement in global offset table. */
1074 HOWTO (R_MIPS_GOT_HI16, /* type */
1076 2, /* size (0 = byte, 1 = short, 2 = long) */
1078 FALSE, /* pc_relative */
1080 complain_overflow_dont, /* complain_on_overflow */
1081 _bfd_mips_elf_generic_reloc, /* special_function */
1082 "R_MIPS_GOT_HI16", /* name */
1083 FALSE, /* partial_inplace */
1085 0x0000ffff, /* dst_mask */
1086 FALSE), /* pcrel_offset */
1088 /* Low 16 bits of displacement in global offset table. */
1089 HOWTO (R_MIPS_GOT_LO16, /* type */
1091 2, /* size (0 = byte, 1 = short, 2 = long) */
1093 FALSE, /* pc_relative */
1095 complain_overflow_dont, /* complain_on_overflow */
1096 _bfd_mips_elf_generic_reloc, /* special_function */
1097 "R_MIPS_GOT_LO16", /* name */
1098 FALSE, /* partial_inplace */
1100 0x0000ffff, /* dst_mask */
1101 FALSE), /* pcrel_offset */
1103 /* 64 bit subtraction. */
1104 HOWTO (R_MIPS_SUB, /* type */
1106 4, /* size (0 = byte, 1 = short, 2 = long) */
1108 FALSE, /* pc_relative */
1110 complain_overflow_dont, /* complain_on_overflow */
1111 _bfd_mips_elf_generic_reloc, /* special_function */
1112 "R_MIPS_SUB", /* name */
1113 FALSE, /* partial_inplace */
1115 MINUS_ONE, /* dst_mask */
1116 FALSE), /* pcrel_offset */
1118 /* Insert the addend as an instruction. */
1119 /* FIXME: Not handled correctly. */
1120 HOWTO (R_MIPS_INSERT_A, /* type */
1122 2, /* size (0 = byte, 1 = short, 2 = long) */
1124 FALSE, /* pc_relative */
1126 complain_overflow_dont, /* complain_on_overflow */
1127 _bfd_mips_elf_generic_reloc, /* special_function */
1128 "R_MIPS_INSERT_A", /* name */
1129 FALSE, /* partial_inplace */
1131 0xffffffff, /* dst_mask */
1132 FALSE), /* pcrel_offset */
1134 /* Insert the addend as an instruction, and change all relocations
1135 to refer to the old instruction at the address. */
1136 /* FIXME: Not handled correctly. */
1137 HOWTO (R_MIPS_INSERT_B, /* type */
1139 2, /* size (0 = byte, 1 = short, 2 = long) */
1141 FALSE, /* pc_relative */
1143 complain_overflow_dont, /* complain_on_overflow */
1144 _bfd_mips_elf_generic_reloc, /* special_function */
1145 "R_MIPS_INSERT_B", /* name */
1146 FALSE, /* partial_inplace */
1148 0xffffffff, /* dst_mask */
1149 FALSE), /* pcrel_offset */
1151 /* Delete a 32 bit instruction. */
1152 /* FIXME: Not handled correctly. */
1153 HOWTO (R_MIPS_DELETE, /* type */
1155 2, /* size (0 = byte, 1 = short, 2 = long) */
1157 FALSE, /* pc_relative */
1159 complain_overflow_dont, /* complain_on_overflow */
1160 _bfd_mips_elf_generic_reloc, /* special_function */
1161 "R_MIPS_DELETE", /* name */
1162 FALSE, /* partial_inplace */
1164 0xffffffff, /* dst_mask */
1165 FALSE), /* pcrel_offset */
1167 /* Get the higher value of a 64 bit addend. */
1168 HOWTO (R_MIPS_HIGHER, /* 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_HIGHER", /* name */
1177 FALSE, /* partial_inplace */
1179 0x0000ffff, /* dst_mask */
1180 FALSE), /* pcrel_offset */
1182 /* Get the highest value of a 64 bit addend. */
1183 HOWTO (R_MIPS_HIGHEST, /* 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_HIGHEST", /* name */
1192 FALSE, /* partial_inplace */
1194 0x0000ffff, /* dst_mask */
1195 FALSE), /* pcrel_offset */
1197 /* High 16 bits of displacement in global offset table. */
1198 HOWTO (R_MIPS_CALL_HI16, /* type */
1200 2, /* 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_CALL_HI16", /* name */
1207 FALSE, /* partial_inplace */
1209 0x0000ffff, /* dst_mask */
1210 FALSE), /* pcrel_offset */
1212 /* Low 16 bits of displacement in global offset table. */
1213 HOWTO (R_MIPS_CALL_LO16, /* type */
1215 2, /* size (0 = byte, 1 = short, 2 = long) */
1217 FALSE, /* pc_relative */
1219 complain_overflow_dont, /* complain_on_overflow */
1220 _bfd_mips_elf_generic_reloc, /* special_function */
1221 "R_MIPS_CALL_LO16", /* name */
1222 FALSE, /* partial_inplace */
1224 0x0000ffff, /* dst_mask */
1225 FALSE), /* pcrel_offset */
1227 /* Section displacement, used by an associated event location section. */
1228 HOWTO (R_MIPS_SCN_DISP, /* type */
1230 2, /* size (0 = byte, 1 = short, 2 = long) */
1232 FALSE, /* pc_relative */
1234 complain_overflow_dont, /* complain_on_overflow */
1235 _bfd_mips_elf_generic_reloc, /* special_function */
1236 "R_MIPS_SCN_DISP", /* name */
1237 FALSE, /* partial_inplace */
1239 0xffffffff, /* dst_mask */
1240 FALSE), /* pcrel_offset */
1242 /* 16 bit relocation. */
1243 HOWTO (R_MIPS_REL16, /* type */
1245 1, /* size (0 = byte, 1 = short, 2 = long) */
1247 FALSE, /* pc_relative */
1249 complain_overflow_signed, /* complain_on_overflow */
1250 _bfd_mips_elf_generic_reloc, /* special_function */
1251 "R_MIPS_REL16", /* name */
1252 FALSE, /* partial_inplace */
1254 0xffff, /* dst_mask */
1255 FALSE), /* pcrel_offset */
1257 /* These two are obsolete. */
1258 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1259 EMPTY_HOWTO (R_MIPS_PJUMP),
1261 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1262 It must be used for multigot GOT's (and only there). */
1263 HOWTO (R_MIPS_RELGOT, /* type */
1265 2, /* size (0 = byte, 1 = short, 2 = long) */
1267 FALSE, /* pc_relative */
1269 complain_overflow_dont, /* complain_on_overflow */
1270 _bfd_mips_elf_generic_reloc, /* special_function */
1271 "R_MIPS_RELGOT", /* name */
1272 FALSE, /* partial_inplace */
1274 0xffffffff, /* dst_mask */
1275 FALSE), /* pcrel_offset */
1277 /* Protected jump conversion. This is an optimization hint. No
1278 relocation is required for correctness. */
1279 HOWTO (R_MIPS_JALR, /* type */
1281 2, /* size (0 = byte, 1 = short, 2 = long) */
1283 FALSE, /* pc_relative */
1285 complain_overflow_dont, /* complain_on_overflow */
1286 _bfd_mips_elf_generic_reloc, /* special_function */
1287 "R_MIPS_JALR", /* name */
1288 FALSE, /* partial_inplace */
1291 FALSE), /* pcrel_offset */
1293 /* TLS GD/LD dynamic relocations. */
1294 HOWTO (R_MIPS_TLS_DTPMOD32, /* type */
1296 2, /* size (0 = byte, 1 = short, 2 = long) */
1298 FALSE, /* pc_relative */
1300 complain_overflow_dont, /* complain_on_overflow */
1301 _bfd_mips_elf_generic_reloc, /* special_function */
1302 "R_MIPS_TLS_DTPMOD32", /* name */
1303 FALSE, /* partial_inplace */
1305 0xffffffff, /* dst_mask */
1306 FALSE), /* pcrel_offset */
1308 HOWTO (R_MIPS_TLS_DTPREL32, /* type */
1310 2, /* size (0 = byte, 1 = short, 2 = long) */
1312 FALSE, /* pc_relative */
1314 complain_overflow_dont, /* complain_on_overflow */
1315 _bfd_mips_elf_generic_reloc, /* special_function */
1316 "R_MIPS_TLS_DTPREL32", /* name */
1317 FALSE, /* partial_inplace */
1319 0xffffffff, /* dst_mask */
1320 FALSE), /* pcrel_offset */
1322 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
1323 EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
1325 /* TLS general dynamic variable reference. */
1326 HOWTO (R_MIPS_TLS_GD, /* type */
1328 2, /* size (0 = byte, 1 = short, 2 = long) */
1330 FALSE, /* pc_relative */
1332 complain_overflow_signed, /* complain_on_overflow */
1333 _bfd_mips_elf_generic_reloc, /* special_function */
1334 "R_MIPS_TLS_GD", /* name */
1335 FALSE, /* partial_inplace */
1337 0x0000ffff, /* dst_mask */
1338 FALSE), /* pcrel_offset */
1340 /* TLS local dynamic variable reference. */
1341 HOWTO (R_MIPS_TLS_LDM, /* type */
1343 2, /* size (0 = byte, 1 = short, 2 = long) */
1345 FALSE, /* pc_relative */
1347 complain_overflow_signed, /* complain_on_overflow */
1348 _bfd_mips_elf_generic_reloc, /* special_function */
1349 "R_MIPS_TLS_LDM", /* name */
1350 FALSE, /* partial_inplace */
1352 0x0000ffff, /* dst_mask */
1353 FALSE), /* pcrel_offset */
1355 /* TLS local dynamic offset. */
1356 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
1358 2, /* size (0 = byte, 1 = short, 2 = long) */
1360 FALSE, /* pc_relative */
1362 complain_overflow_signed, /* complain_on_overflow */
1363 _bfd_mips_elf_generic_reloc, /* special_function */
1364 "R_MIPS_TLS_DTPREL_HI16", /* name */
1365 FALSE, /* partial_inplace */
1367 0x0000ffff, /* dst_mask */
1368 FALSE), /* pcrel_offset */
1370 /* TLS local dynamic offset. */
1371 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
1373 2, /* size (0 = byte, 1 = short, 2 = long) */
1375 FALSE, /* pc_relative */
1377 complain_overflow_signed, /* complain_on_overflow */
1378 _bfd_mips_elf_generic_reloc, /* special_function */
1379 "R_MIPS_TLS_DTPREL_LO16", /* name */
1380 FALSE, /* partial_inplace */
1382 0x0000ffff, /* dst_mask */
1383 FALSE), /* pcrel_offset */
1385 /* TLS thread pointer offset. */
1386 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
1388 2, /* size (0 = byte, 1 = short, 2 = long) */
1390 FALSE, /* pc_relative */
1392 complain_overflow_signed, /* complain_on_overflow */
1393 _bfd_mips_elf_generic_reloc, /* special_function */
1394 "R_MIPS_TLS_GOTTPREL", /* name */
1395 FALSE, /* partial_inplace */
1397 0x0000ffff, /* dst_mask */
1398 FALSE), /* pcrel_offset */
1400 /* TLS IE dynamic relocations. */
1401 HOWTO (R_MIPS_TLS_TPREL32, /* type */
1403 2, /* size (0 = byte, 1 = short, 2 = long) */
1405 FALSE, /* pc_relative */
1407 complain_overflow_dont, /* complain_on_overflow */
1408 _bfd_mips_elf_generic_reloc, /* special_function */
1409 "R_MIPS_TLS_TPREL32", /* name */
1410 FALSE, /* partial_inplace */
1412 0xffffffff, /* dst_mask */
1413 FALSE), /* pcrel_offset */
1415 EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
1417 /* TLS thread pointer offset. */
1418 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
1420 2, /* size (0 = byte, 1 = short, 2 = long) */
1422 FALSE, /* pc_relative */
1424 complain_overflow_signed, /* complain_on_overflow */
1425 _bfd_mips_elf_generic_reloc, /* special_function */
1426 "R_MIPS_TLS_TPREL_HI16", /* name */
1427 FALSE, /* partial_inplace */
1429 0x0000ffff, /* dst_mask */
1430 FALSE), /* pcrel_offset */
1432 /* TLS thread pointer offset. */
1433 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
1435 2, /* size (0 = byte, 1 = short, 2 = long) */
1437 FALSE, /* pc_relative */
1439 complain_overflow_signed, /* complain_on_overflow */
1440 _bfd_mips_elf_generic_reloc, /* special_function */
1441 "R_MIPS_TLS_TPREL_LO16", /* name */
1442 FALSE, /* partial_inplace */
1444 0x0000ffff, /* dst_mask */
1445 FALSE), /* pcrel_offset */
1447 /* 32 bit relocation with no addend. */
1448 HOWTO (R_MIPS_GLOB_DAT, /* type */
1450 2, /* size (0 = byte, 1 = short, 2 = long) */
1452 FALSE, /* pc_relative */
1454 complain_overflow_dont, /* complain_on_overflow */
1455 _bfd_mips_elf_generic_reloc, /* special_function */
1456 "R_MIPS_GLOB_DAT", /* name */
1457 FALSE, /* partial_inplace */
1459 0xffffffff, /* dst_mask */
1460 FALSE), /* pcrel_offset */
1463 static reloc_howto_type elf_mips16_howto_table_rel[] =
1465 /* The reloc used for the mips16 jump instruction. */
1466 HOWTO (R_MIPS16_26, /* type */
1468 2, /* size (0 = byte, 1 = short, 2 = long) */
1470 FALSE, /* pc_relative */
1472 complain_overflow_dont, /* complain_on_overflow */
1473 /* This needs complex overflow
1474 detection, because the upper four
1475 bits must match the PC. */
1476 _bfd_mips_elf_generic_reloc, /* special_function */
1477 "R_MIPS16_26", /* name */
1478 TRUE, /* partial_inplace */
1479 0x3ffffff, /* src_mask */
1480 0x3ffffff, /* dst_mask */
1481 FALSE), /* pcrel_offset */
1483 /* The reloc used for the mips16 gprel instruction. */
1484 HOWTO (R_MIPS16_GPREL, /* type */
1486 2, /* size (0 = byte, 1 = short, 2 = long) */
1488 FALSE, /* pc_relative */
1490 complain_overflow_signed, /* complain_on_overflow */
1491 mips16_gprel_reloc, /* special_function */
1492 "R_MIPS16_GPREL", /* name */
1493 TRUE, /* partial_inplace */
1494 0x0000ffff, /* src_mask */
1495 0x0000ffff, /* dst_mask */
1496 FALSE), /* pcrel_offset */
1498 /* A MIPS16 reference to the global offset table. */
1499 HOWTO (R_MIPS16_GOT16, /* type */
1501 2, /* size (0 = byte, 1 = short, 2 = long) */
1503 FALSE, /* pc_relative */
1505 complain_overflow_dont, /* complain_on_overflow */
1506 _bfd_mips_elf_got16_reloc, /* special_function */
1507 "R_MIPS16_GOT16", /* name */
1508 TRUE, /* partial_inplace */
1509 0x0000ffff, /* src_mask */
1510 0x0000ffff, /* dst_mask */
1511 FALSE), /* pcrel_offset */
1513 /* A MIPS16 call through the global offset table. */
1514 HOWTO (R_MIPS16_CALL16, /* type */
1516 2, /* size (0 = byte, 1 = short, 2 = long) */
1518 FALSE, /* pc_relative */
1520 complain_overflow_dont, /* complain_on_overflow */
1521 _bfd_mips_elf_generic_reloc, /* special_function */
1522 "R_MIPS16_CALL16", /* name */
1523 TRUE, /* partial_inplace */
1524 0x0000ffff, /* src_mask */
1525 0x0000ffff, /* dst_mask */
1526 FALSE), /* pcrel_offset */
1528 /* MIPS16 high 16 bits of symbol value. */
1529 HOWTO (R_MIPS16_HI16, /* type */
1530 16, /* rightshift */
1531 2, /* size (0 = byte, 1 = short, 2 = long) */
1533 FALSE, /* pc_relative */
1535 complain_overflow_dont, /* complain_on_overflow */
1536 _bfd_mips_elf_hi16_reloc, /* special_function */
1537 "R_MIPS16_HI16", /* name */
1538 TRUE, /* partial_inplace */
1539 0x0000ffff, /* src_mask */
1540 0x0000ffff, /* dst_mask */
1541 FALSE), /* pcrel_offset */
1543 /* MIPS16 low 16 bits of symbol value. */
1544 HOWTO (R_MIPS16_LO16, /* type */
1546 2, /* size (0 = byte, 1 = short, 2 = long) */
1548 FALSE, /* pc_relative */
1550 complain_overflow_dont, /* complain_on_overflow */
1551 _bfd_mips_elf_lo16_reloc, /* special_function */
1552 "R_MIPS16_LO16", /* name */
1553 TRUE, /* partial_inplace */
1554 0x0000ffff, /* src_mask */
1555 0x0000ffff, /* dst_mask */
1556 FALSE), /* pcrel_offset */
1558 /* MIPS16 TLS general dynamic variable reference. */
1559 HOWTO (R_MIPS16_TLS_GD, /* type */
1561 2, /* size (0 = byte, 1 = short, 2 = long) */
1563 FALSE, /* pc_relative */
1565 complain_overflow_signed, /* complain_on_overflow */
1566 _bfd_mips_elf_generic_reloc, /* special_function */
1567 "R_MIPS16_TLS_GD", /* name */
1568 TRUE, /* partial_inplace */
1569 0x0000ffff, /* src_mask */
1570 0x0000ffff, /* dst_mask */
1571 FALSE), /* pcrel_offset */
1573 /* MIPS16 TLS local dynamic variable reference. */
1574 HOWTO (R_MIPS16_TLS_LDM, /* type */
1576 2, /* size (0 = byte, 1 = short, 2 = long) */
1578 FALSE, /* pc_relative */
1580 complain_overflow_signed, /* complain_on_overflow */
1581 _bfd_mips_elf_generic_reloc, /* special_function */
1582 "R_MIPS16_TLS_LDM", /* name */
1583 TRUE, /* partial_inplace */
1584 0x0000ffff, /* src_mask */
1585 0x0000ffff, /* dst_mask */
1586 FALSE), /* pcrel_offset */
1588 /* MIPS16 TLS local dynamic offset. */
1589 HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */
1591 2, /* size (0 = byte, 1 = short, 2 = long) */
1593 FALSE, /* pc_relative */
1595 complain_overflow_signed, /* complain_on_overflow */
1596 _bfd_mips_elf_generic_reloc, /* special_function */
1597 "R_MIPS16_TLS_DTPREL_HI16", /* name */
1598 TRUE, /* partial_inplace */
1599 0x0000ffff, /* src_mask */
1600 0x0000ffff, /* dst_mask */
1601 FALSE), /* pcrel_offset */
1603 /* MIPS16 TLS local dynamic offset. */
1604 HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */
1606 2, /* size (0 = byte, 1 = short, 2 = long) */
1608 FALSE, /* pc_relative */
1610 complain_overflow_signed, /* complain_on_overflow */
1611 _bfd_mips_elf_generic_reloc, /* special_function */
1612 "R_MIPS16_TLS_DTPREL_LO16", /* name */
1613 TRUE, /* partial_inplace */
1614 0x0000ffff, /* src_mask */
1615 0x0000ffff, /* dst_mask */
1616 FALSE), /* pcrel_offset */
1618 /* MIPS16 TLS thread pointer offset. */
1619 HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */
1621 2, /* size (0 = byte, 1 = short, 2 = long) */
1623 FALSE, /* pc_relative */
1625 complain_overflow_signed, /* complain_on_overflow */
1626 _bfd_mips_elf_generic_reloc, /* special_function */
1627 "R_MIPS16_TLS_GOTTPREL", /* name */
1628 TRUE, /* partial_inplace */
1629 0x0000ffff, /* src_mask */
1630 0x0000ffff, /* dst_mask */
1631 FALSE), /* pcrel_offset */
1633 /* MIPS16 TLS thread pointer offset. */
1634 HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */
1636 2, /* size (0 = byte, 1 = short, 2 = long) */
1638 FALSE, /* pc_relative */
1640 complain_overflow_signed, /* complain_on_overflow */
1641 _bfd_mips_elf_generic_reloc, /* special_function */
1642 "R_MIPS16_TLS_TPREL_HI16", /* name */
1643 TRUE, /* partial_inplace */
1644 0x0000ffff, /* src_mask */
1645 0x0000ffff, /* dst_mask */
1646 FALSE), /* pcrel_offset */
1648 /* MIPS16 TLS thread pointer offset. */
1649 HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */
1651 2, /* size (0 = byte, 1 = short, 2 = long) */
1653 FALSE, /* pc_relative */
1655 complain_overflow_signed, /* complain_on_overflow */
1656 _bfd_mips_elf_generic_reloc, /* special_function */
1657 "R_MIPS16_TLS_TPREL_LO16", /* name */
1658 TRUE, /* partial_inplace */
1659 0x0000ffff, /* src_mask */
1660 0x0000ffff, /* dst_mask */
1661 FALSE), /* pcrel_offset */
1664 static reloc_howto_type elf_mips16_howto_table_rela[] =
1666 /* The reloc used for the mips16 jump instruction. */
1667 HOWTO (R_MIPS16_26, /* type */
1669 2, /* size (0 = byte, 1 = short, 2 = long) */
1671 FALSE, /* pc_relative */
1673 complain_overflow_dont, /* complain_on_overflow */
1674 /* This needs complex overflow
1675 detection, because the upper four
1676 bits must match the PC. */
1677 _bfd_mips_elf_generic_reloc, /* special_function */
1678 "R_MIPS16_26", /* name */
1679 FALSE, /* partial_inplace */
1681 0x3ffffff, /* dst_mask */
1682 FALSE), /* pcrel_offset */
1684 /* The reloc used for the mips16 gprel instruction. */
1685 HOWTO (R_MIPS16_GPREL, /* type */
1687 2, /* size (0 = byte, 1 = short, 2 = long) */
1689 FALSE, /* pc_relative */
1691 complain_overflow_signed, /* complain_on_overflow */
1692 mips16_gprel_reloc, /* special_function */
1693 "R_MIPS16_GPREL", /* name */
1694 FALSE, /* partial_inplace */
1696 0x0000ffff, /* dst_mask */
1697 FALSE), /* pcrel_offset */
1699 /* A MIPS16 reference to the global offset table. */
1700 HOWTO (R_MIPS16_GOT16, /* type */
1702 2, /* size (0 = byte, 1 = short, 2 = long) */
1704 FALSE, /* pc_relative */
1706 complain_overflow_dont, /* complain_on_overflow */
1707 _bfd_mips_elf_got16_reloc, /* special_function */
1708 "R_MIPS16_GOT16", /* name */
1709 FALSE, /* partial_inplace */
1711 0x0000ffff, /* dst_mask */
1712 FALSE), /* pcrel_offset */
1714 /* A MIPS16 call through the global offset table. */
1715 HOWTO (R_MIPS16_CALL16, /* type */
1717 2, /* size (0 = byte, 1 = short, 2 = long) */
1719 FALSE, /* pc_relative */
1721 complain_overflow_dont, /* complain_on_overflow */
1722 _bfd_mips_elf_generic_reloc, /* special_function */
1723 "R_MIPS16_CALL16", /* name */
1724 FALSE, /* partial_inplace */
1726 0x0000ffff, /* dst_mask */
1727 FALSE), /* pcrel_offset */
1729 /* MIPS16 high 16 bits of symbol value. */
1730 HOWTO (R_MIPS16_HI16, /* type */
1731 16, /* rightshift */
1732 2, /* size (0 = byte, 1 = short, 2 = long) */
1734 FALSE, /* pc_relative */
1736 complain_overflow_dont, /* complain_on_overflow */
1737 _bfd_mips_elf_hi16_reloc, /* special_function */
1738 "R_MIPS16_HI16", /* name */
1739 FALSE, /* partial_inplace */
1741 0x0000ffff, /* dst_mask */
1742 FALSE), /* pcrel_offset */
1744 /* MIPS16 low 16 bits of symbol value. */
1745 HOWTO (R_MIPS16_LO16, /* type */
1747 2, /* size (0 = byte, 1 = short, 2 = long) */
1749 FALSE, /* pc_relative */
1751 complain_overflow_dont, /* complain_on_overflow */
1752 _bfd_mips_elf_lo16_reloc, /* special_function */
1753 "R_MIPS16_LO16", /* name */
1754 FALSE, /* partial_inplace */
1756 0x0000ffff, /* dst_mask */
1757 FALSE), /* pcrel_offset */
1759 /* MIPS16 TLS general dynamic variable reference. */
1760 HOWTO (R_MIPS16_TLS_GD, /* type */
1762 2, /* size (0 = byte, 1 = short, 2 = long) */
1764 FALSE, /* pc_relative */
1766 complain_overflow_signed, /* complain_on_overflow */
1767 _bfd_mips_elf_generic_reloc, /* special_function */
1768 "R_MIPS16_TLS_GD", /* name */
1769 FALSE, /* partial_inplace */
1771 0x0000ffff, /* dst_mask */
1772 FALSE), /* pcrel_offset */
1774 /* MIPS16 TLS local dynamic variable reference. */
1775 HOWTO (R_MIPS16_TLS_LDM, /* type */
1777 2, /* size (0 = byte, 1 = short, 2 = long) */
1779 FALSE, /* pc_relative */
1781 complain_overflow_signed, /* complain_on_overflow */
1782 _bfd_mips_elf_generic_reloc, /* special_function */
1783 "R_MIPS16_TLS_LDM", /* name */
1784 FALSE, /* partial_inplace */
1786 0x0000ffff, /* dst_mask */
1787 FALSE), /* pcrel_offset */
1789 /* MIPS16 TLS local dynamic offset. */
1790 HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */
1792 2, /* size (0 = byte, 1 = short, 2 = long) */
1794 FALSE, /* pc_relative */
1796 complain_overflow_signed, /* complain_on_overflow */
1797 _bfd_mips_elf_generic_reloc, /* special_function */
1798 "R_MIPS16_TLS_DTPREL_HI16", /* name */
1799 FALSE, /* partial_inplace */
1801 0x0000ffff, /* dst_mask */
1802 FALSE), /* pcrel_offset */
1804 /* MIPS16 TLS local dynamic offset. */
1805 HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */
1807 2, /* size (0 = byte, 1 = short, 2 = long) */
1809 FALSE, /* pc_relative */
1811 complain_overflow_signed, /* complain_on_overflow */
1812 _bfd_mips_elf_generic_reloc, /* special_function */
1813 "R_MIPS16_TLS_DTPREL_LO16", /* name */
1814 FALSE, /* partial_inplace */
1816 0x0000ffff, /* dst_mask */
1817 FALSE), /* pcrel_offset */
1819 /* MIPS16 TLS thread pointer offset. */
1820 HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */
1822 2, /* size (0 = byte, 1 = short, 2 = long) */
1824 FALSE, /* pc_relative */
1826 complain_overflow_signed, /* complain_on_overflow */
1827 _bfd_mips_elf_generic_reloc, /* special_function */
1828 "R_MIPS16_TLS_GOTTPREL", /* name */
1829 FALSE, /* partial_inplace */
1831 0x0000ffff, /* dst_mask */
1832 FALSE), /* pcrel_offset */
1834 /* MIPS16 TLS thread pointer offset. */
1835 HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */
1837 2, /* size (0 = byte, 1 = short, 2 = long) */
1839 FALSE, /* pc_relative */
1841 complain_overflow_signed, /* complain_on_overflow */
1842 _bfd_mips_elf_generic_reloc, /* special_function */
1843 "R_MIPS16_TLS_TPREL_HI16", /* name */
1844 FALSE, /* partial_inplace */
1846 0x0000ffff, /* dst_mask */
1847 FALSE), /* pcrel_offset */
1849 /* MIPS16 TLS thread pointer offset. */
1850 HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */
1852 2, /* size (0 = byte, 1 = short, 2 = long) */
1854 FALSE, /* pc_relative */
1856 complain_overflow_signed, /* complain_on_overflow */
1857 _bfd_mips_elf_generic_reloc, /* special_function */
1858 "R_MIPS16_TLS_TPREL_LO16", /* name */
1859 FALSE, /* partial_inplace */
1861 0x0000ffff, /* dst_mask */
1862 FALSE), /* pcrel_offset */
1865 static reloc_howto_type elf_micromips_howto_table_rel[] =
1871 /* 26 bit jump address. */
1872 HOWTO (R_MICROMIPS_26_S1, /* type */
1874 2, /* size (0 = byte, 1 = short, 2 = long) */
1876 FALSE, /* pc_relative */
1878 complain_overflow_dont, /* complain_on_overflow */
1879 /* This needs complex overflow
1880 detection, because the upper four
1881 bits must match the PC. */
1882 _bfd_mips_elf_generic_reloc, /* special_function */
1883 "R_MICROMIPS_26_S1", /* name */
1884 TRUE, /* partial_inplace */
1885 0x3ffffff, /* src_mask */
1886 0x3ffffff, /* dst_mask */
1887 FALSE), /* pcrel_offset */
1889 /* High 16 bits of symbol value. */
1890 HOWTO (R_MICROMIPS_HI16, /* type */
1891 16, /* rightshift */
1892 2, /* size (0 = byte, 1 = short, 2 = long) */
1894 FALSE, /* pc_relative */
1896 complain_overflow_dont, /* complain_on_overflow */
1897 _bfd_mips_elf_hi16_reloc, /* special_function */
1898 "R_MICROMIPS_HI16", /* name */
1899 TRUE, /* partial_inplace */
1900 0x0000ffff, /* src_mask */
1901 0x0000ffff, /* dst_mask */
1902 FALSE), /* pcrel_offset */
1904 /* Low 16 bits of symbol value. */
1905 HOWTO (R_MICROMIPS_LO16, /* type */
1907 2, /* size (0 = byte, 1 = short, 2 = long) */
1909 FALSE, /* pc_relative */
1911 complain_overflow_dont, /* complain_on_overflow */
1912 _bfd_mips_elf_lo16_reloc, /* special_function */
1913 "R_MICROMIPS_LO16", /* name */
1914 TRUE, /* partial_inplace */
1915 0x0000ffff, /* src_mask */
1916 0x0000ffff, /* dst_mask */
1917 FALSE), /* pcrel_offset */
1919 /* GP relative reference. */
1920 HOWTO (R_MICROMIPS_GPREL16, /* type */
1922 2, /* size (0 = byte, 1 = short, 2 = long) */
1924 FALSE, /* pc_relative */
1926 complain_overflow_signed, /* complain_on_overflow */
1927 _bfd_mips_elf32_gprel16_reloc, /* special_function */
1928 "R_MICROMIPS_GPREL16", /* name */
1929 TRUE, /* partial_inplace */
1930 0x0000ffff, /* src_mask */
1931 0x0000ffff, /* dst_mask */
1932 FALSE), /* pcrel_offset */
1934 /* Reference to literal section. */
1935 HOWTO (R_MICROMIPS_LITERAL, /* type */
1937 2, /* size (0 = byte, 1 = short, 2 = long) */
1939 FALSE, /* pc_relative */
1941 complain_overflow_signed, /* complain_on_overflow */
1942 _bfd_mips_elf32_gprel16_reloc, /* special_function */
1943 "R_MICROMIPS_LITERAL", /* name */
1944 TRUE, /* partial_inplace */
1945 0x0000ffff, /* src_mask */
1946 0x0000ffff, /* dst_mask */
1947 FALSE), /* pcrel_offset */
1949 /* Reference to global offset table. */
1950 HOWTO (R_MICROMIPS_GOT16, /* type */
1952 2, /* size (0 = byte, 1 = short, 2 = long) */
1954 FALSE, /* pc_relative */
1956 complain_overflow_signed, /* complain_on_overflow */
1957 _bfd_mips_elf_got16_reloc, /* special_function */
1958 "R_MICROMIPS_GOT16", /* name */
1959 TRUE, /* partial_inplace */
1960 0x0000ffff, /* src_mask */
1961 0x0000ffff, /* dst_mask */
1962 FALSE), /* pcrel_offset */
1964 /* This is for microMIPS branches. */
1965 HOWTO (R_MICROMIPS_PC7_S1, /* type */
1967 1, /* size (0 = byte, 1 = short, 2 = long) */
1969 TRUE, /* pc_relative */
1971 complain_overflow_signed, /* complain_on_overflow */
1972 _bfd_mips_elf_generic_reloc, /* special_function */
1973 "R_MICROMIPS_PC7_S1", /* name */
1974 TRUE, /* partial_inplace */
1975 0x0000007f, /* src_mask */
1976 0x0000007f, /* dst_mask */
1977 TRUE), /* pcrel_offset */
1979 HOWTO (R_MICROMIPS_PC10_S1, /* type */
1981 1, /* size (0 = byte, 1 = short, 2 = long) */
1983 TRUE, /* pc_relative */
1985 complain_overflow_signed, /* complain_on_overflow */
1986 _bfd_mips_elf_generic_reloc, /* special_function */
1987 "R_MICROMIPS_PC10_S1", /* name */
1988 TRUE, /* partial_inplace */
1989 0x000003ff, /* src_mask */
1990 0x000003ff, /* dst_mask */
1991 TRUE), /* pcrel_offset */
1993 HOWTO (R_MICROMIPS_PC16_S1, /* type */
1995 2, /* size (0 = byte, 1 = short, 2 = long) */
1997 TRUE, /* pc_relative */
1999 complain_overflow_signed, /* complain_on_overflow */
2000 _bfd_mips_elf_generic_reloc, /* special_function */
2001 "R_MICROMIPS_PC16_S1", /* name */
2002 TRUE, /* partial_inplace */
2003 0x0000ffff, /* src_mask */
2004 0x0000ffff, /* dst_mask */
2005 TRUE), /* pcrel_offset */
2007 /* 16 bit call through global offset table. */
2008 HOWTO (R_MICROMIPS_CALL16, /* 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_MICROMIPS_CALL16", /* name */
2017 TRUE, /* partial_inplace */
2018 0x0000ffff, /* src_mask */
2019 0x0000ffff, /* dst_mask */
2020 FALSE), /* pcrel_offset */
2025 /* Displacement in the global offset table. */
2026 HOWTO (R_MICROMIPS_GOT_DISP, /* type */
2028 2, /* size (0 = byte, 1 = short, 2 = long) */
2030 FALSE, /* pc_relative */
2032 complain_overflow_signed, /* complain_on_overflow */
2033 _bfd_mips_elf_generic_reloc, /* special_function */
2034 "R_MICROMIPS_GOT_DISP",/* name */
2035 TRUE, /* partial_inplace */
2036 0x0000ffff, /* src_mask */
2037 0x0000ffff, /* dst_mask */
2038 FALSE), /* pcrel_offset */
2040 /* Displacement to page pointer in the global offset table. */
2041 HOWTO (R_MICROMIPS_GOT_PAGE, /* type */
2043 2, /* size (0 = byte, 1 = short, 2 = long) */
2045 FALSE, /* pc_relative */
2047 complain_overflow_signed, /* complain_on_overflow */
2048 _bfd_mips_elf_generic_reloc, /* special_function */
2049 "R_MICROMIPS_GOT_PAGE",/* name */
2050 TRUE, /* partial_inplace */
2051 0x0000ffff, /* src_mask */
2052 0x0000ffff, /* dst_mask */
2053 FALSE), /* pcrel_offset */
2055 /* Offset from page pointer in the global offset table. */
2056 HOWTO (R_MICROMIPS_GOT_OFST, /* type */
2058 2, /* size (0 = byte, 1 = short, 2 = long) */
2060 FALSE, /* pc_relative */
2062 complain_overflow_signed, /* complain_on_overflow */
2063 _bfd_mips_elf_generic_reloc, /* special_function */
2064 "R_MICROMIPS_GOT_OFST",/* name */
2065 TRUE, /* partial_inplace */
2066 0x0000ffff, /* src_mask */
2067 0x0000ffff, /* dst_mask */
2068 FALSE), /* pcrel_offset */
2070 /* High 16 bits of displacement in global offset table. */
2071 HOWTO (R_MICROMIPS_GOT_HI16, /* type */
2073 2, /* size (0 = byte, 1 = short, 2 = long) */
2075 FALSE, /* pc_relative */
2077 complain_overflow_dont, /* complain_on_overflow */
2078 _bfd_mips_elf_generic_reloc, /* special_function */
2079 "R_MICROMIPS_GOT_HI16",/* name */
2080 TRUE, /* partial_inplace */
2081 0x0000ffff, /* src_mask */
2082 0x0000ffff, /* dst_mask */
2083 FALSE), /* pcrel_offset */
2085 /* Low 16 bits of displacement in global offset table. */
2086 HOWTO (R_MICROMIPS_GOT_LO16, /* type */
2088 2, /* size (0 = byte, 1 = short, 2 = long) */
2090 FALSE, /* pc_relative */
2092 complain_overflow_dont, /* complain_on_overflow */
2093 _bfd_mips_elf_generic_reloc, /* special_function */
2094 "R_MICROMIPS_GOT_LO16",/* name */
2095 TRUE, /* partial_inplace */
2096 0x0000ffff, /* src_mask */
2097 0x0000ffff, /* dst_mask */
2098 FALSE), /* pcrel_offset */
2100 /* 64 bit subtraction. Used in the N32 ABI. */
2101 HOWTO (R_MICROMIPS_SUB, /* type */
2103 4, /* size (0 = byte, 1 = short, 2 = long) */
2105 FALSE, /* pc_relative */
2107 complain_overflow_dont, /* complain_on_overflow */
2108 _bfd_mips_elf_generic_reloc, /* special_function */
2109 "R_MICROMIPS_SUB", /* name */
2110 TRUE, /* partial_inplace */
2111 MINUS_ONE, /* src_mask */
2112 MINUS_ONE, /* dst_mask */
2113 FALSE), /* pcrel_offset */
2115 /* We don't support these for REL relocations, because it means building
2116 the addend from a R_MICROMIPS_HIGHEST/R_MICROMIPS_HIGHER/
2117 R_MICROMIPS_HI16/R_MICROMIPS_LO16 sequence with varying ordering,
2118 using fallable heuristics. */
2119 EMPTY_HOWTO (R_MICROMIPS_HIGHER),
2120 EMPTY_HOWTO (R_MICROMIPS_HIGHEST),
2122 /* High 16 bits of displacement in global offset table. */
2123 HOWTO (R_MICROMIPS_CALL_HI16, /* type */
2125 2, /* size (0 = byte, 1 = short, 2 = long) */
2127 FALSE, /* pc_relative */
2129 complain_overflow_dont, /* complain_on_overflow */
2130 _bfd_mips_elf_generic_reloc, /* special_function */
2131 "R_MICROMIPS_CALL_HI16",/* name */
2132 TRUE, /* partial_inplace */
2133 0x0000ffff, /* src_mask */
2134 0x0000ffff, /* dst_mask */
2135 FALSE), /* pcrel_offset */
2137 /* Low 16 bits of displacement in global offset table. */
2138 HOWTO (R_MICROMIPS_CALL_LO16, /* type */
2140 2, /* size (0 = byte, 1 = short, 2 = long) */
2142 FALSE, /* pc_relative */
2144 complain_overflow_dont, /* complain_on_overflow */
2145 _bfd_mips_elf_generic_reloc, /* special_function */
2146 "R_MICROMIPS_CALL_LO16",/* name */
2147 TRUE, /* partial_inplace */
2148 0x0000ffff, /* src_mask */
2149 0x0000ffff, /* dst_mask */
2150 FALSE), /* pcrel_offset */
2152 /* Section displacement. */
2153 HOWTO (R_MICROMIPS_SCN_DISP, /* type */
2155 2, /* size (0 = byte, 1 = short, 2 = long) */
2157 FALSE, /* pc_relative */
2159 complain_overflow_dont, /* complain_on_overflow */
2160 _bfd_mips_elf_generic_reloc, /* special_function */
2161 "R_MICROMIPS_SCN_DISP", /* name */
2162 TRUE, /* partial_inplace */
2163 0xffffffff, /* src_mask */
2164 0xffffffff, /* dst_mask */
2165 FALSE), /* pcrel_offset */
2167 /* Protected jump conversion. This is an optimization hint. No
2168 relocation is required for correctness. */
2169 HOWTO (R_MICROMIPS_JALR, /* type */
2171 2, /* size (0 = byte, 1 = short, 2 = long) */
2173 FALSE, /* pc_relative */
2175 complain_overflow_dont, /* complain_on_overflow */
2176 _bfd_mips_elf_generic_reloc, /* special_function */
2177 "R_MICROMIPS_JALR", /* name */
2178 FALSE, /* partial_inplace */
2180 0x00000000, /* dst_mask */
2181 FALSE), /* pcrel_offset */
2184 static reloc_howto_type elf_micromips_howto_table_rela[] =
2190 /* 26 bit jump address. */
2191 HOWTO (R_MICROMIPS_26_S1, /* type */
2193 2, /* size (0 = byte, 1 = short, 2 = long) */
2195 FALSE, /* pc_relative */
2197 complain_overflow_dont, /* complain_on_overflow */
2198 /* This needs complex overflow
2199 detection, because the upper four
2200 bits must match the PC. */
2201 _bfd_mips_elf_generic_reloc, /* special_function */
2202 "R_MICROMIPS_26_S1", /* name */
2203 FALSE, /* partial_inplace */
2205 0x3ffffff, /* dst_mask */
2206 FALSE), /* pcrel_offset */
2208 /* High 16 bits of symbol value. */
2209 HOWTO (R_MICROMIPS_HI16, /* type */
2210 16, /* rightshift */
2211 2, /* size (0 = byte, 1 = short, 2 = long) */
2213 FALSE, /* pc_relative */
2215 complain_overflow_dont, /* complain_on_overflow */
2216 _bfd_mips_elf_hi16_reloc, /* special_function */
2217 "R_MICROMIPS_HI16", /* name */
2218 FALSE, /* partial_inplace */
2220 0x0000ffff, /* dst_mask */
2221 FALSE), /* pcrel_offset */
2223 /* Low 16 bits of symbol value. */
2224 HOWTO (R_MICROMIPS_LO16, /* type */
2226 2, /* size (0 = byte, 1 = short, 2 = long) */
2228 FALSE, /* pc_relative */
2230 complain_overflow_dont, /* complain_on_overflow */
2231 _bfd_mips_elf_lo16_reloc, /* special_function */
2232 "R_MICROMIPS_LO16", /* name */
2233 FALSE, /* partial_inplace */
2235 0x0000ffff, /* dst_mask */
2236 FALSE), /* pcrel_offset */
2238 /* GP relative reference. */
2239 HOWTO (R_MICROMIPS_GPREL16, /* type */
2241 2, /* size (0 = byte, 1 = short, 2 = long) */
2243 FALSE, /* pc_relative */
2245 complain_overflow_signed, /* complain_on_overflow */
2246 _bfd_mips_elf32_gprel16_reloc, /* special_function */
2247 "R_MICROMIPS_GPREL16", /* name */
2248 FALSE, /* partial_inplace */
2250 0x0000ffff, /* dst_mask */
2251 FALSE), /* pcrel_offset */
2253 /* Reference to literal section. */
2254 HOWTO (R_MICROMIPS_LITERAL, /* type */
2256 2, /* size (0 = byte, 1 = short, 2 = long) */
2258 FALSE, /* pc_relative */
2260 complain_overflow_signed, /* complain_on_overflow */
2261 _bfd_mips_elf32_gprel16_reloc, /* special_function */
2262 "R_MICROMIPS_LITERAL", /* name */
2263 FALSE, /* partial_inplace */
2265 0x0000ffff, /* dst_mask */
2266 FALSE), /* pcrel_offset */
2268 /* Reference to global offset table. */
2269 HOWTO (R_MICROMIPS_GOT16, /* type */
2271 2, /* size (0 = byte, 1 = short, 2 = long) */
2273 FALSE, /* pc_relative */
2275 complain_overflow_signed, /* complain_on_overflow */
2276 _bfd_mips_elf_got16_reloc, /* special_function */
2277 "R_MICROMIPS_GOT16", /* name */
2278 FALSE, /* partial_inplace */
2280 0x0000ffff, /* dst_mask */
2281 FALSE), /* pcrel_offset */
2283 /* This is for microMIPS branches. */
2284 HOWTO (R_MICROMIPS_PC7_S1, /* type */
2286 1, /* size (0 = byte, 1 = short, 2 = long) */
2288 TRUE, /* pc_relative */
2290 complain_overflow_signed, /* complain_on_overflow */
2291 _bfd_mips_elf_generic_reloc, /* special_function */
2292 "R_MICROMIPS_PC7_S1", /* name */
2293 FALSE, /* partial_inplace */
2295 0x0000007f, /* dst_mask */
2296 TRUE), /* pcrel_offset */
2298 HOWTO (R_MICROMIPS_PC10_S1, /* type */
2300 1, /* size (0 = byte, 1 = short, 2 = long) */
2302 TRUE, /* pc_relative */
2304 complain_overflow_signed, /* complain_on_overflow */
2305 _bfd_mips_elf_generic_reloc, /* special_function */
2306 "R_MICROMIPS_PC10_S1", /* name */
2307 FALSE, /* partial_inplace */
2309 0x000003ff, /* dst_mask */
2310 TRUE), /* pcrel_offset */
2312 HOWTO (R_MICROMIPS_PC16_S1, /* type */
2314 2, /* size (0 = byte, 1 = short, 2 = long) */
2316 TRUE, /* pc_relative */
2318 complain_overflow_signed, /* complain_on_overflow */
2319 _bfd_mips_elf_generic_reloc, /* special_function */
2320 "R_MICROMIPS_PC16_S1", /* name */
2321 FALSE, /* partial_inplace */
2323 0x0000ffff, /* dst_mask */
2324 TRUE), /* pcrel_offset */
2326 /* 16 bit call through global offset table. */
2327 HOWTO (R_MICROMIPS_CALL16, /* type */
2329 2, /* size (0 = byte, 1 = short, 2 = long) */
2331 FALSE, /* pc_relative */
2333 complain_overflow_signed, /* complain_on_overflow */
2334 _bfd_mips_elf_generic_reloc, /* special_function */
2335 "R_MICROMIPS_CALL16", /* name */
2336 FALSE, /* partial_inplace */
2338 0x0000ffff, /* dst_mask */
2339 FALSE), /* pcrel_offset */
2344 /* Displacement in the global offset table. */
2345 HOWTO (R_MICROMIPS_GOT_DISP, /* type */
2347 2, /* size (0 = byte, 1 = short, 2 = long) */
2349 FALSE, /* pc_relative */
2351 complain_overflow_signed, /* complain_on_overflow */
2352 _bfd_mips_elf_generic_reloc, /* special_function */
2353 "R_MICROMIPS_GOT_DISP",/* name */
2354 FALSE, /* partial_inplace */
2356 0x0000ffff, /* dst_mask */
2357 FALSE), /* pcrel_offset */
2359 /* Displacement to page pointer in the global offset table. */
2360 HOWTO (R_MICROMIPS_GOT_PAGE, /* type */
2362 2, /* size (0 = byte, 1 = short, 2 = long) */
2364 FALSE, /* pc_relative */
2366 complain_overflow_signed, /* complain_on_overflow */
2367 _bfd_mips_elf_generic_reloc, /* special_function */
2368 "R_MICROMIPS_GOT_PAGE",/* name */
2369 FALSE, /* partial_inplace */
2371 0x0000ffff, /* dst_mask */
2372 FALSE), /* pcrel_offset */
2374 /* Offset from page pointer in the global offset table. */
2375 HOWTO (R_MICROMIPS_GOT_OFST, /* type */
2377 2, /* size (0 = byte, 1 = short, 2 = long) */
2379 FALSE, /* pc_relative */
2381 complain_overflow_signed, /* complain_on_overflow */
2382 _bfd_mips_elf_generic_reloc, /* special_function */
2383 "R_MICROMIPS_GOT_OFST",/* name */
2384 FALSE, /* partial_inplace */
2386 0x0000ffff, /* dst_mask */
2387 FALSE), /* pcrel_offset */
2389 /* High 16 bits of displacement in global offset table. */
2390 HOWTO (R_MICROMIPS_GOT_HI16, /* type */
2392 2, /* size (0 = byte, 1 = short, 2 = long) */
2394 FALSE, /* pc_relative */
2396 complain_overflow_dont, /* complain_on_overflow */
2397 _bfd_mips_elf_generic_reloc, /* special_function */
2398 "R_MICROMIPS_GOT_HI16",/* name */
2399 FALSE, /* partial_inplace */
2401 0x0000ffff, /* dst_mask */
2402 FALSE), /* pcrel_offset */
2404 /* Low 16 bits of displacement in global offset table. */
2405 HOWTO (R_MICROMIPS_GOT_LO16, /* type */
2407 2, /* size (0 = byte, 1 = short, 2 = long) */
2409 FALSE, /* pc_relative */
2411 complain_overflow_dont, /* complain_on_overflow */
2412 _bfd_mips_elf_generic_reloc, /* special_function */
2413 "R_MICROMIPS_GOT_LO16",/* name */
2414 FALSE, /* partial_inplace */
2416 0x0000ffff, /* dst_mask */
2417 FALSE), /* pcrel_offset */
2419 /* 64 bit subtraction. Used in the N32 ABI. */
2420 HOWTO (R_MICROMIPS_SUB, /* type */
2422 4, /* size (0 = byte, 1 = short, 2 = long) */
2424 FALSE, /* pc_relative */
2426 complain_overflow_dont, /* complain_on_overflow */
2427 _bfd_mips_elf_generic_reloc, /* special_function */
2428 "R_MICROMIPS_SUB", /* name */
2429 FALSE, /* partial_inplace */
2431 MINUS_ONE, /* dst_mask */
2432 FALSE), /* pcrel_offset */
2434 /* Get the higher value of a 64 bit addend. */
2435 HOWTO (R_MICROMIPS_HIGHER, /* type */
2437 2, /* size (0 = byte, 1 = short, 2 = long) */
2439 FALSE, /* pc_relative */
2441 complain_overflow_dont, /* complain_on_overflow */
2442 _bfd_mips_elf_generic_reloc, /* special_function */
2443 "R_MICROMIPS_HIGHER", /* name */
2444 FALSE, /* partial_inplace */
2446 0x0000ffff, /* dst_mask */
2447 FALSE), /* pcrel_offset */
2449 /* Get the highest value of a 64 bit addend. */
2450 HOWTO (R_MICROMIPS_HIGHEST, /* type */
2452 2, /* size (0 = byte, 1 = short, 2 = long) */
2454 FALSE, /* pc_relative */
2456 complain_overflow_dont, /* complain_on_overflow */
2457 _bfd_mips_elf_generic_reloc, /* special_function */
2458 "R_MICROMIPS_HIGHEST", /* name */
2459 FALSE, /* partial_inplace */
2461 0x0000ffff, /* dst_mask */
2462 FALSE), /* pcrel_offset */
2464 /* High 16 bits of displacement in global offset table. */
2465 HOWTO (R_MICROMIPS_CALL_HI16, /* type */
2467 2, /* size (0 = byte, 1 = short, 2 = long) */
2469 FALSE, /* pc_relative */
2471 complain_overflow_dont, /* complain_on_overflow */
2472 _bfd_mips_elf_generic_reloc, /* special_function */
2473 "R_MICROMIPS_CALL_HI16",/* name */
2474 FALSE, /* partial_inplace */
2476 0x0000ffff, /* dst_mask */
2477 FALSE), /* pcrel_offset */
2479 /* Low 16 bits of displacement in global offset table. */
2480 HOWTO (R_MICROMIPS_CALL_LO16, /* type */
2482 2, /* size (0 = byte, 1 = short, 2 = long) */
2484 FALSE, /* pc_relative */
2486 complain_overflow_dont, /* complain_on_overflow */
2487 _bfd_mips_elf_generic_reloc, /* special_function */
2488 "R_MICROMIPS_CALL_LO16",/* name */
2489 FALSE, /* partial_inplace */
2491 0x0000ffff, /* dst_mask */
2492 FALSE), /* pcrel_offset */
2494 /* Section displacement. */
2495 HOWTO (R_MICROMIPS_SCN_DISP, /* type */
2497 2, /* size (0 = byte, 1 = short, 2 = long) */
2499 FALSE, /* pc_relative */
2501 complain_overflow_dont, /* complain_on_overflow */
2502 _bfd_mips_elf_generic_reloc, /* special_function */
2503 "R_MICROMIPS_SCN_DISP", /* name */
2504 FALSE, /* partial_inplace */
2506 0xffffffff, /* dst_mask */
2507 FALSE), /* pcrel_offset */
2509 /* Protected jump conversion. This is an optimization hint. No
2510 relocation is required for correctness. */
2511 HOWTO (R_MICROMIPS_JALR, /* type */
2513 2, /* size (0 = byte, 1 = short, 2 = long) */
2515 FALSE, /* pc_relative */
2517 complain_overflow_dont, /* complain_on_overflow */
2518 _bfd_mips_elf_generic_reloc, /* special_function */
2519 "R_MICROMIPS_JALR", /* name */
2520 FALSE, /* partial_inplace */
2522 0x00000000, /* dst_mask */
2523 FALSE), /* pcrel_offset */
2526 /* GNU extension to record C++ vtable hierarchy */
2527 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
2528 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
2530 2, /* size (0 = byte, 1 = short, 2 = long) */
2532 FALSE, /* pc_relative */
2534 complain_overflow_dont, /* complain_on_overflow */
2535 NULL, /* special_function */
2536 "R_MIPS_GNU_VTINHERIT", /* name */
2537 FALSE, /* partial_inplace */
2540 FALSE); /* pcrel_offset */
2542 /* GNU extension to record C++ vtable member usage */
2543 static reloc_howto_type elf_mips_gnu_vtentry_howto =
2544 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
2546 2, /* size (0 = byte, 1 = short, 2 = long) */
2548 FALSE, /* pc_relative */
2550 complain_overflow_dont, /* complain_on_overflow */
2551 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
2552 "R_MIPS_GNU_VTENTRY", /* name */
2553 FALSE, /* partial_inplace */
2556 FALSE); /* pcrel_offset */
2558 /* 16 bit offset for pc-relative branches. */
2559 static reloc_howto_type elf_mips_gnu_rel16_s2 =
2560 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
2562 2, /* size (0 = byte, 1 = short, 2 = long) */
2564 TRUE, /* pc_relative */
2566 complain_overflow_signed, /* complain_on_overflow */
2567 _bfd_mips_elf_generic_reloc, /* special_function */
2568 "R_MIPS_GNU_REL16_S2", /* name */
2569 TRUE, /* partial_inplace */
2570 0x0000ffff, /* src_mask */
2571 0x0000ffff, /* dst_mask */
2572 TRUE); /* pcrel_offset */
2574 /* 16 bit offset for pc-relative branches. */
2575 static reloc_howto_type elf_mips_gnu_rela16_s2 =
2576 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
2578 2, /* size (0 = byte, 1 = short, 2 = long) */
2580 TRUE, /* pc_relative */
2582 complain_overflow_signed, /* complain_on_overflow */
2583 _bfd_mips_elf_generic_reloc, /* special_function */
2584 "R_MIPS_GNU_REL16_S2", /* name */
2585 FALSE, /* partial_inplace */
2587 0x0000ffff, /* dst_mask */
2588 TRUE); /* pcrel_offset */
2590 /* 32 bit pc-relative. Used for compact EH tables. */
2591 static reloc_howto_type elf_mips_gnu_pcrel32 =
2592 HOWTO (R_MIPS_PC32, /* type */
2594 2, /* size (0 = byte, 1 = short, 2 = long) */
2596 TRUE, /* pc_relative */
2598 complain_overflow_signed, /* complain_on_overflow */
2599 _bfd_mips_elf_generic_reloc, /* special_function */
2600 "R_MIPS_PC32", /* name */
2601 TRUE, /* partial_inplace */
2602 0xffffffff, /* src_mask */
2603 0xffffffff, /* dst_mask */
2604 TRUE); /* pcrel_offset */
2607 /* Originally a VxWorks extension, but now used for other systems too. */
2608 static reloc_howto_type elf_mips_copy_howto =
2609 HOWTO (R_MIPS_COPY, /* type */
2611 0, /* this one is variable size */
2613 FALSE, /* pc_relative */
2615 complain_overflow_bitfield, /* complain_on_overflow */
2616 _bfd_mips_elf_generic_reloc, /* special_function */
2617 "R_MIPS_COPY", /* name */
2618 FALSE, /* partial_inplace */
2621 FALSE); /* pcrel_offset */
2623 /* Originally a VxWorks extension, but now used for other systems too. */
2624 static reloc_howto_type elf_mips_jump_slot_howto =
2625 HOWTO (R_MIPS_JUMP_SLOT, /* type */
2627 2, /* size (0 = byte, 1 = short, 2 = long) */
2629 FALSE, /* pc_relative */
2631 complain_overflow_bitfield, /* complain_on_overflow */
2632 _bfd_mips_elf_generic_reloc, /* special_function */
2633 "R_MIPS_JUMP_SLOT", /* name */
2634 FALSE, /* partial_inplace */
2637 FALSE); /* pcrel_offset */
2639 /* Used in EH tables. */
2640 static reloc_howto_type elf_mips_eh_howto =
2641 HOWTO (R_MIPS_EH, /* type */
2643 2, /* size (0 = byte, 1 = short, 2 = long) */
2645 FALSE, /* pc_relative */
2647 complain_overflow_signed, /* complain_on_overflow */
2648 _bfd_mips_elf_generic_reloc, /* special_function */
2649 "R_MIPS_EH", /* name */
2650 TRUE, /* partial_inplace */
2651 0xffffffff, /* src_mask */
2652 0xffffffff, /* dst_mask */
2653 FALSE); /* pcrel_offset */
2656 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
2657 dangerous relocation. */
2660 mips_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
2666 /* If we've already figured out what GP will be, just return it. */
2667 *pgp = _bfd_get_gp_value (output_bfd);
2671 count = bfd_get_symcount (output_bfd);
2672 sym = bfd_get_outsymbols (output_bfd);
2674 /* The linker script will have created a symbol named `_gp' with the
2675 appropriate value. */
2680 for (i = 0; i < count; i++, sym++)
2682 register const char *name;
2684 name = bfd_asymbol_name (*sym);
2685 if (*name == '_' && strcmp (name, "_gp") == 0)
2687 *pgp = bfd_asymbol_value (*sym);
2688 _bfd_set_gp_value (output_bfd, *pgp);
2696 /* Only get the error once. */
2698 _bfd_set_gp_value (output_bfd, *pgp);
2705 /* We have to figure out the gp value, so that we can adjust the
2706 symbol value correctly. We look up the symbol _gp in the output
2707 BFD. If we can't find it, we're stuck. We cache it in the ELF
2708 target data. We don't need to adjust the symbol value for an
2709 external symbol if we are producing relocatable output. */
2711 static bfd_reloc_status_type
2712 mips_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
2713 char **error_message, bfd_vma *pgp)
2715 if (bfd_is_und_section (symbol->section)
2719 return bfd_reloc_undefined;
2722 *pgp = _bfd_get_gp_value (output_bfd);
2725 || (symbol->flags & BSF_SECTION_SYM) != 0))
2729 /* Make up a value. */
2730 *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
2731 _bfd_set_gp_value (output_bfd, *pgp);
2733 else if (!mips_elf_assign_gp (output_bfd, pgp))
2736 (char *) _("GP relative relocation when _gp not defined");
2737 return bfd_reloc_dangerous;
2741 return bfd_reloc_ok;
2744 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
2745 become the offset from the gp register. */
2747 static bfd_reloc_status_type
2748 mips_elf_gprel16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
2749 asymbol *symbol, void *data ATTRIBUTE_UNUSED,
2750 asection *input_section, bfd *output_bfd,
2751 char **error_message ATTRIBUTE_UNUSED)
2753 bfd_boolean relocatable;
2754 bfd_reloc_status_type ret;
2757 if (output_bfd != NULL)
2761 relocatable = FALSE;
2762 output_bfd = symbol->section->output_section->owner;
2765 ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
2767 if (ret != bfd_reloc_ok)
2770 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2771 input_section, relocatable,
2775 /* Do a R_MIPS_LITERAL relocation. */
2777 static bfd_reloc_status_type
2778 mips_elf_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2779 void *data, asection *input_section, bfd *output_bfd,
2780 char **error_message)
2782 bfd_boolean relocatable;
2783 bfd_reloc_status_type ret;
2786 /* R_MIPS_LITERAL relocations are defined for local symbols only. */
2787 if (output_bfd != NULL
2788 && (symbol->flags & BSF_SECTION_SYM) == 0
2789 && (symbol->flags & BSF_LOCAL) != 0)
2791 *error_message = (char *)
2792 _("literal relocation occurs for an external symbol");
2793 return bfd_reloc_outofrange;
2796 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
2797 if (output_bfd != NULL)
2801 relocatable = FALSE;
2802 output_bfd = symbol->section->output_section->owner;
2805 ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
2807 if (ret != bfd_reloc_ok)
2810 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2811 input_section, relocatable,
2815 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
2816 become the offset from the gp register. */
2818 static bfd_reloc_status_type
2819 mips_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2820 void *data, asection *input_section, bfd *output_bfd,
2821 char **error_message)
2823 bfd_boolean relocatable;
2824 bfd_reloc_status_type ret;
2827 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
2828 if (output_bfd != NULL
2829 && (symbol->flags & BSF_SECTION_SYM) == 0
2830 && (symbol->flags & BSF_LOCAL) != 0)
2832 *error_message = (char *)
2833 _("32bits gp relative relocation occurs for an external symbol");
2834 return bfd_reloc_outofrange;
2837 if (output_bfd != NULL)
2840 gp = _bfd_get_gp_value (output_bfd);
2844 relocatable = FALSE;
2845 output_bfd = symbol->section->output_section->owner;
2847 ret = mips_elf_final_gp (output_bfd, symbol, relocatable,
2848 error_message, &gp);
2849 if (ret != bfd_reloc_ok)
2853 return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
2854 relocatable, data, gp);
2857 static bfd_reloc_status_type
2858 gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
2859 asection *input_section, bfd_boolean relocatable,
2860 void *data, bfd_vma gp)
2865 if (bfd_is_com_section (symbol->section))
2868 relocation = symbol->value;
2870 relocation += symbol->section->output_section->vma;
2871 relocation += symbol->section->output_offset;
2873 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
2874 return bfd_reloc_outofrange;
2876 if (reloc_entry->howto->src_mask == 0)
2879 val = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
2881 /* Set val to the offset into the section or symbol. */
2882 val += reloc_entry->addend;
2884 /* Adjust val for the final section location and GP value. If we
2885 are producing relocatable output, we don't want to do this for
2886 an external symbol. */
2888 || (symbol->flags & BSF_SECTION_SYM) != 0)
2889 val += relocation - gp;
2891 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
2894 reloc_entry->address += input_section->output_offset;
2896 return bfd_reloc_ok;
2899 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
2900 the rest is at bits 6-10. The bitpos already got right by the howto. */
2902 static bfd_reloc_status_type
2903 mips_elf_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2904 void *data, asection *input_section, bfd *output_bfd,
2905 char **error_message)
2907 if (reloc_entry->howto->partial_inplace)
2909 reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
2910 | (reloc_entry->addend & 0x00000800) >> 9);
2913 return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
2914 input_section, output_bfd,
2918 /* Handle a mips16 GP relative reloc. */
2920 static bfd_reloc_status_type
2921 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2922 void *data, asection *input_section, bfd *output_bfd,
2923 char **error_message)
2925 bfd_boolean relocatable;
2926 bfd_reloc_status_type ret;
2930 /* If we're relocating, and this is an external symbol, we don't want
2931 to change anything. */
2932 if (output_bfd != NULL
2933 && (symbol->flags & BSF_SECTION_SYM) == 0
2934 && (symbol->flags & BSF_LOCAL) != 0)
2936 reloc_entry->address += input_section->output_offset;
2937 return bfd_reloc_ok;
2940 if (output_bfd != NULL)
2944 relocatable = FALSE;
2945 output_bfd = symbol->section->output_section->owner;
2948 ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
2950 if (ret != bfd_reloc_ok)
2953 location = (bfd_byte *) data + reloc_entry->address;
2954 _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
2956 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2957 input_section, relocatable,
2959 _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
2965 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
2967 struct elf_reloc_map {
2968 bfd_reloc_code_real_type bfd_val;
2969 enum elf_mips_reloc_type elf_val;
2972 static const struct elf_reloc_map mips_reloc_map[] =
2974 { BFD_RELOC_NONE, R_MIPS_NONE },
2975 { BFD_RELOC_16, R_MIPS_16 },
2976 { BFD_RELOC_32, R_MIPS_32 },
2977 /* There is no BFD reloc for R_MIPS_REL32. */
2978 { BFD_RELOC_CTOR, R_MIPS_32 },
2979 { BFD_RELOC_64, R_MIPS_64 },
2980 { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
2981 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
2982 { BFD_RELOC_LO16, R_MIPS_LO16 },
2983 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
2984 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
2985 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
2986 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
2987 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
2988 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
2989 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
2990 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
2991 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
2992 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
2993 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
2994 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
2995 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
2996 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
2997 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
2998 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
2999 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
3000 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
3001 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
3002 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
3003 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
3004 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
3005 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
3006 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
3007 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
3008 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
3009 { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
3010 { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
3011 { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
3012 { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
3013 { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
3014 { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
3015 { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
3016 { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
3017 { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
3018 { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
3019 { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
3020 { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
3021 { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
3024 static const struct elf_reloc_map mips16_reloc_map[] =
3026 { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
3027 { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
3028 { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
3029 { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
3030 { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
3031 { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
3032 { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
3033 { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
3034 { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
3035 R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
3036 { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
3037 R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
3038 { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
3039 { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
3040 { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
3043 static const struct elf_reloc_map micromips_reloc_map[] =
3045 { BFD_RELOC_MICROMIPS_JMP, R_MICROMIPS_26_S1 - R_MICROMIPS_min },
3046 { BFD_RELOC_MICROMIPS_HI16_S, R_MICROMIPS_HI16 - R_MICROMIPS_min },
3047 { BFD_RELOC_MICROMIPS_LO16, R_MICROMIPS_LO16 - R_MICROMIPS_min },
3048 { BFD_RELOC_MICROMIPS_GPREL16, R_MICROMIPS_GPREL16 - R_MICROMIPS_min },
3049 { BFD_RELOC_MICROMIPS_LITERAL, R_MICROMIPS_LITERAL - R_MICROMIPS_min },
3050 { BFD_RELOC_MICROMIPS_GOT16, R_MICROMIPS_GOT16 - R_MICROMIPS_min },
3051 { BFD_RELOC_MICROMIPS_7_PCREL_S1, R_MICROMIPS_PC7_S1 - R_MICROMIPS_min },
3052 { BFD_RELOC_MICROMIPS_10_PCREL_S1, R_MICROMIPS_PC10_S1 - R_MICROMIPS_min },
3053 { BFD_RELOC_MICROMIPS_16_PCREL_S1, R_MICROMIPS_PC16_S1 - R_MICROMIPS_min },
3054 { BFD_RELOC_MICROMIPS_CALL16, R_MICROMIPS_CALL16 - R_MICROMIPS_min },
3055 { BFD_RELOC_MICROMIPS_GOT_DISP, R_MICROMIPS_GOT_DISP - R_MICROMIPS_min },
3056 { BFD_RELOC_MICROMIPS_GOT_PAGE, R_MICROMIPS_GOT_PAGE - R_MICROMIPS_min },
3057 { BFD_RELOC_MICROMIPS_GOT_OFST, R_MICROMIPS_GOT_OFST - R_MICROMIPS_min },
3058 { BFD_RELOC_MICROMIPS_GOT_HI16, R_MICROMIPS_GOT_HI16 - R_MICROMIPS_min },
3059 { BFD_RELOC_MICROMIPS_GOT_LO16, R_MICROMIPS_GOT_LO16 - R_MICROMIPS_min },
3060 { BFD_RELOC_MICROMIPS_SUB, R_MICROMIPS_SUB - R_MICROMIPS_min },
3061 { BFD_RELOC_MICROMIPS_HIGHER, R_MICROMIPS_HIGHER - R_MICROMIPS_min },
3062 { BFD_RELOC_MICROMIPS_HIGHEST, R_MICROMIPS_HIGHEST - R_MICROMIPS_min },
3063 { BFD_RELOC_MICROMIPS_CALL_HI16, R_MICROMIPS_CALL_HI16 - R_MICROMIPS_min },
3064 { BFD_RELOC_MICROMIPS_CALL_LO16, R_MICROMIPS_CALL_LO16 - R_MICROMIPS_min },
3065 { BFD_RELOC_MICROMIPS_SCN_DISP, R_MICROMIPS_SCN_DISP - R_MICROMIPS_min },
3066 { BFD_RELOC_MICROMIPS_JALR, R_MICROMIPS_JALR - R_MICROMIPS_min },
3069 /* Given a BFD reloc type, return a howto structure. */
3071 static reloc_howto_type *
3072 bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3073 bfd_reloc_code_real_type code)
3076 /* FIXME: We default to RELA here instead of choosing the right
3077 relocation variant. */
3078 reloc_howto_type *howto_table = elf_mips_howto_table_rela;
3079 reloc_howto_type *howto16_table = elf_mips16_howto_table_rela;
3080 reloc_howto_type *howto_micromips_table = elf_micromips_howto_table_rela;
3082 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
3085 if (mips_reloc_map[i].bfd_val == code)
3086 return &howto_table[(int) mips_reloc_map[i].elf_val];
3089 for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
3092 if (mips16_reloc_map[i].bfd_val == code)
3093 return &howto16_table[(int) mips16_reloc_map[i].elf_val];
3096 for (i = 0; i < sizeof (micromips_reloc_map) / sizeof (struct elf_reloc_map);
3099 if (micromips_reloc_map[i].bfd_val == code)
3100 return &howto_micromips_table[(int) micromips_reloc_map[i].elf_val];
3105 case BFD_RELOC_VTABLE_INHERIT:
3106 return &elf_mips_gnu_vtinherit_howto;
3107 case BFD_RELOC_VTABLE_ENTRY:
3108 return &elf_mips_gnu_vtentry_howto;
3109 case BFD_RELOC_32_PCREL:
3110 return &elf_mips_gnu_pcrel32;
3111 case BFD_RELOC_MIPS_EH:
3112 return &elf_mips_eh_howto;
3113 case BFD_RELOC_MIPS_COPY:
3114 return &elf_mips_copy_howto;
3115 case BFD_RELOC_MIPS_JUMP_SLOT:
3116 return &elf_mips_jump_slot_howto;
3118 bfd_set_error (bfd_error_bad_value);
3123 static reloc_howto_type *
3124 bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3130 i < (sizeof (elf_mips_howto_table_rela)
3131 / sizeof (elf_mips_howto_table_rela[0]));
3133 if (elf_mips_howto_table_rela[i].name != NULL
3134 && strcasecmp (elf_mips_howto_table_rela[i].name, r_name) == 0)
3135 return &elf_mips_howto_table_rela[i];
3138 i < (sizeof (elf_mips16_howto_table_rela)
3139 / sizeof (elf_mips16_howto_table_rela[0]));
3141 if (elf_mips16_howto_table_rela[i].name != NULL
3142 && strcasecmp (elf_mips16_howto_table_rela[i].name, r_name) == 0)
3143 return &elf_mips16_howto_table_rela[i];
3146 i < (sizeof (elf_micromips_howto_table_rela)
3147 / sizeof (elf_micromips_howto_table_rela[0]));
3149 if (elf_micromips_howto_table_rela[i].name != NULL
3150 && strcasecmp (elf_micromips_howto_table_rela[i].name, r_name) == 0)
3151 return &elf_micromips_howto_table_rela[i];
3153 if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
3154 return &elf_mips_gnu_vtinherit_howto;
3155 if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
3156 return &elf_mips_gnu_vtentry_howto;
3157 if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
3158 return &elf_mips_gnu_rel16_s2;
3159 if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
3160 return &elf_mips_gnu_rela16_s2;
3161 if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
3162 return &elf_mips_gnu_pcrel32;
3163 if (strcasecmp (elf_mips_eh_howto.name, r_name) == 0)
3164 return &elf_mips_eh_howto;
3165 if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
3166 return &elf_mips_copy_howto;
3167 if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
3168 return &elf_mips_jump_slot_howto;
3173 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
3175 static reloc_howto_type *
3176 mips_elf_n32_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
3180 case R_MIPS_GNU_VTINHERIT:
3181 return &elf_mips_gnu_vtinherit_howto;
3182 case R_MIPS_GNU_VTENTRY:
3183 return &elf_mips_gnu_vtentry_howto;
3184 case R_MIPS_GNU_REL16_S2:
3186 return &elf_mips_gnu_rela16_s2;
3188 return &elf_mips_gnu_rel16_s2;
3190 return &elf_mips_gnu_pcrel32;
3192 return &elf_mips_eh_howto;
3194 return &elf_mips_copy_howto;
3195 case R_MIPS_JUMP_SLOT:
3196 return &elf_mips_jump_slot_howto;
3198 if (r_type >= R_MICROMIPS_min && r_type < R_MICROMIPS_max)
3201 return &elf_micromips_howto_table_rela[r_type - R_MICROMIPS_min];
3203 return &elf_micromips_howto_table_rel[r_type - R_MICROMIPS_min];
3205 if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
3208 return &elf_mips16_howto_table_rela[r_type - R_MIPS16_min];
3210 return &elf_mips16_howto_table_rel[r_type - R_MIPS16_min];
3212 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
3214 return &elf_mips_howto_table_rela[r_type];
3216 return &elf_mips_howto_table_rel[r_type];
3221 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
3224 mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
3226 unsigned int r_type;
3228 r_type = ELF32_R_TYPE (dst->r_info);
3229 cache_ptr->howto = mips_elf_n32_rtype_to_howto (r_type, FALSE);
3231 /* The addend for a GPREL16 or LITERAL relocation comes from the GP
3232 value for the object file. We get the addend now, rather than
3233 when we do the relocation, because the symbol manipulations done
3234 by the linker may cause us to lose track of the input BFD. */
3235 if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
3236 && (gprel16_reloc_p (r_type) || r_type == (unsigned int) R_MIPS_LITERAL))
3237 cache_ptr->addend = elf_gp (abfd);
3240 /* Given a MIPS Elf_Internal_Rela, fill in an arelent structure. */
3243 mips_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
3244 arelent *cache_ptr, Elf_Internal_Rela *dst)
3246 unsigned int r_type;
3248 r_type = ELF32_R_TYPE (dst->r_info);
3249 cache_ptr->howto = mips_elf_n32_rtype_to_howto (r_type, TRUE);
3250 cache_ptr->addend = dst->r_addend;
3253 /* Determine whether a symbol is global for the purposes of splitting
3254 the symbol table into global symbols and local symbols. At least
3255 on Irix 5, this split must be between section symbols and all other
3256 symbols. On most ELF targets the split is between static symbols
3257 and externally visible symbols. */
3260 mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
3262 if (SGI_COMPAT (abfd))
3263 return (sym->flags & BSF_SECTION_SYM) == 0;
3265 return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0
3266 || bfd_is_und_section (bfd_get_section (sym))
3267 || bfd_is_com_section (bfd_get_section (sym)));
3270 /* Set the right machine number for a MIPS ELF file. */
3273 mips_elf_n32_object_p (bfd *abfd)
3277 if (!ABI_N32_P (abfd))
3280 /* Irix 5 and 6 are broken. Object file symbol tables are not always
3281 sorted correctly such that local symbols precede global symbols,
3282 and the sh_info field in the symbol table is not always right. */
3283 if (SGI_COMPAT (abfd))
3284 elf_bad_symtab (abfd) = TRUE;
3286 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
3287 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
3291 /* Support for core dump NOTE sections. */
3293 elf32_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3298 switch (note->descsz)
3303 case 440: /* Linux/MIPS N32 */
3305 elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
3308 elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
3317 /* Make a ".reg/999" section. */
3318 return _bfd_elfcore_make_pseudosection (abfd, ".reg", size,
3319 note->descpos + offset);
3323 elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3325 switch (note->descsz)
3330 case 128: /* Linux/MIPS elf_prpsinfo */
3331 elf_tdata (abfd)->core->program
3332 = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
3333 elf_tdata (abfd)->core->command
3334 = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
3337 /* Note that for some reason, a spurious space is tacked
3338 onto the end of the args in some (at least one anyway)
3339 implementations, so strip it off if it exists. */
3342 char *command = elf_tdata (abfd)->core->command;
3343 int n = strlen (command);
3345 if (0 < n && command[n - 1] == ' ')
3346 command[n - 1] = '\0';
3352 /* Depending on the target vector we generate some version of Irix
3353 executables or "normal" MIPS ELF ABI executables. */
3354 static irix_compat_t
3355 elf_n32_mips_irix_compat (bfd *abfd)
3357 if ((abfd->xvec == &mips_elf32_n_be_vec)
3358 || (abfd->xvec == &mips_elf32_n_le_vec))
3364 /* ECOFF swapping routines. These are used when dealing with the
3365 .mdebug section, which is in the ECOFF debugging format. */
3366 static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
3367 /* Symbol table magic number. */
3369 /* Alignment of debugging information. E.g., 4. */
3371 /* Sizes of external symbolic information. */
3372 sizeof (struct hdr_ext),
3373 sizeof (struct dnr_ext),
3374 sizeof (struct pdr_ext),
3375 sizeof (struct sym_ext),
3376 sizeof (struct opt_ext),
3377 sizeof (struct fdr_ext),
3378 sizeof (struct rfd_ext),
3379 sizeof (struct ext_ext),
3380 /* Functions to swap in external symbolic data. */
3389 _bfd_ecoff_swap_tir_in,
3390 _bfd_ecoff_swap_rndx_in,
3391 /* Functions to swap out external symbolic data. */
3400 _bfd_ecoff_swap_tir_out,
3401 _bfd_ecoff_swap_rndx_out,
3402 /* Function to read in symbolic data. */
3403 _bfd_mips_elf_read_ecoff_info
3406 #define ELF_ARCH bfd_arch_mips
3407 #define ELF_TARGET_ID MIPS_ELF_DATA
3408 #define ELF_MACHINE_CODE EM_MIPS
3410 #define elf_backend_collect TRUE
3411 #define elf_backend_type_change_ok TRUE
3412 #define elf_backend_can_gc_sections TRUE
3413 #define elf_info_to_howto mips_info_to_howto_rela
3414 #define elf_info_to_howto_rel mips_info_to_howto_rel
3415 #define elf_backend_sym_is_global mips_elf_sym_is_global
3416 #define elf_backend_object_p mips_elf_n32_object_p
3417 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
3418 #define elf_backend_section_processing _bfd_mips_elf_section_processing
3419 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
3420 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
3421 #define elf_backend_section_from_bfd_section \
3422 _bfd_mips_elf_section_from_bfd_section
3423 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
3424 #define elf_backend_link_output_symbol_hook \
3425 _bfd_mips_elf_link_output_symbol_hook
3426 #define elf_backend_create_dynamic_sections \
3427 _bfd_mips_elf_create_dynamic_sections
3428 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
3429 #define elf_backend_merge_symbol_attribute \
3430 _bfd_mips_elf_merge_symbol_attribute
3431 #define elf_backend_get_target_dtag _bfd_mips_elf_get_target_dtag
3432 #define elf_backend_adjust_dynamic_symbol \
3433 _bfd_mips_elf_adjust_dynamic_symbol
3434 #define elf_backend_always_size_sections \
3435 _bfd_mips_elf_always_size_sections
3436 #define elf_backend_size_dynamic_sections \
3437 _bfd_mips_elf_size_dynamic_sections
3438 #define elf_backend_init_index_section _bfd_elf_init_1_index_section
3439 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
3440 #define elf_backend_finish_dynamic_symbol \
3441 _bfd_mips_elf_finish_dynamic_symbol
3442 #define elf_backend_finish_dynamic_sections \
3443 _bfd_mips_elf_finish_dynamic_sections
3444 #define elf_backend_final_write_processing \
3445 _bfd_mips_elf_final_write_processing
3446 #define elf_backend_additional_program_headers \
3447 _bfd_mips_elf_additional_program_headers
3448 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
3449 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
3450 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
3451 #define elf_backend_copy_indirect_symbol \
3452 _bfd_mips_elf_copy_indirect_symbol
3453 #define elf_backend_grok_prstatus elf32_mips_grok_prstatus
3454 #define elf_backend_grok_psinfo elf32_mips_grok_psinfo
3455 #define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap
3457 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
3459 /* MIPS n32 ELF can use a mixture of REL and RELA, but some Relocations
3460 work better/work only in RELA, so we default to this. */
3461 #define elf_backend_may_use_rel_p 1
3462 #define elf_backend_may_use_rela_p 1
3463 #define elf_backend_default_use_rela_p 1
3464 #define elf_backend_rela_plts_and_copies_p 0
3465 #define elf_backend_sign_extend_vma TRUE
3466 #define elf_backend_plt_readonly 1
3467 #define elf_backend_plt_sym_val _bfd_mips_elf_plt_sym_val
3469 #define elf_backend_discard_info _bfd_mips_elf_discard_info
3470 #define elf_backend_ignore_discarded_relocs \
3471 _bfd_mips_elf_ignore_discarded_relocs
3472 #define elf_backend_write_section _bfd_mips_elf_write_section
3473 #define elf_backend_mips_irix_compat elf_n32_mips_irix_compat
3474 #define elf_backend_mips_rtype_to_howto mips_elf_n32_rtype_to_howto
3475 #define bfd_elf32_bfd_is_target_special_symbol \
3476 _bfd_mips_elf_is_target_special_symbol
3477 #define bfd_elf32_find_nearest_line _bfd_mips_elf_find_nearest_line
3478 #define bfd_elf32_find_inliner_info _bfd_mips_elf_find_inliner_info
3479 #define bfd_elf32_new_section_hook _bfd_mips_elf_new_section_hook
3480 #define bfd_elf32_set_section_contents _bfd_mips_elf_set_section_contents
3481 #define bfd_elf32_bfd_get_relocated_section_contents \
3482 _bfd_elf_mips_get_relocated_section_contents
3483 #define bfd_elf32_bfd_link_hash_table_create \
3484 _bfd_mips_elf_link_hash_table_create
3485 #define bfd_elf32_bfd_final_link _bfd_mips_elf_final_link
3486 #define bfd_elf32_bfd_merge_private_bfd_data \
3487 _bfd_mips_elf_merge_private_bfd_data
3488 #define bfd_elf32_bfd_set_private_flags _bfd_mips_elf_set_private_flags
3489 #define bfd_elf32_bfd_print_private_bfd_data \
3490 _bfd_mips_elf_print_private_bfd_data
3491 #define bfd_elf32_bfd_relax_section _bfd_mips_relax_section
3492 #define bfd_elf32_mkobject _bfd_mips_elf_mkobject
3494 /* Support for SGI-ish mips targets using n32 ABI. */
3496 #define TARGET_LITTLE_SYM mips_elf32_n_le_vec
3497 #define TARGET_LITTLE_NAME "elf32-nlittlemips"
3498 #define TARGET_BIG_SYM mips_elf32_n_be_vec
3499 #define TARGET_BIG_NAME "elf32-nbigmips"
3501 #define ELF_MAXPAGESIZE 0x10000
3502 #define ELF_COMMONPAGESIZE 0x1000
3504 #include "elf32-target.h"
3506 /* Support for traditional mips targets using n32 ABI. */
3507 #undef TARGET_LITTLE_SYM
3508 #undef TARGET_LITTLE_NAME
3509 #undef TARGET_BIG_SYM
3510 #undef TARGET_BIG_NAME
3512 #undef ELF_MAXPAGESIZE
3513 #undef ELF_COMMONPAGESIZE
3515 #define TARGET_LITTLE_SYM mips_elf32_ntrad_le_vec
3516 #define TARGET_LITTLE_NAME "elf32-ntradlittlemips"
3517 #define TARGET_BIG_SYM mips_elf32_ntrad_be_vec
3518 #define TARGET_BIG_NAME "elf32-ntradbigmips"
3520 #define ELF_MAXPAGESIZE 0x10000
3521 #define ELF_COMMONPAGESIZE 0x1000
3522 #define elf32_bed elf32_tradbed
3524 /* Include the target file again for this target. */
3525 #include "elf32-target.h"
3528 /* FreeBSD support. */
3530 #undef TARGET_LITTLE_SYM
3531 #undef TARGET_LITTLE_NAME
3532 #undef TARGET_BIG_SYM
3533 #undef TARGET_BIG_NAME
3535 #define TARGET_LITTLE_SYM mips_elf32_ntradfbsd_le_vec
3536 #define TARGET_LITTLE_NAME "elf32-ntradlittlemips-freebsd"
3537 #define TARGET_BIG_SYM mips_elf32_ntradfbsd_be_vec
3538 #define TARGET_BIG_NAME "elf32-ntradbigmips-freebsd"
3541 #define ELF_OSABI ELFOSABI_FREEBSD
3544 #define elf32_bed elf32_fbsd_tradbed
3546 #include "elf32-target.h"