1 /* BFD back-end for MIPS Extended-Coff files.
2 Copyright (C) 1990-2018 Free Software Foundation, Inc.
3 Original version by Per Bothner.
4 Full support added by Ian Lance Taylor, ian@cygnus.com.
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 3 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., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
27 #include "coff/internal.h"
29 #include "coff/symconst.h"
30 #include "coff/ecoff.h"
31 #include "coff/mips.h"
35 /* Prototypes for static functions. */
36 static bfd_reloc_status_type
38 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
39 static bfd_reloc_status_type
41 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
42 static bfd_reloc_status_type
44 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
45 static bfd_reloc_status_type
47 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
50 /* ECOFF has COFF sections, but the debugging information is stored in
51 a completely different format. ECOFF targets use some of the
52 swapping routines from coffswap.h, and some of the generic COFF
53 routines in coffgen.c, but, unlike the real COFF targets, do not
54 use coffcode.h itself.
56 Get the generic COFF swapping routines, except for the reloc,
57 symbol, and lineno ones. Give them ECOFF names. */
59 #define NO_COFF_RELOCS
60 #define NO_COFF_SYMBOLS
61 #define NO_COFF_LINENOS
62 #define coff_swap_filehdr_in mips_ecoff_swap_filehdr_in
63 #define coff_swap_filehdr_out mips_ecoff_swap_filehdr_out
64 #define coff_swap_aouthdr_in mips_ecoff_swap_aouthdr_in
65 #define coff_swap_aouthdr_out mips_ecoff_swap_aouthdr_out
66 #define coff_swap_scnhdr_in mips_ecoff_swap_scnhdr_in
67 #define coff_swap_scnhdr_out mips_ecoff_swap_scnhdr_out
71 /* Get the ECOFF swapping routines. */
73 #include "ecoffswap.h"
75 /* How to process the various relocs types. */
77 static reloc_howto_type mips_howto_table[] =
79 /* Reloc type 0 is ignored. The reloc reading code ensures that
80 this is a reference to the .abs section, which will cause
81 bfd_perform_relocation to do nothing. */
82 HOWTO (MIPS_R_IGNORE, /* type */
84 0, /* size (0 = byte, 1 = short, 2 = long) */
86 FALSE, /* pc_relative */
88 complain_overflow_dont, /* complain_on_overflow */
89 0, /* special_function */
91 FALSE, /* partial_inplace */
94 FALSE), /* pcrel_offset */
96 /* A 16 bit reference to a symbol, normally from a data section. */
97 HOWTO (MIPS_R_REFHALF, /* type */
99 1, /* size (0 = byte, 1 = short, 2 = long) */
101 FALSE, /* pc_relative */
103 complain_overflow_bitfield, /* complain_on_overflow */
104 mips_generic_reloc, /* special_function */
105 "REFHALF", /* name */
106 TRUE, /* partial_inplace */
107 0xffff, /* src_mask */
108 0xffff, /* dst_mask */
109 FALSE), /* pcrel_offset */
111 /* A 32 bit reference to a symbol, normally from a data section. */
112 HOWTO (MIPS_R_REFWORD, /* type */
114 2, /* size (0 = byte, 1 = short, 2 = long) */
116 FALSE, /* pc_relative */
118 complain_overflow_bitfield, /* complain_on_overflow */
119 mips_generic_reloc, /* special_function */
120 "REFWORD", /* name */
121 TRUE, /* partial_inplace */
122 0xffffffff, /* src_mask */
123 0xffffffff, /* dst_mask */
124 FALSE), /* pcrel_offset */
126 /* A 26 bit absolute jump address. */
127 HOWTO (MIPS_R_JMPADDR, /* type */
129 2, /* size (0 = byte, 1 = short, 2 = long) */
131 FALSE, /* pc_relative */
133 complain_overflow_dont, /* complain_on_overflow */
134 /* This needs complex overflow
135 detection, because the upper four
136 bits must match the PC. */
137 mips_generic_reloc, /* special_function */
138 "JMPADDR", /* name */
139 TRUE, /* partial_inplace */
140 0x3ffffff, /* src_mask */
141 0x3ffffff, /* dst_mask */
142 FALSE), /* pcrel_offset */
144 /* The high 16 bits of a symbol value. Handled by the function
146 HOWTO (MIPS_R_REFHI, /* type */
148 2, /* size (0 = byte, 1 = short, 2 = long) */
150 FALSE, /* pc_relative */
152 complain_overflow_bitfield, /* complain_on_overflow */
153 mips_refhi_reloc, /* special_function */
155 TRUE, /* partial_inplace */
156 0xffff, /* src_mask */
157 0xffff, /* dst_mask */
158 FALSE), /* pcrel_offset */
160 /* The low 16 bits of a symbol value. */
161 HOWTO (MIPS_R_REFLO, /* type */
163 2, /* size (0 = byte, 1 = short, 2 = long) */
165 FALSE, /* pc_relative */
167 complain_overflow_dont, /* complain_on_overflow */
168 mips_reflo_reloc, /* special_function */
170 TRUE, /* partial_inplace */
171 0xffff, /* src_mask */
172 0xffff, /* dst_mask */
173 FALSE), /* pcrel_offset */
175 /* A reference to an offset from the gp register. Handled by the
176 function mips_gprel_reloc. */
177 HOWTO (MIPS_R_GPREL, /* type */
179 2, /* size (0 = byte, 1 = short, 2 = long) */
181 FALSE, /* pc_relative */
183 complain_overflow_signed, /* complain_on_overflow */
184 mips_gprel_reloc, /* special_function */
186 TRUE, /* partial_inplace */
187 0xffff, /* src_mask */
188 0xffff, /* dst_mask */
189 FALSE), /* pcrel_offset */
191 /* A reference to a literal using an offset from the gp register.
192 Handled by the function mips_gprel_reloc. */
193 HOWTO (MIPS_R_LITERAL, /* type */
195 2, /* size (0 = byte, 1 = short, 2 = long) */
197 FALSE, /* pc_relative */
199 complain_overflow_signed, /* complain_on_overflow */
200 mips_gprel_reloc, /* special_function */
201 "LITERAL", /* name */
202 TRUE, /* partial_inplace */
203 0xffff, /* src_mask */
204 0xffff, /* dst_mask */
205 FALSE), /* pcrel_offset */
212 /* FIXME: This relocation is used (internally only) to represent branches
213 when assembling. It should never appear in output files, and
214 be removed. (It used to be used for embedded-PIC support.) */
215 HOWTO (MIPS_R_PCREL16, /* type */
217 2, /* size (0 = byte, 1 = short, 2 = long) */
219 TRUE, /* pc_relative */
221 complain_overflow_signed, /* complain_on_overflow */
222 mips_generic_reloc, /* special_function */
223 "PCREL16", /* name */
224 TRUE, /* partial_inplace */
225 0xffff, /* src_mask */
226 0xffff, /* dst_mask */
227 TRUE), /* pcrel_offset */
230 #define MIPS_HOWTO_COUNT \
231 (sizeof mips_howto_table / sizeof mips_howto_table[0])
233 /* See whether the magic number matches. */
236 mips_ecoff_bad_format_hook (bfd * abfd, void * filehdr)
238 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
240 switch (internal_f->f_magic)
243 /* I don't know what endianness this implies. */
247 case MIPS_MAGIC_BIG2:
248 case MIPS_MAGIC_BIG3:
249 return bfd_big_endian (abfd);
251 case MIPS_MAGIC_LITTLE:
252 case MIPS_MAGIC_LITTLE2:
253 case MIPS_MAGIC_LITTLE3:
254 return bfd_little_endian (abfd);
261 /* Reloc handling. MIPS ECOFF relocs are packed into 8 bytes in
262 external form. They use a bit which indicates whether the symbol
265 /* Swap a reloc in. */
268 mips_ecoff_swap_reloc_in (bfd * abfd,
270 struct internal_reloc *intern)
272 const RELOC *ext = (RELOC *) ext_ptr;
274 intern->r_vaddr = H_GET_32 (abfd, ext->r_vaddr);
275 if (bfd_header_big_endian (abfd))
277 intern->r_symndx = (((int) ext->r_bits[0]
278 << RELOC_BITS0_SYMNDX_SH_LEFT_BIG)
279 | ((int) ext->r_bits[1]
280 << RELOC_BITS1_SYMNDX_SH_LEFT_BIG)
281 | ((int) ext->r_bits[2]
282 << RELOC_BITS2_SYMNDX_SH_LEFT_BIG));
283 intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_BIG)
284 >> RELOC_BITS3_TYPE_SH_BIG);
285 intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_BIG) != 0;
289 intern->r_symndx = (((int) ext->r_bits[0]
290 << RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE)
291 | ((int) ext->r_bits[1]
292 << RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE)
293 | ((int) ext->r_bits[2]
294 << RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE));
295 intern->r_type = (((ext->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
296 >> RELOC_BITS3_TYPE_SH_LITTLE)
297 | ((ext->r_bits[3] & RELOC_BITS3_TYPEHI_LITTLE)
298 << RELOC_BITS3_TYPEHI_SH_LITTLE));
299 intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0;
303 /* Swap a reloc out. */
306 mips_ecoff_swap_reloc_out (bfd * abfd,
307 const struct internal_reloc * intern,
310 RELOC *ext = (RELOC *) dst;
313 BFD_ASSERT (intern->r_extern
314 || (intern->r_symndx >= 0 && intern->r_symndx <= 12));
316 r_symndx = intern->r_symndx;
318 H_PUT_32 (abfd, intern->r_vaddr, ext->r_vaddr);
319 if (bfd_header_big_endian (abfd))
321 ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_BIG;
322 ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_BIG;
323 ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_BIG;
324 ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_BIG)
325 & RELOC_BITS3_TYPE_BIG)
326 | (intern->r_extern ? RELOC_BITS3_EXTERN_BIG : 0));
330 ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE;
331 ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE;
332 ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE;
333 ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_LITTLE)
334 & RELOC_BITS3_TYPE_LITTLE)
335 | ((intern->r_type >> RELOC_BITS3_TYPEHI_SH_LITTLE
336 & RELOC_BITS3_TYPEHI_LITTLE))
337 | (intern->r_extern ? RELOC_BITS3_EXTERN_LITTLE : 0));
341 /* Finish canonicalizing a reloc. Part of this is generic to all
342 ECOFF targets, and that part is in ecoff.c. The rest is done in
343 this backend routine. It must fill in the howto field. */
346 mips_adjust_reloc_in (bfd *abfd,
347 const struct internal_reloc *intern,
350 if (intern->r_type > MIPS_R_PCREL16)
353 if (! intern->r_extern
354 && (intern->r_type == MIPS_R_GPREL
355 || intern->r_type == MIPS_R_LITERAL))
356 rptr->addend += ecoff_data (abfd)->gp;
358 /* If the type is MIPS_R_IGNORE, make sure this is a reference to
359 the absolute section so that the reloc is ignored. */
360 if (intern->r_type == MIPS_R_IGNORE)
361 rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
363 rptr->howto = &mips_howto_table[intern->r_type];
366 /* Make any adjustments needed to a reloc before writing it out. None
367 are needed for MIPS. */
370 mips_adjust_reloc_out (bfd *abfd ATTRIBUTE_UNUSED,
371 const arelent *rel ATTRIBUTE_UNUSED,
372 struct internal_reloc *intern ATTRIBUTE_UNUSED)
376 /* ECOFF relocs are either against external symbols, or against
377 sections. If we are producing relocatable output, and the reloc
378 is against an external symbol, and nothing has given us any
379 additional addend, the resulting reloc will also be against the
380 same symbol. In such a case, we don't want to change anything
381 about the way the reloc is handled, since it will all be done at
382 final link time. Rather than put special case code into
383 bfd_perform_relocation, all the reloc types use this howto
384 function. It just short circuits the reloc if producing
385 relocatable output against an external symbol. */
387 static bfd_reloc_status_type
388 mips_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED,
389 arelent *reloc_entry,
391 void * data ATTRIBUTE_UNUSED,
392 asection *input_section,
394 char **error_message ATTRIBUTE_UNUSED)
396 if (output_bfd != (bfd *) NULL
397 && (symbol->flags & BSF_SECTION_SYM) == 0
398 && reloc_entry->addend == 0)
400 reloc_entry->address += input_section->output_offset;
404 return bfd_reloc_continue;
407 /* Do a REFHI relocation. This has to be done in combination with a
408 REFLO reloc, because there is a carry from the REFLO to the REFHI.
409 Here we just save the information we need; we do the actual
410 relocation when we see the REFLO. MIPS ECOFF requires that the
411 REFLO immediately follow the REFHI. As a GNU extension, we permit
412 an arbitrary number of HI relocs to be associated with a single LO
413 reloc. This extension permits gcc to output the HI and LO relocs
418 struct mips_hi *next;
423 /* FIXME: This should not be a static variable. */
425 static struct mips_hi *mips_refhi_list;
427 static bfd_reloc_status_type
428 mips_refhi_reloc (bfd *abfd ATTRIBUTE_UNUSED,
429 arelent *reloc_entry,
432 asection *input_section,
434 char **error_message ATTRIBUTE_UNUSED)
436 bfd_reloc_status_type ret;
440 /* If we're relocating, and this an external symbol, we don't want
441 to change anything. */
442 if (output_bfd != (bfd *) NULL
443 && (symbol->flags & BSF_SECTION_SYM) == 0
444 && reloc_entry->addend == 0)
446 reloc_entry->address += input_section->output_offset;
451 if (bfd_is_und_section (symbol->section)
452 && output_bfd == (bfd *) NULL)
453 ret = bfd_reloc_undefined;
455 if (bfd_is_com_section (symbol->section))
458 relocation = symbol->value;
460 relocation += symbol->section->output_section->vma;
461 relocation += symbol->section->output_offset;
462 relocation += reloc_entry->addend;
464 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
465 return bfd_reloc_outofrange;
467 /* Save the information, and let REFLO do the actual relocation. */
468 n = (struct mips_hi *) bfd_malloc ((bfd_size_type) sizeof *n);
470 return bfd_reloc_outofrange;
471 n->addr = (bfd_byte *) data + reloc_entry->address;
472 n->addend = relocation;
473 n->next = mips_refhi_list;
476 if (output_bfd != (bfd *) NULL)
477 reloc_entry->address += input_section->output_offset;
482 /* Do a REFLO relocation. This is a straightforward 16 bit inplace
483 relocation; this function exists in order to do the REFHI
484 relocation described above. */
486 static bfd_reloc_status_type
487 mips_reflo_reloc (bfd *abfd ATTRIBUTE_UNUSED,
488 arelent *reloc_entry,
491 asection *input_section,
493 char **error_message ATTRIBUTE_UNUSED)
495 if (mips_refhi_list != NULL)
505 struct mips_hi *next;
507 if (! bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
510 * bfd_octets_per_byte (abfd)))
511 return bfd_reloc_outofrange;
513 /* Do the REFHI relocation. Note that we actually don't
514 need to know anything about the REFLO itself, except
515 where to find the low 16 bits of the addend needed by the
517 insn = bfd_get_32 (abfd, l->addr);
518 vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
520 val = ((insn & 0xffff) << 16) + vallo;
523 /* The low order 16 bits are always treated as a signed
524 value. Therefore, a negative value in the low order bits
525 requires an adjustment in the high order bits. We need
526 to make this adjustment in two ways: once for the bits we
527 took from the data, and once for the bits we are putting
528 back in to the data. */
529 if ((vallo & 0x8000) != 0)
531 if ((val & 0x8000) != 0)
534 insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
535 bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
542 mips_refhi_list = NULL;
545 /* Now do the REFLO reloc in the usual way. */
546 return mips_generic_reloc (abfd, reloc_entry, symbol, data,
547 input_section, output_bfd, error_message);
550 /* Do a GPREL relocation. This is a 16 bit value which must become
551 the offset from the gp register. */
553 static bfd_reloc_status_type
554 mips_gprel_reloc (bfd *abfd ATTRIBUTE_UNUSED,
555 arelent *reloc_entry,
558 asection *input_section,
560 char **error_message ATTRIBUTE_UNUSED)
562 bfd_boolean relocatable;
568 /* If we're relocating, and this is an external symbol with no
569 addend, we don't want to change anything. We will only have an
570 addend if this is a newly created reloc, not read from an ECOFF
572 if (output_bfd != (bfd *) NULL
573 && (symbol->flags & BSF_SECTION_SYM) == 0
574 && reloc_entry->addend == 0)
576 reloc_entry->address += input_section->output_offset;
580 if (output_bfd != (bfd *) NULL)
585 output_bfd = symbol->section->output_section->owner;
588 if (bfd_is_und_section (symbol->section) && ! relocatable)
589 return bfd_reloc_undefined;
591 /* We have to figure out the gp value, so that we can adjust the
592 symbol value correctly. We look up the symbol _gp in the output
593 BFD. If we can't find it, we're stuck. We cache it in the ECOFF
594 target data. We don't need to adjust the symbol value for an
595 external symbol if we are producing relocatable output. */
596 gp = _bfd_get_gp_value (output_bfd);
599 || (symbol->flags & BSF_SECTION_SYM) != 0))
603 /* Make up a value. */
604 gp = symbol->section->output_section->vma + 0x4000;
605 _bfd_set_gp_value (output_bfd, gp);
613 count = bfd_get_symcount (output_bfd);
614 sym = bfd_get_outsymbols (output_bfd);
616 if (sym == (asymbol **) NULL)
620 for (i = 0; i < count; i++, sym++)
622 register const char *name;
624 name = bfd_asymbol_name (*sym);
625 if (*name == '_' && strcmp (name, "_gp") == 0)
627 gp = bfd_asymbol_value (*sym);
628 _bfd_set_gp_value (output_bfd, gp);
636 /* Only get the error once. */
638 _bfd_set_gp_value (output_bfd, gp);
640 (char *) _("GP relative relocation when _gp not defined");
641 return bfd_reloc_dangerous;
646 if (bfd_is_com_section (symbol->section))
649 relocation = symbol->value;
651 relocation += symbol->section->output_section->vma;
652 relocation += symbol->section->output_offset;
654 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
655 return bfd_reloc_outofrange;
657 insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
659 /* Set val to the offset into the section or symbol. */
660 val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;
664 /* Adjust val for the final section location and GP value. If we
665 are producing relocatable output, we don't want to do this for
666 an external symbol. */
668 || (symbol->flags & BSF_SECTION_SYM) != 0)
669 val += relocation - gp;
671 insn = (insn &~ (unsigned) 0xffff) | (val & 0xffff);
672 bfd_put_32 (abfd, (bfd_vma) insn, (bfd_byte *) data + reloc_entry->address);
675 reloc_entry->address += input_section->output_offset;
677 /* Make sure it fit in 16 bits. */
678 if ((long) val >= 0x8000 || (long) val < -0x8000)
679 return bfd_reloc_overflow;
684 /* Get the howto structure for a generic reloc type. */
686 static reloc_howto_type *
687 mips_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
688 bfd_reloc_code_real_type code)
695 mips_type = MIPS_R_REFHALF;
699 mips_type = MIPS_R_REFWORD;
701 case BFD_RELOC_MIPS_JMP:
702 mips_type = MIPS_R_JMPADDR;
704 case BFD_RELOC_HI16_S:
705 mips_type = MIPS_R_REFHI;
708 mips_type = MIPS_R_REFLO;
710 case BFD_RELOC_GPREL16:
711 mips_type = MIPS_R_GPREL;
713 case BFD_RELOC_MIPS_LITERAL:
714 mips_type = MIPS_R_LITERAL;
716 case BFD_RELOC_16_PCREL_S2:
717 mips_type = MIPS_R_PCREL16;
720 return (reloc_howto_type *) NULL;
723 return &mips_howto_table[mips_type];
726 static reloc_howto_type *
727 mips_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
733 i < sizeof (mips_howto_table) / sizeof (mips_howto_table[0]);
735 if (mips_howto_table[i].name != NULL
736 && strcasecmp (mips_howto_table[i].name, r_name) == 0)
737 return &mips_howto_table[i];
742 /* A helper routine for mips_relocate_section which handles the REFHI
743 relocations. The REFHI relocation must be followed by a REFLO
744 relocation, and the addend used is formed from the addends of both
748 mips_relocate_hi (struct internal_reloc *refhi,
749 struct internal_reloc *reflo,
751 asection *input_section,
762 insn = bfd_get_32 (input_bfd,
763 contents + refhi->r_vaddr - input_section->vma);
767 vallo = (bfd_get_32 (input_bfd,
768 contents + reflo->r_vaddr - input_section->vma)
771 val = ((insn & 0xffff) << 16) + vallo;
774 /* The low order 16 bits are always treated as a signed value.
775 Therefore, a negative value in the low order bits requires an
776 adjustment in the high order bits. We need to make this
777 adjustment in two ways: once for the bits we took from the data,
778 and once for the bits we are putting back in to the data. */
779 if ((vallo & 0x8000) != 0)
782 if ((val & 0x8000) != 0)
785 insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
786 bfd_put_32 (input_bfd, (bfd_vma) insn,
787 contents + refhi->r_vaddr - input_section->vma);
790 /* Relocate a section while linking a MIPS ECOFF file. */
793 mips_relocate_section (bfd *output_bfd,
794 struct bfd_link_info *info,
796 asection *input_section,
798 void * external_relocs)
800 asection **symndx_to_section;
801 struct ecoff_link_hash_entry **sym_hashes;
803 bfd_boolean gp_undefined;
804 struct external_reloc *ext_rel;
805 struct external_reloc *ext_rel_end;
808 struct internal_reloc lo_int_rel;
811 BFD_ASSERT (input_bfd->xvec->byteorder
812 == output_bfd->xvec->byteorder);
814 /* We keep a table mapping the symndx found in an internal reloc to
815 the appropriate section. This is faster than looking up the
816 section by name each time. */
817 symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
818 if (symndx_to_section == (asection **) NULL)
820 amt = NUM_RELOC_SECTIONS * sizeof (asection *);
821 symndx_to_section = (asection **) bfd_alloc (input_bfd, amt);
822 if (!symndx_to_section)
825 symndx_to_section[RELOC_SECTION_NONE] = NULL;
826 symndx_to_section[RELOC_SECTION_TEXT] =
827 bfd_get_section_by_name (input_bfd, ".text");
828 symndx_to_section[RELOC_SECTION_RDATA] =
829 bfd_get_section_by_name (input_bfd, ".rdata");
830 symndx_to_section[RELOC_SECTION_DATA] =
831 bfd_get_section_by_name (input_bfd, ".data");
832 symndx_to_section[RELOC_SECTION_SDATA] =
833 bfd_get_section_by_name (input_bfd, ".sdata");
834 symndx_to_section[RELOC_SECTION_SBSS] =
835 bfd_get_section_by_name (input_bfd, ".sbss");
836 symndx_to_section[RELOC_SECTION_BSS] =
837 bfd_get_section_by_name (input_bfd, ".bss");
838 symndx_to_section[RELOC_SECTION_INIT] =
839 bfd_get_section_by_name (input_bfd, ".init");
840 symndx_to_section[RELOC_SECTION_LIT8] =
841 bfd_get_section_by_name (input_bfd, ".lit8");
842 symndx_to_section[RELOC_SECTION_LIT4] =
843 bfd_get_section_by_name (input_bfd, ".lit4");
844 symndx_to_section[RELOC_SECTION_XDATA] = NULL;
845 symndx_to_section[RELOC_SECTION_PDATA] = NULL;
846 symndx_to_section[RELOC_SECTION_FINI] =
847 bfd_get_section_by_name (input_bfd, ".fini");
848 symndx_to_section[RELOC_SECTION_LITA] = NULL;
849 symndx_to_section[RELOC_SECTION_ABS] = NULL;
851 ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
854 sym_hashes = ecoff_data (input_bfd)->sym_hashes;
856 gp = _bfd_get_gp_value (output_bfd);
860 gp_undefined = FALSE;
864 ext_rel = (struct external_reloc *) external_relocs;
865 ext_rel_end = ext_rel + input_section->reloc_count;
866 for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
868 struct internal_reloc int_rel;
869 bfd_boolean use_lo = FALSE;
871 reloc_howto_type *howto;
872 struct ecoff_link_hash_entry *h = NULL;
875 bfd_reloc_status_type r;
878 mips_ecoff_swap_reloc_in (input_bfd, ext_rel, &int_rel);
881 int_rel = lo_int_rel;
885 BFD_ASSERT (int_rel.r_type
886 < sizeof mips_howto_table / sizeof mips_howto_table[0]);
888 /* The REFHI reloc requires special handling. It must be followed
889 by a REFLO reloc, and the addend is formed from both relocs. */
890 if (int_rel.r_type == MIPS_R_REFHI)
892 struct external_reloc *lo_ext_rel;
894 /* As a GNU extension, permit an arbitrary number of REFHI
895 relocs before the REFLO reloc. This permits gcc to emit
896 the HI and LO relocs itself. */
897 for (lo_ext_rel = ext_rel + 1;
898 lo_ext_rel < ext_rel_end;
901 mips_ecoff_swap_reloc_in (input_bfd, lo_ext_rel,
903 if (lo_int_rel.r_type != int_rel.r_type)
907 if (lo_ext_rel < ext_rel_end
908 && lo_int_rel.r_type == MIPS_R_REFLO
909 && int_rel.r_extern == lo_int_rel.r_extern
910 && int_rel.r_symndx == lo_int_rel.r_symndx)
913 if (lo_ext_rel == ext_rel + 1)
918 howto = &mips_howto_table[int_rel.r_type];
920 if (int_rel.r_extern)
922 h = sym_hashes[int_rel.r_symndx];
923 /* If h is NULL, that means that there is a reloc against an
924 external symbol which we thought was just a debugging
925 symbol. This should not happen. */
926 if (h == (struct ecoff_link_hash_entry *) NULL)
931 if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS)
934 s = symndx_to_section[int_rel.r_symndx];
936 if (s == (asection *) NULL)
940 /* The GPREL reloc uses an addend: the difference in the GP
942 if (int_rel.r_type != MIPS_R_GPREL
943 && int_rel.r_type != MIPS_R_LITERAL)
949 (*info->callbacks->reloc_dangerous)
950 (info, _("GP relative relocation used when GP not defined"),
951 input_bfd, input_section,
952 int_rel.r_vaddr - input_section->vma);
953 /* Only give the error once per link. */
955 _bfd_set_gp_value (output_bfd, gp);
956 gp_undefined = FALSE;
958 if (! int_rel.r_extern)
960 /* This is a relocation against a section. The current
961 addend in the instruction is the difference between
962 INPUT_SECTION->vma and the GP value of INPUT_BFD. We
963 must change this to be the difference between the
964 final definition (which will end up in RELOCATION)
965 and the GP value of OUTPUT_BFD (which is in GP). */
966 addend = ecoff_data (input_bfd)->gp - gp;
968 else if (! bfd_link_relocatable (info)
969 || h->root.type == bfd_link_hash_defined
970 || h->root.type == bfd_link_hash_defweak)
972 /* This is a relocation against a defined symbol. The
973 current addend in the instruction is simply the
974 desired offset into the symbol (normally zero). We
975 are going to change this into a relocation against a
976 defined symbol, so we want the instruction to hold
977 the difference between the final definition of the
978 symbol (which will end up in RELOCATION) and the GP
979 value of OUTPUT_BFD (which is in GP). */
984 /* This is a relocation against an undefined or common
985 symbol. The current addend in the instruction is
986 simply the desired offset into the symbol (normally
987 zero). We are generating relocatable output, and we
988 aren't going to define this symbol, so we just leave
989 the instruction alone. */
994 if (bfd_link_relocatable (info))
996 /* We are generating relocatable output, and must convert
997 the existing reloc. */
998 if (int_rel.r_extern)
1000 if ((h->root.type == bfd_link_hash_defined
1001 || h->root.type == bfd_link_hash_defweak)
1002 && ! bfd_is_abs_section (h->root.u.def.section))
1006 /* This symbol is defined in the output. Convert
1007 the reloc from being against the symbol to being
1008 against the section. */
1010 /* Clear the r_extern bit. */
1011 int_rel.r_extern = 0;
1013 /* Compute a new r_symndx value. */
1014 s = h->root.u.def.section;
1015 name = bfd_get_section_name (output_bfd,
1018 int_rel.r_symndx = -1;
1022 if (strcmp (name, ".bss") == 0)
1023 int_rel.r_symndx = RELOC_SECTION_BSS;
1026 if (strcmp (name, ".data") == 0)
1027 int_rel.r_symndx = RELOC_SECTION_DATA;
1030 if (strcmp (name, ".fini") == 0)
1031 int_rel.r_symndx = RELOC_SECTION_FINI;
1034 if (strcmp (name, ".init") == 0)
1035 int_rel.r_symndx = RELOC_SECTION_INIT;
1038 if (strcmp (name, ".lit8") == 0)
1039 int_rel.r_symndx = RELOC_SECTION_LIT8;
1040 else if (strcmp (name, ".lit4") == 0)
1041 int_rel.r_symndx = RELOC_SECTION_LIT4;
1044 if (strcmp (name, ".rdata") == 0)
1045 int_rel.r_symndx = RELOC_SECTION_RDATA;
1048 if (strcmp (name, ".sdata") == 0)
1049 int_rel.r_symndx = RELOC_SECTION_SDATA;
1050 else if (strcmp (name, ".sbss") == 0)
1051 int_rel.r_symndx = RELOC_SECTION_SBSS;
1054 if (strcmp (name, ".text") == 0)
1055 int_rel.r_symndx = RELOC_SECTION_TEXT;
1059 if (int_rel.r_symndx == -1)
1062 /* Add the section VMA and the symbol value. */
1063 relocation = (h->root.u.def.value
1064 + s->output_section->vma
1065 + s->output_offset);
1067 /* For a PC relative relocation, the object file
1068 currently holds just the addend. We must adjust
1069 by the address to get the right value. */
1070 if (howto->pc_relative)
1071 relocation -= int_rel.r_vaddr - input_section->vma;
1077 /* Change the symndx value to the right one for the
1079 int_rel.r_symndx = h->indx;
1080 if (int_rel.r_symndx == -1)
1082 /* This symbol is not being written out. */
1083 (*info->callbacks->unattached_reloc)
1084 (info, h->root.root.string, input_bfd, input_section,
1085 int_rel.r_vaddr - input_section->vma);
1086 int_rel.r_symndx = 0;
1093 /* This is a relocation against a section. Adjust the
1094 value by the amount the section moved. */
1095 relocation = (s->output_section->vma
1100 relocation += addend;
1103 /* Adjust a PC relative relocation by removing the reference
1104 to the original address in the section and including the
1105 reference to the new address. */
1106 if (howto->pc_relative)
1107 relocation -= (input_section->output_section->vma
1108 + input_section->output_offset
1109 - input_section->vma);
1111 /* Adjust the contents. */
1112 if (relocation == 0)
1116 if (int_rel.r_type != MIPS_R_REFHI)
1117 r = _bfd_relocate_contents (howto, input_bfd, relocation,
1120 - input_section->vma));
1123 mips_relocate_hi (&int_rel,
1124 use_lo ? &lo_int_rel : NULL,
1125 input_bfd, input_section, contents,
1131 /* Adjust the reloc address. */
1132 int_rel.r_vaddr += (input_section->output_section->vma
1133 + input_section->output_offset
1134 - input_section->vma);
1136 /* Save the changed reloc information. */
1137 mips_ecoff_swap_reloc_out (input_bfd, &int_rel, ext_rel);
1141 /* We are producing a final executable. */
1142 if (int_rel.r_extern)
1144 /* This is a reloc against a symbol. */
1145 if (h->root.type == bfd_link_hash_defined
1146 || h->root.type == bfd_link_hash_defweak)
1150 hsec = h->root.u.def.section;
1151 relocation = (h->root.u.def.value
1152 + hsec->output_section->vma
1153 + hsec->output_offset);
1157 (*info->callbacks->undefined_symbol)
1158 (info, h->root.root.string, input_bfd, input_section,
1159 int_rel.r_vaddr - input_section->vma, TRUE);
1165 /* This is a reloc against a section. */
1166 relocation = (s->output_section->vma
1170 /* A PC relative reloc is already correct in the object
1171 file. Make it look like a pcrel_offset relocation by
1172 adding in the start address. */
1173 if (howto->pc_relative)
1174 relocation += int_rel.r_vaddr;
1177 if (int_rel.r_type != MIPS_R_REFHI)
1178 r = _bfd_final_link_relocate (howto,
1183 - input_section->vma),
1188 mips_relocate_hi (&int_rel,
1189 use_lo ? &lo_int_rel : NULL,
1190 input_bfd, input_section, contents,
1196 /* MIPS_R_JMPADDR requires peculiar overflow detection. The
1197 instruction provides a 28 bit address (the two lower bits are
1198 implicit zeroes) which is combined with the upper four bits
1199 of the instruction address. */
1200 if (r == bfd_reloc_ok
1201 && int_rel.r_type == MIPS_R_JMPADDR
1204 + (int_rel.r_extern ? 0 : s->vma))
1206 != ((input_section->output_section->vma
1207 + input_section->output_offset
1208 + (int_rel.r_vaddr - input_section->vma))
1210 r = bfd_reloc_overflow;
1212 if (r != bfd_reloc_ok)
1217 case bfd_reloc_outofrange:
1219 case bfd_reloc_overflow:
1223 if (int_rel.r_extern)
1226 name = bfd_section_name (input_bfd, s);
1227 (*info->callbacks->reloc_overflow)
1228 (info, (h ? &h->root : NULL), name, howto->name,
1229 (bfd_vma) 0, input_bfd, input_section,
1230 int_rel.r_vaddr - input_section->vma);
1240 /* This is the ECOFF backend structure. The backend field of the
1241 target vector points to this. */
1243 static const struct ecoff_backend_data mips_ecoff_backend_data =
1245 /* COFF backend structure. */
1247 (void (*) (bfd *,void *,int,int,int,int,void *)) (void (*)) bfd_void, /* aux_in */
1248 (void (*) (bfd *,void *,void *)) (void (*)) bfd_void, /* sym_in */
1249 (void (*) (bfd *,void *,void *)) (void (*)) bfd_void, /* lineno_in */
1250 (unsigned (*) (bfd *,void *,int,int,int,int,void *)) (unsigned (*)) bfd_0u,/*aux_out*/
1251 (unsigned (*) (bfd *,void *,void *)) (unsigned (*)) bfd_0u, /* sym_out */
1252 (unsigned (*) (bfd *,void *,void *)) (unsigned (*)) bfd_0u, /* lineno_out */
1253 (unsigned (*) (bfd *,void *,void *)) (unsigned (*)) bfd_0u, /* reloc_out */
1254 mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
1255 mips_ecoff_swap_scnhdr_out,
1256 FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, TRUE,
1257 ECOFF_NO_LONG_SECTION_NAMES, 4, FALSE, 2, 32768,
1258 mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
1259 mips_ecoff_swap_scnhdr_in, NULL,
1260 mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
1261 _bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
1262 _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
1263 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1266 /* Supported architecture. */
1268 /* Initial portion of armap string. */
1270 /* The page boundary used to align sections in a demand-paged
1271 executable file. E.g., 0x1000. */
1273 /* TRUE if the .rdata section is part of the text segment, as on the
1274 Alpha. FALSE if .rdata is part of the data segment, as on the
1277 /* Bitsize of constructor entries. */
1279 /* Reloc to use for constructor entries. */
1280 &mips_howto_table[MIPS_R_REFWORD],
1282 /* Symbol table magic number. */
1284 /* Alignment of debugging information. E.g., 4. */
1286 /* Sizes of external symbolic information. */
1287 sizeof (struct hdr_ext),
1288 sizeof (struct dnr_ext),
1289 sizeof (struct pdr_ext),
1290 sizeof (struct sym_ext),
1291 sizeof (struct opt_ext),
1292 sizeof (struct fdr_ext),
1293 sizeof (struct rfd_ext),
1294 sizeof (struct ext_ext),
1295 /* Functions to swap in external symbolic data. */
1304 _bfd_ecoff_swap_tir_in,
1305 _bfd_ecoff_swap_rndx_in,
1306 /* Functions to swap out external symbolic data. */
1315 _bfd_ecoff_swap_tir_out,
1316 _bfd_ecoff_swap_rndx_out,
1317 /* Function to read in symbolic data. */
1318 _bfd_ecoff_slurp_symbolic_info
1320 /* External reloc size. */
1322 /* Reloc swapping functions. */
1323 mips_ecoff_swap_reloc_in,
1324 mips_ecoff_swap_reloc_out,
1325 /* Backend reloc tweaking. */
1326 mips_adjust_reloc_in,
1327 mips_adjust_reloc_out,
1328 /* Relocate section contents while linking. */
1329 mips_relocate_section,
1330 /* Do final adjustments to filehdr and aouthdr. */
1332 /* Read an element from an archive at a given file position. */
1333 _bfd_get_elt_at_filepos
1336 /* Looking up a reloc type is MIPS specific. */
1337 #define _bfd_ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
1338 #define _bfd_ecoff_bfd_reloc_name_lookup mips_bfd_reloc_name_lookup
1340 /* Getting relocated section contents is generic. */
1341 #define _bfd_ecoff_bfd_get_relocated_section_contents \
1342 bfd_generic_get_relocated_section_contents
1344 /* Handling file windows is generic. */
1345 #define _bfd_ecoff_get_section_contents_in_window \
1346 _bfd_generic_get_section_contents_in_window
1348 /* Relaxing sections is MIPS specific. */
1349 #define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
1351 /* GC of sections is not done. */
1352 #define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
1354 /* Input section flags is not implemented. */
1355 #define _bfd_ecoff_bfd_lookup_section_flags bfd_generic_lookup_section_flags
1357 /* Merging of sections is not done. */
1358 #define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections
1360 #define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section
1361 #define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
1362 #define _bfd_ecoff_section_already_linked \
1363 _bfd_coff_section_already_linked
1364 #define _bfd_ecoff_bfd_define_common_symbol bfd_generic_define_common_symbol
1365 #define _bfd_ecoff_bfd_define_start_stop bfd_generic_define_start_stop
1366 #define _bfd_ecoff_set_reloc _bfd_generic_set_reloc
1368 extern const bfd_target mips_ecoff_be_vec;
1370 const bfd_target mips_ecoff_le_vec =
1372 "ecoff-littlemips", /* name */
1373 bfd_target_ecoff_flavour,
1374 BFD_ENDIAN_LITTLE, /* data byte order is little */
1375 BFD_ENDIAN_LITTLE, /* header byte order is little */
1377 (HAS_RELOC | EXEC_P | /* object flags */
1378 HAS_LINENO | HAS_DEBUG |
1379 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1381 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1382 0, /* leading underscore */
1383 ' ', /* ar_pad_char */
1384 15, /* ar_max_namelen */
1385 0, /* match priority. */
1386 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1387 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1388 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1389 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1390 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1391 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
1393 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1394 bfd_generic_archive_p, _bfd_dummy_target},
1395 {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
1396 _bfd_generic_mkarchive, bfd_false},
1397 {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
1398 _bfd_write_archive_contents, bfd_false},
1400 BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
1401 BFD_JUMP_TABLE_COPY (_bfd_ecoff),
1402 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1403 BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
1404 BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
1405 BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
1406 BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
1407 BFD_JUMP_TABLE_LINK (_bfd_ecoff),
1408 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1410 & mips_ecoff_be_vec,
1412 & mips_ecoff_backend_data
1415 const bfd_target mips_ecoff_be_vec =
1417 "ecoff-bigmips", /* name */
1418 bfd_target_ecoff_flavour,
1419 BFD_ENDIAN_BIG, /* data byte order is big */
1420 BFD_ENDIAN_BIG, /* header byte order is big */
1422 (HAS_RELOC | EXEC_P | /* object flags */
1423 HAS_LINENO | HAS_DEBUG |
1424 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1426 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1427 0, /* leading underscore */
1428 ' ', /* ar_pad_char */
1429 15, /* ar_max_namelen */
1430 0, /* match priority. */
1431 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1432 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1433 bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1434 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1435 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1436 bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1437 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1438 bfd_generic_archive_p, _bfd_dummy_target},
1439 {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
1440 _bfd_generic_mkarchive, bfd_false},
1441 {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
1442 _bfd_write_archive_contents, bfd_false},
1444 BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
1445 BFD_JUMP_TABLE_COPY (_bfd_ecoff),
1446 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1447 BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
1448 BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
1449 BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
1450 BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
1451 BFD_JUMP_TABLE_LINK (_bfd_ecoff),
1452 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1454 & mips_ecoff_le_vec,
1456 & mips_ecoff_backend_data
1459 const bfd_target mips_ecoff_bele_vec =
1461 "ecoff-biglittlemips", /* name */
1462 bfd_target_ecoff_flavour,
1463 BFD_ENDIAN_LITTLE, /* data byte order is little */
1464 BFD_ENDIAN_BIG, /* header byte order is big */
1466 (HAS_RELOC | EXEC_P | /* object flags */
1467 HAS_LINENO | HAS_DEBUG |
1468 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1470 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1471 0, /* leading underscore */
1472 ' ', /* ar_pad_char */
1473 15, /* ar_max_namelen */
1474 0, /* match priority. */
1475 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1476 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1477 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1478 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1479 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1480 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
1482 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1483 bfd_generic_archive_p, _bfd_dummy_target},
1484 {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
1485 _bfd_generic_mkarchive, bfd_false},
1486 {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
1487 _bfd_write_archive_contents, bfd_false},
1489 BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
1490 BFD_JUMP_TABLE_COPY (_bfd_ecoff),
1491 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1492 BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
1493 BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
1494 BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
1495 BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
1496 BFD_JUMP_TABLE_LINK (_bfd_ecoff),
1497 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1501 & mips_ecoff_backend_data