1 /* MIPS-specific support for 32-bit ELF
2 Copyright (C) 1993-2018 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"
41 #include "elf-vxworks.h"
43 /* Get the ECOFF swapping routines. */
45 #include "coff/symconst.h"
46 #include "coff/internal.h"
47 #include "coff/ecoff.h"
48 #include "coff/mips.h"
49 #define ECOFF_SIGNED_32
50 #include "ecoffswap.h"
52 static bfd_reloc_status_type gprel32_with_gp
53 (bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma);
54 static bfd_reloc_status_type mips_elf_gprel32_reloc
55 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
56 static bfd_reloc_status_type mips32_64bit_reloc
57 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
58 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
59 (bfd *, bfd_reloc_code_real_type);
60 static bfd_boolean mips_info_to_howto_rel
61 (bfd *, arelent *, Elf_Internal_Rela *);
62 static bfd_boolean mips_info_to_howto_rela
63 (bfd *, arelent *, Elf_Internal_Rela *);
64 static bfd_boolean mips_elf_sym_is_global
66 static bfd_boolean mips_elf32_object_p
68 static bfd_boolean mips_elf_is_local_label_name
69 (bfd *, const char *);
70 static bfd_reloc_status_type mips16_gprel_reloc
71 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
72 static bfd_reloc_status_type mips_elf_final_gp
73 (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
74 static bfd_boolean mips_elf_assign_gp
76 static bfd_boolean elf32_mips_grok_prstatus
77 (bfd *, Elf_Internal_Note *);
78 static bfd_boolean elf32_mips_grok_psinfo
79 (bfd *, Elf_Internal_Note *);
80 static irix_compat_t elf32_mips_irix_compat
83 extern const bfd_target mips_elf32_be_vec;
84 extern const bfd_target mips_elf32_le_vec;
86 /* Nonzero if ABFD is using the N32 ABI. */
87 #define ABI_N32_P(abfd) \
88 ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
90 /* Whether we are trying to be compatible with IRIX at all. */
91 #define SGI_COMPAT(abfd) \
92 (elf32_mips_irix_compat (abfd) != ict_none)
94 /* The number of local .got entries we reserve. */
95 #define MIPS_RESERVED_GOTNO (2)
97 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
98 from smaller values. Start with zero, widen, *then* decrement. */
99 #define MINUS_ONE (((bfd_vma)0) - 1)
101 /* The relocation table used for SHT_REL sections. */
103 static reloc_howto_type elf_mips_howto_table_rel[] =
106 HOWTO (R_MIPS_NONE, /* type */
108 3, /* size (0 = byte, 1 = short, 2 = long) */
110 FALSE, /* pc_relative */
112 complain_overflow_dont, /* complain_on_overflow */
113 _bfd_mips_elf_generic_reloc, /* special_function */
114 "R_MIPS_NONE", /* name */
115 FALSE, /* partial_inplace */
118 FALSE), /* pcrel_offset */
120 /* 16 bit relocation. */
121 HOWTO (R_MIPS_16, /* type */
123 2, /* size (0 = byte, 1 = short, 2 = long) */
125 FALSE, /* pc_relative */
127 complain_overflow_signed, /* complain_on_overflow */
128 _bfd_mips_elf_generic_reloc, /* special_function */
129 "R_MIPS_16", /* name */
130 TRUE, /* partial_inplace */
131 0x0000ffff, /* src_mask */
132 0x0000ffff, /* dst_mask */
133 FALSE), /* pcrel_offset */
135 /* 32 bit relocation. */
136 HOWTO (R_MIPS_32, /* type */
138 2, /* size (0 = byte, 1 = short, 2 = long) */
140 FALSE, /* pc_relative */
142 complain_overflow_dont, /* complain_on_overflow */
143 _bfd_mips_elf_generic_reloc, /* special_function */
144 "R_MIPS_32", /* name */
145 TRUE, /* partial_inplace */
146 0xffffffff, /* src_mask */
147 0xffffffff, /* dst_mask */
148 FALSE), /* pcrel_offset */
150 /* 32 bit symbol relative relocation. */
151 HOWTO (R_MIPS_REL32, /* type */
153 2, /* size (0 = byte, 1 = short, 2 = long) */
155 FALSE, /* pc_relative */
157 complain_overflow_dont, /* complain_on_overflow */
158 _bfd_mips_elf_generic_reloc, /* special_function */
159 "R_MIPS_REL32", /* name */
160 TRUE, /* partial_inplace */
161 0xffffffff, /* src_mask */
162 0xffffffff, /* dst_mask */
163 FALSE), /* pcrel_offset */
165 /* 26 bit jump address. */
166 HOWTO (R_MIPS_26, /* type */
168 2, /* size (0 = byte, 1 = short, 2 = long) */
170 FALSE, /* pc_relative */
172 complain_overflow_dont, /* complain_on_overflow */
173 /* This needs complex overflow
174 detection, because the upper four
175 bits must match the PC + 4. */
176 _bfd_mips_elf_generic_reloc, /* special_function */
177 "R_MIPS_26", /* name */
178 TRUE, /* partial_inplace */
179 0x03ffffff, /* src_mask */
180 0x03ffffff, /* dst_mask */
181 FALSE), /* pcrel_offset */
183 /* High 16 bits of symbol value. */
184 HOWTO (R_MIPS_HI16, /* type */
186 2, /* size (0 = byte, 1 = short, 2 = long) */
188 FALSE, /* pc_relative */
190 complain_overflow_dont, /* complain_on_overflow */
191 _bfd_mips_elf_hi16_reloc, /* special_function */
192 "R_MIPS_HI16", /* name */
193 TRUE, /* partial_inplace */
194 0x0000ffff, /* src_mask */
195 0x0000ffff, /* dst_mask */
196 FALSE), /* pcrel_offset */
198 /* Low 16 bits of symbol value. */
199 HOWTO (R_MIPS_LO16, /* type */
201 2, /* size (0 = byte, 1 = short, 2 = long) */
203 FALSE, /* pc_relative */
205 complain_overflow_dont, /* complain_on_overflow */
206 _bfd_mips_elf_lo16_reloc, /* special_function */
207 "R_MIPS_LO16", /* name */
208 TRUE, /* partial_inplace */
209 0x0000ffff, /* src_mask */
210 0x0000ffff, /* dst_mask */
211 FALSE), /* pcrel_offset */
213 /* GP relative reference. */
214 HOWTO (R_MIPS_GPREL16, /* type */
216 2, /* size (0 = byte, 1 = short, 2 = long) */
218 FALSE, /* pc_relative */
220 complain_overflow_signed, /* complain_on_overflow */
221 _bfd_mips_elf32_gprel16_reloc, /* special_function */
222 "R_MIPS_GPREL16", /* name */
223 TRUE, /* partial_inplace */
224 0x0000ffff, /* src_mask */
225 0x0000ffff, /* dst_mask */
226 FALSE), /* pcrel_offset */
228 /* Reference to literal section. */
229 HOWTO (R_MIPS_LITERAL, /* type */
231 2, /* size (0 = byte, 1 = short, 2 = long) */
233 FALSE, /* pc_relative */
235 complain_overflow_signed, /* complain_on_overflow */
236 _bfd_mips_elf32_gprel16_reloc, /* special_function */
237 "R_MIPS_LITERAL", /* name */
238 TRUE, /* partial_inplace */
239 0x0000ffff, /* src_mask */
240 0x0000ffff, /* dst_mask */
241 FALSE), /* pcrel_offset */
243 /* Reference to global offset table. */
244 HOWTO (R_MIPS_GOT16, /* type */
246 2, /* size (0 = byte, 1 = short, 2 = long) */
248 FALSE, /* pc_relative */
250 complain_overflow_signed, /* complain_on_overflow */
251 _bfd_mips_elf_got16_reloc, /* special_function */
252 "R_MIPS_GOT16", /* name */
253 TRUE, /* partial_inplace */
254 0x0000ffff, /* src_mask */
255 0x0000ffff, /* dst_mask */
256 FALSE), /* pcrel_offset */
258 /* 16 bit PC relative reference. Note that the ABI document has a typo
259 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
260 We do the right thing here. */
261 HOWTO (R_MIPS_PC16, /* type */
263 2, /* size (0 = byte, 1 = short, 2 = long) */
265 TRUE, /* pc_relative */
267 complain_overflow_signed, /* complain_on_overflow */
268 _bfd_mips_elf_generic_reloc, /* special_function */
269 "R_MIPS_PC16", /* name */
270 TRUE, /* partial_inplace */
271 0x0000ffff, /* src_mask */
272 0x0000ffff, /* dst_mask */
273 TRUE), /* pcrel_offset */
275 /* 16 bit call through global offset table. */
276 HOWTO (R_MIPS_CALL16, /* type */
278 2, /* size (0 = byte, 1 = short, 2 = long) */
280 FALSE, /* pc_relative */
282 complain_overflow_signed, /* complain_on_overflow */
283 _bfd_mips_elf_generic_reloc, /* special_function */
284 "R_MIPS_CALL16", /* name */
285 TRUE, /* partial_inplace */
286 0x0000ffff, /* src_mask */
287 0x0000ffff, /* dst_mask */
288 FALSE), /* pcrel_offset */
290 /* 32 bit GP relative reference. */
291 HOWTO (R_MIPS_GPREL32, /* type */
293 2, /* size (0 = byte, 1 = short, 2 = long) */
295 FALSE, /* pc_relative */
297 complain_overflow_dont, /* complain_on_overflow */
298 mips_elf_gprel32_reloc, /* special_function */
299 "R_MIPS_GPREL32", /* name */
300 TRUE, /* partial_inplace */
301 0xffffffff, /* src_mask */
302 0xffffffff, /* dst_mask */
303 FALSE), /* pcrel_offset */
305 /* The remaining relocs are defined on Irix 5, although they are
306 not defined by the ABI. */
311 /* A 5 bit shift field. */
312 HOWTO (R_MIPS_SHIFT5, /* type */
314 2, /* size (0 = byte, 1 = short, 2 = long) */
316 FALSE, /* pc_relative */
318 complain_overflow_bitfield, /* complain_on_overflow */
319 _bfd_mips_elf_generic_reloc, /* special_function */
320 "R_MIPS_SHIFT5", /* name */
321 TRUE, /* partial_inplace */
322 0x000007c0, /* src_mask */
323 0x000007c0, /* dst_mask */
324 FALSE), /* pcrel_offset */
326 /* A 6 bit shift field. */
327 /* FIXME: This is not handled correctly; a special function is
328 needed to put the most significant bit in the right place. */
329 HOWTO (R_MIPS_SHIFT6, /* type */
331 2, /* size (0 = byte, 1 = short, 2 = long) */
333 FALSE, /* pc_relative */
335 complain_overflow_bitfield, /* complain_on_overflow */
336 _bfd_mips_elf_generic_reloc, /* special_function */
337 "R_MIPS_SHIFT6", /* name */
338 TRUE, /* partial_inplace */
339 0x000007c4, /* src_mask */
340 0x000007c4, /* dst_mask */
341 FALSE), /* pcrel_offset */
343 /* A 64 bit relocation. */
344 HOWTO (R_MIPS_64, /* type */
346 4, /* size (0 = byte, 1 = short, 2 = long) */
348 FALSE, /* pc_relative */
350 complain_overflow_dont, /* complain_on_overflow */
351 mips32_64bit_reloc, /* special_function */
352 "R_MIPS_64", /* name */
353 TRUE, /* partial_inplace */
354 MINUS_ONE, /* src_mask */
355 MINUS_ONE, /* dst_mask */
356 FALSE), /* pcrel_offset */
358 /* Displacement in the global offset table. */
359 HOWTO (R_MIPS_GOT_DISP, /* type */
361 2, /* size (0 = byte, 1 = short, 2 = long) */
363 FALSE, /* pc_relative */
365 complain_overflow_signed, /* complain_on_overflow */
366 _bfd_mips_elf_generic_reloc, /* special_function */
367 "R_MIPS_GOT_DISP", /* name */
368 TRUE, /* partial_inplace */
369 0x0000ffff, /* src_mask */
370 0x0000ffff, /* dst_mask */
371 FALSE), /* pcrel_offset */
373 /* Displacement to page pointer in the global offset table. */
374 HOWTO (R_MIPS_GOT_PAGE, /* type */
376 2, /* size (0 = byte, 1 = short, 2 = long) */
378 FALSE, /* pc_relative */
380 complain_overflow_signed, /* complain_on_overflow */
381 _bfd_mips_elf_generic_reloc, /* special_function */
382 "R_MIPS_GOT_PAGE", /* name */
383 TRUE, /* partial_inplace */
384 0x0000ffff, /* src_mask */
385 0x0000ffff, /* dst_mask */
386 FALSE), /* pcrel_offset */
388 /* Offset from page pointer in the global offset table. */
389 HOWTO (R_MIPS_GOT_OFST, /* type */
391 2, /* size (0 = byte, 1 = short, 2 = long) */
393 FALSE, /* pc_relative */
395 complain_overflow_signed, /* complain_on_overflow */
396 _bfd_mips_elf_generic_reloc, /* special_function */
397 "R_MIPS_GOT_OFST", /* name */
398 TRUE, /* partial_inplace */
399 0x0000ffff, /* src_mask */
400 0x0000ffff, /* dst_mask */
401 FALSE), /* pcrel_offset */
403 /* High 16 bits of displacement in global offset table. */
404 HOWTO (R_MIPS_GOT_HI16, /* type */
406 2, /* size (0 = byte, 1 = short, 2 = long) */
408 FALSE, /* pc_relative */
410 complain_overflow_dont, /* complain_on_overflow */
411 _bfd_mips_elf_generic_reloc, /* special_function */
412 "R_MIPS_GOT_HI16", /* name */
413 TRUE, /* partial_inplace */
414 0x0000ffff, /* src_mask */
415 0x0000ffff, /* dst_mask */
416 FALSE), /* pcrel_offset */
418 /* Low 16 bits of displacement in global offset table. */
419 HOWTO (R_MIPS_GOT_LO16, /* type */
421 2, /* size (0 = byte, 1 = short, 2 = long) */
423 FALSE, /* pc_relative */
425 complain_overflow_dont, /* complain_on_overflow */
426 _bfd_mips_elf_generic_reloc, /* special_function */
427 "R_MIPS_GOT_LO16", /* name */
428 TRUE, /* partial_inplace */
429 0x0000ffff, /* src_mask */
430 0x0000ffff, /* dst_mask */
431 FALSE), /* pcrel_offset */
433 /* 64 bit subtraction. Used in the N32 ABI. */
434 HOWTO (R_MIPS_SUB, /* type */
436 4, /* size (0 = byte, 1 = short, 2 = long) */
438 FALSE, /* pc_relative */
440 complain_overflow_dont, /* complain_on_overflow */
441 _bfd_mips_elf_generic_reloc, /* special_function */
442 "R_MIPS_SUB", /* name */
443 TRUE, /* partial_inplace */
444 MINUS_ONE, /* src_mask */
445 MINUS_ONE, /* dst_mask */
446 FALSE), /* pcrel_offset */
448 /* Used to cause the linker to insert and delete instructions? */
449 EMPTY_HOWTO (R_MIPS_INSERT_A),
450 EMPTY_HOWTO (R_MIPS_INSERT_B),
451 EMPTY_HOWTO (R_MIPS_DELETE),
453 /* Get the higher value of a 64 bit addend. */
454 HOWTO (R_MIPS_HIGHER, /* 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_HIGHER", /* name */
463 TRUE, /* partial_inplace */
464 0x0000ffff, /* src_mask */
465 0x0000ffff, /* dst_mask */
466 FALSE), /* pcrel_offset */
468 /* Get the highest value of a 64 bit addend. */
469 HOWTO (R_MIPS_HIGHEST, /* type */
471 2, /* size (0 = byte, 1 = short, 2 = long) */
473 FALSE, /* pc_relative */
475 complain_overflow_dont, /* complain_on_overflow */
476 _bfd_mips_elf_generic_reloc, /* special_function */
477 "R_MIPS_HIGHEST", /* name */
478 TRUE, /* partial_inplace */
479 0x0000ffff, /* src_mask */
480 0x0000ffff, /* dst_mask */
481 FALSE), /* pcrel_offset */
483 /* High 16 bits of displacement in global offset table. */
484 HOWTO (R_MIPS_CALL_HI16, /* type */
486 2, /* size (0 = byte, 1 = short, 2 = long) */
488 FALSE, /* pc_relative */
490 complain_overflow_dont, /* complain_on_overflow */
491 _bfd_mips_elf_generic_reloc, /* special_function */
492 "R_MIPS_CALL_HI16", /* name */
493 TRUE, /* partial_inplace */
494 0x0000ffff, /* src_mask */
495 0x0000ffff, /* dst_mask */
496 FALSE), /* pcrel_offset */
498 /* Low 16 bits of displacement in global offset table. */
499 HOWTO (R_MIPS_CALL_LO16, /* type */
501 2, /* size (0 = byte, 1 = short, 2 = long) */
503 FALSE, /* pc_relative */
505 complain_overflow_dont, /* complain_on_overflow */
506 _bfd_mips_elf_generic_reloc, /* special_function */
507 "R_MIPS_CALL_LO16", /* name */
508 TRUE, /* partial_inplace */
509 0x0000ffff, /* src_mask */
510 0x0000ffff, /* dst_mask */
511 FALSE), /* pcrel_offset */
513 /* Section displacement. */
514 HOWTO (R_MIPS_SCN_DISP, /* type */
516 2, /* size (0 = byte, 1 = short, 2 = long) */
518 FALSE, /* pc_relative */
520 complain_overflow_dont, /* complain_on_overflow */
521 _bfd_mips_elf_generic_reloc, /* special_function */
522 "R_MIPS_SCN_DISP", /* name */
523 TRUE, /* partial_inplace */
524 0xffffffff, /* src_mask */
525 0xffffffff, /* dst_mask */
526 FALSE), /* pcrel_offset */
528 EMPTY_HOWTO (R_MIPS_REL16),
529 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
530 EMPTY_HOWTO (R_MIPS_PJUMP),
531 EMPTY_HOWTO (R_MIPS_RELGOT),
533 /* Protected jump conversion. This is an optimization hint. No
534 relocation is required for correctness. */
535 HOWTO (R_MIPS_JALR, /* type */
537 2, /* size (0 = byte, 1 = short, 2 = long) */
539 FALSE, /* pc_relative */
541 complain_overflow_dont, /* complain_on_overflow */
542 _bfd_mips_elf_generic_reloc, /* special_function */
543 "R_MIPS_JALR", /* name */
544 FALSE, /* partial_inplace */
545 0x00000000, /* src_mask */
546 0x00000000, /* dst_mask */
547 FALSE), /* pcrel_offset */
549 /* TLS GD/LD dynamic relocations. */
550 HOWTO (R_MIPS_TLS_DTPMOD32, /* type */
552 2, /* size (0 = byte, 1 = short, 2 = long) */
554 FALSE, /* pc_relative */
556 complain_overflow_dont, /* complain_on_overflow */
557 _bfd_mips_elf_generic_reloc, /* special_function */
558 "R_MIPS_TLS_DTPMOD32", /* name */
559 TRUE, /* partial_inplace */
560 0xffffffff, /* src_mask */
561 0xffffffff, /* dst_mask */
562 FALSE), /* pcrel_offset */
564 HOWTO (R_MIPS_TLS_DTPREL32, /* type */
566 2, /* size (0 = byte, 1 = short, 2 = long) */
568 FALSE, /* pc_relative */
570 complain_overflow_dont, /* complain_on_overflow */
571 _bfd_mips_elf_generic_reloc, /* special_function */
572 "R_MIPS_TLS_DTPREL32", /* name */
573 TRUE, /* partial_inplace */
574 0xffffffff, /* src_mask */
575 0xffffffff, /* dst_mask */
576 FALSE), /* pcrel_offset */
578 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
579 EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
581 /* TLS general dynamic variable reference. */
582 HOWTO (R_MIPS_TLS_GD, /* type */
584 2, /* size (0 = byte, 1 = short, 2 = long) */
586 FALSE, /* pc_relative */
588 complain_overflow_signed, /* complain_on_overflow */
589 _bfd_mips_elf_generic_reloc, /* special_function */
590 "R_MIPS_TLS_GD", /* name */
591 TRUE, /* partial_inplace */
592 0x0000ffff, /* src_mask */
593 0x0000ffff, /* dst_mask */
594 FALSE), /* pcrel_offset */
596 /* TLS local dynamic variable reference. */
597 HOWTO (R_MIPS_TLS_LDM, /* type */
599 2, /* size (0 = byte, 1 = short, 2 = long) */
601 FALSE, /* pc_relative */
603 complain_overflow_signed, /* complain_on_overflow */
604 _bfd_mips_elf_generic_reloc, /* special_function */
605 "R_MIPS_TLS_LDM", /* name */
606 TRUE, /* partial_inplace */
607 0x0000ffff, /* src_mask */
608 0x0000ffff, /* dst_mask */
609 FALSE), /* pcrel_offset */
611 /* TLS local dynamic offset. */
612 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
614 2, /* size (0 = byte, 1 = short, 2 = long) */
616 FALSE, /* pc_relative */
618 complain_overflow_signed, /* complain_on_overflow */
619 _bfd_mips_elf_generic_reloc, /* special_function */
620 "R_MIPS_TLS_DTPREL_HI16", /* name */
621 TRUE, /* partial_inplace */
622 0x0000ffff, /* src_mask */
623 0x0000ffff, /* dst_mask */
624 FALSE), /* pcrel_offset */
626 /* TLS local dynamic offset. */
627 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
629 2, /* size (0 = byte, 1 = short, 2 = long) */
631 FALSE, /* pc_relative */
633 complain_overflow_signed, /* complain_on_overflow */
634 _bfd_mips_elf_generic_reloc, /* special_function */
635 "R_MIPS_TLS_DTPREL_LO16", /* name */
636 TRUE, /* partial_inplace */
637 0x0000ffff, /* src_mask */
638 0x0000ffff, /* dst_mask */
639 FALSE), /* pcrel_offset */
641 /* TLS thread pointer offset. */
642 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
644 2, /* size (0 = byte, 1 = short, 2 = long) */
646 FALSE, /* pc_relative */
648 complain_overflow_signed, /* complain_on_overflow */
649 _bfd_mips_elf_generic_reloc, /* special_function */
650 "R_MIPS_TLS_GOTTPREL", /* name */
651 TRUE, /* partial_inplace */
652 0x0000ffff, /* src_mask */
653 0x0000ffff, /* dst_mask */
654 FALSE), /* pcrel_offset */
656 /* TLS IE dynamic relocations. */
657 HOWTO (R_MIPS_TLS_TPREL32, /* type */
659 2, /* size (0 = byte, 1 = short, 2 = long) */
661 FALSE, /* pc_relative */
663 complain_overflow_dont, /* complain_on_overflow */
664 _bfd_mips_elf_generic_reloc, /* special_function */
665 "R_MIPS_TLS_TPREL32", /* name */
666 TRUE, /* partial_inplace */
667 0xffffffff, /* src_mask */
668 0xffffffff, /* dst_mask */
669 FALSE), /* pcrel_offset */
671 EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
673 /* TLS thread pointer offset. */
674 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
676 2, /* size (0 = byte, 1 = short, 2 = long) */
678 FALSE, /* pc_relative */
680 complain_overflow_signed, /* complain_on_overflow */
681 _bfd_mips_elf_generic_reloc, /* special_function */
682 "R_MIPS_TLS_TPREL_HI16", /* name */
683 TRUE, /* partial_inplace */
684 0x0000ffff, /* src_mask */
685 0x0000ffff, /* dst_mask */
686 FALSE), /* pcrel_offset */
688 /* TLS thread pointer offset. */
689 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
691 2, /* size (0 = byte, 1 = short, 2 = long) */
693 FALSE, /* pc_relative */
695 complain_overflow_signed, /* complain_on_overflow */
696 _bfd_mips_elf_generic_reloc, /* special_function */
697 "R_MIPS_TLS_TPREL_LO16", /* name */
698 TRUE, /* partial_inplace */
699 0x0000ffff, /* src_mask */
700 0x0000ffff, /* dst_mask */
701 FALSE), /* pcrel_offset */
703 /* 32 bit relocation with no addend. */
704 HOWTO (R_MIPS_GLOB_DAT, /* type */
706 2, /* size (0 = byte, 1 = short, 2 = long) */
708 FALSE, /* pc_relative */
710 complain_overflow_dont, /* complain_on_overflow */
711 _bfd_mips_elf_generic_reloc, /* special_function */
712 "R_MIPS_GLOB_DAT", /* name */
713 FALSE, /* partial_inplace */
715 0xffffffff, /* dst_mask */
716 FALSE), /* pcrel_offset */
727 HOWTO (R_MIPS_PC21_S2, /* type */
729 2, /* size (0 = byte, 1 = short, 2 = long) */
731 TRUE, /* pc_relative */
733 complain_overflow_signed, /* complain_on_overflow */
734 _bfd_mips_elf_generic_reloc, /* special_function */
735 "R_MIPS_PC21_S2", /* name */
736 TRUE, /* partial_inplace */
737 0x001fffff, /* src_mask */
738 0x001fffff, /* dst_mask */
739 TRUE), /* pcrel_offset */
741 HOWTO (R_MIPS_PC26_S2, /* type */
743 2, /* size (0 = byte, 1 = short, 2 = long) */
745 TRUE, /* pc_relative */
747 complain_overflow_signed, /* complain_on_overflow */
748 _bfd_mips_elf_generic_reloc, /* special_function */
749 "R_MIPS_PC26_S2", /* name */
750 TRUE, /* partial_inplace */
751 0x03ffffff, /* src_mask */
752 0x03ffffff, /* dst_mask */
753 TRUE), /* pcrel_offset */
755 HOWTO (R_MIPS_PC18_S3, /* type */
757 2, /* size (0 = byte, 1 = short, 2 = long) */
759 TRUE, /* pc_relative */
761 complain_overflow_signed, /* complain_on_overflow */
762 _bfd_mips_elf_generic_reloc, /* special_function */
763 "R_MIPS_PC18_S3", /* name */
764 TRUE, /* partial_inplace */
765 0x0003ffff, /* src_mask */
766 0x0003ffff, /* dst_mask */
767 TRUE), /* pcrel_offset */
769 HOWTO (R_MIPS_PC19_S2, /* type */
771 2, /* size (0 = byte, 1 = short, 2 = long) */
773 TRUE, /* pc_relative */
775 complain_overflow_signed, /* complain_on_overflow */
776 _bfd_mips_elf_generic_reloc, /* special_function */
777 "R_MIPS_PC19_S2", /* name */
778 TRUE, /* partial_inplace */
779 0x0007ffff, /* src_mask */
780 0x0007ffff, /* dst_mask */
781 TRUE), /* pcrel_offset */
783 HOWTO (R_MIPS_PCHI16, /* type */
785 2, /* size (0 = byte, 1 = short, 2 = long) */
787 TRUE, /* pc_relative */
789 complain_overflow_signed, /* complain_on_overflow */
790 _bfd_mips_elf_generic_reloc, /* special_function */
791 "R_MIPS_PCHI16", /* name */
792 TRUE, /* partial_inplace */
793 0x0000ffff, /* src_mask */
794 0x0000ffff, /* dst_mask */
795 TRUE), /* pcrel_offset */
797 HOWTO (R_MIPS_PCLO16, /* type */
799 2, /* size (0 = byte, 1 = short, 2 = long) */
801 TRUE, /* pc_relative */
803 complain_overflow_dont, /* complain_on_overflow */
804 _bfd_mips_elf_generic_reloc, /* special_function */
805 "R_MIPS_PCLO16", /* name */
806 TRUE, /* partial_inplace */
807 0x0000ffff, /* src_mask */
808 0x0000ffff, /* dst_mask */
809 TRUE), /* pcrel_offset */
812 /* The reloc used for BFD_RELOC_CTOR when doing a 64 bit link. This
813 is a hack to make the linker think that we need 64 bit values. */
814 static reloc_howto_type elf_mips_ctor64_howto =
815 HOWTO (R_MIPS_64, /* type */
817 4, /* size (0 = byte, 1 = short, 2 = long) */
819 FALSE, /* pc_relative */
821 complain_overflow_signed, /* complain_on_overflow */
822 mips32_64bit_reloc, /* special_function */
823 "R_MIPS_64", /* name */
824 TRUE, /* partial_inplace */
825 0xffffffff, /* src_mask */
826 0xffffffff, /* dst_mask */
827 FALSE); /* pcrel_offset */
829 static reloc_howto_type elf_mips16_howto_table_rel[] =
831 /* The reloc used for the mips16 jump instruction. */
832 HOWTO (R_MIPS16_26, /* type */
834 2, /* size (0 = byte, 1 = short, 2 = long) */
836 FALSE, /* pc_relative */
838 complain_overflow_dont, /* complain_on_overflow */
839 /* This needs complex overflow
840 detection, because the upper four
841 bits must match the PC. */
842 _bfd_mips_elf_generic_reloc, /* special_function */
843 "R_MIPS16_26", /* name */
844 TRUE, /* partial_inplace */
845 0x3ffffff, /* src_mask */
846 0x3ffffff, /* dst_mask */
847 FALSE), /* pcrel_offset */
849 /* The reloc used for the mips16 gprel instruction. */
850 HOWTO (R_MIPS16_GPREL, /* type */
852 2, /* size (0 = byte, 1 = short, 2 = long) */
854 FALSE, /* pc_relative */
856 complain_overflow_signed, /* complain_on_overflow */
857 mips16_gprel_reloc, /* special_function */
858 "R_MIPS16_GPREL", /* name */
859 TRUE, /* partial_inplace */
860 0x0000ffff, /* src_mask */
861 0x0000ffff, /* dst_mask */
862 FALSE), /* pcrel_offset */
864 /* A MIPS16 reference to the global offset table. */
865 HOWTO (R_MIPS16_GOT16, /* type */
867 2, /* size (0 = byte, 1 = short, 2 = long) */
869 FALSE, /* pc_relative */
871 complain_overflow_dont, /* complain_on_overflow */
872 _bfd_mips_elf_got16_reloc, /* special_function */
873 "R_MIPS16_GOT16", /* name */
874 TRUE, /* partial_inplace */
875 0x0000ffff, /* src_mask */
876 0x0000ffff, /* dst_mask */
877 FALSE), /* pcrel_offset */
879 /* A MIPS16 call through the global offset table. */
880 HOWTO (R_MIPS16_CALL16, /* type */
882 2, /* size (0 = byte, 1 = short, 2 = long) */
884 FALSE, /* pc_relative */
886 complain_overflow_dont, /* complain_on_overflow */
887 _bfd_mips_elf_generic_reloc, /* special_function */
888 "R_MIPS16_CALL16", /* name */
889 TRUE, /* partial_inplace */
890 0x0000ffff, /* src_mask */
891 0x0000ffff, /* dst_mask */
892 FALSE), /* pcrel_offset */
894 /* MIPS16 high 16 bits of symbol value. */
895 HOWTO (R_MIPS16_HI16, /* type */
897 2, /* size (0 = byte, 1 = short, 2 = long) */
899 FALSE, /* pc_relative */
901 complain_overflow_dont, /* complain_on_overflow */
902 _bfd_mips_elf_hi16_reloc, /* special_function */
903 "R_MIPS16_HI16", /* name */
904 TRUE, /* partial_inplace */
905 0x0000ffff, /* src_mask */
906 0x0000ffff, /* dst_mask */
907 FALSE), /* pcrel_offset */
909 /* MIPS16 low 16 bits of symbol value. */
910 HOWTO (R_MIPS16_LO16, /* type */
912 2, /* size (0 = byte, 1 = short, 2 = long) */
914 FALSE, /* pc_relative */
916 complain_overflow_dont, /* complain_on_overflow */
917 _bfd_mips_elf_lo16_reloc, /* special_function */
918 "R_MIPS16_LO16", /* name */
919 TRUE, /* partial_inplace */
920 0x0000ffff, /* src_mask */
921 0x0000ffff, /* dst_mask */
922 FALSE), /* pcrel_offset */
924 /* MIPS16 TLS general dynamic variable reference. */
925 HOWTO (R_MIPS16_TLS_GD, /* type */
927 2, /* size (0 = byte, 1 = short, 2 = long) */
929 FALSE, /* pc_relative */
931 complain_overflow_signed, /* complain_on_overflow */
932 _bfd_mips_elf_generic_reloc, /* special_function */
933 "R_MIPS16_TLS_GD", /* name */
934 TRUE, /* partial_inplace */
935 0x0000ffff, /* src_mask */
936 0x0000ffff, /* dst_mask */
937 FALSE), /* pcrel_offset */
939 /* MIPS16 TLS local dynamic variable reference. */
940 HOWTO (R_MIPS16_TLS_LDM, /* type */
942 2, /* size (0 = byte, 1 = short, 2 = long) */
944 FALSE, /* pc_relative */
946 complain_overflow_signed, /* complain_on_overflow */
947 _bfd_mips_elf_generic_reloc, /* special_function */
948 "R_MIPS16_TLS_LDM", /* name */
949 TRUE, /* partial_inplace */
950 0x0000ffff, /* src_mask */
951 0x0000ffff, /* dst_mask */
952 FALSE), /* pcrel_offset */
954 /* MIPS16 TLS local dynamic offset. */
955 HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */
957 2, /* size (0 = byte, 1 = short, 2 = long) */
959 FALSE, /* pc_relative */
961 complain_overflow_signed, /* complain_on_overflow */
962 _bfd_mips_elf_generic_reloc, /* special_function */
963 "R_MIPS16_TLS_DTPREL_HI16", /* name */
964 TRUE, /* partial_inplace */
965 0x0000ffff, /* src_mask */
966 0x0000ffff, /* dst_mask */
967 FALSE), /* pcrel_offset */
969 /* MIPS16 TLS local dynamic offset. */
970 HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */
972 2, /* size (0 = byte, 1 = short, 2 = long) */
974 FALSE, /* pc_relative */
976 complain_overflow_signed, /* complain_on_overflow */
977 _bfd_mips_elf_generic_reloc, /* special_function */
978 "R_MIPS16_TLS_DTPREL_LO16", /* name */
979 TRUE, /* partial_inplace */
980 0x0000ffff, /* src_mask */
981 0x0000ffff, /* dst_mask */
982 FALSE), /* pcrel_offset */
984 /* MIPS16 TLS thread pointer offset. */
985 HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */
987 2, /* size (0 = byte, 1 = short, 2 = long) */
989 FALSE, /* pc_relative */
991 complain_overflow_signed, /* complain_on_overflow */
992 _bfd_mips_elf_generic_reloc, /* special_function */
993 "R_MIPS16_TLS_GOTTPREL", /* name */
994 TRUE, /* partial_inplace */
995 0x0000ffff, /* src_mask */
996 0x0000ffff, /* dst_mask */
997 FALSE), /* pcrel_offset */
999 /* MIPS16 TLS thread pointer offset. */
1000 HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */
1002 2, /* size (0 = byte, 1 = short, 2 = long) */
1004 FALSE, /* pc_relative */
1006 complain_overflow_signed, /* complain_on_overflow */
1007 _bfd_mips_elf_generic_reloc, /* special_function */
1008 "R_MIPS16_TLS_TPREL_HI16", /* name */
1009 TRUE, /* partial_inplace */
1010 0x0000ffff, /* src_mask */
1011 0x0000ffff, /* dst_mask */
1012 FALSE), /* pcrel_offset */
1014 /* MIPS16 TLS thread pointer offset. */
1015 HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */
1017 2, /* size (0 = byte, 1 = short, 2 = long) */
1019 FALSE, /* pc_relative */
1021 complain_overflow_signed, /* complain_on_overflow */
1022 _bfd_mips_elf_generic_reloc, /* special_function */
1023 "R_MIPS16_TLS_TPREL_LO16", /* name */
1024 TRUE, /* partial_inplace */
1025 0x0000ffff, /* src_mask */
1026 0x0000ffff, /* dst_mask */
1027 FALSE), /* pcrel_offset */
1029 /* MIPS16 16-bit PC-relative branch offset. */
1030 HOWTO (R_MIPS16_PC16_S1, /* type */
1032 2, /* size (0 = byte, 1 = short, 2 = long) */
1034 TRUE, /* pc_relative */
1036 complain_overflow_signed, /* complain_on_overflow */
1037 _bfd_mips_elf_generic_reloc, /* special_function */
1038 "R_MIPS16_PC16_S1", /* name */
1039 TRUE, /* partial_inplace */
1040 0x0000ffff, /* src_mask */
1041 0x0000ffff, /* dst_mask */
1042 TRUE), /* pcrel_offset */
1045 static reloc_howto_type elf_micromips_howto_table_rel[] =
1051 /* 26 bit jump address. */
1052 HOWTO (R_MICROMIPS_26_S1, /* type */
1054 2, /* size (0 = byte, 1 = short, 2 = long) */
1056 FALSE, /* pc_relative */
1058 complain_overflow_dont, /* complain_on_overflow */
1059 /* This needs complex overflow
1060 detection, because the upper four
1061 bits must match the PC. */
1062 _bfd_mips_elf_generic_reloc, /* special_function */
1063 "R_MICROMIPS_26_S1", /* name */
1064 TRUE, /* partial_inplace */
1065 0x3ffffff, /* src_mask */
1066 0x3ffffff, /* dst_mask */
1067 FALSE), /* pcrel_offset */
1069 /* High 16 bits of symbol value. */
1070 HOWTO (R_MICROMIPS_HI16, /* type */
1071 16, /* rightshift */
1072 2, /* size (0 = byte, 1 = short, 2 = long) */
1074 FALSE, /* pc_relative */
1076 complain_overflow_dont, /* complain_on_overflow */
1077 _bfd_mips_elf_hi16_reloc, /* special_function */
1078 "R_MICROMIPS_HI16", /* name */
1079 TRUE, /* partial_inplace */
1080 0x0000ffff, /* src_mask */
1081 0x0000ffff, /* dst_mask */
1082 FALSE), /* pcrel_offset */
1084 /* Low 16 bits of symbol value. */
1085 HOWTO (R_MICROMIPS_LO16, /* type */
1087 2, /* size (0 = byte, 1 = short, 2 = long) */
1089 FALSE, /* pc_relative */
1091 complain_overflow_dont, /* complain_on_overflow */
1092 _bfd_mips_elf_lo16_reloc, /* special_function */
1093 "R_MICROMIPS_LO16", /* name */
1094 TRUE, /* partial_inplace */
1095 0x0000ffff, /* src_mask */
1096 0x0000ffff, /* dst_mask */
1097 FALSE), /* pcrel_offset */
1099 /* GP relative reference. */
1100 HOWTO (R_MICROMIPS_GPREL16, /* type */
1102 2, /* size (0 = byte, 1 = short, 2 = long) */
1104 FALSE, /* pc_relative */
1106 complain_overflow_signed, /* complain_on_overflow */
1107 _bfd_mips_elf32_gprel16_reloc, /* special_function */
1108 "R_MICROMIPS_GPREL16", /* name */
1109 TRUE, /* partial_inplace */
1110 0x0000ffff, /* src_mask */
1111 0x0000ffff, /* dst_mask */
1112 FALSE), /* pcrel_offset */
1114 /* Reference to literal section. */
1115 HOWTO (R_MICROMIPS_LITERAL, /* type */
1117 2, /* size (0 = byte, 1 = short, 2 = long) */
1119 FALSE, /* pc_relative */
1121 complain_overflow_signed, /* complain_on_overflow */
1122 _bfd_mips_elf32_gprel16_reloc, /* special_function */
1123 "R_MICROMIPS_LITERAL", /* name */
1124 TRUE, /* partial_inplace */
1125 0x0000ffff, /* src_mask */
1126 0x0000ffff, /* dst_mask */
1127 FALSE), /* pcrel_offset */
1129 /* Reference to global offset table. */
1130 HOWTO (R_MICROMIPS_GOT16, /* type */
1132 2, /* size (0 = byte, 1 = short, 2 = long) */
1134 FALSE, /* pc_relative */
1136 complain_overflow_signed, /* complain_on_overflow */
1137 _bfd_mips_elf_got16_reloc, /* special_function */
1138 "R_MICROMIPS_GOT16", /* name */
1139 TRUE, /* partial_inplace */
1140 0x0000ffff, /* src_mask */
1141 0x0000ffff, /* dst_mask */
1142 FALSE), /* pcrel_offset */
1144 /* This is for microMIPS branches. */
1145 HOWTO (R_MICROMIPS_PC7_S1, /* type */
1147 1, /* size (0 = byte, 1 = short, 2 = long) */
1149 TRUE, /* pc_relative */
1151 complain_overflow_signed, /* complain_on_overflow */
1152 _bfd_mips_elf_generic_reloc, /* special_function */
1153 "R_MICROMIPS_PC7_S1", /* name */
1154 TRUE, /* partial_inplace */
1155 0x0000007f, /* src_mask */
1156 0x0000007f, /* dst_mask */
1157 TRUE), /* pcrel_offset */
1159 HOWTO (R_MICROMIPS_PC10_S1, /* type */
1161 1, /* size (0 = byte, 1 = short, 2 = long) */
1163 TRUE, /* pc_relative */
1165 complain_overflow_signed, /* complain_on_overflow */
1166 _bfd_mips_elf_generic_reloc, /* special_function */
1167 "R_MICROMIPS_PC10_S1", /* name */
1168 TRUE, /* partial_inplace */
1169 0x000003ff, /* src_mask */
1170 0x000003ff, /* dst_mask */
1171 TRUE), /* pcrel_offset */
1173 HOWTO (R_MICROMIPS_PC16_S1, /* type */
1175 2, /* size (0 = byte, 1 = short, 2 = long) */
1177 TRUE, /* pc_relative */
1179 complain_overflow_signed, /* complain_on_overflow */
1180 _bfd_mips_elf_generic_reloc, /* special_function */
1181 "R_MICROMIPS_PC16_S1", /* name */
1182 TRUE, /* partial_inplace */
1183 0x0000ffff, /* src_mask */
1184 0x0000ffff, /* dst_mask */
1185 TRUE), /* pcrel_offset */
1187 /* 16 bit call through global offset table. */
1188 HOWTO (R_MICROMIPS_CALL16, /* type */
1190 2, /* size (0 = byte, 1 = short, 2 = long) */
1192 FALSE, /* pc_relative */
1194 complain_overflow_signed, /* complain_on_overflow */
1195 _bfd_mips_elf_generic_reloc, /* special_function */
1196 "R_MICROMIPS_CALL16", /* name */
1197 TRUE, /* partial_inplace */
1198 0x0000ffff, /* src_mask */
1199 0x0000ffff, /* dst_mask */
1200 FALSE), /* pcrel_offset */
1205 /* Displacement in the global offset table. */
1206 HOWTO (R_MICROMIPS_GOT_DISP, /* type */
1208 2, /* size (0 = byte, 1 = short, 2 = long) */
1210 FALSE, /* pc_relative */
1212 complain_overflow_signed, /* complain_on_overflow */
1213 _bfd_mips_elf_generic_reloc, /* special_function */
1214 "R_MICROMIPS_GOT_DISP",/* name */
1215 TRUE, /* partial_inplace */
1216 0x0000ffff, /* src_mask */
1217 0x0000ffff, /* dst_mask */
1218 FALSE), /* pcrel_offset */
1220 /* Displacement to page pointer in the global offset table. */
1221 HOWTO (R_MICROMIPS_GOT_PAGE, /* type */
1223 2, /* size (0 = byte, 1 = short, 2 = long) */
1225 FALSE, /* pc_relative */
1227 complain_overflow_signed, /* complain_on_overflow */
1228 _bfd_mips_elf_generic_reloc, /* special_function */
1229 "R_MICROMIPS_GOT_PAGE",/* name */
1230 TRUE, /* partial_inplace */
1231 0x0000ffff, /* src_mask */
1232 0x0000ffff, /* dst_mask */
1233 FALSE), /* pcrel_offset */
1235 /* Offset from page pointer in the global offset table. */
1236 HOWTO (R_MICROMIPS_GOT_OFST, /* type */
1238 2, /* size (0 = byte, 1 = short, 2 = long) */
1240 FALSE, /* pc_relative */
1242 complain_overflow_signed, /* complain_on_overflow */
1243 _bfd_mips_elf_generic_reloc, /* special_function */
1244 "R_MICROMIPS_GOT_OFST",/* name */
1245 TRUE, /* partial_inplace */
1246 0x0000ffff, /* src_mask */
1247 0x0000ffff, /* dst_mask */
1248 FALSE), /* pcrel_offset */
1250 /* High 16 bits of displacement in global offset table. */
1251 HOWTO (R_MICROMIPS_GOT_HI16, /* type */
1253 2, /* size (0 = byte, 1 = short, 2 = long) */
1255 FALSE, /* pc_relative */
1257 complain_overflow_dont, /* complain_on_overflow */
1258 _bfd_mips_elf_generic_reloc, /* special_function */
1259 "R_MICROMIPS_GOT_HI16",/* name */
1260 TRUE, /* partial_inplace */
1261 0x0000ffff, /* src_mask */
1262 0x0000ffff, /* dst_mask */
1263 FALSE), /* pcrel_offset */
1265 /* Low 16 bits of displacement in global offset table. */
1266 HOWTO (R_MICROMIPS_GOT_LO16, /* type */
1268 2, /* size (0 = byte, 1 = short, 2 = long) */
1270 FALSE, /* pc_relative */
1272 complain_overflow_dont, /* complain_on_overflow */
1273 _bfd_mips_elf_generic_reloc, /* special_function */
1274 "R_MICROMIPS_GOT_LO16",/* name */
1275 TRUE, /* partial_inplace */
1276 0x0000ffff, /* src_mask */
1277 0x0000ffff, /* dst_mask */
1278 FALSE), /* pcrel_offset */
1280 /* 64 bit subtraction. Used in the N32 ABI. */
1281 HOWTO (R_MICROMIPS_SUB, /* type */
1283 4, /* size (0 = byte, 1 = short, 2 = long) */
1285 FALSE, /* pc_relative */
1287 complain_overflow_dont, /* complain_on_overflow */
1288 _bfd_mips_elf_generic_reloc, /* special_function */
1289 "R_MICROMIPS_SUB", /* name */
1290 TRUE, /* partial_inplace */
1291 MINUS_ONE, /* src_mask */
1292 MINUS_ONE, /* dst_mask */
1293 FALSE), /* pcrel_offset */
1295 /* Get the higher value of a 64 bit addend. */
1296 HOWTO (R_MICROMIPS_HIGHER, /* type */
1298 2, /* size (0 = byte, 1 = short, 2 = long) */
1300 FALSE, /* pc_relative */
1302 complain_overflow_dont, /* complain_on_overflow */
1303 _bfd_mips_elf_generic_reloc, /* special_function */
1304 "R_MICROMIPS_HIGHER", /* name */
1305 TRUE, /* partial_inplace */
1306 0x0000ffff, /* src_mask */
1307 0x0000ffff, /* dst_mask */
1308 FALSE), /* pcrel_offset */
1310 /* Get the highest value of a 64 bit addend. */
1311 HOWTO (R_MICROMIPS_HIGHEST, /* type */
1313 2, /* size (0 = byte, 1 = short, 2 = long) */
1315 FALSE, /* pc_relative */
1317 complain_overflow_dont, /* complain_on_overflow */
1318 _bfd_mips_elf_generic_reloc, /* special_function */
1319 "R_MICROMIPS_HIGHEST", /* name */
1320 TRUE, /* partial_inplace */
1321 0x0000ffff, /* src_mask */
1322 0x0000ffff, /* dst_mask */
1323 FALSE), /* pcrel_offset */
1325 /* High 16 bits of displacement in global offset table. */
1326 HOWTO (R_MICROMIPS_CALL_HI16, /* type */
1328 2, /* size (0 = byte, 1 = short, 2 = long) */
1330 FALSE, /* pc_relative */
1332 complain_overflow_dont, /* complain_on_overflow */
1333 _bfd_mips_elf_generic_reloc, /* special_function */
1334 "R_MICROMIPS_CALL_HI16",/* name */
1335 TRUE, /* partial_inplace */
1336 0x0000ffff, /* src_mask */
1337 0x0000ffff, /* dst_mask */
1338 FALSE), /* pcrel_offset */
1340 /* Low 16 bits of displacement in global offset table. */
1341 HOWTO (R_MICROMIPS_CALL_LO16, /* type */
1343 2, /* size (0 = byte, 1 = short, 2 = long) */
1345 FALSE, /* pc_relative */
1347 complain_overflow_dont, /* complain_on_overflow */
1348 _bfd_mips_elf_generic_reloc, /* special_function */
1349 "R_MICROMIPS_CALL_LO16",/* name */
1350 TRUE, /* partial_inplace */
1351 0x0000ffff, /* src_mask */
1352 0x0000ffff, /* dst_mask */
1353 FALSE), /* pcrel_offset */
1355 /* Section displacement. */
1356 HOWTO (R_MICROMIPS_SCN_DISP, /* type */
1358 2, /* size (0 = byte, 1 = short, 2 = long) */
1360 FALSE, /* pc_relative */
1362 complain_overflow_dont, /* complain_on_overflow */
1363 _bfd_mips_elf_generic_reloc, /* special_function */
1364 "R_MICROMIPS_SCN_DISP",/* name */
1365 TRUE, /* partial_inplace */
1366 0xffffffff, /* src_mask */
1367 0xffffffff, /* dst_mask */
1368 FALSE), /* pcrel_offset */
1370 /* Protected jump conversion. This is an optimization hint. No
1371 relocation is required for correctness. */
1372 HOWTO (R_MICROMIPS_JALR, /* type */
1374 2, /* size (0 = byte, 1 = short, 2 = long) */
1376 FALSE, /* pc_relative */
1378 complain_overflow_dont, /* complain_on_overflow */
1379 _bfd_mips_elf_generic_reloc, /* special_function */
1380 "R_MICROMIPS_JALR", /* name */
1381 FALSE, /* partial_inplace */
1382 0x00000000, /* src_mask */
1383 0x00000000, /* dst_mask */
1384 FALSE), /* pcrel_offset */
1386 /* Low 16 bits of symbol value. Note that the high 16 bits of symbol values
1387 must be zero. This is used for relaxation. */
1388 HOWTO (R_MICROMIPS_HI0_LO16, /* type */
1390 2, /* size (0 = byte, 1 = short, 2 = long) */
1392 FALSE, /* pc_relative */
1394 complain_overflow_dont, /* complain_on_overflow */
1395 _bfd_mips_elf_generic_reloc, /* special_function */
1396 "R_MICROMIPS_HI0_LO16",/* name */
1397 TRUE, /* partial_inplace */
1398 0x0000ffff, /* src_mask */
1399 0x0000ffff, /* dst_mask */
1400 FALSE), /* pcrel_offset */
1407 /* TLS general dynamic variable reference. */
1408 HOWTO (R_MICROMIPS_TLS_GD, /* type */
1410 2, /* size (0 = byte, 1 = short, 2 = long) */
1412 FALSE, /* pc_relative */
1414 complain_overflow_signed, /* complain_on_overflow */
1415 _bfd_mips_elf_generic_reloc, /* special_function */
1416 "R_MICROMIPS_TLS_GD", /* name */
1417 TRUE, /* partial_inplace */
1418 0x0000ffff, /* src_mask */
1419 0x0000ffff, /* dst_mask */
1420 FALSE), /* pcrel_offset */
1422 /* TLS local dynamic variable reference. */
1423 HOWTO (R_MICROMIPS_TLS_LDM, /* type */
1425 2, /* size (0 = byte, 1 = short, 2 = long) */
1427 FALSE, /* pc_relative */
1429 complain_overflow_signed, /* complain_on_overflow */
1430 _bfd_mips_elf_generic_reloc, /* special_function */
1431 "R_MICROMIPS_TLS_LDM", /* name */
1432 TRUE, /* partial_inplace */
1433 0x0000ffff, /* src_mask */
1434 0x0000ffff, /* dst_mask */
1435 FALSE), /* pcrel_offset */
1437 /* TLS local dynamic offset. */
1438 HOWTO (R_MICROMIPS_TLS_DTPREL_HI16, /* type */
1440 2, /* size (0 = byte, 1 = short, 2 = long) */
1442 FALSE, /* pc_relative */
1444 complain_overflow_signed, /* complain_on_overflow */
1445 _bfd_mips_elf_generic_reloc, /* special_function */
1446 "R_MICROMIPS_TLS_DTPREL_HI16", /* name */
1447 TRUE, /* partial_inplace */
1448 0x0000ffff, /* src_mask */
1449 0x0000ffff, /* dst_mask */
1450 FALSE), /* pcrel_offset */
1452 /* TLS local dynamic offset. */
1453 HOWTO (R_MICROMIPS_TLS_DTPREL_LO16, /* type */
1455 2, /* size (0 = byte, 1 = short, 2 = long) */
1457 FALSE, /* pc_relative */
1459 complain_overflow_signed, /* complain_on_overflow */
1460 _bfd_mips_elf_generic_reloc, /* special_function */
1461 "R_MICROMIPS_TLS_DTPREL_LO16", /* name */
1462 TRUE, /* partial_inplace */
1463 0x0000ffff, /* src_mask */
1464 0x0000ffff, /* dst_mask */
1465 FALSE), /* pcrel_offset */
1467 /* TLS thread pointer offset. */
1468 HOWTO (R_MICROMIPS_TLS_GOTTPREL, /* type */
1470 2, /* size (0 = byte, 1 = short, 2 = long) */
1472 FALSE, /* pc_relative */
1474 complain_overflow_signed, /* complain_on_overflow */
1475 _bfd_mips_elf_generic_reloc, /* special_function */
1476 "R_MICROMIPS_TLS_GOTTPREL", /* name */
1477 TRUE, /* partial_inplace */
1478 0x0000ffff, /* src_mask */
1479 0x0000ffff, /* dst_mask */
1480 FALSE), /* pcrel_offset */
1485 /* TLS thread pointer offset. */
1486 HOWTO (R_MICROMIPS_TLS_TPREL_HI16, /* type */
1488 2, /* size (0 = byte, 1 = short, 2 = long) */
1490 FALSE, /* pc_relative */
1492 complain_overflow_signed, /* complain_on_overflow */
1493 _bfd_mips_elf_generic_reloc, /* special_function */
1494 "R_MICROMIPS_TLS_TPREL_HI16", /* name */
1495 TRUE, /* partial_inplace */
1496 0x0000ffff, /* src_mask */
1497 0x0000ffff, /* dst_mask */
1498 FALSE), /* pcrel_offset */
1500 /* TLS thread pointer offset. */
1501 HOWTO (R_MICROMIPS_TLS_TPREL_LO16, /* type */
1503 2, /* size (0 = byte, 1 = short, 2 = long) */
1505 FALSE, /* pc_relative */
1507 complain_overflow_signed, /* complain_on_overflow */
1508 _bfd_mips_elf_generic_reloc, /* special_function */
1509 "R_MICROMIPS_TLS_TPREL_LO16", /* name */
1510 TRUE, /* partial_inplace */
1511 0x0000ffff, /* src_mask */
1512 0x0000ffff, /* dst_mask */
1513 FALSE), /* pcrel_offset */
1517 /* GP- and PC-relative relocations. */
1518 HOWTO (R_MICROMIPS_GPREL7_S2, /* type */
1520 1, /* size (0 = byte, 1 = short, 2 = long) */
1522 FALSE, /* pc_relative */
1524 complain_overflow_signed, /* complain_on_overflow */
1525 _bfd_mips_elf32_gprel16_reloc, /* special_function */
1526 "R_MICROMIPS_GPREL7_S2", /* name */
1527 TRUE, /* partial_inplace */
1528 0x0000007f, /* src_mask */
1529 0x0000007f, /* dst_mask */
1530 FALSE), /* pcrel_offset */
1532 HOWTO (R_MICROMIPS_PC23_S2, /* type */
1534 2, /* size (0 = byte, 1 = short, 2 = long) */
1536 TRUE, /* pc_relative */
1538 complain_overflow_signed, /* complain_on_overflow */
1539 _bfd_mips_elf_generic_reloc, /* special_function */
1540 "R_MICROMIPS_PC23_S2", /* name */
1541 TRUE, /* partial_inplace */
1542 0x007fffff, /* src_mask */
1543 0x007fffff, /* dst_mask */
1544 TRUE), /* pcrel_offset */
1547 /* 16 bit offset for pc-relative branches. */
1548 static reloc_howto_type elf_mips_gnu_rel16_s2 =
1549 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
1551 2, /* size (0 = byte, 1 = short, 2 = long) */
1553 TRUE, /* pc_relative */
1555 complain_overflow_signed, /* complain_on_overflow */
1556 _bfd_mips_elf_generic_reloc, /* special_function */
1557 "R_MIPS_GNU_REL16_S2", /* name */
1558 TRUE, /* partial_inplace */
1559 0xffff, /* src_mask */
1560 0xffff, /* dst_mask */
1561 TRUE); /* pcrel_offset */
1563 /* 32 bit pc-relative. This was a GNU extension used by embedded-PIC.
1564 It was co-opted by mips-linux for exception-handling data. GCC stopped
1565 using it in May, 2004, then started using it again for compact unwind
1567 static reloc_howto_type elf_mips_gnu_pcrel32 =
1568 HOWTO (R_MIPS_PC32, /* type */
1570 2, /* size (0 = byte, 1 = short, 2 = long) */
1572 TRUE, /* pc_relative */
1574 complain_overflow_signed, /* complain_on_overflow */
1575 _bfd_mips_elf_generic_reloc, /* special_function */
1576 "R_MIPS_PC32", /* name */
1577 TRUE, /* partial_inplace */
1578 0xffffffff, /* src_mask */
1579 0xffffffff, /* dst_mask */
1580 TRUE); /* pcrel_offset */
1582 /* GNU extension to record C++ vtable hierarchy */
1583 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
1584 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
1586 2, /* size (0 = byte, 1 = short, 2 = long) */
1588 FALSE, /* pc_relative */
1590 complain_overflow_dont, /* complain_on_overflow */
1591 NULL, /* special_function */
1592 "R_MIPS_GNU_VTINHERIT", /* name */
1593 FALSE, /* partial_inplace */
1596 FALSE); /* pcrel_offset */
1598 /* GNU extension to record C++ vtable member usage */
1599 static reloc_howto_type elf_mips_gnu_vtentry_howto =
1600 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
1602 2, /* size (0 = byte, 1 = short, 2 = long) */
1604 FALSE, /* pc_relative */
1606 complain_overflow_dont, /* complain_on_overflow */
1607 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1608 "R_MIPS_GNU_VTENTRY", /* name */
1609 FALSE, /* partial_inplace */
1612 FALSE); /* pcrel_offset */
1614 /* Originally a VxWorks extension, but now used for other systems too. */
1615 static reloc_howto_type elf_mips_copy_howto =
1616 HOWTO (R_MIPS_COPY, /* type */
1618 0, /* this one is variable size */
1620 FALSE, /* pc_relative */
1622 complain_overflow_bitfield, /* complain_on_overflow */
1623 _bfd_mips_elf_generic_reloc, /* special_function */
1624 "R_MIPS_COPY", /* name */
1625 FALSE, /* partial_inplace */
1628 FALSE); /* pcrel_offset */
1630 /* Originally a VxWorks extension, but now used for other systems too. */
1631 static reloc_howto_type elf_mips_jump_slot_howto =
1632 HOWTO (R_MIPS_JUMP_SLOT, /* type */
1634 2, /* size (0 = byte, 1 = short, 2 = long) */
1636 FALSE, /* pc_relative */
1638 complain_overflow_bitfield, /* complain_on_overflow */
1639 _bfd_mips_elf_generic_reloc, /* special_function */
1640 "R_MIPS_JUMP_SLOT", /* name */
1641 FALSE, /* partial_inplace */
1644 FALSE); /* pcrel_offset */
1646 /* Used in EH tables. */
1647 static reloc_howto_type elf_mips_eh_howto =
1648 HOWTO (R_MIPS_EH, /* type */
1650 2, /* size (0 = byte, 1 = short, 2 = long) */
1652 FALSE, /* pc_relative */
1654 complain_overflow_signed, /* complain_on_overflow */
1655 _bfd_mips_elf_generic_reloc, /* special_function */
1656 "R_MIPS_EH", /* name */
1657 TRUE, /* partial_inplace */
1658 0xffffffff, /* src_mask */
1659 0xffffffff, /* dst_mask */
1660 FALSE); /* pcrel_offset */
1662 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
1663 dangerous relocation. */
1666 mips_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
1672 /* If we've already figured out what GP will be, just return it. */
1673 *pgp = _bfd_get_gp_value (output_bfd);
1677 count = bfd_get_symcount (output_bfd);
1678 sym = bfd_get_outsymbols (output_bfd);
1680 /* The linker script will have created a symbol named `_gp' with the
1681 appropriate value. */
1686 for (i = 0; i < count; i++, sym++)
1688 register const char *name;
1690 name = bfd_asymbol_name (*sym);
1691 if (*name == '_' && strcmp (name, "_gp") == 0)
1693 *pgp = bfd_asymbol_value (*sym);
1694 _bfd_set_gp_value (output_bfd, *pgp);
1702 /* Only get the error once. */
1704 _bfd_set_gp_value (output_bfd, *pgp);
1711 /* We have to figure out the gp value, so that we can adjust the
1712 symbol value correctly. We look up the symbol _gp in the output
1713 BFD. If we can't find it, we're stuck. We cache it in the ELF
1714 target data. We don't need to adjust the symbol value for an
1715 external symbol if we are producing relocatable output. */
1717 static bfd_reloc_status_type
1718 mips_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
1719 char **error_message, bfd_vma *pgp)
1721 if (bfd_is_und_section (symbol->section)
1725 return bfd_reloc_undefined;
1728 *pgp = _bfd_get_gp_value (output_bfd);
1731 || (symbol->flags & BSF_SECTION_SYM) != 0))
1735 /* Make up a value. */
1736 *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
1737 _bfd_set_gp_value (output_bfd, *pgp);
1739 else if (!mips_elf_assign_gp (output_bfd, pgp))
1742 (char *) _("GP relative relocation when _gp not defined");
1743 return bfd_reloc_dangerous;
1747 return bfd_reloc_ok;
1750 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1751 become the offset from the gp register. This function also handles
1752 R_MIPS_LITERAL relocations, although those can be handled more
1753 cleverly because the entries in the .lit8 and .lit4 sections can be
1756 bfd_reloc_status_type
1757 _bfd_mips_elf32_gprel16_reloc (bfd *abfd, arelent *reloc_entry,
1758 asymbol *symbol, void *data,
1759 asection *input_section, bfd *output_bfd,
1760 char **error_message)
1762 bfd_boolean relocatable;
1763 bfd_reloc_status_type ret;
1767 /* R_MIPS_LITERAL/R_MICROMIPS_LITERAL relocations are defined for local
1769 if (literal_reloc_p (reloc_entry->howto->type)
1770 && output_bfd != NULL
1771 && (symbol->flags & BSF_SECTION_SYM) == 0
1772 && (symbol->flags & BSF_LOCAL) != 0)
1774 *error_message = (char *)
1775 _("literal relocation occurs for an external symbol");
1776 return bfd_reloc_outofrange;
1779 if (output_bfd != NULL)
1783 relocatable = FALSE;
1784 output_bfd = symbol->section->output_section->owner;
1787 ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
1789 if (ret != bfd_reloc_ok)
1792 location = (bfd_byte *) data + reloc_entry->address;
1793 _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
1795 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1796 input_section, relocatable,
1798 _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
1804 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
1805 become the offset from the gp register. */
1807 static bfd_reloc_status_type
1808 mips_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1809 void *data, asection *input_section, bfd *output_bfd,
1810 char **error_message)
1812 bfd_boolean relocatable;
1813 bfd_reloc_status_type ret;
1816 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
1817 if (output_bfd != NULL
1818 && (symbol->flags & BSF_SECTION_SYM) == 0
1819 && (symbol->flags & BSF_LOCAL) != 0)
1821 *error_message = (char *)
1822 _("32bits gp relative relocation occurs for an external symbol");
1823 return bfd_reloc_outofrange;
1826 if (output_bfd != NULL)
1830 relocatable = FALSE;
1831 output_bfd = symbol->section->output_section->owner;
1834 ret = mips_elf_final_gp (output_bfd, symbol, relocatable,
1835 error_message, &gp);
1836 if (ret != bfd_reloc_ok)
1839 return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
1840 relocatable, data, gp);
1843 static bfd_reloc_status_type
1844 gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
1845 asection *input_section, bfd_boolean relocatable,
1846 void *data, bfd_vma gp)
1851 if (bfd_is_com_section (symbol->section))
1854 relocation = symbol->value;
1856 relocation += symbol->section->output_section->vma;
1857 relocation += symbol->section->output_offset;
1859 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
1860 return bfd_reloc_outofrange;
1862 /* Set val to the offset into the section or symbol. */
1863 val = reloc_entry->addend;
1865 if (reloc_entry->howto->partial_inplace)
1866 val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1868 /* Adjust val for the final section location and GP value. If we
1869 are producing relocatable output, we don't want to do this for
1870 an external symbol. */
1872 || (symbol->flags & BSF_SECTION_SYM) != 0)
1873 val += relocation - gp;
1875 if (reloc_entry->howto->partial_inplace)
1876 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
1878 reloc_entry->addend = val;
1881 reloc_entry->address += input_section->output_offset;
1883 return bfd_reloc_ok;
1886 /* Handle a 64 bit reloc in a 32 bit MIPS ELF file. These are
1887 generated when addresses are 64 bits. The upper 32 bits are a simple
1890 static bfd_reloc_status_type
1891 mips32_64bit_reloc (bfd *abfd, arelent *reloc_entry,
1892 asymbol *symbol ATTRIBUTE_UNUSED,
1893 void *data, asection *input_section,
1894 bfd *output_bfd, char **error_message)
1896 bfd_reloc_status_type r;
1901 /* Do a normal 32 bit relocation on the lower 32 bits. */
1902 reloc32 = *reloc_entry;
1903 if (bfd_big_endian (abfd))
1904 reloc32.address += 4;
1905 reloc32.howto = &elf_mips_howto_table_rel[R_MIPS_32];
1906 r = bfd_perform_relocation (abfd, &reloc32, data, input_section,
1907 output_bfd, error_message);
1909 /* Sign extend into the upper 32 bits. */
1910 val = bfd_get_32 (abfd, (bfd_byte *) data + reloc32.address);
1911 if ((val & 0x80000000) != 0)
1915 addr = reloc_entry->address;
1916 if (bfd_little_endian (abfd))
1918 bfd_put_32 (abfd, val, (bfd_byte *) data + addr);
1923 /* Handle a mips16 GP relative reloc. */
1925 static bfd_reloc_status_type
1926 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1927 void *data, asection *input_section, bfd *output_bfd,
1928 char **error_message)
1930 bfd_boolean relocatable;
1931 bfd_reloc_status_type ret;
1935 /* If we're relocating, and this is an external symbol, we don't want
1936 to change anything. */
1937 if (output_bfd != NULL
1938 && (symbol->flags & BSF_SECTION_SYM) == 0
1939 && (symbol->flags & BSF_LOCAL) != 0)
1941 reloc_entry->address += input_section->output_offset;
1942 return bfd_reloc_ok;
1945 if (output_bfd != NULL)
1949 relocatable = FALSE;
1950 output_bfd = symbol->section->output_section->owner;
1953 ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
1955 if (ret != bfd_reloc_ok)
1958 location = (bfd_byte *) data + reloc_entry->address;
1959 _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
1961 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1962 input_section, relocatable,
1964 _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
1970 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
1972 struct elf_reloc_map {
1973 bfd_reloc_code_real_type bfd_val;
1974 enum elf_mips_reloc_type elf_val;
1977 static const struct elf_reloc_map mips_reloc_map[] =
1979 { BFD_RELOC_NONE, R_MIPS_NONE },
1980 { BFD_RELOC_16, R_MIPS_16 },
1981 { BFD_RELOC_32, R_MIPS_32 },
1982 /* There is no BFD reloc for R_MIPS_REL32. */
1983 { BFD_RELOC_64, R_MIPS_64 },
1984 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1985 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1986 { BFD_RELOC_LO16, R_MIPS_LO16 },
1987 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
1988 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1989 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
1990 { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
1991 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
1992 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
1993 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1994 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1995 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
1996 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1997 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1998 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1999 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
2000 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
2001 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
2002 { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
2003 { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
2004 { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
2005 { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
2006 { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
2007 { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
2008 { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
2009 { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
2010 { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
2011 { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
2012 { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
2013 { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
2014 { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 },
2015 { BFD_RELOC_MIPS_21_PCREL_S2, R_MIPS_PC21_S2 },
2016 { BFD_RELOC_MIPS_26_PCREL_S2, R_MIPS_PC26_S2 },
2017 { BFD_RELOC_MIPS_18_PCREL_S3, R_MIPS_PC18_S3 },
2018 { BFD_RELOC_MIPS_19_PCREL_S2, R_MIPS_PC19_S2 },
2019 { BFD_RELOC_HI16_S_PCREL, R_MIPS_PCHI16 },
2020 { BFD_RELOC_LO16_PCREL, R_MIPS_PCLO16 }
2023 static const struct elf_reloc_map mips16_reloc_map[] =
2025 { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
2026 { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
2027 { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
2028 { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
2029 { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
2030 { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
2031 { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
2032 { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
2033 { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
2034 R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
2035 { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
2036 R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
2037 { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
2038 { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
2039 { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min },
2040 { BFD_RELOC_MIPS16_16_PCREL_S1, R_MIPS16_PC16_S1 - R_MIPS16_min }
2043 static const struct elf_reloc_map micromips_reloc_map[] =
2045 { BFD_RELOC_MICROMIPS_JMP, R_MICROMIPS_26_S1 - R_MICROMIPS_min },
2046 { BFD_RELOC_MICROMIPS_HI16_S, R_MICROMIPS_HI16 - R_MICROMIPS_min },
2047 { BFD_RELOC_MICROMIPS_LO16, R_MICROMIPS_LO16 - R_MICROMIPS_min },
2048 { BFD_RELOC_MICROMIPS_GPREL16, R_MICROMIPS_GPREL16 - R_MICROMIPS_min },
2049 { BFD_RELOC_MICROMIPS_LITERAL, R_MICROMIPS_LITERAL - R_MICROMIPS_min },
2050 { BFD_RELOC_MICROMIPS_GOT16, R_MICROMIPS_GOT16 - R_MICROMIPS_min },
2051 { BFD_RELOC_MICROMIPS_7_PCREL_S1, R_MICROMIPS_PC7_S1 - R_MICROMIPS_min },
2052 { BFD_RELOC_MICROMIPS_10_PCREL_S1, R_MICROMIPS_PC10_S1 - R_MICROMIPS_min },
2053 { BFD_RELOC_MICROMIPS_16_PCREL_S1, R_MICROMIPS_PC16_S1 - R_MICROMIPS_min },
2054 { BFD_RELOC_MICROMIPS_CALL16, R_MICROMIPS_CALL16 - R_MICROMIPS_min },
2055 { BFD_RELOC_MICROMIPS_GOT_DISP, R_MICROMIPS_GOT_DISP - R_MICROMIPS_min },
2056 { BFD_RELOC_MICROMIPS_GOT_PAGE, R_MICROMIPS_GOT_PAGE - R_MICROMIPS_min },
2057 { BFD_RELOC_MICROMIPS_GOT_OFST, R_MICROMIPS_GOT_OFST - R_MICROMIPS_min },
2058 { BFD_RELOC_MICROMIPS_GOT_HI16, R_MICROMIPS_GOT_HI16 - R_MICROMIPS_min },
2059 { BFD_RELOC_MICROMIPS_GOT_LO16, R_MICROMIPS_GOT_LO16 - R_MICROMIPS_min },
2060 { BFD_RELOC_MICROMIPS_SUB, R_MICROMIPS_SUB - R_MICROMIPS_min },
2061 { BFD_RELOC_MICROMIPS_HIGHER, R_MICROMIPS_HIGHER - R_MICROMIPS_min },
2062 { BFD_RELOC_MICROMIPS_HIGHEST, R_MICROMIPS_HIGHEST - R_MICROMIPS_min },
2063 { BFD_RELOC_MICROMIPS_CALL_HI16, R_MICROMIPS_CALL_HI16 - R_MICROMIPS_min },
2064 { BFD_RELOC_MICROMIPS_CALL_LO16, R_MICROMIPS_CALL_LO16 - R_MICROMIPS_min },
2065 { BFD_RELOC_MICROMIPS_SCN_DISP, R_MICROMIPS_SCN_DISP - R_MICROMIPS_min },
2066 { BFD_RELOC_MICROMIPS_JALR, R_MICROMIPS_JALR - R_MICROMIPS_min },
2067 /* There is no BFD reloc for R_MICROMIPS_HI0_LO16. */
2068 { BFD_RELOC_MICROMIPS_TLS_GD, R_MICROMIPS_TLS_GD - R_MICROMIPS_min },
2069 { BFD_RELOC_MICROMIPS_TLS_LDM, R_MICROMIPS_TLS_LDM - R_MICROMIPS_min },
2070 { BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16,
2071 R_MICROMIPS_TLS_DTPREL_HI16 - R_MICROMIPS_min },
2072 { BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16,
2073 R_MICROMIPS_TLS_DTPREL_LO16 - R_MICROMIPS_min },
2074 { BFD_RELOC_MICROMIPS_TLS_GOTTPREL,
2075 R_MICROMIPS_TLS_GOTTPREL - R_MICROMIPS_min },
2076 { BFD_RELOC_MICROMIPS_TLS_TPREL_HI16,
2077 R_MICROMIPS_TLS_TPREL_HI16 - R_MICROMIPS_min },
2078 { BFD_RELOC_MICROMIPS_TLS_TPREL_LO16,
2079 R_MICROMIPS_TLS_TPREL_LO16 - R_MICROMIPS_min },
2080 /* There is no BFD reloc for R_MICROMIPS_GPREL7_S2. */
2081 /* There is no BFD reloc for R_MICROMIPS_PC23_S2. */
2084 /* Given a BFD reloc type, return a howto structure. */
2086 static reloc_howto_type *
2087 bfd_elf32_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
2090 reloc_howto_type *howto_table = elf_mips_howto_table_rel;
2091 reloc_howto_type *howto16_table = elf_mips16_howto_table_rel;
2092 reloc_howto_type *howto_micromips_table = elf_micromips_howto_table_rel;
2094 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
2097 if (mips_reloc_map[i].bfd_val == code)
2098 return &howto_table[(int) mips_reloc_map[i].elf_val];
2101 for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
2104 if (mips16_reloc_map[i].bfd_val == code)
2105 return &howto16_table[(int) mips16_reloc_map[i].elf_val];
2108 for (i = 0; i < sizeof (micromips_reloc_map) / sizeof (struct elf_reloc_map);
2111 if (micromips_reloc_map[i].bfd_val == code)
2112 return &howto_micromips_table[(int) micromips_reloc_map[i].elf_val];
2118 bfd_set_error (bfd_error_bad_value);
2121 case BFD_RELOC_CTOR:
2122 /* We need to handle BFD_RELOC_CTOR specially.
2123 Select the right relocation (R_MIPS_32 or R_MIPS_64) based on the
2124 size of addresses of the ABI. */
2125 if ((elf_elfheader (abfd)->e_flags & (E_MIPS_ABI_O64
2126 | E_MIPS_ABI_EABI64)) != 0)
2127 return &elf_mips_ctor64_howto;
2129 return &howto_table[(int) R_MIPS_32];
2131 case BFD_RELOC_VTABLE_INHERIT:
2132 return &elf_mips_gnu_vtinherit_howto;
2133 case BFD_RELOC_VTABLE_ENTRY:
2134 return &elf_mips_gnu_vtentry_howto;
2135 case BFD_RELOC_32_PCREL:
2136 return &elf_mips_gnu_pcrel32;
2137 case BFD_RELOC_MIPS_COPY:
2138 return &elf_mips_copy_howto;
2139 case BFD_RELOC_MIPS_JUMP_SLOT:
2140 return &elf_mips_jump_slot_howto;
2141 case BFD_RELOC_MIPS_EH:
2142 return &elf_mips_eh_howto;
2146 static reloc_howto_type *
2147 bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
2153 i < (sizeof (elf_mips_howto_table_rel)
2154 / sizeof (elf_mips_howto_table_rel[0]));
2156 if (elf_mips_howto_table_rel[i].name != NULL
2157 && strcasecmp (elf_mips_howto_table_rel[i].name, r_name) == 0)
2158 return &elf_mips_howto_table_rel[i];
2161 i < (sizeof (elf_mips16_howto_table_rel)
2162 / sizeof (elf_mips16_howto_table_rel[0]));
2164 if (elf_mips16_howto_table_rel[i].name != NULL
2165 && strcasecmp (elf_mips16_howto_table_rel[i].name, r_name) == 0)
2166 return &elf_mips16_howto_table_rel[i];
2169 i < (sizeof (elf_micromips_howto_table_rel)
2170 / sizeof (elf_micromips_howto_table_rel[0]));
2172 if (elf_micromips_howto_table_rel[i].name != NULL
2173 && strcasecmp (elf_micromips_howto_table_rel[i].name, r_name) == 0)
2174 return &elf_micromips_howto_table_rel[i];
2176 if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
2177 return &elf_mips_gnu_pcrel32;
2178 if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
2179 return &elf_mips_gnu_rel16_s2;
2180 if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
2181 return &elf_mips_gnu_vtinherit_howto;
2182 if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
2183 return &elf_mips_gnu_vtentry_howto;
2184 if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
2185 return &elf_mips_copy_howto;
2186 if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
2187 return &elf_mips_jump_slot_howto;
2188 if (strcasecmp (elf_mips_eh_howto.name, r_name) == 0)
2189 return &elf_mips_eh_howto;
2194 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
2196 static reloc_howto_type *
2197 mips_elf32_rtype_to_howto (bfd *abfd,
2198 unsigned int r_type,
2199 bfd_boolean rela_p ATTRIBUTE_UNUSED)
2201 reloc_howto_type *howto = NULL;
2205 case R_MIPS_GNU_VTINHERIT:
2206 return &elf_mips_gnu_vtinherit_howto;
2207 case R_MIPS_GNU_VTENTRY:
2208 return &elf_mips_gnu_vtentry_howto;
2209 case R_MIPS_GNU_REL16_S2:
2210 return &elf_mips_gnu_rel16_s2;
2212 return &elf_mips_gnu_pcrel32;
2214 return &elf_mips_copy_howto;
2215 case R_MIPS_JUMP_SLOT:
2216 return &elf_mips_jump_slot_howto;
2218 return &elf_mips_eh_howto;
2220 if (r_type >= R_MICROMIPS_min && r_type < R_MICROMIPS_max)
2221 howto = &elf_micromips_howto_table_rel[r_type - R_MICROMIPS_min];
2222 if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
2223 howto = &elf_mips16_howto_table_rel[r_type - R_MIPS16_min];
2224 if (r_type < R_MIPS_max)
2225 howto = &elf_mips_howto_table_rel[r_type];
2226 if (howto != NULL && howto->name != NULL)
2229 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
2231 bfd_set_error (bfd_error_bad_value);
2236 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
2239 mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
2241 unsigned int r_type;
2243 r_type = ELF32_R_TYPE (dst->r_info);
2244 cache_ptr->howto = mips_elf32_rtype_to_howto (abfd, r_type, FALSE);
2246 if (cache_ptr->howto == NULL)
2249 /* The addend for a GPREL16 or LITERAL relocation comes from the GP
2250 value for the object file. We get the addend now, rather than
2251 when we do the relocation, because the symbol manipulations done
2252 by the linker may cause us to lose track of the input BFD. */
2253 if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
2254 && (gprel16_reloc_p (r_type) || literal_reloc_p (r_type)))
2255 cache_ptr->addend = elf_gp (abfd);
2260 /* Given a MIPS Elf_Internal_Rela, fill in an arelent structure. */
2263 mips_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
2265 return mips_info_to_howto_rel (abfd, cache_ptr, dst);
2267 /* If we ever need to do any extra processing with dst->r_addend
2268 (the field omitted in an Elf_Internal_Rel) we can do it here. */
2271 /* Determine whether a symbol is global for the purposes of splitting
2272 the symbol table into global symbols and local symbols. At least
2273 on Irix 5, this split must be between section symbols and all other
2274 symbols. On most ELF targets the split is between static symbols
2275 and externally visible symbols. */
2278 mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
2280 if (SGI_COMPAT (abfd))
2281 return (sym->flags & BSF_SECTION_SYM) == 0;
2283 return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0
2284 || bfd_is_und_section (bfd_get_section (sym))
2285 || bfd_is_com_section (bfd_get_section (sym)));
2288 /* Set the right machine number for a MIPS ELF file. */
2291 mips_elf32_object_p (bfd *abfd)
2295 if (ABI_N32_P (abfd))
2298 /* Irix 5 and 6 are broken. Object file symbol tables are not always
2299 sorted correctly such that local symbols precede global symbols,
2300 and the sh_info field in the symbol table is not always right. */
2301 if (SGI_COMPAT (abfd))
2302 elf_bad_symtab (abfd) = TRUE;
2304 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
2305 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
2309 /* MIPS ELF local labels start with '$', not 'L'. */
2312 mips_elf_is_local_label_name (bfd *abfd, const char *name)
2317 /* On Irix 6, the labels go back to starting with '.', so we accept
2318 the generic ELF local label syntax as well. */
2319 return _bfd_elf_is_local_label_name (abfd, name);
2322 /* Support for core dump NOTE sections. */
2324 elf32_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
2329 switch (note->descsz)
2334 case 256: /* Linux/MIPS */
2336 elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
2339 elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
2348 /* Make a ".reg/999" section. */
2349 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
2350 size, note->descpos + offset);
2354 elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
2356 switch (note->descsz)
2361 case 128: /* Linux/MIPS elf_prpsinfo */
2362 elf_tdata (abfd)->core->pid
2363 = bfd_get_32 (abfd, note->descdata + 16);
2364 elf_tdata (abfd)->core->program
2365 = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
2366 elf_tdata (abfd)->core->command
2367 = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
2370 /* Note that for some reason, a spurious space is tacked
2371 onto the end of the args in some (at least one anyway)
2372 implementations, so strip it off if it exists. */
2375 char *command = elf_tdata (abfd)->core->command;
2376 int n = strlen (command);
2378 if (0 < n && command[n - 1] == ' ')
2379 command[n - 1] = '\0';
2385 /* Write Linux core PRSTATUS note into core file. */
2388 elf32_mips_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
2408 va_start (ap, note_type);
2409 memset (data, 0, 72);
2410 pid = va_arg (ap, long);
2411 bfd_put_32 (abfd, pid, data + 24);
2412 cursig = va_arg (ap, int);
2413 bfd_put_16 (abfd, cursig, data + 12);
2414 greg = va_arg (ap, const void *);
2415 memcpy (data + 72, greg, 180);
2416 memset (data + 252, 0, 4);
2418 return elfcore_write_note (abfd, buf, bufsiz,
2419 "CORE", note_type, data, sizeof (data));
2424 /* Remove the magic _gp_disp symbol from the symbol tables. */
2427 elf32_mips_fixup_symbol (struct bfd_link_info *info,
2428 struct elf_link_hash_entry *h)
2430 if (strcmp (h->root.root.string, "_gp_disp") == 0)
2431 _bfd_elf_link_hash_hide_symbol (info, h, TRUE);
2435 /* Depending on the target vector we generate some version of Irix
2436 executables or "normal" MIPS ELF ABI executables. */
2437 static irix_compat_t
2438 elf32_mips_irix_compat (bfd *abfd)
2440 if ((abfd->xvec == &mips_elf32_be_vec)
2441 || (abfd->xvec == &mips_elf32_le_vec))
2447 /* ECOFF swapping routines. These are used when dealing with the
2448 .mdebug section, which is in the ECOFF debugging format. */
2449 static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
2450 /* Symbol table magic number. */
2452 /* Alignment of debugging information. E.g., 4. */
2454 /* Sizes of external symbolic information. */
2455 sizeof (struct hdr_ext),
2456 sizeof (struct dnr_ext),
2457 sizeof (struct pdr_ext),
2458 sizeof (struct sym_ext),
2459 sizeof (struct opt_ext),
2460 sizeof (struct fdr_ext),
2461 sizeof (struct rfd_ext),
2462 sizeof (struct ext_ext),
2463 /* Functions to swap in external symbolic data. */
2472 _bfd_ecoff_swap_tir_in,
2473 _bfd_ecoff_swap_rndx_in,
2474 /* Functions to swap out external symbolic data. */
2483 _bfd_ecoff_swap_tir_out,
2484 _bfd_ecoff_swap_rndx_out,
2485 /* Function to read in symbolic data. */
2486 _bfd_mips_elf_read_ecoff_info
2489 #define ELF_ARCH bfd_arch_mips
2490 #define ELF_TARGET_ID MIPS_ELF_DATA
2491 #define ELF_MACHINE_CODE EM_MIPS
2493 #define elf_backend_collect TRUE
2494 #define elf_backend_type_change_ok TRUE
2495 #define elf_backend_can_gc_sections TRUE
2496 #define elf_backend_gc_mark_extra_sections \
2497 _bfd_mips_elf_gc_mark_extra_sections
2498 #define elf_info_to_howto mips_info_to_howto_rela
2499 #define elf_info_to_howto_rel mips_info_to_howto_rel
2500 #define elf_backend_sym_is_global mips_elf_sym_is_global
2501 #define elf_backend_object_p mips_elf32_object_p
2502 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
2503 #define elf_backend_section_processing _bfd_mips_elf_section_processing
2504 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
2505 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
2506 #define elf_backend_section_from_bfd_section \
2507 _bfd_mips_elf_section_from_bfd_section
2508 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
2509 #define elf_backend_link_output_symbol_hook \
2510 _bfd_mips_elf_link_output_symbol_hook
2511 #define elf_backend_create_dynamic_sections \
2512 _bfd_mips_elf_create_dynamic_sections
2513 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
2514 #define elf_backend_merge_symbol_attribute \
2515 _bfd_mips_elf_merge_symbol_attribute
2516 #define elf_backend_get_target_dtag _bfd_mips_elf_get_target_dtag
2517 #define elf_backend_adjust_dynamic_symbol \
2518 _bfd_mips_elf_adjust_dynamic_symbol
2519 #define elf_backend_always_size_sections \
2520 _bfd_mips_elf_always_size_sections
2521 #define elf_backend_size_dynamic_sections \
2522 _bfd_mips_elf_size_dynamic_sections
2523 #define elf_backend_init_index_section _bfd_elf_init_1_index_section
2524 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
2525 #define elf_backend_finish_dynamic_symbol \
2526 _bfd_mips_elf_finish_dynamic_symbol
2527 #define elf_backend_finish_dynamic_sections \
2528 _bfd_mips_elf_finish_dynamic_sections
2529 #define elf_backend_final_write_processing \
2530 _bfd_mips_elf_final_write_processing
2531 #define elf_backend_additional_program_headers \
2532 _bfd_mips_elf_additional_program_headers
2533 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
2534 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
2535 #define elf_backend_copy_indirect_symbol \
2536 _bfd_mips_elf_copy_indirect_symbol
2537 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
2538 #define elf_backend_fixup_symbol elf32_mips_fixup_symbol
2539 #define elf_backend_grok_prstatus elf32_mips_grok_prstatus
2540 #define elf_backend_grok_psinfo elf32_mips_grok_psinfo
2541 #define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap
2543 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
2544 #define elf_backend_want_dynrelro 1
2545 #define elf_backend_may_use_rel_p 1
2546 #define elf_backend_may_use_rela_p 0
2547 #define elf_backend_default_use_rela_p 0
2548 #define elf_backend_sign_extend_vma TRUE
2549 #define elf_backend_plt_readonly 1
2551 #define elf_backend_discard_info _bfd_mips_elf_discard_info
2552 #define elf_backend_ignore_discarded_relocs \
2553 _bfd_mips_elf_ignore_discarded_relocs
2554 #define elf_backend_write_section _bfd_mips_elf_write_section
2555 #define elf_backend_mips_irix_compat elf32_mips_irix_compat
2556 #define elf_backend_mips_rtype_to_howto mips_elf32_rtype_to_howto
2557 #define elf_backend_sort_relocs_p _bfd_mips_elf_sort_relocs_p
2559 #define bfd_elf32_bfd_is_local_label_name \
2560 mips_elf_is_local_label_name
2561 #define bfd_elf32_bfd_is_target_special_symbol \
2562 _bfd_mips_elf_is_target_special_symbol
2563 #define bfd_elf32_get_synthetic_symtab _bfd_mips_elf_get_synthetic_symtab
2564 #define bfd_elf32_find_nearest_line _bfd_mips_elf_find_nearest_line
2565 #define bfd_elf32_find_inliner_info _bfd_mips_elf_find_inliner_info
2566 #define bfd_elf32_new_section_hook _bfd_mips_elf_new_section_hook
2567 #define bfd_elf32_set_section_contents _bfd_mips_elf_set_section_contents
2568 #define bfd_elf32_bfd_get_relocated_section_contents \
2569 _bfd_elf_mips_get_relocated_section_contents
2570 #define bfd_elf32_bfd_link_hash_table_create \
2571 _bfd_mips_elf_link_hash_table_create
2572 #define bfd_elf32_bfd_final_link _bfd_mips_elf_final_link
2573 #define bfd_elf32_bfd_merge_private_bfd_data \
2574 _bfd_mips_elf_merge_private_bfd_data
2575 #define bfd_elf32_bfd_set_private_flags _bfd_mips_elf_set_private_flags
2576 #define bfd_elf32_bfd_print_private_bfd_data \
2577 _bfd_mips_elf_print_private_bfd_data
2578 #define bfd_elf32_bfd_relax_section _bfd_mips_elf_relax_section
2579 #define bfd_elf32_mkobject _bfd_mips_elf_mkobject
2581 /* Support for SGI-ish mips targets. */
2582 #define TARGET_LITTLE_SYM mips_elf32_le_vec
2583 #define TARGET_LITTLE_NAME "elf32-littlemips"
2584 #define TARGET_BIG_SYM mips_elf32_be_vec
2585 #define TARGET_BIG_NAME "elf32-bigmips"
2587 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
2588 a value of 0x1000, and we are compatible. */
2589 #define ELF_MAXPAGESIZE 0x1000
2590 #define ELF_COMMONPAGESIZE 0x1000
2592 #include "elf32-target.h"
2594 /* Support for traditional mips targets. */
2595 #undef TARGET_LITTLE_SYM
2596 #undef TARGET_LITTLE_NAME
2597 #undef TARGET_BIG_SYM
2598 #undef TARGET_BIG_NAME
2600 #undef ELF_MAXPAGESIZE
2601 #undef ELF_COMMONPAGESIZE
2603 #define TARGET_LITTLE_SYM mips_elf32_trad_le_vec
2604 #define TARGET_LITTLE_NAME "elf32-tradlittlemips"
2605 #define TARGET_BIG_SYM mips_elf32_trad_be_vec
2606 #define TARGET_BIG_NAME "elf32-tradbigmips"
2608 /* The MIPS ABI says at Page 5-1:
2609 Virtual addresses and file offsets for MIPS segments are congruent
2610 modulo 64 KByte (0x10000) or larger powers of 2. Because 64 KBytes
2611 is the maximum page size, the files are suitable for paging
2612 regardless of physical page size. */
2613 #define ELF_MAXPAGESIZE 0x10000
2614 #define ELF_COMMONPAGESIZE 0x1000
2615 #define elf32_bed elf32_tradbed
2617 #undef elf_backend_write_core_note
2618 #define elf_backend_write_core_note elf32_mips_write_core_note
2620 /* Include the target file again for this target. */
2621 #include "elf32-target.h"
2623 /* FreeBSD support. */
2625 #undef TARGET_LITTLE_SYM
2626 #undef TARGET_LITTLE_NAME
2627 #undef TARGET_BIG_SYM
2628 #undef TARGET_BIG_NAME
2630 #define TARGET_LITTLE_SYM mips_elf32_tradfbsd_le_vec
2631 #define TARGET_LITTLE_NAME "elf32-tradlittlemips-freebsd"
2632 #define TARGET_BIG_SYM mips_elf32_tradfbsd_be_vec
2633 #define TARGET_BIG_NAME "elf32-tradbigmips-freebsd"
2636 #define ELF_OSABI ELFOSABI_FREEBSD
2639 #define elf32_bed elf32_fbsd_tradbed
2641 #undef elf_backend_write_core_note
2643 #include "elf32-target.h"
2644 /* Implement elf_backend_final_write_processing for VxWorks. */
2647 mips_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
2649 _bfd_mips_elf_final_write_processing (abfd, linker);
2650 elf_vxworks_final_write_processing (abfd, linker);
2653 #undef TARGET_LITTLE_SYM
2654 #undef TARGET_LITTLE_NAME
2655 #undef TARGET_BIG_SYM
2656 #undef TARGET_BIG_NAME
2658 #undef ELF_MAXPAGESIZE
2659 #undef ELF_COMMONPAGESIZE
2661 #define TARGET_LITTLE_SYM mips_elf32_vxworks_le_vec
2662 #define TARGET_LITTLE_NAME "elf32-littlemips-vxworks"
2663 #define TARGET_BIG_SYM mips_elf32_vxworks_be_vec
2664 #define TARGET_BIG_NAME "elf32-bigmips-vxworks"
2668 #define elf32_bed elf32_mips_vxworks_bed
2670 #define ELF_MAXPAGESIZE 0x1000
2671 #define ELF_COMMONPAGESIZE 0x1000
2673 #undef elf_backend_want_got_plt
2674 #define elf_backend_want_got_plt 1
2675 #undef elf_backend_want_plt_sym
2676 #define elf_backend_want_plt_sym 1
2677 #undef elf_backend_may_use_rel_p
2678 #define elf_backend_may_use_rel_p 0
2679 #undef elf_backend_may_use_rela_p
2680 #define elf_backend_may_use_rela_p 1
2681 #undef elf_backend_default_use_rela_p
2682 #define elf_backend_default_use_rela_p 1
2683 #undef elf_backend_got_header_size
2684 #define elf_backend_got_header_size (4 * 3)
2685 #undef elf_backend_dtrel_excludes_plt
2686 #define elf_backend_dtrel_excludes_plt 1
2688 #undef elf_backend_finish_dynamic_symbol
2689 #define elf_backend_finish_dynamic_symbol \
2690 _bfd_mips_vxworks_finish_dynamic_symbol
2691 #undef bfd_elf32_bfd_link_hash_table_create
2692 #define bfd_elf32_bfd_link_hash_table_create \
2693 _bfd_mips_vxworks_link_hash_table_create
2694 #undef elf_backend_add_symbol_hook
2695 #define elf_backend_add_symbol_hook \
2696 elf_vxworks_add_symbol_hook
2697 #undef elf_backend_link_output_symbol_hook
2698 #define elf_backend_link_output_symbol_hook \
2699 elf_vxworks_link_output_symbol_hook
2700 #undef elf_backend_emit_relocs
2701 #define elf_backend_emit_relocs \
2702 elf_vxworks_emit_relocs
2703 #undef elf_backend_final_write_processing
2704 #define elf_backend_final_write_processing \
2705 mips_vxworks_final_write_processing
2707 #undef elf_backend_additional_program_headers
2708 #undef elf_backend_modify_segment_map
2709 #undef elf_backend_symbol_processing
2710 /* NOTE: elf_backend_rela_normal is not defined for MIPS. */
2712 #undef bfd_elf32_get_synthetic_symtab
2714 #include "elf32-target.h"