1 /* BFD back-end for MIPS Extended-Coff files.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009
4 Free Software Foundation, Inc.
5 Original version by Per Bothner.
6 Full support added by Ian Lance Taylor, ian@cygnus.com.
8 This file is part of BFD, the Binary File Descriptor library.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23 MA 02110-1301, USA. */
29 #include "coff/internal.h"
31 #include "coff/symconst.h"
32 #include "coff/ecoff.h"
33 #include "coff/mips.h"
37 /* Prototypes for static functions. */
39 static bfd_boolean mips_ecoff_bad_format_hook
40 PARAMS ((bfd *abfd, PTR filehdr));
41 static void mips_ecoff_swap_reloc_in
42 PARAMS ((bfd *, PTR, struct internal_reloc *));
43 static void mips_ecoff_swap_reloc_out
44 PARAMS ((bfd *, const struct internal_reloc *, PTR));
45 static void mips_adjust_reloc_in
46 PARAMS ((bfd *, const struct internal_reloc *, arelent *));
47 static void mips_adjust_reloc_out
48 PARAMS ((bfd *, const arelent *, struct internal_reloc *));
49 static bfd_reloc_status_type mips_generic_reloc
50 PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
51 asection *section, bfd *output_bfd, char **error));
52 static bfd_reloc_status_type mips_refhi_reloc
53 PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
54 asection *section, bfd *output_bfd, char **error));
55 static bfd_reloc_status_type mips_reflo_reloc
56 PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
57 asection *section, bfd *output_bfd, char **error));
58 static bfd_reloc_status_type mips_gprel_reloc
59 PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
60 asection *section, bfd *output_bfd, char **error));
61 static void mips_relocate_hi
62 PARAMS ((struct internal_reloc *refhi, struct internal_reloc *reflo,
63 bfd *input_bfd, asection *input_section, bfd_byte *contents,
65 static bfd_boolean mips_relocate_section
66 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, PTR));
67 static reloc_howto_type *mips_bfd_reloc_type_lookup
68 PARAMS ((bfd *, bfd_reloc_code_real_type));
70 /* ECOFF has COFF sections, but the debugging information is stored in
71 a completely different format. ECOFF targets use some of the
72 swapping routines from coffswap.h, and some of the generic COFF
73 routines in coffgen.c, but, unlike the real COFF targets, do not
74 use coffcode.h itself.
76 Get the generic COFF swapping routines, except for the reloc,
77 symbol, and lineno ones. Give them ECOFF names. */
79 #define NO_COFF_RELOCS
80 #define NO_COFF_SYMBOLS
81 #define NO_COFF_LINENOS
82 #define coff_swap_filehdr_in mips_ecoff_swap_filehdr_in
83 #define coff_swap_filehdr_out mips_ecoff_swap_filehdr_out
84 #define coff_swap_aouthdr_in mips_ecoff_swap_aouthdr_in
85 #define coff_swap_aouthdr_out mips_ecoff_swap_aouthdr_out
86 #define coff_swap_scnhdr_in mips_ecoff_swap_scnhdr_in
87 #define coff_swap_scnhdr_out mips_ecoff_swap_scnhdr_out
91 /* Get the ECOFF swapping routines. */
93 #include "ecoffswap.h"
95 /* How to process the various relocs types. */
97 static reloc_howto_type mips_howto_table[] =
99 /* Reloc type 0 is ignored. The reloc reading code ensures that
100 this is a reference to the .abs section, which will cause
101 bfd_perform_relocation to do nothing. */
102 HOWTO (MIPS_R_IGNORE, /* type */
104 0, /* size (0 = byte, 1 = short, 2 = long) */
106 FALSE, /* pc_relative */
108 complain_overflow_dont, /* complain_on_overflow */
109 0, /* special_function */
111 FALSE, /* partial_inplace */
114 FALSE), /* pcrel_offset */
116 /* A 16 bit reference to a symbol, normally from a data section. */
117 HOWTO (MIPS_R_REFHALF, /* type */
119 1, /* size (0 = byte, 1 = short, 2 = long) */
121 FALSE, /* pc_relative */
123 complain_overflow_bitfield, /* complain_on_overflow */
124 mips_generic_reloc, /* special_function */
125 "REFHALF", /* name */
126 TRUE, /* partial_inplace */
127 0xffff, /* src_mask */
128 0xffff, /* dst_mask */
129 FALSE), /* pcrel_offset */
131 /* A 32 bit reference to a symbol, normally from a data section. */
132 HOWTO (MIPS_R_REFWORD, /* type */
134 2, /* size (0 = byte, 1 = short, 2 = long) */
136 FALSE, /* pc_relative */
138 complain_overflow_bitfield, /* complain_on_overflow */
139 mips_generic_reloc, /* special_function */
140 "REFWORD", /* name */
141 TRUE, /* partial_inplace */
142 0xffffffff, /* src_mask */
143 0xffffffff, /* dst_mask */
144 FALSE), /* pcrel_offset */
146 /* A 26 bit absolute jump address. */
147 HOWTO (MIPS_R_JMPADDR, /* type */
149 2, /* size (0 = byte, 1 = short, 2 = long) */
151 FALSE, /* pc_relative */
153 complain_overflow_dont, /* complain_on_overflow */
154 /* This needs complex overflow
155 detection, because the upper four
156 bits must match the PC. */
157 mips_generic_reloc, /* special_function */
158 "JMPADDR", /* name */
159 TRUE, /* partial_inplace */
160 0x3ffffff, /* src_mask */
161 0x3ffffff, /* dst_mask */
162 FALSE), /* pcrel_offset */
164 /* The high 16 bits of a symbol value. Handled by the function
166 HOWTO (MIPS_R_REFHI, /* type */
168 2, /* size (0 = byte, 1 = short, 2 = long) */
170 FALSE, /* pc_relative */
172 complain_overflow_bitfield, /* complain_on_overflow */
173 mips_refhi_reloc, /* special_function */
175 TRUE, /* partial_inplace */
176 0xffff, /* src_mask */
177 0xffff, /* dst_mask */
178 FALSE), /* pcrel_offset */
180 /* The low 16 bits of a symbol value. */
181 HOWTO (MIPS_R_REFLO, /* type */
183 2, /* size (0 = byte, 1 = short, 2 = long) */
185 FALSE, /* pc_relative */
187 complain_overflow_dont, /* complain_on_overflow */
188 mips_reflo_reloc, /* special_function */
190 TRUE, /* partial_inplace */
191 0xffff, /* src_mask */
192 0xffff, /* dst_mask */
193 FALSE), /* pcrel_offset */
195 /* A reference to an offset from the gp register. Handled by the
196 function mips_gprel_reloc. */
197 HOWTO (MIPS_R_GPREL, /* type */
199 2, /* size (0 = byte, 1 = short, 2 = long) */
201 FALSE, /* pc_relative */
203 complain_overflow_signed, /* complain_on_overflow */
204 mips_gprel_reloc, /* special_function */
206 TRUE, /* partial_inplace */
207 0xffff, /* src_mask */
208 0xffff, /* dst_mask */
209 FALSE), /* pcrel_offset */
211 /* A reference to a literal using an offset from the gp register.
212 Handled by the function mips_gprel_reloc. */
213 HOWTO (MIPS_R_LITERAL, /* type */
215 2, /* size (0 = byte, 1 = short, 2 = long) */
217 FALSE, /* pc_relative */
219 complain_overflow_signed, /* complain_on_overflow */
220 mips_gprel_reloc, /* special_function */
221 "LITERAL", /* name */
222 TRUE, /* partial_inplace */
223 0xffff, /* src_mask */
224 0xffff, /* dst_mask */
225 FALSE), /* pcrel_offset */
232 /* FIXME: This relocation is used (internally only) to represent branches
233 when assembling. It should never appear in output files, and
234 be removed. (It used to be used for embedded-PIC support.) */
235 HOWTO (MIPS_R_PCREL16, /* type */
237 2, /* size (0 = byte, 1 = short, 2 = long) */
239 TRUE, /* pc_relative */
241 complain_overflow_signed, /* complain_on_overflow */
242 mips_generic_reloc, /* special_function */
243 "PCREL16", /* name */
244 TRUE, /* partial_inplace */
245 0xffff, /* src_mask */
246 0xffff, /* dst_mask */
247 TRUE), /* pcrel_offset */
250 #define MIPS_HOWTO_COUNT \
251 (sizeof mips_howto_table / sizeof mips_howto_table[0])
253 /* See whether the magic number matches. */
256 mips_ecoff_bad_format_hook (abfd, filehdr)
260 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
262 switch (internal_f->f_magic)
265 /* I don't know what endianness this implies. */
269 case MIPS_MAGIC_BIG2:
270 case MIPS_MAGIC_BIG3:
271 return bfd_big_endian (abfd);
273 case MIPS_MAGIC_LITTLE:
274 case MIPS_MAGIC_LITTLE2:
275 case MIPS_MAGIC_LITTLE3:
276 return bfd_little_endian (abfd);
283 /* Reloc handling. MIPS ECOFF relocs are packed into 8 bytes in
284 external form. They use a bit which indicates whether the symbol
287 /* Swap a reloc in. */
290 mips_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
293 struct internal_reloc *intern;
295 const RELOC *ext = (RELOC *) ext_ptr;
297 intern->r_vaddr = H_GET_32 (abfd, ext->r_vaddr);
298 if (bfd_header_big_endian (abfd))
300 intern->r_symndx = (((int) ext->r_bits[0]
301 << RELOC_BITS0_SYMNDX_SH_LEFT_BIG)
302 | ((int) ext->r_bits[1]
303 << RELOC_BITS1_SYMNDX_SH_LEFT_BIG)
304 | ((int) ext->r_bits[2]
305 << RELOC_BITS2_SYMNDX_SH_LEFT_BIG));
306 intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_BIG)
307 >> RELOC_BITS3_TYPE_SH_BIG);
308 intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_BIG) != 0;
312 intern->r_symndx = (((int) ext->r_bits[0]
313 << RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE)
314 | ((int) ext->r_bits[1]
315 << RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE)
316 | ((int) ext->r_bits[2]
317 << RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE));
318 intern->r_type = (((ext->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
319 >> RELOC_BITS3_TYPE_SH_LITTLE)
320 | ((ext->r_bits[3] & RELOC_BITS3_TYPEHI_LITTLE)
321 << RELOC_BITS3_TYPEHI_SH_LITTLE));
322 intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0;
326 /* Swap a reloc out. */
329 mips_ecoff_swap_reloc_out (abfd, intern, dst)
331 const struct internal_reloc *intern;
334 RELOC *ext = (RELOC *) dst;
337 BFD_ASSERT (intern->r_extern
338 || (intern->r_symndx >= 0 && intern->r_symndx <= 12));
340 r_symndx = intern->r_symndx;
342 H_PUT_32 (abfd, intern->r_vaddr, ext->r_vaddr);
343 if (bfd_header_big_endian (abfd))
345 ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_BIG;
346 ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_BIG;
347 ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_BIG;
348 ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_BIG)
349 & RELOC_BITS3_TYPE_BIG)
350 | (intern->r_extern ? RELOC_BITS3_EXTERN_BIG : 0));
354 ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE;
355 ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE;
356 ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE;
357 ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_LITTLE)
358 & RELOC_BITS3_TYPE_LITTLE)
359 | ((intern->r_type >> RELOC_BITS3_TYPEHI_SH_LITTLE
360 & RELOC_BITS3_TYPEHI_LITTLE))
361 | (intern->r_extern ? RELOC_BITS3_EXTERN_LITTLE : 0));
365 /* Finish canonicalizing a reloc. Part of this is generic to all
366 ECOFF targets, and that part is in ecoff.c. The rest is done in
367 this backend routine. It must fill in the howto field. */
370 mips_adjust_reloc_in (abfd, intern, rptr)
372 const struct internal_reloc *intern;
375 if (intern->r_type > MIPS_R_PCREL16)
378 if (! intern->r_extern
379 && (intern->r_type == MIPS_R_GPREL
380 || intern->r_type == MIPS_R_LITERAL))
381 rptr->addend += ecoff_data (abfd)->gp;
383 /* If the type is MIPS_R_IGNORE, make sure this is a reference to
384 the absolute section so that the reloc is ignored. */
385 if (intern->r_type == MIPS_R_IGNORE)
386 rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
388 rptr->howto = &mips_howto_table[intern->r_type];
391 /* Make any adjustments needed to a reloc before writing it out. None
392 are needed for MIPS. */
395 mips_adjust_reloc_out (abfd, rel, intern)
396 bfd *abfd ATTRIBUTE_UNUSED;
397 const arelent *rel ATTRIBUTE_UNUSED;
398 struct internal_reloc *intern ATTRIBUTE_UNUSED;
402 /* ECOFF relocs are either against external symbols, or against
403 sections. If we are producing relocatable output, and the reloc
404 is against an external symbol, and nothing has given us any
405 additional addend, the resulting reloc will also be against the
406 same symbol. In such a case, we don't want to change anything
407 about the way the reloc is handled, since it will all be done at
408 final link time. Rather than put special case code into
409 bfd_perform_relocation, all the reloc types use this howto
410 function. It just short circuits the reloc if producing
411 relocatable output against an external symbol. */
413 static bfd_reloc_status_type
414 mips_generic_reloc (abfd,
421 bfd *abfd ATTRIBUTE_UNUSED;
422 arelent *reloc_entry;
424 PTR data ATTRIBUTE_UNUSED;
425 asection *input_section;
427 char **error_message ATTRIBUTE_UNUSED;
429 if (output_bfd != (bfd *) NULL
430 && (symbol->flags & BSF_SECTION_SYM) == 0
431 && reloc_entry->addend == 0)
433 reloc_entry->address += input_section->output_offset;
437 return bfd_reloc_continue;
440 /* Do a REFHI relocation. This has to be done in combination with a
441 REFLO reloc, because there is a carry from the REFLO to the REFHI.
442 Here we just save the information we need; we do the actual
443 relocation when we see the REFLO. MIPS ECOFF requires that the
444 REFLO immediately follow the REFHI. As a GNU extension, we permit
445 an arbitrary number of HI relocs to be associated with a single LO
446 reloc. This extension permits gcc to output the HI and LO relocs
451 struct mips_hi *next;
456 /* FIXME: This should not be a static variable. */
458 static struct mips_hi *mips_refhi_list;
460 static bfd_reloc_status_type
461 mips_refhi_reloc (abfd,
468 bfd *abfd ATTRIBUTE_UNUSED;
469 arelent *reloc_entry;
472 asection *input_section;
474 char **error_message ATTRIBUTE_UNUSED;
476 bfd_reloc_status_type ret;
480 /* If we're relocating, and this an external symbol, we don't want
481 to change anything. */
482 if (output_bfd != (bfd *) NULL
483 && (symbol->flags & BSF_SECTION_SYM) == 0
484 && reloc_entry->addend == 0)
486 reloc_entry->address += input_section->output_offset;
491 if (bfd_is_und_section (symbol->section)
492 && output_bfd == (bfd *) NULL)
493 ret = bfd_reloc_undefined;
495 if (bfd_is_com_section (symbol->section))
498 relocation = symbol->value;
500 relocation += symbol->section->output_section->vma;
501 relocation += symbol->section->output_offset;
502 relocation += reloc_entry->addend;
504 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
505 return bfd_reloc_outofrange;
507 /* Save the information, and let REFLO do the actual relocation. */
508 n = (struct mips_hi *) bfd_malloc ((bfd_size_type) sizeof *n);
510 return bfd_reloc_outofrange;
511 n->addr = (bfd_byte *) data + reloc_entry->address;
512 n->addend = relocation;
513 n->next = mips_refhi_list;
516 if (output_bfd != (bfd *) NULL)
517 reloc_entry->address += input_section->output_offset;
522 /* Do a REFLO relocation. This is a straightforward 16 bit inplace
523 relocation; this function exists in order to do the REFHI
524 relocation described above. */
526 static bfd_reloc_status_type
527 mips_reflo_reloc (abfd,
535 arelent *reloc_entry;
538 asection *input_section;
540 char **error_message;
542 if (mips_refhi_list != NULL)
552 struct mips_hi *next;
554 /* Do the REFHI relocation. Note that we actually don't
555 need to know anything about the REFLO itself, except
556 where to find the low 16 bits of the addend needed by the
558 insn = bfd_get_32 (abfd, l->addr);
559 vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
561 val = ((insn & 0xffff) << 16) + vallo;
564 /* The low order 16 bits are always treated as a signed
565 value. Therefore, a negative value in the low order bits
566 requires an adjustment in the high order bits. We need
567 to make this adjustment in two ways: once for the bits we
568 took from the data, and once for the bits we are putting
569 back in to the data. */
570 if ((vallo & 0x8000) != 0)
572 if ((val & 0x8000) != 0)
575 insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
576 bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
583 mips_refhi_list = NULL;
586 /* Now do the REFLO reloc in the usual way. */
587 return mips_generic_reloc (abfd, reloc_entry, symbol, data,
588 input_section, output_bfd, error_message);
591 /* Do a GPREL relocation. This is a 16 bit value which must become
592 the offset from the gp register. */
594 static bfd_reloc_status_type
595 mips_gprel_reloc (abfd,
603 arelent *reloc_entry;
606 asection *input_section;
608 char **error_message;
610 bfd_boolean relocatable;
616 /* If we're relocating, and this is an external symbol with no
617 addend, we don't want to change anything. We will only have an
618 addend if this is a newly created reloc, not read from an ECOFF
620 if (output_bfd != (bfd *) NULL
621 && (symbol->flags & BSF_SECTION_SYM) == 0
622 && reloc_entry->addend == 0)
624 reloc_entry->address += input_section->output_offset;
628 if (output_bfd != (bfd *) NULL)
633 output_bfd = symbol->section->output_section->owner;
636 if (bfd_is_und_section (symbol->section) && ! relocatable)
637 return bfd_reloc_undefined;
639 /* We have to figure out the gp value, so that we can adjust the
640 symbol value correctly. We look up the symbol _gp in the output
641 BFD. If we can't find it, we're stuck. We cache it in the ECOFF
642 target data. We don't need to adjust the symbol value for an
643 external symbol if we are producing relocatable output. */
644 gp = _bfd_get_gp_value (output_bfd);
647 || (symbol->flags & BSF_SECTION_SYM) != 0))
651 /* Make up a value. */
652 gp = symbol->section->output_section->vma + 0x4000;
653 _bfd_set_gp_value (output_bfd, gp);
661 count = bfd_get_symcount (output_bfd);
662 sym = bfd_get_outsymbols (output_bfd);
664 if (sym == (asymbol **) NULL)
668 for (i = 0; i < count; i++, sym++)
670 register const char *name;
672 name = bfd_asymbol_name (*sym);
673 if (*name == '_' && strcmp (name, "_gp") == 0)
675 gp = bfd_asymbol_value (*sym);
676 _bfd_set_gp_value (output_bfd, gp);
684 /* Only get the error once. */
686 _bfd_set_gp_value (output_bfd, gp);
688 (char *) _("GP relative relocation when _gp not defined");
689 return bfd_reloc_dangerous;
694 if (bfd_is_com_section (symbol->section))
697 relocation = symbol->value;
699 relocation += symbol->section->output_section->vma;
700 relocation += symbol->section->output_offset;
702 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
703 return bfd_reloc_outofrange;
705 insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
707 /* Set val to the offset into the section or symbol. */
708 val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;
712 /* Adjust val for the final section location and GP value. If we
713 are producing relocatable output, we don't want to do this for
714 an external symbol. */
716 || (symbol->flags & BSF_SECTION_SYM) != 0)
717 val += relocation - gp;
719 insn = (insn &~ (unsigned) 0xffff) | (val & 0xffff);
720 bfd_put_32 (abfd, (bfd_vma) insn, (bfd_byte *) data + reloc_entry->address);
723 reloc_entry->address += input_section->output_offset;
725 /* Make sure it fit in 16 bits. */
726 if ((long) val >= 0x8000 || (long) val < -0x8000)
727 return bfd_reloc_overflow;
732 /* Get the howto structure for a generic reloc type. */
734 static reloc_howto_type *
735 mips_bfd_reloc_type_lookup (abfd, code)
736 bfd *abfd ATTRIBUTE_UNUSED;
737 bfd_reloc_code_real_type code;
744 mips_type = MIPS_R_REFHALF;
748 mips_type = MIPS_R_REFWORD;
750 case BFD_RELOC_MIPS_JMP:
751 mips_type = MIPS_R_JMPADDR;
753 case BFD_RELOC_HI16_S:
754 mips_type = MIPS_R_REFHI;
757 mips_type = MIPS_R_REFLO;
759 case BFD_RELOC_GPREL16:
760 mips_type = MIPS_R_GPREL;
762 case BFD_RELOC_MIPS_LITERAL:
763 mips_type = MIPS_R_LITERAL;
765 case BFD_RELOC_16_PCREL_S2:
766 mips_type = MIPS_R_PCREL16;
769 return (reloc_howto_type *) NULL;
772 return &mips_howto_table[mips_type];
775 static reloc_howto_type *
776 mips_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
782 i < sizeof (mips_howto_table) / sizeof (mips_howto_table[0]);
784 if (mips_howto_table[i].name != NULL
785 && strcasecmp (mips_howto_table[i].name, r_name) == 0)
786 return &mips_howto_table[i];
791 /* A helper routine for mips_relocate_section which handles the REFHI
792 relocations. The REFHI relocation must be followed by a REFLO
793 relocation, and the addend used is formed from the addends of both
797 mips_relocate_hi (refhi, reflo, input_bfd, input_section, contents,
799 struct internal_reloc *refhi;
800 struct internal_reloc *reflo;
802 asection *input_section;
813 insn = bfd_get_32 (input_bfd,
814 contents + refhi->r_vaddr - input_section->vma);
818 vallo = (bfd_get_32 (input_bfd,
819 contents + reflo->r_vaddr - input_section->vma)
822 val = ((insn & 0xffff) << 16) + vallo;
825 /* The low order 16 bits are always treated as a signed value.
826 Therefore, a negative value in the low order bits requires an
827 adjustment in the high order bits. We need to make this
828 adjustment in two ways: once for the bits we took from the data,
829 and once for the bits we are putting back in to the data. */
830 if ((vallo & 0x8000) != 0)
833 if ((val & 0x8000) != 0)
836 insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
837 bfd_put_32 (input_bfd, (bfd_vma) insn,
838 contents + refhi->r_vaddr - input_section->vma);
841 /* Relocate a section while linking a MIPS ECOFF file. */
844 mips_relocate_section (output_bfd, info, input_bfd, input_section,
845 contents, external_relocs)
847 struct bfd_link_info *info;
849 asection *input_section;
853 asection **symndx_to_section;
854 struct ecoff_link_hash_entry **sym_hashes;
856 bfd_boolean gp_undefined;
857 struct external_reloc *ext_rel;
858 struct external_reloc *ext_rel_end;
861 struct internal_reloc lo_int_rel;
864 BFD_ASSERT (input_bfd->xvec->byteorder
865 == output_bfd->xvec->byteorder);
867 /* We keep a table mapping the symndx found in an internal reloc to
868 the appropriate section. This is faster than looking up the
869 section by name each time. */
870 symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
871 if (symndx_to_section == (asection **) NULL)
873 amt = NUM_RELOC_SECTIONS * sizeof (asection *);
874 symndx_to_section = (asection **) bfd_alloc (input_bfd, amt);
875 if (!symndx_to_section)
878 symndx_to_section[RELOC_SECTION_NONE] = NULL;
879 symndx_to_section[RELOC_SECTION_TEXT] =
880 bfd_get_section_by_name (input_bfd, ".text");
881 symndx_to_section[RELOC_SECTION_RDATA] =
882 bfd_get_section_by_name (input_bfd, ".rdata");
883 symndx_to_section[RELOC_SECTION_DATA] =
884 bfd_get_section_by_name (input_bfd, ".data");
885 symndx_to_section[RELOC_SECTION_SDATA] =
886 bfd_get_section_by_name (input_bfd, ".sdata");
887 symndx_to_section[RELOC_SECTION_SBSS] =
888 bfd_get_section_by_name (input_bfd, ".sbss");
889 symndx_to_section[RELOC_SECTION_BSS] =
890 bfd_get_section_by_name (input_bfd, ".bss");
891 symndx_to_section[RELOC_SECTION_INIT] =
892 bfd_get_section_by_name (input_bfd, ".init");
893 symndx_to_section[RELOC_SECTION_LIT8] =
894 bfd_get_section_by_name (input_bfd, ".lit8");
895 symndx_to_section[RELOC_SECTION_LIT4] =
896 bfd_get_section_by_name (input_bfd, ".lit4");
897 symndx_to_section[RELOC_SECTION_XDATA] = NULL;
898 symndx_to_section[RELOC_SECTION_PDATA] = NULL;
899 symndx_to_section[RELOC_SECTION_FINI] =
900 bfd_get_section_by_name (input_bfd, ".fini");
901 symndx_to_section[RELOC_SECTION_LITA] = NULL;
902 symndx_to_section[RELOC_SECTION_ABS] = NULL;
904 ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
907 sym_hashes = ecoff_data (input_bfd)->sym_hashes;
909 gp = _bfd_get_gp_value (output_bfd);
913 gp_undefined = FALSE;
917 ext_rel = (struct external_reloc *) external_relocs;
918 ext_rel_end = ext_rel + input_section->reloc_count;
919 for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
921 struct internal_reloc int_rel;
922 bfd_boolean use_lo = FALSE;
924 reloc_howto_type *howto;
925 struct ecoff_link_hash_entry *h = NULL;
928 bfd_reloc_status_type r;
931 mips_ecoff_swap_reloc_in (input_bfd, (PTR) ext_rel, &int_rel);
934 int_rel = lo_int_rel;
938 BFD_ASSERT (int_rel.r_type
939 < sizeof mips_howto_table / sizeof mips_howto_table[0]);
941 /* The REFHI reloc requires special handling. It must be followed
942 by a REFLO reloc, and the addend is formed from both relocs. */
943 if (int_rel.r_type == MIPS_R_REFHI)
945 struct external_reloc *lo_ext_rel;
947 /* As a GNU extension, permit an arbitrary number of REFHI
948 relocs before the REFLO reloc. This permits gcc to emit
949 the HI and LO relocs itself. */
950 for (lo_ext_rel = ext_rel + 1;
951 lo_ext_rel < ext_rel_end;
954 mips_ecoff_swap_reloc_in (input_bfd, (PTR) lo_ext_rel,
956 if (lo_int_rel.r_type != int_rel.r_type)
960 if (lo_ext_rel < ext_rel_end
961 && lo_int_rel.r_type == MIPS_R_REFLO
962 && int_rel.r_extern == lo_int_rel.r_extern
963 && int_rel.r_symndx == lo_int_rel.r_symndx)
966 if (lo_ext_rel == ext_rel + 1)
971 howto = &mips_howto_table[int_rel.r_type];
973 if (int_rel.r_extern)
975 h = sym_hashes[int_rel.r_symndx];
976 /* If h is NULL, that means that there is a reloc against an
977 external symbol which we thought was just a debugging
978 symbol. This should not happen. */
979 if (h == (struct ecoff_link_hash_entry *) NULL)
984 if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS)
987 s = symndx_to_section[int_rel.r_symndx];
989 if (s == (asection *) NULL)
993 /* The GPREL reloc uses an addend: the difference in the GP
995 if (int_rel.r_type != MIPS_R_GPREL
996 && int_rel.r_type != MIPS_R_LITERAL)
1002 if (! ((*info->callbacks->reloc_dangerous)
1003 (info, _("GP relative relocation used when GP not defined"),
1004 input_bfd, input_section,
1005 int_rel.r_vaddr - input_section->vma)))
1007 /* Only give the error once per link. */
1009 _bfd_set_gp_value (output_bfd, gp);
1010 gp_undefined = FALSE;
1012 if (! int_rel.r_extern)
1014 /* This is a relocation against a section. The current
1015 addend in the instruction is the difference between
1016 INPUT_SECTION->vma and the GP value of INPUT_BFD. We
1017 must change this to be the difference between the
1018 final definition (which will end up in RELOCATION)
1019 and the GP value of OUTPUT_BFD (which is in GP). */
1020 addend = ecoff_data (input_bfd)->gp - gp;
1022 else if (! info->relocatable
1023 || h->root.type == bfd_link_hash_defined
1024 || h->root.type == bfd_link_hash_defweak)
1026 /* This is a relocation against a defined symbol. The
1027 current addend in the instruction is simply the
1028 desired offset into the symbol (normally zero). We
1029 are going to change this into a relocation against a
1030 defined symbol, so we want the instruction to hold
1031 the difference between the final definition of the
1032 symbol (which will end up in RELOCATION) and the GP
1033 value of OUTPUT_BFD (which is in GP). */
1038 /* This is a relocation against an undefined or common
1039 symbol. The current addend in the instruction is
1040 simply the desired offset into the symbol (normally
1041 zero). We are generating relocatable output, and we
1042 aren't going to define this symbol, so we just leave
1043 the instruction alone. */
1048 if (info->relocatable)
1050 /* We are generating relocatable output, and must convert
1051 the existing reloc. */
1052 if (int_rel.r_extern)
1054 if ((h->root.type == bfd_link_hash_defined
1055 || h->root.type == bfd_link_hash_defweak)
1056 && ! bfd_is_abs_section (h->root.u.def.section))
1060 /* This symbol is defined in the output. Convert
1061 the reloc from being against the symbol to being
1062 against the section. */
1064 /* Clear the r_extern bit. */
1065 int_rel.r_extern = 0;
1067 /* Compute a new r_symndx value. */
1068 s = h->root.u.def.section;
1069 name = bfd_get_section_name (output_bfd,
1072 int_rel.r_symndx = -1;
1076 if (strcmp (name, ".bss") == 0)
1077 int_rel.r_symndx = RELOC_SECTION_BSS;
1080 if (strcmp (name, ".data") == 0)
1081 int_rel.r_symndx = RELOC_SECTION_DATA;
1084 if (strcmp (name, ".fini") == 0)
1085 int_rel.r_symndx = RELOC_SECTION_FINI;
1088 if (strcmp (name, ".init") == 0)
1089 int_rel.r_symndx = RELOC_SECTION_INIT;
1092 if (strcmp (name, ".lit8") == 0)
1093 int_rel.r_symndx = RELOC_SECTION_LIT8;
1094 else if (strcmp (name, ".lit4") == 0)
1095 int_rel.r_symndx = RELOC_SECTION_LIT4;
1098 if (strcmp (name, ".rdata") == 0)
1099 int_rel.r_symndx = RELOC_SECTION_RDATA;
1102 if (strcmp (name, ".sdata") == 0)
1103 int_rel.r_symndx = RELOC_SECTION_SDATA;
1104 else if (strcmp (name, ".sbss") == 0)
1105 int_rel.r_symndx = RELOC_SECTION_SBSS;
1108 if (strcmp (name, ".text") == 0)
1109 int_rel.r_symndx = RELOC_SECTION_TEXT;
1113 if (int_rel.r_symndx == -1)
1116 /* Add the section VMA and the symbol value. */
1117 relocation = (h->root.u.def.value
1118 + s->output_section->vma
1119 + s->output_offset);
1121 /* For a PC relative relocation, the object file
1122 currently holds just the addend. We must adjust
1123 by the address to get the right value. */
1124 if (howto->pc_relative)
1125 relocation -= int_rel.r_vaddr - input_section->vma;
1131 /* Change the symndx value to the right one for the
1133 int_rel.r_symndx = h->indx;
1134 if (int_rel.r_symndx == -1)
1136 /* This symbol is not being written out. */
1137 if (! ((*info->callbacks->unattached_reloc)
1138 (info, h->root.root.string, input_bfd,
1140 int_rel.r_vaddr - input_section->vma)))
1142 int_rel.r_symndx = 0;
1149 /* This is a relocation against a section. Adjust the
1150 value by the amount the section moved. */
1151 relocation = (s->output_section->vma
1156 relocation += addend;
1159 /* Adjust a PC relative relocation by removing the reference
1160 to the original address in the section and including the
1161 reference to the new address. */
1162 if (howto->pc_relative)
1163 relocation -= (input_section->output_section->vma
1164 + input_section->output_offset
1165 - input_section->vma);
1167 /* Adjust the contents. */
1168 if (relocation == 0)
1172 if (int_rel.r_type != MIPS_R_REFHI)
1173 r = _bfd_relocate_contents (howto, input_bfd, relocation,
1176 - input_section->vma));
1179 mips_relocate_hi (&int_rel,
1180 use_lo ? &lo_int_rel : NULL,
1181 input_bfd, input_section, contents,
1187 /* Adjust the reloc address. */
1188 int_rel.r_vaddr += (input_section->output_section->vma
1189 + input_section->output_offset
1190 - input_section->vma);
1192 /* Save the changed reloc information. */
1193 mips_ecoff_swap_reloc_out (input_bfd, &int_rel, (PTR) ext_rel);
1197 /* We are producing a final executable. */
1198 if (int_rel.r_extern)
1200 /* This is a reloc against a symbol. */
1201 if (h->root.type == bfd_link_hash_defined
1202 || h->root.type == bfd_link_hash_defweak)
1206 hsec = h->root.u.def.section;
1207 relocation = (h->root.u.def.value
1208 + hsec->output_section->vma
1209 + hsec->output_offset);
1213 if (! ((*info->callbacks->undefined_symbol)
1214 (info, h->root.root.string, input_bfd,
1216 int_rel.r_vaddr - input_section->vma, TRUE)))
1223 /* This is a reloc against a section. */
1224 relocation = (s->output_section->vma
1228 /* A PC relative reloc is already correct in the object
1229 file. Make it look like a pcrel_offset relocation by
1230 adding in the start address. */
1231 if (howto->pc_relative)
1232 relocation += int_rel.r_vaddr;
1235 if (int_rel.r_type != MIPS_R_REFHI)
1236 r = _bfd_final_link_relocate (howto,
1241 - input_section->vma),
1246 mips_relocate_hi (&int_rel,
1247 use_lo ? &lo_int_rel : NULL,
1248 input_bfd, input_section, contents,
1254 /* MIPS_R_JMPADDR requires peculiar overflow detection. The
1255 instruction provides a 28 bit address (the two lower bits are
1256 implicit zeroes) which is combined with the upper four bits
1257 of the instruction address. */
1258 if (r == bfd_reloc_ok
1259 && int_rel.r_type == MIPS_R_JMPADDR
1262 + (int_rel.r_extern ? 0 : s->vma))
1264 != ((input_section->output_section->vma
1265 + input_section->output_offset
1266 + (int_rel.r_vaddr - input_section->vma))
1268 r = bfd_reloc_overflow;
1270 if (r != bfd_reloc_ok)
1275 case bfd_reloc_outofrange:
1277 case bfd_reloc_overflow:
1281 if (int_rel.r_extern)
1284 name = bfd_section_name (input_bfd, s);
1285 if (! ((*info->callbacks->reloc_overflow)
1286 (info, (h ? &h->root : NULL), name, howto->name,
1287 (bfd_vma) 0, input_bfd, input_section,
1288 int_rel.r_vaddr - input_section->vma)))
1299 /* This is the ECOFF backend structure. The backend field of the
1300 target vector points to this. */
1302 static const struct ecoff_backend_data mips_ecoff_backend_data =
1304 /* COFF backend structure. */
1306 (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */
1307 (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
1308 (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
1309 (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/
1310 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
1311 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
1312 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
1313 mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
1314 mips_ecoff_swap_scnhdr_out,
1315 FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, TRUE,
1316 ECOFF_NO_LONG_SECTION_NAMES, 4, FALSE, 2,
1317 mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
1318 mips_ecoff_swap_scnhdr_in, NULL,
1319 mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
1320 _bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
1321 _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
1322 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1325 /* Supported architecture. */
1327 /* Initial portion of armap string. */
1329 /* The page boundary used to align sections in a demand-paged
1330 executable file. E.g., 0x1000. */
1332 /* TRUE if the .rdata section is part of the text segment, as on the
1333 Alpha. FALSE if .rdata is part of the data segment, as on the
1336 /* Bitsize of constructor entries. */
1338 /* Reloc to use for constructor entries. */
1339 &mips_howto_table[MIPS_R_REFWORD],
1341 /* Symbol table magic number. */
1343 /* Alignment of debugging information. E.g., 4. */
1345 /* Sizes of external symbolic information. */
1346 sizeof (struct hdr_ext),
1347 sizeof (struct dnr_ext),
1348 sizeof (struct pdr_ext),
1349 sizeof (struct sym_ext),
1350 sizeof (struct opt_ext),
1351 sizeof (struct fdr_ext),
1352 sizeof (struct rfd_ext),
1353 sizeof (struct ext_ext),
1354 /* Functions to swap in external symbolic data. */
1363 _bfd_ecoff_swap_tir_in,
1364 _bfd_ecoff_swap_rndx_in,
1365 /* Functions to swap out external symbolic data. */
1374 _bfd_ecoff_swap_tir_out,
1375 _bfd_ecoff_swap_rndx_out,
1376 /* Function to read in symbolic data. */
1377 _bfd_ecoff_slurp_symbolic_info
1379 /* External reloc size. */
1381 /* Reloc swapping functions. */
1382 mips_ecoff_swap_reloc_in,
1383 mips_ecoff_swap_reloc_out,
1384 /* Backend reloc tweaking. */
1385 mips_adjust_reloc_in,
1386 mips_adjust_reloc_out,
1387 /* Relocate section contents while linking. */
1388 mips_relocate_section,
1389 /* Do final adjustments to filehdr and aouthdr. */
1391 /* Read an element from an archive at a given file position. */
1392 _bfd_get_elt_at_filepos
1395 /* Looking up a reloc type is MIPS specific. */
1396 #define _bfd_ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
1397 #define _bfd_ecoff_bfd_reloc_name_lookup mips_bfd_reloc_name_lookup
1399 /* Getting relocated section contents is generic. */
1400 #define _bfd_ecoff_bfd_get_relocated_section_contents \
1401 bfd_generic_get_relocated_section_contents
1403 /* Handling file windows is generic. */
1404 #define _bfd_ecoff_get_section_contents_in_window \
1405 _bfd_generic_get_section_contents_in_window
1407 /* Relaxing sections is MIPS specific. */
1408 #define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
1410 /* GC of sections is not done. */
1411 #define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
1413 /* Merging of sections is not done. */
1414 #define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections
1416 #define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section
1417 #define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
1418 #define _bfd_ecoff_section_already_linked \
1419 _bfd_generic_section_already_linked
1420 #define _bfd_ecoff_bfd_define_common_symbol bfd_generic_define_common_symbol
1422 extern const bfd_target ecoff_big_vec;
1424 const bfd_target ecoff_little_vec =
1426 "ecoff-littlemips", /* name */
1427 bfd_target_ecoff_flavour,
1428 BFD_ENDIAN_LITTLE, /* data byte order is little */
1429 BFD_ENDIAN_LITTLE, /* header byte order is little */
1431 (HAS_RELOC | EXEC_P | /* object flags */
1432 HAS_LINENO | HAS_DEBUG |
1433 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1435 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1436 0, /* leading underscore */
1437 ' ', /* ar_pad_char */
1438 15, /* ar_max_namelen */
1439 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1440 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1441 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1442 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1443 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1444 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
1446 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1447 bfd_generic_archive_p, _bfd_dummy_target},
1448 {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
1449 _bfd_generic_mkarchive, bfd_false},
1450 {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
1451 _bfd_write_archive_contents, bfd_false},
1453 BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
1454 BFD_JUMP_TABLE_COPY (_bfd_ecoff),
1455 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1456 BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
1457 BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
1458 BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
1459 BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
1460 BFD_JUMP_TABLE_LINK (_bfd_ecoff),
1461 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1465 (PTR) &mips_ecoff_backend_data
1468 const bfd_target ecoff_big_vec =
1470 "ecoff-bigmips", /* name */
1471 bfd_target_ecoff_flavour,
1472 BFD_ENDIAN_BIG, /* data byte order is big */
1473 BFD_ENDIAN_BIG, /* header byte order is big */
1475 (HAS_RELOC | EXEC_P | /* object flags */
1476 HAS_LINENO | HAS_DEBUG |
1477 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1479 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1480 0, /* leading underscore */
1481 ' ', /* ar_pad_char */
1482 15, /* ar_max_namelen */
1483 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1484 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1485 bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1486 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1487 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1488 bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1489 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1490 bfd_generic_archive_p, _bfd_dummy_target},
1491 {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
1492 _bfd_generic_mkarchive, bfd_false},
1493 {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
1494 _bfd_write_archive_contents, bfd_false},
1496 BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
1497 BFD_JUMP_TABLE_COPY (_bfd_ecoff),
1498 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1499 BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
1500 BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
1501 BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
1502 BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
1503 BFD_JUMP_TABLE_LINK (_bfd_ecoff),
1504 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1508 (PTR) &mips_ecoff_backend_data
1511 const bfd_target ecoff_biglittle_vec =
1513 "ecoff-biglittlemips", /* name */
1514 bfd_target_ecoff_flavour,
1515 BFD_ENDIAN_LITTLE, /* data byte order is little */
1516 BFD_ENDIAN_BIG, /* header byte order is big */
1518 (HAS_RELOC | EXEC_P | /* object flags */
1519 HAS_LINENO | HAS_DEBUG |
1520 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1522 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1523 0, /* leading underscore */
1524 ' ', /* ar_pad_char */
1525 15, /* ar_max_namelen */
1526 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1527 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1528 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1529 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1530 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1531 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
1533 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1534 bfd_generic_archive_p, _bfd_dummy_target},
1535 {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
1536 _bfd_generic_mkarchive, bfd_false},
1537 {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
1538 _bfd_write_archive_contents, bfd_false},
1540 BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
1541 BFD_JUMP_TABLE_COPY (_bfd_ecoff),
1542 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1543 BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
1544 BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
1545 BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
1546 BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
1547 BFD_JUMP_TABLE_LINK (_bfd_ecoff),
1548 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1552 (PTR) &mips_ecoff_backend_data