1 /* MIPS-specific support for 32-bit ELF
2 Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 2003 Free Software Foundation, Inc.
5 Most of the information added by Ian Lance Taylor, Cygnus Support,
7 N32/64 ABI support added by Mark Mitchell, CodeSourcery, LLC.
8 <mark@codesourcery.com>
9 Traditional MIPS targets support added by Koundinya.K, Dansk Data
10 Elektronik & Operations Research Group. <kk@ddeorg.soft.net>
12 This file is part of BFD, the Binary File Descriptor library.
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
28 /* This file handles MIPS ELF targets. SGI Irix 5 uses a slightly
29 different MIPS ELF from other targets. This matters when linking.
30 This file supports both, switching at runtime. */
38 #include "elfxx-mips.h"
41 /* Get the ECOFF swapping routines. */
43 #include "coff/symconst.h"
44 #include "coff/internal.h"
45 #include "coff/ecoff.h"
46 #include "coff/mips.h"
47 #define ECOFF_SIGNED_32
48 #include "ecoffswap.h"
50 static bfd_reloc_status_type mips_elf_generic_reloc
51 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
52 static bfd_reloc_status_type mips_elf_hi16_reloc
53 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
54 static bfd_reloc_status_type mips_elf_lo16_reloc
55 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
56 static bfd_reloc_status_type mips_elf_got16_reloc
57 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
58 static bfd_boolean mips_elf_assign_gp
59 PARAMS ((bfd *, bfd_vma *));
60 static bfd_reloc_status_type mips_elf_final_gp
61 PARAMS ((bfd *, asymbol *, bfd_boolean, char **, bfd_vma *));
62 static bfd_reloc_status_type mips_elf_gprel16_reloc
63 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
64 static bfd_reloc_status_type mips_elf_literal_reloc
65 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
66 static bfd_reloc_status_type mips_elf_gprel32_reloc
67 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
68 static bfd_reloc_status_type gprel32_with_gp
69 PARAMS ((bfd *, asymbol *, arelent *, asection *, bfd_boolean, PTR,
71 static bfd_reloc_status_type mips_elf_shift6_reloc
72 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
73 static bfd_reloc_status_type mips16_jump_reloc
74 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
75 static bfd_reloc_status_type mips16_gprel_reloc
76 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
77 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
78 PARAMS ((bfd *, bfd_reloc_code_real_type));
79 static reloc_howto_type *mips_elf_n32_rtype_to_howto
80 PARAMS ((unsigned int, bfd_boolean));
81 static void mips_info_to_howto_rel
82 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
83 static void mips_info_to_howto_rela
84 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
85 static bfd_boolean mips_elf_sym_is_global
86 PARAMS ((bfd *, asymbol *));
87 static bfd_boolean mips_elf_n32_object_p
89 static bfd_boolean elf32_mips_grok_prstatus
90 PARAMS ((bfd *, Elf_Internal_Note *));
91 static bfd_boolean elf32_mips_grok_psinfo
92 PARAMS ((bfd *, Elf_Internal_Note *));
93 static irix_compat_t elf_n32_mips_irix_compat
96 extern const bfd_target bfd_elf32_nbigmips_vec;
97 extern const bfd_target bfd_elf32_nlittlemips_vec;
99 static asection *prev_reloc_section = NULL;
100 static bfd_vma prev_reloc_address = -1;
101 static bfd_vma prev_reloc_addend = 0;
103 /* Nonzero if ABFD is using the N32 ABI. */
104 #define ABI_N32_P(abfd) \
105 ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
107 /* Whether we are trying to be compatible with IRIX at all. */
108 #define SGI_COMPAT(abfd) \
109 (elf_n32_mips_irix_compat (abfd) != ict_none)
111 /* The number of local .got entries we reserve. */
112 #define MIPS_RESERVED_GOTNO (2)
114 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
115 from smaller values. Start with zero, widen, *then* decrement. */
116 #define MINUS_ONE (((bfd_vma)0) - 1)
118 /* The relocation table used for SHT_REL sections. */
120 static reloc_howto_type elf_mips_howto_table_rel[] =
123 HOWTO (R_MIPS_NONE, /* type */
125 0, /* size (0 = byte, 1 = short, 2 = long) */
127 FALSE, /* pc_relative */
129 complain_overflow_dont, /* complain_on_overflow */
130 mips_elf_generic_reloc, /* special_function */
131 "R_MIPS_NONE", /* name */
132 FALSE, /* partial_inplace */
135 FALSE), /* pcrel_offset */
137 /* 16 bit relocation. */
138 HOWTO (R_MIPS_16, /* type */
140 2, /* size (0 = byte, 1 = short, 2 = long) */
142 FALSE, /* pc_relative */
144 complain_overflow_signed, /* complain_on_overflow */
145 mips_elf_generic_reloc, /* special_function */
146 "R_MIPS_16", /* name */
147 TRUE, /* partial_inplace */
148 0x0000ffff, /* src_mask */
149 0x0000ffff, /* dst_mask */
150 FALSE), /* pcrel_offset */
152 /* 32 bit relocation. */
153 HOWTO (R_MIPS_32, /* type */
155 2, /* size (0 = byte, 1 = short, 2 = long) */
157 FALSE, /* pc_relative */
159 complain_overflow_dont, /* complain_on_overflow */
160 mips_elf_generic_reloc, /* special_function */
161 "R_MIPS_32", /* name */
162 TRUE, /* partial_inplace */
163 0xffffffff, /* src_mask */
164 0xffffffff, /* dst_mask */
165 FALSE), /* pcrel_offset */
167 /* 32 bit symbol relative relocation. */
168 HOWTO (R_MIPS_REL32, /* type */
170 2, /* size (0 = byte, 1 = short, 2 = long) */
172 FALSE, /* pc_relative */
174 complain_overflow_dont, /* complain_on_overflow */
175 mips_elf_generic_reloc, /* special_function */
176 "R_MIPS_REL32", /* name */
177 TRUE, /* partial_inplace */
178 0xffffffff, /* src_mask */
179 0xffffffff, /* dst_mask */
180 FALSE), /* pcrel_offset */
182 /* 26 bit jump address. */
183 HOWTO (R_MIPS_26, /* type */
185 2, /* size (0 = byte, 1 = short, 2 = long) */
187 FALSE, /* pc_relative */
189 complain_overflow_dont, /* complain_on_overflow */
190 /* This needs complex overflow
191 detection, because the upper four
192 bits must match the PC + 4. */
193 mips_elf_generic_reloc, /* special_function */
194 "R_MIPS_26", /* name */
195 TRUE, /* partial_inplace */
196 0x03ffffff, /* src_mask */
197 0x03ffffff, /* dst_mask */
198 FALSE), /* pcrel_offset */
200 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
201 However, the native IRIX6 tools use them, so we try our best. */
203 /* High 16 bits of symbol value. */
204 HOWTO (R_MIPS_HI16, /* type */
206 2, /* size (0 = byte, 1 = short, 2 = long) */
208 FALSE, /* pc_relative */
210 complain_overflow_dont, /* complain_on_overflow */
211 mips_elf_hi16_reloc, /* special_function */
212 "R_MIPS_HI16", /* name */
213 TRUE, /* partial_inplace */
214 0x0000ffff, /* src_mask */
215 0x0000ffff, /* dst_mask */
216 FALSE), /* pcrel_offset */
218 /* Low 16 bits of symbol value. */
219 HOWTO (R_MIPS_LO16, /* type */
221 2, /* size (0 = byte, 1 = short, 2 = long) */
223 FALSE, /* pc_relative */
225 complain_overflow_dont, /* complain_on_overflow */
226 mips_elf_lo16_reloc, /* special_function */
227 "R_MIPS_LO16", /* name */
228 TRUE, /* partial_inplace */
229 0x0000ffff, /* src_mask */
230 0x0000ffff, /* dst_mask */
231 FALSE), /* pcrel_offset */
233 /* GP relative reference. */
234 HOWTO (R_MIPS_GPREL16, /* type */
236 2, /* size (0 = byte, 1 = short, 2 = long) */
238 FALSE, /* pc_relative */
240 complain_overflow_signed, /* complain_on_overflow */
241 mips_elf_gprel16_reloc, /* special_function */
242 "R_MIPS_GPREL16", /* name */
243 TRUE, /* partial_inplace */
244 0x0000ffff, /* src_mask */
245 0x0000ffff, /* dst_mask */
246 FALSE), /* pcrel_offset */
248 /* Reference to literal section. */
249 HOWTO (R_MIPS_LITERAL, /* type */
251 2, /* size (0 = byte, 1 = short, 2 = long) */
253 FALSE, /* pc_relative */
255 complain_overflow_signed, /* complain_on_overflow */
256 mips_elf_literal_reloc, /* special_function */
257 "R_MIPS_LITERAL", /* name */
258 TRUE, /* partial_inplace */
259 0x0000ffff, /* src_mask */
260 0x0000ffff, /* dst_mask */
261 FALSE), /* pcrel_offset */
263 /* Reference to global offset table. */
264 HOWTO (R_MIPS_GOT16, /* type */
266 2, /* size (0 = byte, 1 = short, 2 = long) */
268 FALSE, /* pc_relative */
270 complain_overflow_signed, /* complain_on_overflow */
271 mips_elf_got16_reloc, /* special_function */
272 "R_MIPS_GOT16", /* name */
273 TRUE, /* partial_inplace */
274 0x0000ffff, /* src_mask */
275 0x0000ffff, /* dst_mask */
276 FALSE), /* pcrel_offset */
278 /* 16 bit PC relative reference. Note that the ABI document has a typo
279 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
280 We do the right thing here. */
281 HOWTO (R_MIPS_PC16, /* type */
283 2, /* size (0 = byte, 1 = short, 2 = long) */
285 TRUE, /* pc_relative */
287 complain_overflow_signed, /* complain_on_overflow */
288 mips_elf_generic_reloc, /* special_function */
289 "R_MIPS_PC16", /* name */
290 TRUE, /* partial_inplace */
291 0x0000ffff, /* src_mask */
292 0x0000ffff, /* dst_mask */
293 TRUE), /* pcrel_offset */
295 /* 16 bit call through global offset table. */
296 HOWTO (R_MIPS_CALL16, /* type */
298 2, /* size (0 = byte, 1 = short, 2 = long) */
300 FALSE, /* pc_relative */
302 complain_overflow_signed, /* complain_on_overflow */
303 mips_elf_generic_reloc, /* special_function */
304 "R_MIPS_CALL16", /* name */
305 TRUE, /* partial_inplace */
306 0x0000ffff, /* src_mask */
307 0x0000ffff, /* dst_mask */
308 FALSE), /* pcrel_offset */
310 /* 32 bit GP relative reference. */
311 HOWTO (R_MIPS_GPREL32, /* type */
313 2, /* size (0 = byte, 1 = short, 2 = long) */
315 FALSE, /* pc_relative */
317 complain_overflow_dont, /* complain_on_overflow */
318 mips_elf_gprel32_reloc, /* special_function */
319 "R_MIPS_GPREL32", /* name */
320 TRUE, /* partial_inplace */
321 0xffffffff, /* src_mask */
322 0xffffffff, /* dst_mask */
323 FALSE), /* pcrel_offset */
325 /* The remaining relocs are defined on Irix 5, although they are
326 not defined by the ABI. */
331 /* A 5 bit shift field. */
332 HOWTO (R_MIPS_SHIFT5, /* type */
334 2, /* size (0 = byte, 1 = short, 2 = long) */
336 FALSE, /* pc_relative */
338 complain_overflow_bitfield, /* complain_on_overflow */
339 mips_elf_generic_reloc, /* special_function */
340 "R_MIPS_SHIFT5", /* name */
341 TRUE, /* partial_inplace */
342 0x000007c0, /* src_mask */
343 0x000007c0, /* dst_mask */
344 FALSE), /* pcrel_offset */
346 /* A 6 bit shift field. */
347 HOWTO (R_MIPS_SHIFT6, /* type */
349 2, /* size (0 = byte, 1 = short, 2 = long) */
351 FALSE, /* pc_relative */
353 complain_overflow_bitfield, /* complain_on_overflow */
354 mips_elf_shift6_reloc, /* special_function */
355 "R_MIPS_SHIFT6", /* name */
356 TRUE, /* partial_inplace */
357 0x000007c4, /* src_mask */
358 0x000007c4, /* dst_mask */
359 FALSE), /* pcrel_offset */
361 /* A 64 bit relocation. */
362 HOWTO (R_MIPS_64, /* type */
364 4, /* size (0 = byte, 1 = short, 2 = long) */
366 FALSE, /* pc_relative */
368 complain_overflow_dont, /* complain_on_overflow */
369 mips_elf_generic_reloc, /* special_function */
370 "R_MIPS_64", /* name */
371 TRUE, /* partial_inplace */
372 MINUS_ONE, /* src_mask */
373 MINUS_ONE, /* dst_mask */
374 FALSE), /* pcrel_offset */
376 /* Displacement in the global offset table. */
377 HOWTO (R_MIPS_GOT_DISP, /* type */
379 2, /* size (0 = byte, 1 = short, 2 = long) */
381 FALSE, /* pc_relative */
383 complain_overflow_signed, /* complain_on_overflow */
384 mips_elf_generic_reloc, /* special_function */
385 "R_MIPS_GOT_DISP", /* name */
386 TRUE, /* partial_inplace */
387 0x0000ffff, /* src_mask */
388 0x0000ffff, /* dst_mask */
389 FALSE), /* pcrel_offset */
391 /* Displacement to page pointer in the global offset table. */
392 HOWTO (R_MIPS_GOT_PAGE, /* type */
394 2, /* size (0 = byte, 1 = short, 2 = long) */
396 FALSE, /* pc_relative */
398 complain_overflow_signed, /* complain_on_overflow */
399 mips_elf_generic_reloc, /* special_function */
400 "R_MIPS_GOT_PAGE", /* name */
401 TRUE, /* partial_inplace */
402 0x0000ffff, /* src_mask */
403 0x0000ffff, /* dst_mask */
404 FALSE), /* pcrel_offset */
406 /* Offset from page pointer in the global offset table. */
407 HOWTO (R_MIPS_GOT_OFST, /* type */
409 2, /* size (0 = byte, 1 = short, 2 = long) */
411 FALSE, /* pc_relative */
413 complain_overflow_signed, /* complain_on_overflow */
414 mips_elf_generic_reloc, /* special_function */
415 "R_MIPS_GOT_OFST", /* name */
416 TRUE, /* partial_inplace */
417 0x0000ffff, /* src_mask */
418 0x0000ffff, /* dst_mask */
419 FALSE), /* pcrel_offset */
421 /* High 16 bits of displacement in global offset table. */
422 HOWTO (R_MIPS_GOT_HI16, /* type */
424 2, /* size (0 = byte, 1 = short, 2 = long) */
426 FALSE, /* pc_relative */
428 complain_overflow_dont, /* complain_on_overflow */
429 mips_elf_generic_reloc, /* special_function */
430 "R_MIPS_GOT_HI16", /* name */
431 TRUE, /* partial_inplace */
432 0x0000ffff, /* src_mask */
433 0x0000ffff, /* dst_mask */
434 FALSE), /* pcrel_offset */
436 /* Low 16 bits of displacement in global offset table. */
437 HOWTO (R_MIPS_GOT_LO16, /* type */
439 2, /* size (0 = byte, 1 = short, 2 = long) */
441 FALSE, /* pc_relative */
443 complain_overflow_dont, /* complain_on_overflow */
444 mips_elf_generic_reloc, /* special_function */
445 "R_MIPS_GOT_LO16", /* name */
446 TRUE, /* partial_inplace */
447 0x0000ffff, /* src_mask */
448 0x0000ffff, /* dst_mask */
449 FALSE), /* pcrel_offset */
451 /* 64 bit subtraction. */
452 HOWTO (R_MIPS_SUB, /* type */
454 4, /* size (0 = byte, 1 = short, 2 = long) */
456 FALSE, /* pc_relative */
458 complain_overflow_dont, /* complain_on_overflow */
459 mips_elf_generic_reloc, /* special_function */
460 "R_MIPS_SUB", /* name */
461 TRUE, /* partial_inplace */
462 MINUS_ONE, /* src_mask */
463 MINUS_ONE, /* dst_mask */
464 FALSE), /* pcrel_offset */
466 /* Insert the addend as an instruction. */
467 /* FIXME: Not handled correctly. */
468 HOWTO (R_MIPS_INSERT_A, /* type */
470 2, /* size (0 = byte, 1 = short, 2 = long) */
472 FALSE, /* pc_relative */
474 complain_overflow_dont, /* complain_on_overflow */
475 mips_elf_generic_reloc, /* special_function */
476 "R_MIPS_INSERT_A", /* name */
477 TRUE, /* partial_inplace */
478 0xffffffff, /* src_mask */
479 0xffffffff, /* dst_mask */
480 FALSE), /* pcrel_offset */
482 /* Insert the addend as an instruction, and change all relocations
483 to refer to the old instruction at the address. */
484 /* FIXME: Not handled correctly. */
485 HOWTO (R_MIPS_INSERT_B, /* type */
487 2, /* size (0 = byte, 1 = short, 2 = long) */
489 FALSE, /* pc_relative */
491 complain_overflow_dont, /* complain_on_overflow */
492 mips_elf_generic_reloc, /* special_function */
493 "R_MIPS_INSERT_B", /* name */
494 TRUE, /* partial_inplace */
495 0xffffffff, /* src_mask */
496 0xffffffff, /* dst_mask */
497 FALSE), /* pcrel_offset */
499 /* Delete a 32 bit instruction. */
500 /* FIXME: Not handled correctly. */
501 HOWTO (R_MIPS_DELETE, /* type */
503 2, /* size (0 = byte, 1 = short, 2 = long) */
505 FALSE, /* pc_relative */
507 complain_overflow_dont, /* complain_on_overflow */
508 mips_elf_generic_reloc, /* special_function */
509 "R_MIPS_DELETE", /* name */
510 TRUE, /* partial_inplace */
511 0xffffffff, /* src_mask */
512 0xffffffff, /* dst_mask */
513 FALSE), /* pcrel_offset */
515 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
517 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
518 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
520 b) No other NEwABI toolchain actually emits such relocations. */
521 EMPTY_HOWTO (R_MIPS_HIGHER),
522 EMPTY_HOWTO (R_MIPS_HIGHEST),
524 /* High 16 bits of displacement in global offset table. */
525 HOWTO (R_MIPS_CALL_HI16, /* type */
527 2, /* size (0 = byte, 1 = short, 2 = long) */
529 FALSE, /* pc_relative */
531 complain_overflow_dont, /* complain_on_overflow */
532 mips_elf_generic_reloc, /* special_function */
533 "R_MIPS_CALL_HI16", /* name */
534 TRUE, /* partial_inplace */
535 0x0000ffff, /* src_mask */
536 0x0000ffff, /* dst_mask */
537 FALSE), /* pcrel_offset */
539 /* Low 16 bits of displacement in global offset table. */
540 HOWTO (R_MIPS_CALL_LO16, /* type */
542 2, /* size (0 = byte, 1 = short, 2 = long) */
544 FALSE, /* pc_relative */
546 complain_overflow_dont, /* complain_on_overflow */
547 mips_elf_generic_reloc, /* special_function */
548 "R_MIPS_CALL_LO16", /* name */
549 TRUE, /* partial_inplace */
550 0x0000ffff, /* src_mask */
551 0x0000ffff, /* dst_mask */
552 FALSE), /* pcrel_offset */
554 /* Section displacement. */
555 HOWTO (R_MIPS_SCN_DISP, /* type */
557 2, /* size (0 = byte, 1 = short, 2 = long) */
559 FALSE, /* pc_relative */
561 complain_overflow_dont, /* complain_on_overflow */
562 mips_elf_generic_reloc, /* special_function */
563 "R_MIPS_SCN_DISP", /* name */
564 TRUE, /* partial_inplace */
565 0xffffffff, /* src_mask */
566 0xffffffff, /* dst_mask */
567 FALSE), /* pcrel_offset */
569 HOWTO (R_MIPS_REL16, /* type */
571 1, /* size (0 = byte, 1 = short, 2 = long) */
573 FALSE, /* pc_relative */
575 complain_overflow_signed, /* complain_on_overflow */
576 mips_elf_generic_reloc, /* special_function */
577 "R_MIPS_REL16", /* name */
578 TRUE, /* partial_inplace */
579 0xffff, /* src_mask */
580 0xffff, /* dst_mask */
581 FALSE), /* pcrel_offset */
583 /* These two are obsolete. */
584 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
585 EMPTY_HOWTO (R_MIPS_PJUMP),
587 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
588 It must be used for multigot GOT's (and only there). */
589 HOWTO (R_MIPS_RELGOT, /* type */
591 2, /* size (0 = byte, 1 = short, 2 = long) */
593 FALSE, /* pc_relative */
595 complain_overflow_dont, /* complain_on_overflow */
596 mips_elf_generic_reloc, /* special_function */
597 "R_MIPS_RELGOT", /* name */
598 TRUE, /* partial_inplace */
599 0xffffffff, /* src_mask */
600 0xffffffff, /* dst_mask */
601 FALSE), /* pcrel_offset */
603 /* Protected jump conversion. This is an optimization hint. No
604 relocation is required for correctness. */
605 HOWTO (R_MIPS_JALR, /* type */
607 2, /* size (0 = byte, 1 = short, 2 = long) */
609 FALSE, /* pc_relative */
611 complain_overflow_dont, /* complain_on_overflow */
612 mips_elf_generic_reloc, /* special_function */
613 "R_MIPS_JALR", /* name */
614 FALSE, /* partial_inplace */
615 0x00000000, /* src_mask */
616 0x00000000, /* dst_mask */
617 FALSE), /* pcrel_offset */
620 /* The relocation table used for SHT_RELA sections. */
622 static reloc_howto_type elf_mips_howto_table_rela[] =
625 HOWTO (R_MIPS_NONE, /* type */
627 0, /* size (0 = byte, 1 = short, 2 = long) */
629 FALSE, /* pc_relative */
631 complain_overflow_dont, /* complain_on_overflow */
632 mips_elf_generic_reloc, /* special_function */
633 "R_MIPS_NONE", /* name */
634 FALSE, /* partial_inplace */
637 FALSE), /* pcrel_offset */
639 /* 16 bit relocation. */
640 HOWTO (R_MIPS_16, /* type */
642 2, /* size (0 = byte, 1 = short, 2 = long) */
644 FALSE, /* pc_relative */
646 complain_overflow_signed, /* complain_on_overflow */
647 mips_elf_generic_reloc, /* special_function */
648 "R_MIPS_16", /* name */
649 FALSE, /* partial_inplace */
651 0x0000, /* dst_mask */
652 FALSE), /* pcrel_offset */
654 /* 32 bit relocation. */
655 HOWTO (R_MIPS_32, /* type */
657 2, /* size (0 = byte, 1 = short, 2 = long) */
659 FALSE, /* pc_relative */
661 complain_overflow_dont, /* complain_on_overflow */
662 mips_elf_generic_reloc, /* special_function */
663 "R_MIPS_32", /* name */
664 FALSE, /* partial_inplace */
666 0xffffffff, /* dst_mask */
667 FALSE), /* pcrel_offset */
669 /* 32 bit symbol relative relocation. */
670 HOWTO (R_MIPS_REL32, /* type */
672 2, /* size (0 = byte, 1 = short, 2 = long) */
674 FALSE, /* pc_relative */
676 complain_overflow_dont, /* complain_on_overflow */
677 mips_elf_generic_reloc, /* special_function */
678 "R_MIPS_REL32", /* name */
679 FALSE, /* partial_inplace */
681 0xffffffff, /* dst_mask */
682 FALSE), /* pcrel_offset */
684 /* 26 bit jump address. */
685 HOWTO (R_MIPS_26, /* type */
687 2, /* size (0 = byte, 1 = short, 2 = long) */
689 FALSE, /* pc_relative */
691 complain_overflow_dont, /* complain_on_overflow */
692 /* This needs complex overflow
693 detection, because the upper 36
694 bits must match the PC + 4. */
695 mips_elf_generic_reloc, /* special_function */
696 "R_MIPS_26", /* name */
697 FALSE, /* partial_inplace */
699 0x03ffffff, /* dst_mask */
700 FALSE), /* pcrel_offset */
702 /* High 16 bits of symbol value. */
703 HOWTO (R_MIPS_HI16, /* type */
705 2, /* size (0 = byte, 1 = short, 2 = long) */
707 FALSE, /* pc_relative */
709 complain_overflow_dont, /* complain_on_overflow */
710 mips_elf_generic_reloc, /* special_function */
711 "R_MIPS_HI16", /* name */
712 FALSE, /* partial_inplace */
714 0x0000ffff, /* dst_mask */
715 FALSE), /* pcrel_offset */
717 /* Low 16 bits of symbol value. */
718 HOWTO (R_MIPS_LO16, /* type */
720 2, /* size (0 = byte, 1 = short, 2 = long) */
722 FALSE, /* pc_relative */
724 complain_overflow_dont, /* complain_on_overflow */
725 mips_elf_generic_reloc, /* special_function */
726 "R_MIPS_LO16", /* name */
727 FALSE, /* partial_inplace */
729 0x0000ffff, /* dst_mask */
730 FALSE), /* pcrel_offset */
732 /* GP relative reference. */
733 HOWTO (R_MIPS_GPREL16, /* type */
735 2, /* size (0 = byte, 1 = short, 2 = long) */
737 FALSE, /* pc_relative */
739 complain_overflow_signed, /* complain_on_overflow */
740 mips_elf_gprel16_reloc, /* special_function */
741 "R_MIPS_GPREL16", /* name */
742 FALSE, /* partial_inplace */
744 0x0000ffff, /* dst_mask */
745 FALSE), /* pcrel_offset */
747 /* Reference to literal section. */
748 HOWTO (R_MIPS_LITERAL, /* type */
750 2, /* size (0 = byte, 1 = short, 2 = long) */
752 FALSE, /* pc_relative */
754 complain_overflow_signed, /* complain_on_overflow */
755 mips_elf_literal_reloc, /* special_function */
756 "R_MIPS_LITERAL", /* name */
757 FALSE, /* partial_inplace */
759 0x0000ffff, /* dst_mask */
760 FALSE), /* pcrel_offset */
762 /* Reference to global offset table. */
763 HOWTO (R_MIPS_GOT16, /* type */
765 2, /* size (0 = byte, 1 = short, 2 = long) */
767 FALSE, /* pc_relative */
769 complain_overflow_signed, /* complain_on_overflow */
770 mips_elf_got16_reloc, /* special_function */
771 "R_MIPS_GOT16", /* name */
772 FALSE, /* partial_inplace */
774 0x0000ffff, /* dst_mask */
775 FALSE), /* pcrel_offset */
777 /* 16 bit PC relative reference. Note that the ABI document has a typo
778 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
779 We do the right thing here. */
780 HOWTO (R_MIPS_PC16, /* type */
782 2, /* size (0 = byte, 1 = short, 2 = long) */
784 TRUE, /* pc_relative */
786 complain_overflow_signed, /* complain_on_overflow */
787 mips_elf_generic_reloc, /* special_function */
788 "R_MIPS_PC16", /* name */
789 FALSE, /* partial_inplace */
791 0x0000ffff, /* dst_mask */
792 TRUE), /* pcrel_offset */
794 /* 16 bit call through global offset table. */
795 HOWTO (R_MIPS_CALL16, /* type */
797 2, /* size (0 = byte, 1 = short, 2 = long) */
799 FALSE, /* pc_relative */
801 complain_overflow_signed, /* complain_on_overflow */
802 mips_elf_generic_reloc, /* special_function */
803 "R_MIPS_CALL16", /* name */
804 FALSE, /* partial_inplace */
806 0x0000ffff, /* dst_mask */
807 FALSE), /* pcrel_offset */
809 /* 32 bit GP relative reference. */
810 HOWTO (R_MIPS_GPREL32, /* type */
812 2, /* size (0 = byte, 1 = short, 2 = long) */
814 FALSE, /* pc_relative */
816 complain_overflow_dont, /* complain_on_overflow */
817 mips_elf_gprel32_reloc, /* special_function */
818 "R_MIPS_GPREL32", /* name */
819 FALSE, /* partial_inplace */
821 0xffffffff, /* dst_mask */
822 FALSE), /* pcrel_offset */
828 /* A 5 bit shift field. */
829 HOWTO (R_MIPS_SHIFT5, /* type */
831 2, /* size (0 = byte, 1 = short, 2 = long) */
833 FALSE, /* pc_relative */
835 complain_overflow_bitfield, /* complain_on_overflow */
836 mips_elf_generic_reloc, /* special_function */
837 "R_MIPS_SHIFT5", /* name */
838 FALSE, /* partial_inplace */
840 0x000007c0, /* dst_mask */
841 FALSE), /* pcrel_offset */
843 /* A 6 bit shift field. */
844 HOWTO (R_MIPS_SHIFT6, /* type */
846 2, /* size (0 = byte, 1 = short, 2 = long) */
848 FALSE, /* pc_relative */
850 complain_overflow_bitfield, /* complain_on_overflow */
851 mips_elf_shift6_reloc, /* special_function */
852 "R_MIPS_SHIFT6", /* name */
853 FALSE, /* partial_inplace */
855 0x000007c4, /* dst_mask */
856 FALSE), /* pcrel_offset */
858 /* 64 bit relocation. */
859 HOWTO (R_MIPS_64, /* type */
861 4, /* size (0 = byte, 1 = short, 2 = long) */
863 FALSE, /* pc_relative */
865 complain_overflow_dont, /* complain_on_overflow */
866 mips_elf_generic_reloc, /* special_function */
867 "R_MIPS_64", /* name */
868 FALSE, /* partial_inplace */
870 MINUS_ONE, /* dst_mask */
871 FALSE), /* pcrel_offset */
873 /* Displacement in the global offset table. */
874 HOWTO (R_MIPS_GOT_DISP, /* type */
876 2, /* size (0 = byte, 1 = short, 2 = long) */
878 FALSE, /* pc_relative */
880 complain_overflow_signed, /* complain_on_overflow */
881 mips_elf_generic_reloc, /* special_function */
882 "R_MIPS_GOT_DISP", /* name */
883 FALSE, /* partial_inplace */
885 0x0000ffff, /* dst_mask */
886 FALSE), /* pcrel_offset */
888 /* Displacement to page pointer in the global offset table. */
889 HOWTO (R_MIPS_GOT_PAGE, /* type */
891 2, /* size (0 = byte, 1 = short, 2 = long) */
893 FALSE, /* pc_relative */
895 complain_overflow_signed, /* complain_on_overflow */
896 mips_elf_generic_reloc, /* special_function */
897 "R_MIPS_GOT_PAGE", /* name */
898 FALSE, /* partial_inplace */
900 0x0000ffff, /* dst_mask */
901 FALSE), /* pcrel_offset */
903 /* Offset from page pointer in the global offset table. */
904 HOWTO (R_MIPS_GOT_OFST, /* type */
906 2, /* size (0 = byte, 1 = short, 2 = long) */
908 FALSE, /* pc_relative */
910 complain_overflow_signed, /* complain_on_overflow */
911 mips_elf_generic_reloc, /* special_function */
912 "R_MIPS_GOT_OFST", /* name */
913 FALSE, /* partial_inplace */
915 0x0000ffff, /* dst_mask */
916 FALSE), /* pcrel_offset */
918 /* High 16 bits of displacement in global offset table. */
919 HOWTO (R_MIPS_GOT_HI16, /* type */
921 2, /* size (0 = byte, 1 = short, 2 = long) */
923 FALSE, /* pc_relative */
925 complain_overflow_dont, /* complain_on_overflow */
926 mips_elf_generic_reloc, /* special_function */
927 "R_MIPS_GOT_HI16", /* name */
928 FALSE, /* partial_inplace */
930 0x0000ffff, /* dst_mask */
931 FALSE), /* pcrel_offset */
933 /* Low 16 bits of displacement in global offset table. */
934 HOWTO (R_MIPS_GOT_LO16, /* type */
936 2, /* size (0 = byte, 1 = short, 2 = long) */
938 FALSE, /* pc_relative */
940 complain_overflow_dont, /* complain_on_overflow */
941 mips_elf_generic_reloc, /* special_function */
942 "R_MIPS_GOT_LO16", /* name */
943 FALSE, /* partial_inplace */
945 0x0000ffff, /* dst_mask */
946 FALSE), /* pcrel_offset */
948 /* 64 bit substraction. */
949 HOWTO (R_MIPS_SUB, /* type */
951 4, /* size (0 = byte, 1 = short, 2 = long) */
953 FALSE, /* pc_relative */
955 complain_overflow_dont, /* complain_on_overflow */
956 mips_elf_generic_reloc, /* special_function */
957 "R_MIPS_SUB", /* name */
958 FALSE, /* partial_inplace */
960 MINUS_ONE, /* dst_mask */
961 FALSE), /* pcrel_offset */
963 /* Insert the addend as an instruction. */
964 /* FIXME: Not handled correctly. */
965 HOWTO (R_MIPS_INSERT_A, /* type */
967 2, /* size (0 = byte, 1 = short, 2 = long) */
969 FALSE, /* pc_relative */
971 complain_overflow_dont, /* complain_on_overflow */
972 mips_elf_generic_reloc, /* special_function */
973 "R_MIPS_INSERT_A", /* name */
974 FALSE, /* partial_inplace */
976 0xffffffff, /* dst_mask */
977 FALSE), /* pcrel_offset */
979 /* Insert the addend as an instruction, and change all relocations
980 to refer to the old instruction at the address. */
981 /* FIXME: Not handled correctly. */
982 HOWTO (R_MIPS_INSERT_B, /* type */
984 2, /* size (0 = byte, 1 = short, 2 = long) */
986 FALSE, /* pc_relative */
988 complain_overflow_dont, /* complain_on_overflow */
989 mips_elf_generic_reloc, /* special_function */
990 "R_MIPS_INSERT_B", /* name */
991 FALSE, /* partial_inplace */
993 0xffffffff, /* dst_mask */
994 FALSE), /* pcrel_offset */
996 /* Delete a 32 bit instruction. */
997 /* FIXME: Not handled correctly. */
998 HOWTO (R_MIPS_DELETE, /* type */
1000 2, /* size (0 = byte, 1 = short, 2 = long) */
1002 FALSE, /* pc_relative */
1004 complain_overflow_dont, /* complain_on_overflow */
1005 mips_elf_generic_reloc, /* special_function */
1006 "R_MIPS_DELETE", /* name */
1007 FALSE, /* partial_inplace */
1009 0xffffffff, /* dst_mask */
1010 FALSE), /* pcrel_offset */
1012 /* Get the higher value of a 64 bit addend. */
1013 HOWTO (R_MIPS_HIGHER, /* type */
1015 2, /* size (0 = byte, 1 = short, 2 = long) */
1017 FALSE, /* pc_relative */
1019 complain_overflow_dont, /* complain_on_overflow */
1020 mips_elf_generic_reloc, /* special_function */
1021 "R_MIPS_HIGHER", /* name */
1022 FALSE, /* partial_inplace */
1024 0x0000ffff, /* dst_mask */
1025 FALSE), /* pcrel_offset */
1027 /* Get the highest value of a 64 bit addend. */
1028 HOWTO (R_MIPS_HIGHEST, /* type */
1030 2, /* size (0 = byte, 1 = short, 2 = long) */
1032 FALSE, /* pc_relative */
1034 complain_overflow_dont, /* complain_on_overflow */
1035 mips_elf_generic_reloc, /* special_function */
1036 "R_MIPS_HIGHEST", /* name */
1037 FALSE, /* partial_inplace */
1039 0x0000ffff, /* dst_mask */
1040 FALSE), /* pcrel_offset */
1042 /* High 16 bits of displacement in global offset table. */
1043 HOWTO (R_MIPS_CALL_HI16, /* type */
1045 2, /* size (0 = byte, 1 = short, 2 = long) */
1047 FALSE, /* pc_relative */
1049 complain_overflow_dont, /* complain_on_overflow */
1050 mips_elf_generic_reloc, /* special_function */
1051 "R_MIPS_CALL_HI16", /* name */
1052 FALSE, /* partial_inplace */
1054 0x0000ffff, /* dst_mask */
1055 FALSE), /* pcrel_offset */
1057 /* Low 16 bits of displacement in global offset table. */
1058 HOWTO (R_MIPS_CALL_LO16, /* type */
1060 2, /* size (0 = byte, 1 = short, 2 = long) */
1062 FALSE, /* pc_relative */
1064 complain_overflow_dont, /* complain_on_overflow */
1065 mips_elf_generic_reloc, /* special_function */
1066 "R_MIPS_CALL_LO16", /* name */
1067 FALSE, /* partial_inplace */
1069 0x0000ffff, /* dst_mask */
1070 FALSE), /* pcrel_offset */
1072 /* Section displacement, used by an associated event location section. */
1073 HOWTO (R_MIPS_SCN_DISP, /* type */
1075 2, /* size (0 = byte, 1 = short, 2 = long) */
1077 FALSE, /* pc_relative */
1079 complain_overflow_dont, /* complain_on_overflow */
1080 mips_elf_generic_reloc, /* special_function */
1081 "R_MIPS_SCN_DISP", /* name */
1082 FALSE, /* partial_inplace */
1084 0xffffffff, /* dst_mask */
1085 FALSE), /* pcrel_offset */
1087 /* 16 bit relocation. */
1088 HOWTO (R_MIPS_REL16, /* type */
1090 1, /* size (0 = byte, 1 = short, 2 = long) */
1092 FALSE, /* pc_relative */
1094 complain_overflow_signed, /* complain_on_overflow */
1095 mips_elf_generic_reloc, /* special_function */
1096 "R_MIPS_REL16", /* name */
1097 FALSE, /* partial_inplace */
1099 0xffff, /* dst_mask */
1100 FALSE), /* pcrel_offset */
1102 /* These two are obsolete. */
1103 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1104 EMPTY_HOWTO (R_MIPS_PJUMP),
1106 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1107 It must be used for multigot GOT's (and only there). */
1108 HOWTO (R_MIPS_RELGOT, /* type */
1110 2, /* size (0 = byte, 1 = short, 2 = long) */
1112 FALSE, /* pc_relative */
1114 complain_overflow_dont, /* complain_on_overflow */
1115 mips_elf_generic_reloc, /* special_function */
1116 "R_MIPS_RELGOT", /* name */
1117 FALSE, /* partial_inplace */
1119 0xffffffff, /* dst_mask */
1120 FALSE), /* pcrel_offset */
1122 /* Protected jump conversion. This is an optimization hint. No
1123 relocation is required for correctness. */
1124 HOWTO (R_MIPS_JALR, /* type */
1126 2, /* size (0 = byte, 1 = short, 2 = long) */
1128 FALSE, /* pc_relative */
1130 complain_overflow_dont, /* complain_on_overflow */
1131 mips_elf_generic_reloc, /* special_function */
1132 "R_MIPS_JALR", /* name */
1133 FALSE, /* partial_inplace */
1135 0xffffffff, /* dst_mask */
1136 FALSE), /* pcrel_offset */
1139 /* The reloc used for the mips16 jump instruction. */
1140 static reloc_howto_type elf_mips16_jump_howto =
1141 HOWTO (R_MIPS16_26, /* type */
1143 2, /* size (0 = byte, 1 = short, 2 = long) */
1145 FALSE, /* pc_relative */
1147 complain_overflow_dont, /* complain_on_overflow */
1148 /* This needs complex overflow
1149 detection, because the upper four
1150 bits must match the PC. */
1151 mips16_jump_reloc, /* special_function */
1152 "R_MIPS16_26", /* name */
1153 TRUE, /* partial_inplace */
1154 0x3ffffff, /* src_mask */
1155 0x3ffffff, /* dst_mask */
1156 FALSE); /* pcrel_offset */
1158 /* The reloc used for the mips16 gprel instruction. */
1159 static reloc_howto_type elf_mips16_gprel_howto =
1160 HOWTO (R_MIPS16_GPREL, /* type */
1162 2, /* size (0 = byte, 1 = short, 2 = long) */
1164 FALSE, /* pc_relative */
1166 complain_overflow_signed, /* complain_on_overflow */
1167 mips16_gprel_reloc, /* special_function */
1168 "R_MIPS16_GPREL", /* name */
1169 TRUE, /* partial_inplace */
1170 0x07ff001f, /* src_mask */
1171 0x07ff001f, /* dst_mask */
1172 FALSE); /* pcrel_offset */
1174 /* GNU extension to record C++ vtable hierarchy */
1175 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
1176 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
1178 2, /* size (0 = byte, 1 = short, 2 = long) */
1180 FALSE, /* pc_relative */
1182 complain_overflow_dont, /* complain_on_overflow */
1183 NULL, /* special_function */
1184 "R_MIPS_GNU_VTINHERIT", /* name */
1185 FALSE, /* partial_inplace */
1188 FALSE); /* pcrel_offset */
1190 /* GNU extension to record C++ vtable member usage */
1191 static reloc_howto_type elf_mips_gnu_vtentry_howto =
1192 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
1194 2, /* size (0 = byte, 1 = short, 2 = long) */
1196 FALSE, /* pc_relative */
1198 complain_overflow_dont, /* complain_on_overflow */
1199 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1200 "R_MIPS_GNU_VTENTRY", /* name */
1201 FALSE, /* partial_inplace */
1204 FALSE); /* pcrel_offset */
1206 /* This is derived from bfd_elf_generic_reloc. NewABI allows us to have
1207 several relocations against the same address. The addend is derived
1208 from the addends of preceding relocations. If we don't need to
1209 do something special, we simply keep track of the addend. */
1211 #define GET_RELOC_ADDEND(obfd, sym, entry, sec) \
1213 /* If we're relocating, and this is an external symbol, we don't \
1214 want to change anything. */ \
1215 if ((obfd) != (bfd *) NULL \
1216 && ((sym)->flags & BSF_SECTION_SYM) == 0 \
1217 && (! (entry)->howto->partial_inplace \
1218 || (entry)->addend == 0)) \
1220 (entry)->address += (sec)->output_offset; \
1221 return bfd_reloc_ok; \
1224 /* The addend of combined relocs is remembered and left for \
1225 subsequent relocs. */ \
1226 if (prev_reloc_address != (entry)->address \
1227 || prev_reloc_section != (sec)) \
1229 prev_reloc_section = (sec); \
1230 prev_reloc_address = (entry)->address; \
1231 prev_reloc_addend = (entry)->addend; \
1234 (entry)->addend = prev_reloc_addend; \
1237 #define SET_RELOC_ADDEND(entry) \
1239 prev_reloc_addend = (entry)->addend; \
1242 static bfd_reloc_status_type
1243 mips_elf_generic_reloc (abfd, reloc_entry, symbol, data, input_section,
1244 output_bfd, error_message)
1245 bfd *abfd ATTRIBUTE_UNUSED;
1246 arelent *reloc_entry;
1248 PTR data ATTRIBUTE_UNUSED;
1249 asection *input_section;
1251 char **error_message ATTRIBUTE_UNUSED;
1253 GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
1255 return bfd_reloc_continue;
1258 /* Do a R_MIPS_HI16 relocation. This has to be done in combination
1259 with a R_MIPS_LO16 reloc, because there is a carry from the LO16 to
1260 the HI16. Here we just save the information we need; we do the
1261 actual relocation when we see the LO16.
1263 MIPS ELF requires that the LO16 immediately follow the HI16. As a
1264 GNU extension, for non-pc-relative relocations, we permit an
1265 arbitrary number of HI16 relocs to be associated with a single LO16
1266 reloc. This extension permits gcc to output the HI and LO relocs
1269 This cannot be done for PC-relative relocations because both the HI16
1270 and LO16 parts of the relocations must be done relative to the LO16
1271 part, and there can be carry to or borrow from the HI16 part. */
1275 struct mips_hi16 *next;
1280 /* FIXME: This should not be a static variable. */
1282 static struct mips_hi16 *mips_hi16_list;
1284 static bfd_reloc_status_type
1285 mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data, input_section,
1286 output_bfd, error_message)
1287 bfd *abfd ATTRIBUTE_UNUSED;
1288 arelent *reloc_entry;
1291 asection *input_section;
1293 char **error_message ATTRIBUTE_UNUSED;
1295 bfd_reloc_status_type ret;
1297 struct mips_hi16 *n;
1299 GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
1303 if (bfd_is_und_section (symbol->section) && output_bfd == (bfd *) NULL)
1304 ret = bfd_reloc_undefined;
1306 if (bfd_is_com_section (symbol->section))
1309 relocation = symbol->value;
1311 relocation += symbol->section->output_section->vma;
1312 relocation += symbol->section->output_offset;
1313 relocation += reloc_entry->addend;
1315 if (reloc_entry->address > input_section->_cooked_size)
1316 return bfd_reloc_outofrange;
1318 /* Save the information, and let LO16 do the actual relocation. */
1319 n = (struct mips_hi16 *) bfd_malloc ((bfd_size_type) sizeof *n);
1321 return bfd_reloc_outofrange;
1322 n->addr = (bfd_byte *) data + reloc_entry->address;
1323 n->addend = relocation;
1324 n->next = mips_hi16_list;
1327 if (output_bfd != (bfd *) NULL)
1328 reloc_entry->address += input_section->output_offset;
1333 /* Do a R_MIPS_LO16 relocation. This is a straightforward 16 bit
1334 inplace relocation; this function exists in order to do the
1335 R_MIPS_HI16 relocation described above. */
1337 static bfd_reloc_status_type
1338 mips_elf_lo16_reloc (abfd, reloc_entry, symbol, data, input_section,
1339 output_bfd, error_message)
1341 arelent *reloc_entry;
1344 asection *input_section;
1346 char **error_message;
1348 if (mips_hi16_list != NULL)
1350 struct mips_hi16 *l;
1357 unsigned long vallo;
1358 struct mips_hi16 *next;
1360 /* Do the HI16 relocation. Note that we actually don't need
1361 to know anything about the LO16 itself, except where to
1362 find the low 16 bits of the addend needed by the LO16. */
1363 insn = bfd_get_32 (abfd, l->addr);
1364 vallo = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1366 /* The low order 16 bits are always treated as a signed
1368 vallo = ((vallo & 0xffff) ^ 0x8000) - 0x8000;
1369 val = ((insn & 0xffff) << 16) + vallo;
1372 /* If PC-relative, we need to subtract out the address of the LO
1373 half of the HI/LO. (The actual relocation is relative
1374 to that instruction.) */
1375 if (reloc_entry->howto->pc_relative)
1376 val -= reloc_entry->address;
1378 /* At this point, "val" has the value of the combined HI/LO
1379 pair. If the low order 16 bits (which will be used for
1380 the LO16 insn) are negative, then we will need an
1381 adjustment for the high order 16 bits. */
1383 val = (val >> 16) & 0xffff;
1385 insn &= ~ (bfd_vma) 0xffff;
1387 bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
1394 mips_hi16_list = NULL;
1397 /* Now do the LO16 reloc in the usual way. */
1398 return mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
1399 input_section, output_bfd, error_message);
1402 /* Do a R_MIPS_GOT16 reloc. This is a reloc against the global offset
1403 table used for PIC code. If the symbol is an external symbol, the
1404 instruction is modified to contain the offset of the appropriate
1405 entry in the global offset table. If the symbol is a section
1406 symbol, the next reloc is a R_MIPS_LO16 reloc. The two 16 bit
1407 addends are combined to form the real addend against the section
1408 symbol; the GOT16 is modified to contain the offset of an entry in
1409 the global offset table, and the LO16 is modified to offset it
1410 appropriately. Thus an offset larger than 16 bits requires a
1411 modified value in the global offset table.
1413 This implementation suffices for the assembler, but the linker does
1414 not yet know how to create global offset tables. */
1416 static bfd_reloc_status_type
1417 mips_elf_got16_reloc (abfd, reloc_entry, symbol, data, input_section,
1418 output_bfd, error_message)
1420 arelent *reloc_entry;
1423 asection *input_section;
1425 char **error_message;
1427 /* If we're relocating, and this is a local symbol, we can handle it
1429 if (output_bfd != (bfd *) NULL
1430 && (symbol->flags & BSF_SECTION_SYM) != 0)
1431 return mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
1432 input_section, output_bfd, error_message);
1434 /* Otherwise we try to handle it as R_MIPS_GOT_DISP. */
1435 return mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
1436 input_section, output_bfd, error_message);
1439 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
1440 dangerous relocation. */
1443 mips_elf_assign_gp (output_bfd, pgp)
1451 /* If we've already figured out what GP will be, just return it. */
1452 *pgp = _bfd_get_gp_value (output_bfd);
1456 count = bfd_get_symcount (output_bfd);
1457 sym = bfd_get_outsymbols (output_bfd);
1459 /* The linker script will have created a symbol named `_gp' with the
1460 appropriate value. */
1461 if (sym == (asymbol **) NULL)
1465 for (i = 0; i < count; i++, sym++)
1467 register const char *name;
1469 name = bfd_asymbol_name (*sym);
1470 if (*name == '_' && strcmp (name, "_gp") == 0)
1472 *pgp = bfd_asymbol_value (*sym);
1473 _bfd_set_gp_value (output_bfd, *pgp);
1481 /* Only get the error once. */
1483 _bfd_set_gp_value (output_bfd, *pgp);
1490 /* We have to figure out the gp value, so that we can adjust the
1491 symbol value correctly. We look up the symbol _gp in the output
1492 BFD. If we can't find it, we're stuck. We cache it in the ELF
1493 target data. We don't need to adjust the symbol value for an
1494 external symbol if we are producing relocateable output. */
1496 static bfd_reloc_status_type
1497 mips_elf_final_gp (output_bfd, symbol, relocateable, error_message, pgp)
1500 bfd_boolean relocateable;
1501 char **error_message;
1504 if (bfd_is_und_section (symbol->section)
1508 return bfd_reloc_undefined;
1511 *pgp = _bfd_get_gp_value (output_bfd);
1514 || (symbol->flags & BSF_SECTION_SYM) != 0))
1518 /* Make up a value. */
1519 *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
1520 _bfd_set_gp_value (output_bfd, *pgp);
1522 else if (!mips_elf_assign_gp (output_bfd, pgp))
1525 (char *) _("GP relative relocation when _gp not defined");
1526 return bfd_reloc_dangerous;
1530 return bfd_reloc_ok;
1533 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1534 become the offset from the gp register. */
1536 static bfd_reloc_status_type
1537 mips_elf_gprel16_reloc (abfd, reloc_entry, symbol, data, input_section,
1538 output_bfd, error_message)
1539 bfd *abfd ATTRIBUTE_UNUSED;
1540 arelent *reloc_entry;
1542 PTR data ATTRIBUTE_UNUSED;
1543 asection *input_section;
1545 char **error_message ATTRIBUTE_UNUSED;
1547 bfd_boolean relocateable;
1548 bfd_reloc_status_type ret;
1551 GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
1553 if (output_bfd != (bfd *) NULL)
1554 relocateable = TRUE;
1557 relocateable = FALSE;
1558 output_bfd = symbol->section->output_section->owner;
1561 ret = mips_elf_final_gp (output_bfd, symbol, relocateable, error_message,
1563 if (ret != bfd_reloc_ok)
1566 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1567 input_section, relocateable,
1571 /* Do a R_MIPS_LITERAL relocation. */
1573 static bfd_reloc_status_type
1574 mips_elf_literal_reloc (abfd, reloc_entry, symbol, data, input_section,
1575 output_bfd, error_message)
1577 arelent *reloc_entry;
1580 asection *input_section;
1582 char **error_message;
1584 bfd_boolean relocateable;
1585 bfd_reloc_status_type ret;
1588 GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
1590 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
1591 if (output_bfd != (bfd *) NULL)
1592 relocateable = TRUE;
1595 relocateable = FALSE;
1596 output_bfd = symbol->section->output_section->owner;
1599 ret = mips_elf_final_gp (output_bfd, symbol, relocateable, error_message,
1601 if (ret != bfd_reloc_ok)
1604 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1605 input_section, relocateable,
1609 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
1610 become the offset from the gp register. */
1612 static bfd_reloc_status_type
1613 mips_elf_gprel32_reloc (abfd, reloc_entry, symbol, data, input_section,
1614 output_bfd, error_message)
1616 arelent *reloc_entry;
1619 asection *input_section;
1621 char **error_message;
1623 bfd_boolean relocateable;
1624 bfd_reloc_status_type ret;
1627 GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
1629 /* R_MIPS_GPREL32 relocations are defined for local symbols only.
1630 We will only have an addend if this is a newly created reloc,
1631 not read from an ELF file. */
1632 if (output_bfd != (bfd *) NULL
1633 && (symbol->flags & BSF_SECTION_SYM) == 0
1634 && reloc_entry->addend == 0)
1636 *error_message = (char *)
1637 _("32bits gp relative relocation occurs for an external symbol");
1638 return bfd_reloc_outofrange;
1641 if (output_bfd != (bfd *) NULL)
1643 relocateable = TRUE;
1644 gp = _bfd_get_gp_value (output_bfd);
1648 relocateable = FALSE;
1649 output_bfd = symbol->section->output_section->owner;
1651 ret = mips_elf_final_gp (output_bfd, symbol, relocateable,
1652 error_message, &gp);
1653 if (ret != bfd_reloc_ok)
1657 return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
1658 relocateable, data, gp);
1661 static bfd_reloc_status_type
1662 gprel32_with_gp (abfd, symbol, reloc_entry, input_section, relocateable, data,
1666 arelent *reloc_entry;
1667 asection *input_section;
1668 bfd_boolean relocateable;
1675 if (bfd_is_com_section (symbol->section))
1678 relocation = symbol->value;
1680 relocation += symbol->section->output_section->vma;
1681 relocation += symbol->section->output_offset;
1683 if (reloc_entry->address > input_section->_cooked_size)
1684 return bfd_reloc_outofrange;
1686 if (reloc_entry->howto->src_mask == 0)
1689 val = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1691 /* Set val to the offset into the section or symbol. */
1692 val += reloc_entry->addend;
1694 /* Adjust val for the final section location and GP value. If we
1695 are producing relocateable output, we don't want to do this for
1696 an external symbol. */
1698 || (symbol->flags & BSF_SECTION_SYM) != 0)
1699 val += relocation - gp;
1701 bfd_put_32 (abfd, (bfd_vma) val, (bfd_byte *) data + reloc_entry->address);
1704 reloc_entry->address += input_section->output_offset;
1706 return bfd_reloc_ok;
1709 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
1710 the rest is at bits 6-10. The bitpos already got right by the howto. */
1712 static bfd_reloc_status_type
1713 mips_elf_shift6_reloc (abfd, reloc_entry, symbol, data, input_section,
1714 output_bfd, error_message)
1715 bfd *abfd ATTRIBUTE_UNUSED;
1716 arelent *reloc_entry;
1718 PTR data ATTRIBUTE_UNUSED;
1719 asection *input_section;
1721 char **error_message ATTRIBUTE_UNUSED;
1723 GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
1725 reloc_entry->addend = (reloc_entry->addend & 0x00007c0)
1726 | (reloc_entry->addend & 0x00000800) >> 9;
1728 SET_RELOC_ADDEND (reloc_entry)
1730 return bfd_reloc_continue;
1733 /* Handle a mips16 jump. */
1735 static bfd_reloc_status_type
1736 mips16_jump_reloc (abfd, reloc_entry, symbol, data, input_section,
1737 output_bfd, error_message)
1738 bfd *abfd ATTRIBUTE_UNUSED;
1739 arelent *reloc_entry;
1741 PTR data ATTRIBUTE_UNUSED;
1742 asection *input_section;
1744 char **error_message ATTRIBUTE_UNUSED;
1746 static bfd_boolean warned = FALSE;
1748 GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
1752 (*_bfd_error_handler)
1753 (_("Linking mips16 objects into %s format is not supported"),
1754 bfd_get_target (input_section->output_section->owner));
1757 return bfd_reloc_undefined;
1760 /* Handle a mips16 GP relative reloc. */
1762 static bfd_reloc_status_type
1763 mips16_gprel_reloc (abfd, reloc_entry, symbol, data, input_section,
1764 output_bfd, error_message)
1766 arelent *reloc_entry;
1769 asection *input_section;
1771 char **error_message;
1773 bfd_boolean relocateable;
1774 bfd_reloc_status_type ret;
1776 unsigned short extend, insn;
1777 unsigned long final;
1779 GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
1781 if (output_bfd != NULL)
1782 relocateable = TRUE;
1785 relocateable = FALSE;
1786 output_bfd = symbol->section->output_section->owner;
1789 ret = mips_elf_final_gp (output_bfd, symbol, relocateable, error_message,
1791 if (ret != bfd_reloc_ok)
1794 if (reloc_entry->address > input_section->_cooked_size)
1795 return bfd_reloc_outofrange;
1797 /* Pick up the mips16 extend instruction and the real instruction. */
1798 extend = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address);
1799 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address + 2);
1801 /* Stuff the current addend back as a 32 bit value, do the usual
1802 relocation, and then clean up. */
1804 (bfd_vma) (((extend & 0x1f) << 11)
1807 (bfd_byte *) data + reloc_entry->address);
1809 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1810 input_section, relocateable, data, gp);
1812 final = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1814 (bfd_vma) ((extend & 0xf800)
1815 | ((final >> 11) & 0x1f)
1817 (bfd_byte *) data + reloc_entry->address);
1819 (bfd_vma) ((insn & 0xffe0)
1821 (bfd_byte *) data + reloc_entry->address + 2);
1826 #undef GET_RELOC_ADDEND
1827 #undef SET_RELOC_ADDEND
1829 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
1831 struct elf_reloc_map {
1832 bfd_reloc_code_real_type bfd_val;
1833 enum elf_mips_reloc_type elf_val;
1836 static const struct elf_reloc_map mips_reloc_map[] =
1838 { BFD_RELOC_NONE, R_MIPS_NONE },
1839 { BFD_RELOC_16, R_MIPS_16 },
1840 { BFD_RELOC_32, R_MIPS_32 },
1841 /* There is no BFD reloc for R_MIPS_REL32. */
1842 { BFD_RELOC_CTOR, R_MIPS_32 },
1843 { BFD_RELOC_64, R_MIPS_64 },
1844 { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
1845 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1846 { BFD_RELOC_LO16, R_MIPS_LO16 },
1847 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
1848 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
1849 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1850 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1851 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
1852 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
1853 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
1854 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
1855 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
1856 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1857 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
1858 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1859 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1860 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1861 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
1862 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
1863 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
1864 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
1865 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
1866 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
1867 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1868 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
1869 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
1870 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
1871 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
1872 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR }
1875 /* Given a BFD reloc type, return a howto structure. */
1877 static reloc_howto_type *
1878 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
1879 bfd *abfd ATTRIBUTE_UNUSED;
1880 bfd_reloc_code_real_type code;
1883 /* FIXME: We default to RELA here instead of choosing the right
1884 relocation variant. */
1885 reloc_howto_type *howto_table = elf_mips_howto_table_rela;
1887 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
1890 if (mips_reloc_map[i].bfd_val == code)
1891 return &howto_table[(int) mips_reloc_map[i].elf_val];
1896 case BFD_RELOC_MIPS16_JMP:
1897 return &elf_mips16_jump_howto;
1898 case BFD_RELOC_MIPS16_GPREL:
1899 return &elf_mips16_gprel_howto;
1900 case BFD_RELOC_VTABLE_INHERIT:
1901 return &elf_mips_gnu_vtinherit_howto;
1902 case BFD_RELOC_VTABLE_ENTRY:
1903 return &elf_mips_gnu_vtentry_howto;
1905 bfd_set_error (bfd_error_bad_value);
1910 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
1912 static reloc_howto_type *
1913 mips_elf_n32_rtype_to_howto (r_type, rela_p)
1914 unsigned int r_type;
1920 return &elf_mips16_jump_howto;
1921 case R_MIPS16_GPREL:
1922 return &elf_mips16_gprel_howto;
1923 case R_MIPS_GNU_VTINHERIT:
1924 return &elf_mips_gnu_vtinherit_howto;
1925 case R_MIPS_GNU_VTENTRY:
1926 return &elf_mips_gnu_vtentry_howto;
1928 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
1930 return &elf_mips_howto_table_rela[r_type];
1932 return &elf_mips_howto_table_rel[r_type];
1937 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
1940 mips_info_to_howto_rel (abfd, cache_ptr, dst)
1943 Elf_Internal_Rela *dst;
1945 unsigned int r_type;
1947 r_type = ELF32_R_TYPE (dst->r_info);
1948 cache_ptr->howto = mips_elf_n32_rtype_to_howto (r_type, FALSE);
1950 /* The addend for a GPREL16 or LITERAL relocation comes from the GP
1951 value for the object file. We get the addend now, rather than
1952 when we do the relocation, because the symbol manipulations done
1953 by the linker may cause us to lose track of the input BFD. */
1954 if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
1955 && (r_type == (unsigned int) R_MIPS_GPREL16
1956 || r_type == (unsigned int) R_MIPS_LITERAL))
1957 cache_ptr->addend = elf_gp (abfd);
1960 /* Given a MIPS Elf_Internal_Rela, fill in an arelent structure. */
1963 mips_info_to_howto_rela (abfd, cache_ptr, dst)
1964 bfd *abfd ATTRIBUTE_UNUSED;
1966 Elf_Internal_Rela *dst;
1968 unsigned int r_type;
1970 r_type = ELF32_R_TYPE (dst->r_info);
1971 cache_ptr->howto = mips_elf_n32_rtype_to_howto (r_type, TRUE);
1972 cache_ptr->addend = dst->r_addend;
1975 /* Determine whether a symbol is global for the purposes of splitting
1976 the symbol table into global symbols and local symbols. At least
1977 on Irix 5, this split must be between section symbols and all other
1978 symbols. On most ELF targets the split is between static symbols
1979 and externally visible symbols. */
1982 mips_elf_sym_is_global (abfd, sym)
1983 bfd *abfd ATTRIBUTE_UNUSED;
1986 if (SGI_COMPAT (abfd))
1987 return (sym->flags & BSF_SECTION_SYM) == 0;
1989 return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
1990 || bfd_is_und_section (bfd_get_section (sym))
1991 || bfd_is_com_section (bfd_get_section (sym)));
1994 /* Set the right machine number for a MIPS ELF file. */
1997 mips_elf_n32_object_p (abfd)
2002 /* Irix 5 and 6 are broken. Object file symbol tables are not always
2003 sorted correctly such that local symbols precede global symbols,
2004 and the sh_info field in the symbol table is not always right. */
2005 if (SGI_COMPAT (abfd))
2006 elf_bad_symtab (abfd) = TRUE;
2008 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
2009 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
2011 if (! ABI_N32_P(abfd))
2017 /* Support for core dump NOTE sections. */
2019 elf32_mips_grok_prstatus (abfd, note)
2021 Elf_Internal_Note *note;
2024 unsigned int raw_size;
2026 switch (note->descsz)
2031 case 256: /* Linux/MIPS */
2033 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
2036 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
2045 /* Make a ".reg/999" section. */
2046 return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size,
2047 note->descpos + offset);
2051 elf32_mips_grok_psinfo (abfd, note)
2053 Elf_Internal_Note *note;
2055 switch (note->descsz)
2060 case 128: /* Linux/MIPS elf_prpsinfo */
2061 elf_tdata (abfd)->core_program
2062 = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
2063 elf_tdata (abfd)->core_command
2064 = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
2067 /* Note that for some reason, a spurious space is tacked
2068 onto the end of the args in some (at least one anyway)
2069 implementations, so strip it off if it exists. */
2072 char *command = elf_tdata (abfd)->core_command;
2073 int n = strlen (command);
2075 if (0 < n && command[n - 1] == ' ')
2076 command[n - 1] = '\0';
2082 /* Depending on the target vector we generate some version of Irix
2083 executables or "normal" MIPS ELF ABI executables. */
2084 static irix_compat_t
2085 elf_n32_mips_irix_compat (abfd)
2088 if ((abfd->xvec == &bfd_elf32_nbigmips_vec)
2089 || (abfd->xvec == &bfd_elf32_nlittlemips_vec))
2095 /* ECOFF swapping routines. These are used when dealing with the
2096 .mdebug section, which is in the ECOFF debugging format. */
2097 static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
2098 /* Symbol table magic number. */
2100 /* Alignment of debugging information. E.g., 4. */
2102 /* Sizes of external symbolic information. */
2103 sizeof (struct hdr_ext),
2104 sizeof (struct dnr_ext),
2105 sizeof (struct pdr_ext),
2106 sizeof (struct sym_ext),
2107 sizeof (struct opt_ext),
2108 sizeof (struct fdr_ext),
2109 sizeof (struct rfd_ext),
2110 sizeof (struct ext_ext),
2111 /* Functions to swap in external symbolic data. */
2120 _bfd_ecoff_swap_tir_in,
2121 _bfd_ecoff_swap_rndx_in,
2122 /* Functions to swap out external symbolic data. */
2131 _bfd_ecoff_swap_tir_out,
2132 _bfd_ecoff_swap_rndx_out,
2133 /* Function to read in symbolic data. */
2134 _bfd_mips_elf_read_ecoff_info
2137 #define ELF_ARCH bfd_arch_mips
2138 #define ELF_MACHINE_CODE EM_MIPS
2140 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
2141 a value of 0x1000, and we are compatible.
2142 FIXME: How does this affect NewABI? */
2143 #define ELF_MAXPAGESIZE 0x1000
2145 #define elf_backend_collect TRUE
2146 #define elf_backend_type_change_ok TRUE
2147 #define elf_backend_can_gc_sections TRUE
2148 #define elf_info_to_howto mips_info_to_howto_rela
2149 #define elf_info_to_howto_rel mips_info_to_howto_rel
2150 #define elf_backend_sym_is_global mips_elf_sym_is_global
2151 #define elf_backend_object_p mips_elf_n32_object_p
2152 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
2153 #define elf_backend_section_processing _bfd_mips_elf_section_processing
2154 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
2155 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
2156 #define elf_backend_section_from_bfd_section \
2157 _bfd_mips_elf_section_from_bfd_section
2158 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
2159 #define elf_backend_link_output_symbol_hook \
2160 _bfd_mips_elf_link_output_symbol_hook
2161 #define elf_backend_create_dynamic_sections \
2162 _bfd_mips_elf_create_dynamic_sections
2163 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
2164 #define elf_backend_adjust_dynamic_symbol \
2165 _bfd_mips_elf_adjust_dynamic_symbol
2166 #define elf_backend_always_size_sections \
2167 _bfd_mips_elf_always_size_sections
2168 #define elf_backend_size_dynamic_sections \
2169 _bfd_mips_elf_size_dynamic_sections
2170 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
2171 #define elf_backend_finish_dynamic_symbol \
2172 _bfd_mips_elf_finish_dynamic_symbol
2173 #define elf_backend_finish_dynamic_sections \
2174 _bfd_mips_elf_finish_dynamic_sections
2175 #define elf_backend_final_write_processing \
2176 _bfd_mips_elf_final_write_processing
2177 #define elf_backend_additional_program_headers \
2178 _bfd_mips_elf_additional_program_headers
2179 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
2180 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
2181 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
2182 #define elf_backend_copy_indirect_symbol \
2183 _bfd_mips_elf_copy_indirect_symbol
2184 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
2185 #define elf_backend_grok_prstatus elf32_mips_grok_prstatus
2186 #define elf_backend_grok_psinfo elf32_mips_grok_psinfo
2187 #define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap
2189 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
2190 #define elf_backend_plt_header_size 0
2192 /* MIPS n32 ELF can use a mixture of REL and RELA, but some Relocations
2193 work better/work only in RELA, so we default to this. */
2194 #define elf_backend_may_use_rel_p 1
2195 #define elf_backend_may_use_rela_p 1
2196 #define elf_backend_default_use_rela_p 1
2197 #define elf_backend_sign_extend_vma TRUE
2199 #define elf_backend_discard_info _bfd_mips_elf_discard_info
2200 #define elf_backend_ignore_discarded_relocs \
2201 _bfd_mips_elf_ignore_discarded_relocs
2202 #define elf_backend_write_section _bfd_mips_elf_write_section
2203 #define elf_backend_mips_irix_compat elf_n32_mips_irix_compat
2204 #define elf_backend_mips_rtype_to_howto mips_elf_n32_rtype_to_howto
2205 #define bfd_elf32_find_nearest_line _bfd_mips_elf_find_nearest_line
2206 #define bfd_elf32_new_section_hook _bfd_mips_elf_new_section_hook
2207 #define bfd_elf32_set_section_contents _bfd_mips_elf_set_section_contents
2208 #define bfd_elf32_bfd_get_relocated_section_contents \
2209 _bfd_elf_mips_get_relocated_section_contents
2210 #define bfd_elf32_bfd_link_hash_table_create \
2211 _bfd_mips_elf_link_hash_table_create
2212 #define bfd_elf32_bfd_final_link _bfd_mips_elf_final_link
2213 #define bfd_elf32_bfd_merge_private_bfd_data \
2214 _bfd_mips_elf_merge_private_bfd_data
2215 #define bfd_elf32_bfd_set_private_flags _bfd_mips_elf_set_private_flags
2216 #define bfd_elf32_bfd_print_private_bfd_data \
2217 _bfd_mips_elf_print_private_bfd_data
2219 /* Support for SGI-ish mips targets using n32 ABI. */
2221 #define TARGET_LITTLE_SYM bfd_elf32_nlittlemips_vec
2222 #define TARGET_LITTLE_NAME "elf32-nlittlemips"
2223 #define TARGET_BIG_SYM bfd_elf32_nbigmips_vec
2224 #define TARGET_BIG_NAME "elf32-nbigmips"
2226 #include "elf32-target.h"
2228 /* Support for traditional mips targets using n32 ABI. */
2229 #define INCLUDED_TARGET_FILE /* More a type of flag. */
2231 #undef TARGET_LITTLE_SYM
2232 #undef TARGET_LITTLE_NAME
2233 #undef TARGET_BIG_SYM
2234 #undef TARGET_BIG_NAME
2236 #define TARGET_LITTLE_SYM bfd_elf32_ntradlittlemips_vec
2237 #define TARGET_LITTLE_NAME "elf32-ntradlittlemips"
2238 #define TARGET_BIG_SYM bfd_elf32_ntradbigmips_vec
2239 #define TARGET_BIG_NAME "elf32-ntradbigmips"
2241 /* Include the target file again for this target. */
2242 #include "elf32-target.h"