Support for link_order types which generate relocs in order to
[platform/upstream/binutils.git] / bfd / coff-mips.c
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.
4    Full support added by Ian Lance Taylor, ian@cygnus.com.
5
6 This file is part of BFD, the Binary File Descriptor library.
7
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.
12
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.
17
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.  */
21
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "bfdlink.h"
25 #include "libbfd.h"
26 #include "coff/internal.h"
27 #include "coff/sym.h"
28 #include "coff/symconst.h"
29 #include "coff/ecoff.h"
30 #include "coff/mips.h"
31 #include "libcoff.h"
32 #include "libecoff.h"
33 \f
34 /* Prototypes for static functions.  */
35
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 *,
41                                                PTR));
42 static void mips_adjust_reloc_in PARAMS ((bfd *,
43                                           const struct internal_reloc *,
44                                           arelent *));
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,
48                                                          arelent *reloc,
49                                                          asymbol *symbol,
50                                                          PTR data,
51                                                          asection *section,
52                                                          bfd *output_bfd,
53                                                          char **error));
54 static bfd_reloc_status_type mips_refhi_reloc PARAMS ((bfd *abfd,
55                                                        arelent *reloc,
56                                                        asymbol *symbol,
57                                                        PTR data,
58                                                        asection *section,
59                                                        bfd *output_bfd,
60                                                        char **error));
61 static bfd_reloc_status_type mips_reflo_reloc PARAMS ((bfd *abfd,
62                                                        arelent *reloc,
63                                                        asymbol *symbol,
64                                                        PTR data,
65                                                        asection *section,
66                                                        bfd *output_bfd,
67                                                        char **error));
68 static bfd_reloc_status_type mips_gprel_reloc PARAMS ((bfd *abfd,
69                                                        arelent *reloc,
70                                                        asymbol *symbol,
71                                                        PTR data,
72                                                        asection *section,
73                                                        bfd *output_bfd,
74                                                        char **error));
75 static void mips_relocate_refhi PARAMS ((struct internal_reloc *refhi,
76                                          struct internal_reloc *reflo,
77                                          bfd *input_bfd,
78                                          asection *input_section,
79                                          bfd_byte *contents,
80                                          bfd_vma relocation));
81 static boolean mips_relocate_section PARAMS ((bfd *, struct bfd_link_info *,
82                                               bfd *, asection *,
83                                               bfd_byte *, PTR));
84 \f
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.
90
91    Get the generic COFF swapping routines, except for the reloc,
92    symbol, and lineno ones.  Give them ECOFF names.  */
93 #define MIPSECOFF
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"
104
105 /* Get the ECOFF swapping routines.  */
106 #define ECOFF_32
107 #include "ecoffswap.h"
108 \f
109 /* How to process the various relocs types.  */
110
111 static reloc_howto_type mips_howto_table[] =
112 {
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 */
117          0,                     /* rightshift */
118          0,                     /* size (0 = byte, 1 = short, 2 = long) */
119          8,                     /* bitsize */
120          false,                 /* pc_relative */
121          0,                     /* bitpos */
122          complain_overflow_dont, /* complain_on_overflow */
123          0,                     /* special_function */
124          "IGNORE",              /* name */
125          false,                 /* partial_inplace */
126          0,                     /* src_mask */
127          0,                     /* dst_mask */
128          false),                /* pcrel_offset */
129
130   /* A 16 bit reference to a symbol, normally from a data section.  */
131   HOWTO (MIPS_R_REFHALF,        /* type */
132          0,                     /* rightshift */
133          1,                     /* size (0 = byte, 1 = short, 2 = long) */
134          16,                    /* bitsize */
135          false,                 /* pc_relative */
136          0,                     /* bitpos */
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 */
144
145   /* A 32 bit reference to a symbol, normally from a data section.  */
146   HOWTO (MIPS_R_REFWORD,        /* type */
147          0,                     /* rightshift */
148          2,                     /* size (0 = byte, 1 = short, 2 = long) */
149          32,                    /* bitsize */
150          false,                 /* pc_relative */
151          0,                     /* bitpos */
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 */
159
160   /* A 26 bit absolute jump address.  */
161   HOWTO (MIPS_R_JMPADDR,        /* type */
162          2,                     /* rightshift */
163          2,                     /* size (0 = byte, 1 = short, 2 = long) */
164          26,                    /* bitsize */
165          false,                 /* pc_relative */
166          0,                     /* bitpos */
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 */
177
178   /* The high 16 bits of a symbol value.  Handled by the function
179      mips_refhi_reloc.  */
180   HOWTO (MIPS_R_REFHI,          /* type */
181          16,                    /* rightshift */
182          2,                     /* size (0 = byte, 1 = short, 2 = long) */
183          16,                    /* bitsize */
184          false,                 /* pc_relative */
185          0,                     /* bitpos */
186          complain_overflow_bitfield, /* complain_on_overflow */
187          mips_refhi_reloc,      /* special_function */
188          "REFHI",               /* name */
189          true,                  /* partial_inplace */
190          0xffff,                /* src_mask */
191          0xffff,                /* dst_mask */
192          false),                /* pcrel_offset */
193
194   /* The low 16 bits of a symbol value.  */
195   HOWTO (MIPS_R_REFLO,          /* type */
196          0,                     /* rightshift */
197          2,                     /* size (0 = byte, 1 = short, 2 = long) */
198          16,                    /* bitsize */
199          false,                 /* pc_relative */
200          0,                     /* bitpos */
201          complain_overflow_dont, /* complain_on_overflow */
202          mips_reflo_reloc,      /* special_function */
203          "REFLO",               /* name */
204          true,                  /* partial_inplace */
205          0xffff,                /* src_mask */
206          0xffff,                /* dst_mask */
207          false),                /* pcrel_offset */
208
209   /* A reference to an offset from the gp register.  Handled by the
210      function mips_gprel_reloc.  */
211   HOWTO (MIPS_R_GPREL,          /* type */
212          0,                     /* rightshift */
213          2,                     /* size (0 = byte, 1 = short, 2 = long) */
214          16,                    /* bitsize */
215          false,                 /* pc_relative */
216          0,                     /* bitpos */
217          complain_overflow_signed, /* complain_on_overflow */
218          mips_gprel_reloc,      /* special_function */
219          "GPREL",               /* name */
220          true,                  /* partial_inplace */
221          0xffff,                /* src_mask */
222          0xffff,                /* dst_mask */
223          false),                /* pcrel_offset */
224
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 */
228          0,                     /* rightshift */
229          2,                     /* size (0 = byte, 1 = short, 2 = long) */
230          16,                    /* bitsize */
231          false,                 /* pc_relative */
232          0,                     /* bitpos */
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 */
240 };
241
242 #define MIPS_HOWTO_COUNT \
243   (sizeof mips_howto_table / sizeof mips_howto_table[0])
244 \f
245 /* See whether the magic number matches.  */
246
247 static boolean
248 mips_ecoff_bad_format_hook (abfd, filehdr)
249      bfd *abfd;
250      PTR filehdr;
251 {
252   struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
253
254   switch (internal_f->f_magic)
255     {
256     case MIPS_MAGIC_1:
257       /* I don't know what endianness this implies.  */
258       return true;
259
260     case MIPS_MAGIC_BIG:
261     case MIPS_MAGIC_BIG2:
262     case MIPS_MAGIC_BIG3:
263       return abfd->xvec->byteorder_big_p;
264
265     case MIPS_MAGIC_LITTLE:
266     case MIPS_MAGIC_LITTLE2:
267     case MIPS_MAGIC_LITTLE3:
268       return abfd->xvec->byteorder_big_p == false;
269
270     default:
271       return false;
272     }
273 }
274 \f
275 /* Reloc handling.  MIPS ECOFF relocs are packed into 8 bytes in
276    external form.  They use a bit which indicates whether the symbol
277    is external.  */
278
279 /* Swap a reloc in.  */
280
281 static void
282 mips_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
283      bfd *abfd;
284      PTR ext_ptr;
285      struct internal_reloc *intern;
286 {
287   const RELOC *ext = (RELOC *) ext_ptr;
288
289   intern->r_vaddr = bfd_h_get_32 (abfd, (bfd_byte *) ext->r_vaddr);
290   if (abfd->xvec->header_byteorder_big_p != false)
291     {
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;
301     }
302   else
303     {
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;
313     }
314 }
315
316 /* Swap a reloc out.  */
317
318 static void
319 mips_ecoff_swap_reloc_out (abfd, intern, dst)
320      bfd *abfd;
321      const struct internal_reloc *intern;
322      PTR dst;
323 {
324   RELOC *ext = (RELOC *) dst;
325
326   BFD_ASSERT (intern->r_extern
327               || (intern->r_symndx >= 0 && intern->r_symndx <= 12));
328
329   bfd_h_put_32 (abfd, intern->r_vaddr, (bfd_byte *) ext->r_vaddr);
330   if (abfd->xvec->header_byteorder_big_p != false)
331     {
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));
338     }
339   else
340     {
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));
347     }
348 }
349
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.  */
353
354 static void
355 mips_adjust_reloc_in (abfd, intern, rptr)
356      bfd *abfd;
357      const struct internal_reloc *intern;
358      arelent *rptr;
359 {
360   if (intern->r_type > MIPS_R_LITERAL)
361     abort ();
362
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;
367
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;
372
373   rptr->howto = &mips_howto_table[intern->r_type];
374 }
375
376 /* Make any adjustments needed to a reloc before writing it out.  None
377    are needed for MIPS.  */
378
379 static void
380 mips_adjust_reloc_out (abfd, rel, intern)
381      bfd *abfd;
382      const arelent *rel;
383      struct internal_reloc *intern;
384 {
385 }
386
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.  */
397
398 static bfd_reloc_status_type
399 mips_generic_reloc (abfd,
400                     reloc_entry,
401                     symbol,
402                     data,
403                     input_section,
404                     output_bfd,
405                     error_message)
406      bfd *abfd;
407      arelent *reloc_entry;
408      asymbol *symbol;
409      PTR data;
410      asection *input_section;
411      bfd *output_bfd;
412      char **error_message;
413 {
414   if (output_bfd != (bfd *) NULL
415       && (symbol->flags & BSF_SECTION_SYM) == 0
416       && reloc_entry->addend == 0)
417     {
418       reloc_entry->address += input_section->output_offset;
419       return bfd_reloc_ok;
420     }
421
422   return bfd_reloc_continue;
423 }
424
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.  */
430
431 static bfd_byte *mips_refhi_addr;
432 static bfd_vma mips_refhi_addend;
433
434 static bfd_reloc_status_type
435 mips_refhi_reloc (abfd,
436                   reloc_entry,
437                   symbol,
438                   data,
439                   input_section,
440                   output_bfd,
441                   error_message)
442      bfd *abfd;
443      arelent *reloc_entry;
444      asymbol *symbol;
445      PTR data;
446      asection *input_section;
447      bfd *output_bfd;
448      char **error_message;
449 {
450   bfd_reloc_status_type ret;
451   bfd_vma relocation;
452
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)
458     {
459       reloc_entry->address += input_section->output_offset;
460       return bfd_reloc_ok;
461     }
462
463   ret = bfd_reloc_ok;
464   if (symbol->section == &bfd_und_section
465       && output_bfd == (bfd *) NULL)
466     ret = bfd_reloc_undefined;
467
468   if (bfd_is_com_section (symbol->section))
469     relocation = 0;
470   else
471     relocation = symbol->value;
472
473   relocation += symbol->section->output_section->vma;
474   relocation += symbol->section->output_offset;
475   relocation += reloc_entry->addend;
476
477   if (reloc_entry->address > input_section->_cooked_size)
478     return bfd_reloc_outofrange;
479
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;
483
484   if (output_bfd != (bfd *) NULL)
485     reloc_entry->address += input_section->output_offset;
486
487   return ret;
488 }
489
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.  */
493
494 static bfd_reloc_status_type
495 mips_reflo_reloc (abfd,
496                   reloc_entry,
497                   symbol,
498                   data,
499                   input_section,
500                   output_bfd,
501                   error_message)
502      bfd *abfd;
503      arelent *reloc_entry;
504      asymbol *symbol;
505      PTR data;
506      asection *input_section;
507      bfd *output_bfd;
508      char **error_message;
509 {
510   if (mips_refhi_addr != (bfd_byte *) NULL)
511     {
512       unsigned long insn;
513       unsigned long val;
514       unsigned long vallo;
515
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)
521                & 0xffff);
522       val = ((insn & 0xffff) << 16) + vallo;
523       val += mips_refhi_addend;
524
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
530          data.  */
531       if ((vallo & 0x8000) != 0)
532         val -= 0x10000;
533       if ((val & 0x8000) != 0)
534         val += 0x10000;
535
536       insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
537       bfd_put_32 (abfd, insn, mips_refhi_addr);
538
539       mips_refhi_addr = (bfd_byte *) NULL;
540     }
541
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);
545 }
546
547 /* Do a GPREL relocation.  This is a 16 bit value which must become
548    the offset from the gp register.  */
549
550 static bfd_reloc_status_type
551 mips_gprel_reloc (abfd,
552                   reloc_entry,
553                   symbol,
554                   data,
555                   input_section,
556                   output_bfd,
557                   error_message)
558      bfd *abfd;
559      arelent *reloc_entry;
560      asymbol *symbol;
561      PTR data;
562      asection *input_section;
563      bfd *output_bfd;
564      char **error_message;
565 {
566   boolean relocateable;
567   bfd_vma relocation;
568   unsigned long val;
569   unsigned long insn;
570
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
574      file.  */
575   if (output_bfd != (bfd *) NULL
576       && (symbol->flags & BSF_SECTION_SYM) == 0
577       && reloc_entry->addend == 0)
578     {
579       reloc_entry->address += input_section->output_offset;
580       return bfd_reloc_ok;
581     }
582
583   if (output_bfd != (bfd *) NULL)
584     relocateable = true;
585   else
586     {
587       relocateable = false;
588       output_bfd = symbol->section->output_section->owner;
589     }
590
591   if (symbol->section == &bfd_und_section
592       && relocateable == false)
593     return bfd_reloc_undefined;
594
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))
603     {
604       if (relocateable != false)
605         {
606           /* Make up a value.  */
607           ecoff_data (output_bfd)->gp =
608             symbol->section->output_section->vma + 0x4000;
609         }
610       else
611         {
612           unsigned int count;
613           asymbol **sym;
614           unsigned int i;
615
616           count = bfd_get_symcount (output_bfd);
617           sym = bfd_get_outsymbols (output_bfd);
618
619           if (sym == (asymbol **) NULL)
620             i = count;
621           else
622             {
623               for (i = 0; i < count; i++, sym++)
624                 {
625                   register CONST char *name;
626
627                   name = bfd_asymbol_name (*sym);
628                   if (*name == '_' && strcmp (name, "_gp") == 0)
629                     {
630                       ecoff_data (output_bfd)->gp = bfd_asymbol_value (*sym);
631                       break;
632                     }
633                 }
634             }
635
636           if (i >= count)
637             {
638               /* Only get the error once.  */
639               ecoff_data (output_bfd)->gp = 4;
640               *error_message =
641                 (char *) "GP relative relocation when _gp not defined";
642               return bfd_reloc_dangerous;
643             }
644         }
645     }
646
647   if (bfd_is_com_section (symbol->section))
648     relocation = 0;
649   else
650     relocation = symbol->value;
651
652   relocation += symbol->section->output_section->vma;
653   relocation += symbol->section->output_offset;
654
655   if (reloc_entry->address > input_section->_cooked_size)
656     return bfd_reloc_outofrange;
657
658   insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
659
660   /* Set val to the offset into the section or symbol.  */
661   val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;
662   if (val & 0x8000)
663     val -= 0x10000;
664
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;
671
672   insn = (insn &~ 0xffff) | (val & 0xffff);
673   bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
674
675   if (relocateable != false)
676     reloc_entry->address += input_section->output_offset;
677
678   /* Make sure it fit in 16 bits.  */
679   if (val >= 0x8000 && val < 0xffff8000)
680     return bfd_reloc_overflow;
681
682   return bfd_reloc_ok;
683 }
684
685 /* Get the howto structure for a generic reloc type.  */
686
687 static CONST struct reloc_howto_struct *
688 mips_bfd_reloc_type_lookup (abfd, code)
689      bfd *abfd;
690      bfd_reloc_code_real_type code;
691 {
692   int mips_type;
693
694   switch (code)
695     {
696     case BFD_RELOC_16:
697       mips_type = MIPS_R_REFHALF;
698       break;
699     case BFD_RELOC_32:
700     case BFD_RELOC_CTOR:
701       mips_type = MIPS_R_REFWORD;
702       break;
703     case BFD_RELOC_MIPS_JMP:
704       mips_type = MIPS_R_JMPADDR;
705       break;
706     case BFD_RELOC_HI16_S:
707       mips_type = MIPS_R_REFHI;
708       break;
709     case BFD_RELOC_LO16:
710       mips_type = MIPS_R_REFLO;
711       break;
712     case BFD_RELOC_MIPS_GPREL:
713       mips_type = MIPS_R_GPREL;
714       break;
715     case BFD_RELOC_MIPS_LITERAL:
716       mips_type = MIPS_R_LITERAL;
717       break;
718     default:
719       return (CONST struct reloc_howto_struct *) NULL;
720     }
721
722   return &mips_howto_table[mips_type];
723 }
724 \f
725 /* A helper routine for mips_relocate_section which handles the REFHI
726    relocation.  The REFHI relocation must be followed by a REFLO
727    relocation, and the addend used is formed from the addends of both
728    instructions.  */
729
730 static void
731 mips_relocate_refhi (refhi, reflo, input_bfd, input_section, contents,
732                      relocation)
733      struct internal_reloc *refhi;
734      struct internal_reloc *reflo;
735      bfd *input_bfd;
736      asection *input_section;
737      bfd_byte *contents;
738      bfd_vma relocation;
739 {
740   unsigned long insn;
741   unsigned long val;
742   unsigned long vallo;
743
744   insn = bfd_get_32 (input_bfd,
745                      contents + refhi->r_vaddr - input_section->vma);
746   vallo = (bfd_get_32 (input_bfd,
747                        contents + reflo->r_vaddr - input_section->vma)
748            & 0xffff);
749   val = ((insn & 0xffff) << 16) + vallo;
750   val += relocation;
751
752   /* The low order 16 bits are always treated as a signed value.
753      Therefore, a negative value in the low order bits requires an
754      adjustment in the high order bits.  We need to make this
755      adjustment in two ways: once for the bits we took from the data,
756      and once for the bits we are putting back in to the data.  */
757   if ((vallo & 0x8000) != 0)
758     val -= 0x10000;
759   if ((val & 0x8000) != 0)
760     val += 0x10000;
761
762   insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
763   bfd_put_32 (input_bfd, (bfd_vma) insn,
764               contents + refhi->r_vaddr - input_section->vma);
765 }
766
767 /* Relocate a section while linking a MIPS ECOFF file.  */
768
769 static boolean
770 mips_relocate_section (output_bfd, info, input_bfd, input_section,
771                        contents, external_relocs)
772      bfd *output_bfd;
773      struct bfd_link_info *info;
774      bfd *input_bfd;
775      asection *input_section;
776      bfd_byte *contents;
777      PTR external_relocs;
778 {
779   asection **symndx_to_section;
780   struct ecoff_link_hash_entry **sym_hashes;
781   bfd_vma gp;
782   boolean gp_undefined;
783   struct external_reloc *ext_rel;
784   struct external_reloc *ext_rel_end;
785   boolean got_reflo;
786
787   BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
788               == output_bfd->xvec->header_byteorder_big_p);
789
790   /* We keep a table mapping the symndx found in an internal reloc to
791      the appropriate section.  This is faster than looking up the
792      section by name each time.  */
793   symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
794   if (symndx_to_section == (asection **) NULL)
795     {
796       symndx_to_section = ((asection **)
797                            bfd_alloc (input_bfd,
798                                       (NUM_RELOC_SECTIONS
799                                        * sizeof (asection *))));
800       if (!symndx_to_section)
801         {
802           bfd_set_error (bfd_error_no_memory);
803           return false;
804         }
805
806       symndx_to_section[RELOC_SECTION_NONE] = NULL;
807       symndx_to_section[RELOC_SECTION_TEXT] =
808         bfd_get_section_by_name (input_bfd, ".text");
809       symndx_to_section[RELOC_SECTION_RDATA] =
810         bfd_get_section_by_name (input_bfd, ".rdata");
811       symndx_to_section[RELOC_SECTION_DATA] =
812         bfd_get_section_by_name (input_bfd, ".data");
813       symndx_to_section[RELOC_SECTION_SDATA] =
814         bfd_get_section_by_name (input_bfd, ".sdata");
815       symndx_to_section[RELOC_SECTION_SBSS] =
816         bfd_get_section_by_name (input_bfd, ".sbss");
817       symndx_to_section[RELOC_SECTION_BSS] =
818         bfd_get_section_by_name (input_bfd, ".bss");
819       symndx_to_section[RELOC_SECTION_INIT] =
820         bfd_get_section_by_name (input_bfd, ".init");
821       symndx_to_section[RELOC_SECTION_LIT8] =
822         bfd_get_section_by_name (input_bfd, ".lit8");
823       symndx_to_section[RELOC_SECTION_LIT4] =
824         bfd_get_section_by_name (input_bfd, ".lit4");
825       symndx_to_section[RELOC_SECTION_XDATA] = NULL;
826       symndx_to_section[RELOC_SECTION_PDATA] = NULL;
827       symndx_to_section[RELOC_SECTION_FINI] =
828         bfd_get_section_by_name (input_bfd, ".fini");
829       symndx_to_section[RELOC_SECTION_LITA] = NULL;
830       symndx_to_section[RELOC_SECTION_ABS] = NULL;
831
832       ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
833     }
834
835   sym_hashes = ecoff_data (input_bfd)->sym_hashes;
836
837   gp = ecoff_data (output_bfd)->gp;
838   if (gp == 0)
839     gp_undefined = true;
840   else
841     gp_undefined = false;
842
843   got_reflo = false;
844
845   ext_rel = (struct external_reloc *) external_relocs;
846   ext_rel_end = ext_rel + input_section->reloc_count;
847   for (; ext_rel < ext_rel_end; ext_rel++)
848     {
849       struct internal_reloc int_rel;
850       struct internal_reloc reflo_int_rel;
851       bfd_vma addend;
852       reloc_howto_type *howto;
853       struct ecoff_link_hash_entry *h = NULL;
854       asection *s = NULL;
855       bfd_vma relocation;
856       bfd_reloc_status_type r;
857
858       if (! got_reflo)
859         mips_ecoff_swap_reloc_in (input_bfd, (PTR) ext_rel, &int_rel);
860       else
861         {
862           int_rel = reflo_int_rel;
863           got_reflo = false;
864         }
865
866       BFD_ASSERT (int_rel.r_type
867                   < sizeof mips_howto_table / sizeof mips_howto_table[0]);
868
869       /* The REFHI reloc requires special handling.  It must be
870          followed by a REFLO reloc, and the addend is formed from both
871          fields.  */
872       if (int_rel.r_type == MIPS_R_REFHI)
873         {
874           BFD_ASSERT ((ext_rel + 1) < ext_rel_end);
875           mips_ecoff_swap_reloc_in (input_bfd, (PTR) (ext_rel + 1),
876                                     &reflo_int_rel);
877           BFD_ASSERT (reflo_int_rel.r_type == MIPS_R_REFLO
878                       && int_rel.r_extern == reflo_int_rel.r_extern
879                       && int_rel.r_symndx == reflo_int_rel.r_symndx);
880           got_reflo = true;
881         }
882
883       howto = &mips_howto_table[int_rel.r_type];
884
885       if (int_rel.r_extern)
886         {
887           h = sym_hashes[int_rel.r_symndx];
888           /* If h is NULL, that means that there is a reloc against an
889              external symbol which we thought was just a debugging
890              symbol.  This should not happen.  */
891           if (h == (struct ecoff_link_hash_entry *) NULL)
892             abort ();
893         }
894       else
895         {
896           if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS)
897             s = NULL;
898           else
899             s = symndx_to_section[int_rel.r_symndx];
900
901           if (s == (asection *) NULL)
902             abort ();
903         }
904
905       /* The GPREL reloc uses an addend: the difference in the GP
906          values.  */
907       if (int_rel.r_type != MIPS_R_GPREL
908           && int_rel.r_type != MIPS_R_LITERAL)
909         addend = 0;
910       else
911         {
912           if (gp_undefined)
913             {
914               if (! ((*info->callbacks->reloc_dangerous)
915                      (info, "GP relative relocation when GP not defined",
916                       input_bfd, input_section,
917                       int_rel.r_vaddr - input_section->vma)))
918                 return false;
919               /* Only give the error once per link.  */
920               ecoff_data (output_bfd)->gp = gp = 4;
921               gp_undefined = false;
922             }
923           if (! int_rel.r_extern)
924             {
925               /* This is a relocation against a section.  The current
926                  addend in the instruction is the difference between
927                  INPUT_SECTION->vma and the GP value of INPUT_BFD.  We
928                  must change this to be the difference between the
929                  final definition (which will end up in RELOCATION)
930                  and the GP value of OUTPUT_BFD (which is in GP).  */
931               addend = ecoff_data (input_bfd)->gp - gp;
932             }
933           else if (! info->relocateable
934                    || h->root.type == bfd_link_hash_defined)
935             {
936               /* This is a relocation against an undefined or common
937                  symbol.  The current addend in the instruction is
938                  simply the desired offset into the symbol (normally
939                  zero).  We are going to change this into a relocation
940                  against a defined symbol, so we want the instruction
941                  to hold the difference between the final definition
942                  of the symbol (which will end up in RELOCATION) and
943                  the GP value of OUTPUT_BFD (which is in GP).  */
944               addend = - gp;
945             }
946           else
947             {
948               /* This is a relocation against an undefined or common
949                  symbol.  The current addend in the instruction is
950                  simply the desired offset into the symbol (normally
951                  zero).  We are generating relocateable output, and we
952                  aren't going to define this symbol, so we just leave
953                  the instruction alone.  */
954               addend = 0;
955             }
956         }
957
958       if (info->relocateable)
959         {
960           /* We are generating relocateable output, and must convert
961              the existing reloc.  */
962           if (int_rel.r_extern)
963             {
964               if (h->root.type == bfd_link_hash_defined)
965                 {
966                   asection *hsec;
967                   const char *name;
968
969                   /* This symbol is defined in the output.  Convert
970                      the reloc from being against the symbol to being
971                      against the section.  */
972
973                   /* Clear the r_extern bit.  */
974                   int_rel.r_extern = 0;
975
976                   /* Compute a new r_symndx value.  */
977                   hsec = h->root.u.def.section;
978                   name = bfd_get_section_name (output_bfd,
979                                                hsec->output_section);
980
981                   int_rel.r_symndx = -1;
982                   switch (name[1])
983                     {
984                     case 'b':
985                       if (strcmp (name, ".bss") == 0)
986                         int_rel.r_symndx = RELOC_SECTION_BSS;
987                       break;
988                     case 'd':
989                       if (strcmp (name, ".data") == 0)
990                         int_rel.r_symndx = RELOC_SECTION_DATA;
991                       break;
992                     case 'f':
993                       if (strcmp (name, ".fini") == 0)
994                         int_rel.r_symndx = RELOC_SECTION_FINI;
995                       break;
996                     case 'i':
997                       if (strcmp (name, ".init") == 0)
998                         int_rel.r_symndx = RELOC_SECTION_INIT;
999                       break;
1000                     case 'l':
1001                       if (strcmp (name, ".lit8") == 0)
1002                         int_rel.r_symndx = RELOC_SECTION_LIT8;
1003                       else if (strcmp (name, ".lit4") == 0)
1004                         int_rel.r_symndx = RELOC_SECTION_LIT4;
1005                       break;
1006                     case 'r':
1007                       if (strcmp (name, ".rdata") == 0)
1008                         int_rel.r_symndx = RELOC_SECTION_RDATA;
1009                       break;
1010                     case 's':
1011                       if (strcmp (name, ".sdata") == 0)
1012                         int_rel.r_symndx = RELOC_SECTION_SDATA;
1013                       else if (strcmp (name, ".sbss") == 0)
1014                         int_rel.r_symndx = RELOC_SECTION_SBSS;
1015                       break;
1016                     case 't':
1017                       if (strcmp (name, ".text") == 0)
1018                         int_rel.r_symndx = RELOC_SECTION_TEXT;
1019                       break;
1020                     }
1021                       
1022                   if (int_rel.r_symndx == -1)
1023                     abort ();
1024
1025                   /* Add the section VMA and the symbol value.  */
1026                   relocation = (h->root.u.def.value
1027                                 + hsec->output_section->vma
1028                                 + hsec->output_offset);
1029                 }
1030               else
1031                 {
1032                   /* Change the symndx value to the right one for the
1033                      output BFD.  */
1034                   int_rel.r_symndx = h->indx;
1035                   if (int_rel.r_symndx == -1)
1036                     {
1037                       /* This symbol is not being written out.  */
1038                       if (! ((*info->callbacks->unattached_reloc)
1039                              (info, h->root.root.string, input_bfd,
1040                               input_section,
1041                               int_rel.r_vaddr - input_section->vma)))
1042                         return false;
1043                       int_rel.r_symndx = 0;
1044                     }
1045                   relocation = 0;
1046                 }
1047             }
1048           else
1049             {
1050               /* This is a relocation against a section.  Adjust the
1051                  value by the amount the section moved.  */
1052               relocation = (s->output_section->vma
1053                             + s->output_offset
1054                             - s->vma);
1055             }
1056
1057           relocation += addend;
1058
1059           /* Adjust the contents.  */
1060           if (relocation == 0)
1061             r = bfd_reloc_ok;
1062           else
1063             {
1064               if (int_rel.r_type != MIPS_R_REFHI)
1065                 r = _bfd_relocate_contents (howto, input_bfd, relocation,
1066                                             (contents
1067                                              + int_rel.r_vaddr
1068                                              - input_section->vma));
1069               else
1070                 {
1071                   mips_relocate_refhi (&int_rel, &reflo_int_rel,
1072                                        input_bfd, input_section, contents,
1073                                        relocation);
1074                   r = bfd_reloc_ok;
1075                 }
1076             }
1077
1078           /* Adjust the reloc address.  */
1079           int_rel.r_vaddr += (input_section->output_section->vma
1080                               + input_section->output_offset
1081                               - input_section->vma);
1082
1083           /* Save the changed reloc information.  */
1084           mips_ecoff_swap_reloc_out (input_bfd, &int_rel, (PTR) ext_rel);
1085         }
1086       else
1087         {
1088           /* We are producing a final executable.  */
1089           if (int_rel.r_extern)
1090             {
1091               /* This is a reloc against a symbol.  */
1092               if (h->root.type == bfd_link_hash_defined)
1093                 {
1094                   asection *hsec;
1095
1096                   hsec = h->root.u.def.section;
1097                   relocation = (h->root.u.def.value
1098                                 + hsec->output_section->vma
1099                                 + hsec->output_offset);
1100                 }
1101               else
1102                 {
1103                   if (! ((*info->callbacks->undefined_symbol)
1104                          (info, h->root.root.string, input_bfd,
1105                           input_section,
1106                           int_rel.r_vaddr - input_section->vma)))
1107                     return false;
1108                   relocation = 0;
1109                 }
1110             }
1111           else
1112             {
1113               /* This is a reloc against a section.  */
1114               relocation = (s->output_section->vma
1115                             + s->output_offset
1116                             - s->vma);
1117
1118               /* Adjust a PC relative relocation by removing the
1119                  reference to the original source section.  */
1120               if (howto->pc_relative)
1121                 relocation += input_section->vma;
1122             }
1123
1124           if (int_rel.r_type != MIPS_R_REFHI)
1125             r = _bfd_final_link_relocate (howto,
1126                                           input_bfd,
1127                                           input_section,
1128                                           contents,
1129                                           int_rel.r_vaddr - input_section->vma,
1130                                           relocation,
1131                                           addend);
1132           else
1133             {
1134               mips_relocate_refhi (&int_rel, &reflo_int_rel, input_bfd,
1135                                    input_section, contents, relocation);
1136               r = bfd_reloc_ok;
1137             }
1138         }
1139
1140       if (r != bfd_reloc_ok)
1141         {
1142           switch (r)
1143             {
1144             default:
1145             case bfd_reloc_outofrange:
1146               abort ();
1147             case bfd_reloc_overflow:
1148               {
1149                 const char *name;
1150
1151                 if (int_rel.r_extern)
1152                   name = h->root.root.string;
1153                 else
1154                   name = bfd_section_name (input_bfd, s);
1155                 if (! ((*info->callbacks->reloc_overflow)
1156                        (info, name, howto->name, (bfd_vma) 0,
1157                         input_bfd, input_section,
1158                         int_rel.r_vaddr - input_section->vma)))
1159                   return false;
1160               }
1161               break;
1162             }
1163         }
1164     }
1165
1166   return true;
1167 }
1168 \f
1169 /* This is the ECOFF backend structure.  The backend field of the
1170    target vector points to this.  */
1171
1172 static const struct ecoff_backend_data mips_ecoff_backend_data =
1173 {
1174   /* COFF backend structure.  */
1175   {
1176     (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */
1177     (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
1178     (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
1179     (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/
1180     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
1181     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
1182     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
1183     mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
1184     mips_ecoff_swap_scnhdr_out,
1185     FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, true,
1186     mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
1187     mips_ecoff_swap_scnhdr_in, mips_ecoff_bad_format_hook,
1188     ecoff_set_arch_mach_hook, ecoff_mkobject_hook,
1189     ecoff_styp_to_sec_flags, ecoff_make_section_hook, ecoff_set_alignment_hook,
1190     ecoff_slurp_symbol_table, NULL, NULL
1191   },
1192   /* Supported architecture.  */
1193   bfd_arch_mips,
1194   /* Initial portion of armap string.  */
1195   "__________",
1196   /* The page boundary used to align sections in a demand-paged
1197      executable file.  E.g., 0x1000.  */
1198   0x1000,
1199   /* True if the .rdata section is part of the text segment, as on the
1200      Alpha.  False if .rdata is part of the data segment, as on the
1201      MIPS.  */
1202   false,
1203   /* Bitsize of constructor entries.  */
1204   32,
1205   /* Reloc to use for constructor entries.  */
1206   &mips_howto_table[MIPS_R_REFWORD],
1207   {
1208     /* Symbol table magic number.  */
1209     magicSym,
1210     /* Alignment of debugging information.  E.g., 4.  */
1211     4,
1212     /* Sizes of external symbolic information.  */
1213     sizeof (struct hdr_ext),
1214     sizeof (struct dnr_ext),
1215     sizeof (struct pdr_ext),
1216     sizeof (struct sym_ext),
1217     sizeof (struct opt_ext),
1218     sizeof (struct fdr_ext),
1219     sizeof (struct rfd_ext),
1220     sizeof (struct ext_ext),
1221     /* Functions to swap in external symbolic data.  */
1222     ecoff_swap_hdr_in,
1223     ecoff_swap_dnr_in,
1224     ecoff_swap_pdr_in,
1225     ecoff_swap_sym_in,
1226     ecoff_swap_opt_in,
1227     ecoff_swap_fdr_in,
1228     ecoff_swap_rfd_in,
1229     ecoff_swap_ext_in,
1230     /* Functions to swap out external symbolic data.  */
1231     ecoff_swap_hdr_out,
1232     ecoff_swap_dnr_out,
1233     ecoff_swap_pdr_out,
1234     ecoff_swap_sym_out,
1235     ecoff_swap_opt_out,
1236     ecoff_swap_fdr_out,
1237     ecoff_swap_rfd_out,
1238     ecoff_swap_ext_out
1239   },
1240   /* External reloc size.  */
1241   RELSZ,
1242   /* Reloc swapping functions.  */
1243   mips_ecoff_swap_reloc_in,
1244   mips_ecoff_swap_reloc_out,
1245   /* Backend reloc tweaking.  */
1246   mips_adjust_reloc_in,
1247   mips_adjust_reloc_out,
1248   /* Relocate section contents while linking.  */
1249   mips_relocate_section
1250 };
1251
1252 /* Looking up a reloc type is MIPS specific.  */
1253 #define ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
1254
1255 /* Getting relocated section contents is generic.  */
1256 #define ecoff_bfd_get_relocated_section_contents \
1257   bfd_generic_get_relocated_section_contents
1258
1259 /* Core file support is usually traditional (but note that Irix uses
1260    irix-core.c).  */
1261 #define ecoff_core_file_p _bfd_dummy_target
1262 #define ecoff_core_file_failing_command _bfd_dummy_core_file_failing_command
1263 #define ecoff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
1264 #define ecoff_core_file_matches_executable_p \
1265   _bfd_dummy_core_file_matches_executable_p
1266
1267 bfd_target ecoff_little_vec =
1268 {
1269   "ecoff-littlemips",           /* name */
1270   bfd_target_ecoff_flavour,
1271   false,                        /* data byte order is little */
1272   false,                        /* header byte order is little */
1273
1274   (HAS_RELOC | EXEC_P |         /* object flags */
1275    HAS_LINENO | HAS_DEBUG |
1276    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1277
1278   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect
1279                                                             flags */
1280   0,                            /* leading underscore */
1281   ' ',                          /* ar_pad_char */
1282   15,                           /* ar_max_namelen */
1283   4,                            /* minimum alignment power */
1284   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1285      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1286      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1287   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1288      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1289      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
1290
1291   {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1292      ecoff_archive_p, _bfd_dummy_target},
1293   {bfd_false, ecoff_mkobject,  /* bfd_set_format */
1294      _bfd_generic_mkarchive, bfd_false},
1295   {bfd_false, ecoff_write_object_contents, /* bfd_write_contents */
1296      _bfd_write_archive_contents, bfd_false},
1297   JUMP_TABLE (ecoff),
1298   (PTR) &mips_ecoff_backend_data
1299 };
1300
1301 bfd_target ecoff_big_vec =
1302 {
1303   "ecoff-bigmips",              /* name */
1304   bfd_target_ecoff_flavour,
1305   true,                         /* data byte order is big */
1306   true,                         /* header byte order is big */
1307
1308   (HAS_RELOC | EXEC_P |         /* object flags */
1309    HAS_LINENO | HAS_DEBUG |
1310    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1311
1312   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect flags */
1313   0,                            /* leading underscore */
1314   ' ',                          /* ar_pad_char */
1315   15,                           /* ar_max_namelen */
1316   4,                            /* minimum alignment power */
1317   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1318      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1319      bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1320   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1321      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1322      bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1323  {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1324     ecoff_archive_p, ecoff_core_file_p},
1325  {bfd_false, ecoff_mkobject, /* bfd_set_format */
1326     _bfd_generic_mkarchive, bfd_false},
1327  {bfd_false, ecoff_write_object_contents, /* bfd_write_contents */
1328     _bfd_write_archive_contents, bfd_false},
1329   JUMP_TABLE(ecoff),
1330   (PTR) &mips_ecoff_backend_data
1331   /* Note that there is another bfd_target just above this one.  If
1332      you are adding initializers here, you should be adding them there
1333      as well.  */
1334 };