1 /* BFD back-end for MIPS Extended-Coff files.
2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3 Original version by Per Bothner.
6 This file is part of BFD, the Binary File Descriptor library.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
26 #include "coff/internal.h"
28 #include "coff/symconst.h"
29 #include "coff/ecoff.h"
30 #include "coff/mips.h"
34 /* Prototypes for static functions. */
36 static boolean mips_ecoff_bad_format_hook PARAMS ((bfd *abfd, PTR filehdr));
37 static void mips_ecoff_swap_reloc_in PARAMS ((bfd *, PTR,
38 struct internal_reloc *));
39 static void mips_ecoff_swap_reloc_out PARAMS ((bfd *,
40 const struct internal_reloc *,
42 static void mips_adjust_reloc_in PARAMS ((bfd *,
43 const struct internal_reloc *,
45 static void mips_adjust_reloc_out PARAMS ((bfd *, const arelent *,
46 struct internal_reloc *));
47 static bfd_reloc_status_type mips_generic_reloc PARAMS ((bfd *abfd,
54 static bfd_reloc_status_type mips_refhi_reloc PARAMS ((bfd *abfd,
61 static bfd_reloc_status_type mips_reflo_reloc PARAMS ((bfd *abfd,
68 static bfd_reloc_status_type mips_gprel_reloc PARAMS ((bfd *abfd,
75 static void mips_relocate_refhi PARAMS ((struct internal_reloc *refhi,
76 struct internal_reloc *reflo,
78 asection *input_section,
81 static boolean mips_relocate_section PARAMS ((bfd *, struct bfd_link_info *,
85 /* ECOFF has COFF sections, but the debugging information is stored in
86 a completely different format. ECOFF targets use some of the
87 swapping routines from coffswap.h, and some of the generic COFF
88 routines in coffgen.c, but, unlike the real COFF targets, do not
89 use coffcode.h itself.
91 Get the generic COFF swapping routines, except for the reloc,
92 symbol, and lineno ones. Give them ECOFF names. */
94 #define NO_COFF_RELOCS
95 #define NO_COFF_SYMBOLS
96 #define NO_COFF_LINENOS
97 #define coff_swap_filehdr_in mips_ecoff_swap_filehdr_in
98 #define coff_swap_filehdr_out mips_ecoff_swap_filehdr_out
99 #define coff_swap_aouthdr_in mips_ecoff_swap_aouthdr_in
100 #define coff_swap_aouthdr_out mips_ecoff_swap_aouthdr_out
101 #define coff_swap_scnhdr_in mips_ecoff_swap_scnhdr_in
102 #define coff_swap_scnhdr_out mips_ecoff_swap_scnhdr_out
103 #include "coffswap.h"
105 /* Get the ECOFF swapping routines. */
107 #include "ecoffswap.h"
109 /* How to process the various relocs types. */
111 static reloc_howto_type mips_howto_table[] =
113 /* Reloc type 0 is ignored. The reloc reading code ensures that
114 this is a reference to the .abs section, which will cause
115 bfd_perform_relocation to do nothing. */
116 HOWTO (MIPS_R_IGNORE, /* type */
118 0, /* size (0 = byte, 1 = short, 2 = long) */
120 false, /* pc_relative */
122 complain_overflow_dont, /* complain_on_overflow */
123 0, /* special_function */
125 false, /* partial_inplace */
128 false), /* pcrel_offset */
130 /* A 16 bit reference to a symbol, normally from a data section. */
131 HOWTO (MIPS_R_REFHALF, /* type */
133 1, /* size (0 = byte, 1 = short, 2 = long) */
135 false, /* pc_relative */
137 complain_overflow_bitfield, /* complain_on_overflow */
138 mips_generic_reloc, /* special_function */
139 "REFHALF", /* name */
140 true, /* partial_inplace */
141 0xffff, /* src_mask */
142 0xffff, /* dst_mask */
143 false), /* pcrel_offset */
145 /* A 32 bit reference to a symbol, normally from a data section. */
146 HOWTO (MIPS_R_REFWORD, /* type */
148 2, /* size (0 = byte, 1 = short, 2 = long) */
150 false, /* pc_relative */
152 complain_overflow_bitfield, /* complain_on_overflow */
153 mips_generic_reloc, /* special_function */
154 "REFWORD", /* name */
155 true, /* partial_inplace */
156 0xffffffff, /* src_mask */
157 0xffffffff, /* dst_mask */
158 false), /* pcrel_offset */
160 /* A 26 bit absolute jump address. */
161 HOWTO (MIPS_R_JMPADDR, /* type */
163 2, /* size (0 = byte, 1 = short, 2 = long) */
165 false, /* pc_relative */
167 complain_overflow_dont, /* complain_on_overflow */
168 /* This needs complex overflow
169 detection, because the upper four
170 bits must match the PC. */
171 mips_generic_reloc, /* special_function */
172 "JMPADDR", /* name */
173 true, /* partial_inplace */
174 0x3ffffff, /* src_mask */
175 0x3ffffff, /* dst_mask */
176 false), /* pcrel_offset */
178 /* The high 16 bits of a symbol value. Handled by the function
180 HOWTO (MIPS_R_REFHI, /* type */
182 2, /* size (0 = byte, 1 = short, 2 = long) */
184 false, /* pc_relative */
186 complain_overflow_bitfield, /* complain_on_overflow */
187 mips_refhi_reloc, /* special_function */
189 true, /* partial_inplace */
190 0xffff, /* src_mask */
191 0xffff, /* dst_mask */
192 false), /* pcrel_offset */
194 /* The low 16 bits of a symbol value. */
195 HOWTO (MIPS_R_REFLO, /* type */
197 2, /* size (0 = byte, 1 = short, 2 = long) */
199 false, /* pc_relative */
201 complain_overflow_dont, /* complain_on_overflow */
202 mips_reflo_reloc, /* special_function */
204 true, /* partial_inplace */
205 0xffff, /* src_mask */
206 0xffff, /* dst_mask */
207 false), /* pcrel_offset */
209 /* A reference to an offset from the gp register. Handled by the
210 function mips_gprel_reloc. */
211 HOWTO (MIPS_R_GPREL, /* type */
213 2, /* size (0 = byte, 1 = short, 2 = long) */
215 false, /* pc_relative */
217 complain_overflow_signed, /* complain_on_overflow */
218 mips_gprel_reloc, /* special_function */
220 true, /* partial_inplace */
221 0xffff, /* src_mask */
222 0xffff, /* dst_mask */
223 false), /* pcrel_offset */
225 /* A reference to a literal using an offset from the gp register.
226 Handled by the function mips_gprel_reloc. */
227 HOWTO (MIPS_R_LITERAL, /* type */
229 2, /* size (0 = byte, 1 = short, 2 = long) */
231 false, /* pc_relative */
233 complain_overflow_signed, /* complain_on_overflow */
234 mips_gprel_reloc, /* special_function */
235 "LITERAL", /* name */
236 true, /* partial_inplace */
237 0xffff, /* src_mask */
238 0xffff, /* dst_mask */
239 false) /* pcrel_offset */
242 #define MIPS_HOWTO_COUNT \
243 (sizeof mips_howto_table / sizeof mips_howto_table[0])
245 /* See whether the magic number matches. */
248 mips_ecoff_bad_format_hook (abfd, filehdr)
252 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
254 switch (internal_f->f_magic)
257 /* I don't know what endianness this implies. */
261 case MIPS_MAGIC_BIG2:
262 case MIPS_MAGIC_BIG3:
263 return abfd->xvec->byteorder_big_p;
265 case MIPS_MAGIC_LITTLE:
266 case MIPS_MAGIC_LITTLE2:
267 case MIPS_MAGIC_LITTLE3:
268 return abfd->xvec->byteorder_big_p == false;
275 /* Reloc handling. MIPS ECOFF relocs are packed into 8 bytes in
276 external form. They use a bit which indicates whether the symbol
279 /* Swap a reloc in. */
282 mips_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
285 struct internal_reloc *intern;
287 const RELOC *ext = (RELOC *) ext_ptr;
289 intern->r_vaddr = bfd_h_get_32 (abfd, (bfd_byte *) ext->r_vaddr);
290 if (abfd->xvec->header_byteorder_big_p != false)
292 intern->r_symndx = (((int) ext->r_bits[0]
293 << RELOC_BITS0_SYMNDX_SH_LEFT_BIG)
294 | ((int) ext->r_bits[1]
295 << RELOC_BITS1_SYMNDX_SH_LEFT_BIG)
296 | ((int) ext->r_bits[2]
297 << RELOC_BITS2_SYMNDX_SH_LEFT_BIG));
298 intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_BIG)
299 >> RELOC_BITS3_TYPE_SH_BIG);
300 intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_BIG) != 0;
304 intern->r_symndx = (((int) ext->r_bits[0]
305 << RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE)
306 | ((int) ext->r_bits[1]
307 << RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE)
308 | ((int) ext->r_bits[2]
309 << RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE));
310 intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
311 >> RELOC_BITS3_TYPE_SH_LITTLE);
312 intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0;
316 /* Swap a reloc out. */
319 mips_ecoff_swap_reloc_out (abfd, intern, dst)
321 const struct internal_reloc *intern;
324 RELOC *ext = (RELOC *) dst;
326 BFD_ASSERT (intern->r_extern
327 || (intern->r_symndx >= 0 && intern->r_symndx <= 12));
329 bfd_h_put_32 (abfd, intern->r_vaddr, (bfd_byte *) ext->r_vaddr);
330 if (abfd->xvec->header_byteorder_big_p != false)
332 ext->r_bits[0] = intern->r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_BIG;
333 ext->r_bits[1] = intern->r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_BIG;
334 ext->r_bits[2] = intern->r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_BIG;
335 ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_BIG)
336 & RELOC_BITS3_TYPE_BIG)
337 | (intern->r_extern ? RELOC_BITS3_EXTERN_BIG : 0));
341 ext->r_bits[0] = intern->r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE;
342 ext->r_bits[1] = intern->r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE;
343 ext->r_bits[2] = intern->r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE;
344 ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_LITTLE)
345 & RELOC_BITS3_TYPE_LITTLE)
346 | (intern->r_extern ? RELOC_BITS3_EXTERN_LITTLE : 0));
350 /* Finish canonicalizing a reloc. Part of this is generic to all
351 ECOFF targets, and that part is in ecoff.c. The rest is done in
352 this backend routine. It must fill in the howto field. */
355 mips_adjust_reloc_in (abfd, intern, rptr)
357 const struct internal_reloc *intern;
360 if (intern->r_type > MIPS_R_LITERAL)
363 if (! intern->r_extern
364 && (intern->r_type == MIPS_R_GPREL
365 || intern->r_type == MIPS_R_LITERAL))
366 rptr->addend += ecoff_data (abfd)->gp;
368 /* If the type is MIPS_R_IGNORE, make sure this is a reference to
369 the absolute section so that the reloc is ignored. */
370 if (intern->r_type == MIPS_R_IGNORE)
371 rptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
373 rptr->howto = &mips_howto_table[intern->r_type];
376 /* Make any adjustments needed to a reloc before writing it out. None
377 are needed for MIPS. */
380 mips_adjust_reloc_out (abfd, rel, intern)
383 struct internal_reloc *intern;
387 /* ECOFF relocs are either against external symbols, or against
388 sections. If we are producing relocateable output, and the reloc
389 is against an external symbol, and nothing has given us any
390 additional addend, the resulting reloc will also be against the
391 same symbol. In such a case, we don't want to change anything
392 about the way the reloc is handled, since it will all be done at
393 final link time. Rather than put special case code into
394 bfd_perform_relocation, all the reloc types use this howto
395 function. It just short circuits the reloc if producing
396 relocateable output against an external symbol. */
398 static bfd_reloc_status_type
399 mips_generic_reloc (abfd,
407 arelent *reloc_entry;
410 asection *input_section;
412 char **error_message;
414 if (output_bfd != (bfd *) NULL
415 && (symbol->flags & BSF_SECTION_SYM) == 0
416 && reloc_entry->addend == 0)
418 reloc_entry->address += input_section->output_offset;
422 return bfd_reloc_continue;
425 /* Do a REFHI relocation. This has to be done in combination with a
426 REFLO reloc, because there is a carry from the REFLO to the REFHI.
427 Here we just save the information we need; we do the actual
428 relocation when we see the REFLO. MIPS ECOFF requires that the
429 REFLO immediately follow the REFHI, so this ought to work. */
431 static bfd_byte *mips_refhi_addr;
432 static bfd_vma mips_refhi_addend;
434 static bfd_reloc_status_type
435 mips_refhi_reloc (abfd,
443 arelent *reloc_entry;
446 asection *input_section;
448 char **error_message;
450 bfd_reloc_status_type ret;
453 /* If we're relocating, and this an external symbol, we don't want
454 to change anything. */
455 if (output_bfd != (bfd *) NULL
456 && (symbol->flags & BSF_SECTION_SYM) == 0
457 && reloc_entry->addend == 0)
459 reloc_entry->address += input_section->output_offset;
464 if (symbol->section == &bfd_und_section
465 && output_bfd == (bfd *) NULL)
466 ret = bfd_reloc_undefined;
468 if (bfd_is_com_section (symbol->section))
471 relocation = symbol->value;
473 relocation += symbol->section->output_section->vma;
474 relocation += symbol->section->output_offset;
475 relocation += reloc_entry->addend;
477 if (reloc_entry->address > input_section->_cooked_size)
478 return bfd_reloc_outofrange;
480 /* Save the information, and let REFLO do the actual relocation. */
481 mips_refhi_addr = (bfd_byte *) data + reloc_entry->address;
482 mips_refhi_addend = relocation;
484 if (output_bfd != (bfd *) NULL)
485 reloc_entry->address += input_section->output_offset;
490 /* Do a REFLO relocation. This is a straightforward 16 bit inplace
491 relocation; this function exists in order to do the REFHI
492 relocation described above. */
494 static bfd_reloc_status_type
495 mips_reflo_reloc (abfd,
503 arelent *reloc_entry;
506 asection *input_section;
508 char **error_message;
510 if (mips_refhi_addr != (bfd_byte *) NULL)
516 /* Do the REFHI relocation. Note that we actually don't need to
517 know anything about the REFLO itself, except where to find
518 the low 16 bits of the addend needed by the REFHI. */
519 insn = bfd_get_32 (abfd, mips_refhi_addr);
520 vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
522 val = ((insn & 0xffff) << 16) + vallo;
523 val += mips_refhi_addend;
525 /* The low order 16 bits are always treated as a signed value.
526 Therefore, a negative value in the low order bits requires an
527 adjustment in the high order bits. We need to make this
528 adjustment in two ways: once for the bits we took from the
529 data, and once for the bits we are putting back in to the
531 if ((vallo & 0x8000) != 0)
533 if ((val & 0x8000) != 0)
536 insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
537 bfd_put_32 (abfd, insn, mips_refhi_addr);
539 mips_refhi_addr = (bfd_byte *) NULL;
542 /* Now do the REFLO reloc in the usual way. */
543 return mips_generic_reloc (abfd, reloc_entry, symbol, data,
544 input_section, output_bfd, error_message);
547 /* Do a GPREL relocation. This is a 16 bit value which must become
548 the offset from the gp register. */
550 static bfd_reloc_status_type
551 mips_gprel_reloc (abfd,
559 arelent *reloc_entry;
562 asection *input_section;
564 char **error_message;
566 boolean relocateable;
571 /* If we're relocating, and this is an external symbol with no
572 addend, we don't want to change anything. We will only have an
573 addend if this is a newly created reloc, not read from an ECOFF
575 if (output_bfd != (bfd *) NULL
576 && (symbol->flags & BSF_SECTION_SYM) == 0
577 && reloc_entry->addend == 0)
579 reloc_entry->address += input_section->output_offset;
583 if (output_bfd != (bfd *) NULL)
587 relocateable = false;
588 output_bfd = symbol->section->output_section->owner;
591 if (symbol->section == &bfd_und_section
592 && relocateable == false)
593 return bfd_reloc_undefined;
595 /* We have to figure out the gp value, so that we can adjust the
596 symbol value correctly. We look up the symbol _gp in the output
597 BFD. If we can't find it, we're stuck. We cache it in the ECOFF
598 target data. We don't need to adjust the symbol value for an
599 external symbol if we are producing relocateable output. */
600 if (ecoff_data (output_bfd)->gp == 0
601 && (relocateable == false
602 || (symbol->flags & BSF_SECTION_SYM) != 0))
604 if (relocateable != false)
606 /* Make up a value. */
607 ecoff_data (output_bfd)->gp =
608 symbol->section->output_section->vma + 0x4000;
616 count = bfd_get_symcount (output_bfd);
617 sym = bfd_get_outsymbols (output_bfd);
619 if (sym == (asymbol **) NULL)
623 for (i = 0; i < count; i++, sym++)
625 register CONST char *name;
627 name = bfd_asymbol_name (*sym);
628 if (*name == '_' && strcmp (name, "_gp") == 0)
630 ecoff_data (output_bfd)->gp = bfd_asymbol_value (*sym);
638 /* Only get the error once. */
639 ecoff_data (output_bfd)->gp = 4;
641 (char *) "GP relative relocation when _gp not defined";
642 return bfd_reloc_dangerous;
647 if (bfd_is_com_section (symbol->section))
650 relocation = symbol->value;
652 relocation += symbol->section->output_section->vma;
653 relocation += symbol->section->output_offset;
655 if (reloc_entry->address > input_section->_cooked_size)
656 return bfd_reloc_outofrange;
658 insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
660 /* Set val to the offset into the section or symbol. */
661 val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;
665 /* Adjust val for the final section location and GP value. If we
666 are producing relocateable output, we don't want to do this for
667 an external symbol. */
668 if (relocateable == false
669 || (symbol->flags & BSF_SECTION_SYM) != 0)
670 val += relocation - ecoff_data (output_bfd)->gp;
672 insn = (insn &~ 0xffff) | (val & 0xffff);
673 bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
675 if (relocateable != false)
676 reloc_entry->address += input_section->output_offset;
678 /* Make sure it fit in 16 bits. */
679 if (val >= 0x8000 && val < 0xffff8000)
680 return bfd_reloc_overflow;
685 /* Get the howto structure for a generic reloc type. */
687 static CONST struct reloc_howto_struct *
688 mips_bfd_reloc_type_lookup (abfd, code)
690 bfd_reloc_code_real_type code;
697 mips_type = MIPS_R_REFHALF;
700 mips_type = MIPS_R_REFWORD;
702 case BFD_RELOC_MIPS_JMP:
703 mips_type = MIPS_R_JMPADDR;
705 case BFD_RELOC_HI16_S:
706 mips_type = MIPS_R_REFHI;
709 mips_type = MIPS_R_REFLO;
711 case BFD_RELOC_MIPS_GPREL:
712 mips_type = MIPS_R_GPREL;
714 case BFD_RELOC_MIPS_LITERAL:
715 mips_type = MIPS_R_LITERAL;
718 return (CONST struct reloc_howto_struct *) NULL;
721 return &mips_howto_table[mips_type];
724 /* A helper routine for mips_relocate_section which handles the REFHI
725 relocation. The REFHI relocation must be followed by a REFLO
726 relocation, and the addend used is formed from the addends of both
730 mips_relocate_refhi (refhi, reflo, input_bfd, input_section, contents,
732 struct internal_reloc *refhi;
733 struct internal_reloc *reflo;
735 asection *input_section;
743 insn = bfd_get_32 (input_bfd,
744 contents + refhi->r_vaddr - input_section->vma);
745 vallo = (bfd_get_32 (input_bfd,
746 contents + reflo->r_vaddr - input_section->vma)
748 val = ((insn & 0xffff) << 16) + vallo;
751 /* The low order 16 bits are always treated as a signed value.
752 Therefore, a negative value in the low order bits requires an
753 adjustment in the high order bits. We need to make this
754 adjustment in two ways: once for the bits we took from the data,
755 and once for the bits we are putting back in to the data. */
756 if ((vallo & 0x8000) != 0)
758 if ((val & 0x8000) != 0)
761 insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
762 bfd_put_32 (input_bfd, (bfd_vma) insn,
763 contents + refhi->r_vaddr - input_section->vma);
766 /* Relocate a section while linking a MIPS ECOFF file. */
769 mips_relocate_section (output_bfd, info, input_bfd, input_section,
770 contents, external_relocs)
772 struct bfd_link_info *info;
774 asection *input_section;
778 asection **symndx_to_section;
779 struct ecoff_link_hash_entry **sym_hashes;
781 boolean gp_undefined;
782 struct external_reloc *ext_rel;
783 struct external_reloc *ext_rel_end;
786 BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
787 == output_bfd->xvec->header_byteorder_big_p);
789 /* We keep a table mapping the symndx found in an internal reloc to
790 the appropriate section. This is faster than looking up the
791 section by name each time. */
792 symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
793 if (symndx_to_section == (asection **) NULL)
795 symndx_to_section = ((asection **)
796 bfd_alloc (input_bfd,
798 * sizeof (asection *))));
800 symndx_to_section[RELOC_SECTION_NONE] = NULL;
801 symndx_to_section[RELOC_SECTION_TEXT] =
802 bfd_get_section_by_name (input_bfd, ".text");
803 symndx_to_section[RELOC_SECTION_RDATA] =
804 bfd_get_section_by_name (input_bfd, ".rdata");
805 symndx_to_section[RELOC_SECTION_DATA] =
806 bfd_get_section_by_name (input_bfd, ".data");
807 symndx_to_section[RELOC_SECTION_SDATA] =
808 bfd_get_section_by_name (input_bfd, ".sdata");
809 symndx_to_section[RELOC_SECTION_SBSS] =
810 bfd_get_section_by_name (input_bfd, ".sbss");
811 symndx_to_section[RELOC_SECTION_BSS] =
812 bfd_get_section_by_name (input_bfd, ".bss");
813 symndx_to_section[RELOC_SECTION_INIT] =
814 bfd_get_section_by_name (input_bfd, ".init");
815 symndx_to_section[RELOC_SECTION_LIT8] =
816 bfd_get_section_by_name (input_bfd, ".lit8");
817 symndx_to_section[RELOC_SECTION_LIT4] =
818 bfd_get_section_by_name (input_bfd, ".lit4");
819 symndx_to_section[RELOC_SECTION_XDATA] = NULL;
820 symndx_to_section[RELOC_SECTION_PDATA] = NULL;
821 symndx_to_section[RELOC_SECTION_FINI] =
822 bfd_get_section_by_name (input_bfd, ".fini");
823 symndx_to_section[RELOC_SECTION_LITA] = NULL;
824 symndx_to_section[RELOC_SECTION_ABS] = NULL;
826 ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
829 sym_hashes = ecoff_data (input_bfd)->sym_hashes;
831 gp = ecoff_data (output_bfd)->gp;
835 gp_undefined = false;
839 ext_rel = (struct external_reloc *) external_relocs;
840 ext_rel_end = ext_rel + input_section->reloc_count;
841 for (; ext_rel < ext_rel_end; ext_rel++)
843 struct internal_reloc int_rel;
844 struct internal_reloc reflo_int_rel;
846 reloc_howto_type *howto;
847 struct ecoff_link_hash_entry *h = NULL;
850 bfd_reloc_status_type r;
853 mips_ecoff_swap_reloc_in (input_bfd, (PTR) ext_rel, &int_rel);
856 int_rel = reflo_int_rel;
860 BFD_ASSERT (int_rel.r_type
861 < sizeof mips_howto_table / sizeof mips_howto_table[0]);
863 /* The REFHI reloc requires special handling. It must be
864 followed by a REFLO reloc, and the addend is formed from both
866 if (int_rel.r_type == MIPS_R_REFHI)
868 BFD_ASSERT ((ext_rel + 1) < ext_rel_end);
869 mips_ecoff_swap_reloc_in (input_bfd, (PTR) (ext_rel + 1),
871 BFD_ASSERT (reflo_int_rel.r_type == MIPS_R_REFLO
872 && int_rel.r_extern == reflo_int_rel.r_extern
873 && int_rel.r_symndx == reflo_int_rel.r_symndx);
877 howto = &mips_howto_table[int_rel.r_type];
879 if (int_rel.r_extern)
881 h = sym_hashes[int_rel.r_symndx];
882 /* If h is NULL, that means that there is a reloc against an
883 external symbol which we thought was just a debugging
884 symbol. This should not happen. */
885 if (h == (struct ecoff_link_hash_entry *) NULL)
890 if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS)
893 s = symndx_to_section[int_rel.r_symndx];
895 if (s == (asection *) NULL)
899 /* The GPREL reloc uses an addend: the difference in the GP
901 if (int_rel.r_type != MIPS_R_GPREL)
907 if (! ((*info->callbacks->reloc_dangerous)
908 (info, "GP relative relocation when GP not defined",
909 input_bfd, input_section,
910 int_rel.r_vaddr - input_section->vma)))
912 /* Only give the error once per link. */
913 ecoff_data (output_bfd)->gp = gp = 4;
914 gp_undefined = false;
916 if (! int_rel.r_extern)
918 /* This is a relocation against a section. The current
919 addend in the instruction is the difference between
920 INPUT_SECTION->vma and the GP value of INPUT_BFD. We
921 must change this to be the difference between the
922 final definition (which will end up in RELOCATION)
923 and the GP value of OUTPUT_BFD (which is in GP). */
924 addend = ecoff_data (input_bfd)->gp - gp;
926 else if (! info->relocateable
927 || h->root.type == bfd_link_hash_defined)
929 /* This is a relocation against an undefined or common
930 symbol. The current addend in the instruction is
931 simply the desired offset into the symbol (normally
932 zero). We are going to change this into a relocation
933 against a defined symbol, so we want the instruction
934 to hold the difference between the final definition
935 of the symbol (which will end up in RELOCATION) and
936 the GP value of OUTPUT_BFD (which is in GP). */
941 /* This is a relocation against an undefined or common
942 symbol. The current addend in the instruction is
943 simply the desired offset into the symbol (normally
944 zero). We are generating relocateable output, and we
945 aren't going to define this symbol, so we just leave
946 the instruction alone. */
951 if (info->relocateable)
953 /* We are generating relocateable output, and must convert
954 the existing reloc. */
955 if (int_rel.r_extern)
957 if (h->root.type == bfd_link_hash_defined)
962 /* This symbol is defined in the output. Convert
963 the reloc from being against the symbol to being
964 against the section. */
966 /* Clear the r_extern bit. */
967 int_rel.r_extern = 0;
969 /* Compute a new r_symndx value. */
970 hsec = h->root.u.def.section;
971 name = bfd_get_section_name (output_bfd,
972 hsec->output_section);
974 int_rel.r_symndx = -1;
978 if (strcmp (name, ".bss") == 0)
979 int_rel.r_symndx = RELOC_SECTION_BSS;
982 if (strcmp (name, ".data") == 0)
983 int_rel.r_symndx = RELOC_SECTION_DATA;
986 if (strcmp (name, ".fini") == 0)
987 int_rel.r_symndx = RELOC_SECTION_FINI;
990 if (strcmp (name, ".init") == 0)
991 int_rel.r_symndx = RELOC_SECTION_INIT;
994 if (strcmp (name, ".lit8") == 0)
995 int_rel.r_symndx = RELOC_SECTION_LIT8;
996 else if (strcmp (name, ".lit4") == 0)
997 int_rel.r_symndx = RELOC_SECTION_LIT4;
1000 if (strcmp (name, ".rdata") == 0)
1001 int_rel.r_symndx = RELOC_SECTION_RDATA;
1004 if (strcmp (name, ".sdata") == 0)
1005 int_rel.r_symndx = RELOC_SECTION_SDATA;
1006 else if (strcmp (name, ".sbss") == 0)
1007 int_rel.r_symndx = RELOC_SECTION_SBSS;
1010 if (strcmp (name, ".text") == 0)
1011 int_rel.r_symndx = RELOC_SECTION_TEXT;
1015 if (int_rel.r_symndx == -1)
1018 /* Add the section VMA and the symbol value. */
1019 relocation = (h->root.u.def.value
1020 + hsec->output_section->vma
1021 + hsec->output_offset);
1025 /* Change the symndx value to the right one for the
1027 int_rel.r_symndx = h->indx;
1028 if (int_rel.r_symndx == -1)
1030 /* This symbol is not being written out. */
1031 if (! ((*info->callbacks->unattached_reloc)
1032 (info, h->root.root.string, input_bfd,
1034 int_rel.r_vaddr - input_section->vma)))
1036 int_rel.r_symndx = 0;
1043 /* This is a relocation against a section. Adjust the
1044 value by the amount the section moved. */
1045 relocation = (s->output_section->vma
1050 relocation += addend;
1052 /* Adjust the contents. */
1053 if (relocation == 0)
1057 if (int_rel.r_type != MIPS_R_REFHI)
1058 r = _bfd_relocate_contents (howto, input_bfd, relocation,
1061 - input_section->vma));
1064 mips_relocate_refhi (&int_rel, &reflo_int_rel,
1065 input_bfd, input_section, contents,
1071 /* Adjust the reloc address. */
1072 int_rel.r_vaddr += (input_section->output_section->vma
1073 + input_section->output_offset
1074 - input_section->vma);
1076 /* Save the changed reloc information. */
1077 mips_ecoff_swap_reloc_out (input_bfd, &int_rel, (PTR) ext_rel);
1081 /* We are producing a final executable. */
1082 if (int_rel.r_extern)
1084 /* This is a reloc against a symbol. */
1085 if (h->root.type == bfd_link_hash_defined)
1089 hsec = h->root.u.def.section;
1090 relocation = (h->root.u.def.value
1091 + hsec->output_section->vma
1092 + hsec->output_offset);
1096 if (! ((*info->callbacks->undefined_symbol)
1097 (info, h->root.root.string, input_bfd,
1099 int_rel.r_vaddr - input_section->vma)))
1106 /* This is a reloc against a section. */
1107 relocation = (s->output_section->vma
1111 /* Adjust a PC relative relocation by removing the
1112 reference to the original source section. */
1113 if (howto->pc_relative)
1114 relocation += input_section->vma;
1117 if (int_rel.r_type != MIPS_R_REFHI)
1118 r = _bfd_final_link_relocate (howto,
1122 int_rel.r_vaddr - input_section->vma,
1127 mips_relocate_refhi (&int_rel, &reflo_int_rel, input_bfd,
1128 input_section, contents, relocation);
1133 if (r != bfd_reloc_ok)
1138 case bfd_reloc_outofrange:
1140 case bfd_reloc_overflow:
1144 if (int_rel.r_extern)
1145 name = h->root.root.string;
1147 name = bfd_section_name (input_bfd, s);
1148 if (! ((*info->callbacks->reloc_overflow)
1149 (info, name, howto->name, (bfd_vma) 0,
1150 input_bfd, input_section,
1151 int_rel.r_vaddr - input_section->vma)))
1162 /* This is the ECOFF backend structure. The backend field of the
1163 target vector points to this. */
1165 static const struct ecoff_backend_data mips_ecoff_backend_data =
1167 /* COFF backend structure. */
1169 (void (*) PARAMS ((bfd *,PTR,int,int,PTR))) bfd_void, /* aux_in */
1170 (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
1171 (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
1172 (unsigned (*) PARAMS ((bfd *,PTR,int,int,PTR))) bfd_void, /* aux_out */
1173 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
1174 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
1175 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
1176 mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
1177 mips_ecoff_swap_scnhdr_out,
1178 FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, true,
1179 mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
1180 mips_ecoff_swap_scnhdr_in, mips_ecoff_bad_format_hook,
1181 ecoff_set_arch_mach_hook, ecoff_mkobject_hook,
1182 ecoff_styp_to_sec_flags, ecoff_make_section_hook, ecoff_set_alignment_hook,
1183 ecoff_slurp_symbol_table, NULL, NULL
1185 /* Supported architecture. */
1187 /* Initial portion of armap string. */
1189 /* The page boundary used to align sections in a demand-paged
1190 executable file. E.g., 0x1000. */
1192 /* True if the .rdata section is part of the text segment, as on the
1193 Alpha. False if .rdata is part of the data segment, as on the
1196 /* Bitsize of constructor entries. */
1198 /* Reloc to use for constructor entries. */
1199 &mips_howto_table[MIPS_R_REFWORD],
1201 /* Symbol table magic number. */
1203 /* Alignment of debugging information. E.g., 4. */
1205 /* Sizes of external symbolic information. */
1206 sizeof (struct hdr_ext),
1207 sizeof (struct dnr_ext),
1208 sizeof (struct pdr_ext),
1209 sizeof (struct sym_ext),
1210 sizeof (struct opt_ext),
1211 sizeof (struct fdr_ext),
1212 sizeof (struct rfd_ext),
1213 sizeof (struct ext_ext),
1214 /* Functions to swap in external symbolic data. */
1223 /* Functions to swap out external symbolic data. */
1233 /* External reloc size. */
1235 /* Reloc swapping functions. */
1236 mips_ecoff_swap_reloc_in,
1237 mips_ecoff_swap_reloc_out,
1238 /* Backend reloc tweaking. */
1239 mips_adjust_reloc_in,
1240 mips_adjust_reloc_out,
1241 /* Relocate section contents while linking. */
1242 mips_relocate_section
1245 /* Looking up a reloc type is MIPS specific. */
1246 #define ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
1248 /* Getting relocated section contents is generic. */
1249 #define ecoff_bfd_get_relocated_section_contents \
1250 bfd_generic_get_relocated_section_contents
1252 /* Core file support is usually traditional (but note that Irix uses
1254 #define ecoff_core_file_p _bfd_dummy_target
1255 #define ecoff_core_file_failing_command _bfd_dummy_core_file_failing_command
1256 #define ecoff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
1257 #define ecoff_core_file_matches_executable_p \
1258 _bfd_dummy_core_file_matches_executable_p
1260 bfd_target ecoff_little_vec =
1262 "ecoff-littlemips", /* name */
1263 bfd_target_ecoff_flavour,
1264 false, /* data byte order is little */
1265 false, /* header byte order is little */
1267 (HAS_RELOC | EXEC_P | /* object flags */
1268 HAS_LINENO | HAS_DEBUG |
1269 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1271 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect
1273 0, /* leading underscore */
1274 ' ', /* ar_pad_char */
1275 15, /* ar_max_namelen */
1276 4, /* minimum alignment power */
1277 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1278 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1279 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1280 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1281 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1282 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
1284 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1285 ecoff_archive_p, _bfd_dummy_target},
1286 {bfd_false, ecoff_mkobject, /* bfd_set_format */
1287 _bfd_generic_mkarchive, bfd_false},
1288 {bfd_false, ecoff_write_object_contents, /* bfd_write_contents */
1289 _bfd_write_archive_contents, bfd_false},
1291 (PTR) &mips_ecoff_backend_data
1294 bfd_target ecoff_big_vec =
1296 "ecoff-bigmips", /* name */
1297 bfd_target_ecoff_flavour,
1298 true, /* data byte order is big */
1299 true, /* header byte order is big */
1301 (HAS_RELOC | EXEC_P | /* object flags */
1302 HAS_LINENO | HAS_DEBUG |
1303 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1305 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect flags */
1306 0, /* leading underscore */
1307 ' ', /* ar_pad_char */
1308 15, /* ar_max_namelen */
1309 4, /* minimum alignment power */
1310 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1311 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1312 bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1313 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1314 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1315 bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1316 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1317 ecoff_archive_p, ecoff_core_file_p},
1318 {bfd_false, ecoff_mkobject, /* bfd_set_format */
1319 _bfd_generic_mkarchive, bfd_false},
1320 {bfd_false, ecoff_write_object_contents, /* bfd_write_contents */
1321 _bfd_write_archive_contents, bfd_false},
1323 (PTR) &mips_ecoff_backend_data
1324 /* Note that there is another bfd_target just above this one. If
1325 you are adding initializers here, you should be adding them there