* bfd/aoutx.h (aout_link_input_section_std,
[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       mips_type = MIPS_R_REFWORD;
701       break;
702     case BFD_RELOC_MIPS_JMP:
703       mips_type = MIPS_R_JMPADDR;
704       break;
705     case BFD_RELOC_HI16_S:
706       mips_type = MIPS_R_REFHI;
707       break;
708     case BFD_RELOC_LO16:
709       mips_type = MIPS_R_REFLO;
710       break;
711     case BFD_RELOC_MIPS_GPREL:
712       mips_type = MIPS_R_GPREL;
713       break;
714     case BFD_RELOC_MIPS_LITERAL:
715       mips_type = MIPS_R_LITERAL;
716       break;
717     default:
718       return (CONST struct reloc_howto_struct *) NULL;
719     }
720
721   return &mips_howto_table[mips_type];
722 }
723 \f
724 /* A helper routine for mips_relocate_section which handles the REFHI
725    relocation.  The REFHI relocation must be followed by a REFLO
726    relocation, and the addend used is formed from the addends of both
727    instructions.  */
728
729 static void
730 mips_relocate_refhi (refhi, reflo, input_bfd, input_section, contents,
731                      relocation)
732      struct internal_reloc *refhi;
733      struct internal_reloc *reflo;
734      bfd *input_bfd;
735      asection *input_section;
736      bfd_byte *contents;
737      bfd_vma relocation;
738 {
739   unsigned long insn;
740   unsigned long val;
741   unsigned long vallo;
742
743   insn = bfd_get_32 (input_bfd,
744                      contents + refhi->r_vaddr - input_section->vma);
745   vallo = (bfd_get_32 (input_bfd,
746                        contents + reflo->r_vaddr - input_section->vma)
747            & 0xffff);
748   val = ((insn & 0xffff) << 16) + vallo;
749   val += relocation;
750
751   /* The low order 16 bits are always treated as a signed value.
752      Therefore, a negative value in the low order bits requires an
753      adjustment in the high order bits.  We need to make this
754      adjustment in two ways: once for the bits we took from the data,
755      and once for the bits we are putting back in to the data.  */
756   if ((vallo & 0x8000) != 0)
757     val -= 0x10000;
758   if ((val & 0x8000) != 0)
759     val += 0x10000;
760
761   insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
762   bfd_put_32 (input_bfd, (bfd_vma) insn,
763               contents + refhi->r_vaddr - input_section->vma);
764 }
765
766 /* Relocate a section while linking a MIPS ECOFF file.  */
767
768 static boolean
769 mips_relocate_section (output_bfd, info, input_bfd, input_section,
770                        contents, external_relocs)
771      bfd *output_bfd;
772      struct bfd_link_info *info;
773      bfd *input_bfd;
774      asection *input_section;
775      bfd_byte *contents;
776      PTR external_relocs;
777 {
778   asection **symndx_to_section;
779   struct ecoff_link_hash_entry **sym_hashes;
780   bfd_vma gp;
781   boolean gp_undefined;
782   struct external_reloc *ext_rel;
783   struct external_reloc *ext_rel_end;
784   boolean got_reflo;
785
786   BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
787               == output_bfd->xvec->header_byteorder_big_p);
788
789   /* We keep a table mapping the symndx found in an internal reloc to
790      the appropriate section.  This is faster than looking up the
791      section by name each time.  */
792   symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
793   if (symndx_to_section == (asection **) NULL)
794     {
795       symndx_to_section = ((asection **)
796                            bfd_alloc (input_bfd,
797                                       (NUM_RELOC_SECTIONS
798                                        * sizeof (asection *))));
799
800       symndx_to_section[RELOC_SECTION_NONE] = NULL;
801       symndx_to_section[RELOC_SECTION_TEXT] =
802         bfd_get_section_by_name (input_bfd, ".text");
803       symndx_to_section[RELOC_SECTION_RDATA] =
804         bfd_get_section_by_name (input_bfd, ".rdata");
805       symndx_to_section[RELOC_SECTION_DATA] =
806         bfd_get_section_by_name (input_bfd, ".data");
807       symndx_to_section[RELOC_SECTION_SDATA] =
808         bfd_get_section_by_name (input_bfd, ".sdata");
809       symndx_to_section[RELOC_SECTION_SBSS] =
810         bfd_get_section_by_name (input_bfd, ".sbss");
811       symndx_to_section[RELOC_SECTION_BSS] =
812         bfd_get_section_by_name (input_bfd, ".bss");
813       symndx_to_section[RELOC_SECTION_INIT] =
814         bfd_get_section_by_name (input_bfd, ".init");
815       symndx_to_section[RELOC_SECTION_LIT8] =
816         bfd_get_section_by_name (input_bfd, ".lit8");
817       symndx_to_section[RELOC_SECTION_LIT4] =
818         bfd_get_section_by_name (input_bfd, ".lit4");
819       symndx_to_section[RELOC_SECTION_XDATA] = NULL;
820       symndx_to_section[RELOC_SECTION_PDATA] = NULL;
821       symndx_to_section[RELOC_SECTION_FINI] =
822         bfd_get_section_by_name (input_bfd, ".fini");
823       symndx_to_section[RELOC_SECTION_LITA] = NULL;
824       symndx_to_section[RELOC_SECTION_ABS] = NULL;
825
826       ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
827     }
828
829   sym_hashes = ecoff_data (input_bfd)->sym_hashes;
830
831   gp = ecoff_data (output_bfd)->gp;
832   if (gp == 0)
833     gp_undefined = true;
834   else
835     gp_undefined = false;
836
837   got_reflo = false;
838
839   ext_rel = (struct external_reloc *) external_relocs;
840   ext_rel_end = ext_rel + input_section->reloc_count;
841   for (; ext_rel < ext_rel_end; ext_rel++)
842     {
843       struct internal_reloc int_rel;
844       struct internal_reloc reflo_int_rel;
845       bfd_vma addend;
846       reloc_howto_type *howto;
847       struct ecoff_link_hash_entry *h = NULL;
848       asection *s = NULL;
849       bfd_vma relocation;
850       bfd_reloc_status_type r;
851
852       if (! got_reflo)
853         mips_ecoff_swap_reloc_in (input_bfd, (PTR) ext_rel, &int_rel);
854       else
855         {
856           int_rel = reflo_int_rel;
857           got_reflo = false;
858         }
859
860       BFD_ASSERT (int_rel.r_type
861                   < sizeof mips_howto_table / sizeof mips_howto_table[0]);
862
863       /* The REFHI reloc requires special handling.  It must be
864          followed by a REFLO reloc, and the addend is formed from both
865          fields.  */
866       if (int_rel.r_type == MIPS_R_REFHI)
867         {
868           BFD_ASSERT ((ext_rel + 1) < ext_rel_end);
869           mips_ecoff_swap_reloc_in (input_bfd, (PTR) (ext_rel + 1),
870                                     &reflo_int_rel);
871           BFD_ASSERT (reflo_int_rel.r_type == MIPS_R_REFLO
872                       && int_rel.r_extern == reflo_int_rel.r_extern
873                       && int_rel.r_symndx == reflo_int_rel.r_symndx);
874           got_reflo = true;
875         }
876
877       howto = &mips_howto_table[int_rel.r_type];
878
879       if (int_rel.r_extern)
880         {
881           h = sym_hashes[int_rel.r_symndx];
882           /* If h is NULL, that means that there is a reloc against an
883              external symbol which we thought was just a debugging
884              symbol.  This should not happen.  */
885           if (h == (struct ecoff_link_hash_entry *) NULL)
886             abort ();
887         }
888       else
889         {
890           if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS)
891             s = NULL;
892           else
893             s = symndx_to_section[int_rel.r_symndx];
894
895           if (s == (asection *) NULL)
896             abort ();
897         }
898
899       /* The GPREL reloc uses an addend: the difference in the GP
900          values.  */
901       if (int_rel.r_type != MIPS_R_GPREL)
902         addend = 0;
903       else
904         {
905           if (gp_undefined)
906             {
907               if (! ((*info->callbacks->reloc_dangerous)
908                      (info, "GP relative relocation when GP not defined",
909                       input_bfd, input_section,
910                       int_rel.r_vaddr - input_section->vma)))
911                 return false;
912               /* Only give the error once per link.  */
913               ecoff_data (output_bfd)->gp = gp = 4;
914               gp_undefined = false;
915             }
916           if (! int_rel.r_extern)
917             {
918               /* This is a relocation against a section.  The current
919                  addend in the instruction is the difference between
920                  INPUT_SECTION->vma and the GP value of INPUT_BFD.  We
921                  must change this to be the difference between the
922                  final definition (which will end up in RELOCATION)
923                  and the GP value of OUTPUT_BFD (which is in GP).  */
924               addend = ecoff_data (input_bfd)->gp - gp;
925             }
926           else if (! info->relocateable
927                    || h->root.type == bfd_link_hash_defined)
928             {
929               /* This is a relocation against an undefined or common
930                  symbol.  The current addend in the instruction is
931                  simply the desired offset into the symbol (normally
932                  zero).  We are going to change this into a relocation
933                  against a defined symbol, so we want the instruction
934                  to hold the difference between the final definition
935                  of the symbol (which will end up in RELOCATION) and
936                  the GP value of OUTPUT_BFD (which is in GP).  */
937               addend = - gp;
938             }
939           else
940             {
941               /* This is a relocation against an undefined or common
942                  symbol.  The current addend in the instruction is
943                  simply the desired offset into the symbol (normally
944                  zero).  We are generating relocateable output, and we
945                  aren't going to define this symbol, so we just leave
946                  the instruction alone.  */
947               addend = 0;
948             }
949         }
950
951       if (info->relocateable)
952         {
953           /* We are generating relocateable output, and must convert
954              the existing reloc.  */
955           if (int_rel.r_extern)
956             {
957               if (h->root.type == bfd_link_hash_defined)
958                 {
959                   asection *hsec;
960                   const char *name;
961
962                   /* This symbol is defined in the output.  Convert
963                      the reloc from being against the symbol to being
964                      against the section.  */
965
966                   /* Clear the r_extern bit.  */
967                   int_rel.r_extern = 0;
968
969                   /* Compute a new r_symndx value.  */
970                   hsec = h->root.u.def.section;
971                   name = bfd_get_section_name (output_bfd,
972                                                hsec->output_section);
973
974                   int_rel.r_symndx = -1;
975                   switch (name[1])
976                     {
977                     case 'b':
978                       if (strcmp (name, ".bss") == 0)
979                         int_rel.r_symndx = RELOC_SECTION_BSS;
980                       break;
981                     case 'd':
982                       if (strcmp (name, ".data") == 0)
983                         int_rel.r_symndx = RELOC_SECTION_DATA;
984                       break;
985                     case 'f':
986                       if (strcmp (name, ".fini") == 0)
987                         int_rel.r_symndx = RELOC_SECTION_FINI;
988                       break;
989                     case 'i':
990                       if (strcmp (name, ".init") == 0)
991                         int_rel.r_symndx = RELOC_SECTION_INIT;
992                       break;
993                     case 'l':
994                       if (strcmp (name, ".lit8") == 0)
995                         int_rel.r_symndx = RELOC_SECTION_LIT8;
996                       else if (strcmp (name, ".lit4") == 0)
997                         int_rel.r_symndx = RELOC_SECTION_LIT4;
998                       break;
999                     case 'r':
1000                       if (strcmp (name, ".rdata") == 0)
1001                         int_rel.r_symndx = RELOC_SECTION_RDATA;
1002                       break;
1003                     case 's':
1004                       if (strcmp (name, ".sdata") == 0)
1005                         int_rel.r_symndx = RELOC_SECTION_SDATA;
1006                       else if (strcmp (name, ".sbss") == 0)
1007                         int_rel.r_symndx = RELOC_SECTION_SBSS;
1008                       break;
1009                     case 't':
1010                       if (strcmp (name, ".text") == 0)
1011                         int_rel.r_symndx = RELOC_SECTION_TEXT;
1012                       break;
1013                     }
1014                       
1015                   if (int_rel.r_symndx == -1)
1016                     abort ();
1017
1018                   /* Add the section VMA and the symbol value.  */
1019                   relocation = (h->root.u.def.value
1020                                 + hsec->output_section->vma
1021                                 + hsec->output_offset);
1022                 }
1023               else
1024                 {
1025                   /* Change the symndx value to the right one for the
1026                      output BFD.  */
1027                   int_rel.r_symndx = h->indx;
1028                   if (int_rel.r_symndx == -1)
1029                     {
1030                       /* This symbol is not being written out.  */
1031                       if (! ((*info->callbacks->unattached_reloc)
1032                              (info, h->root.root.string, input_bfd,
1033                               input_section,
1034                               int_rel.r_vaddr - input_section->vma)))
1035                         return false;
1036                       int_rel.r_symndx = 0;
1037                     }
1038                   relocation = 0;
1039                 }
1040             }
1041           else
1042             {
1043               /* This is a relocation against a section.  Adjust the
1044                  value by the amount the section moved.  */
1045               relocation = (s->output_section->vma
1046                             + s->output_offset
1047                             - s->vma);
1048             }
1049
1050           relocation += addend;
1051
1052           /* Adjust the contents.  */
1053           if (relocation == 0)
1054             r = bfd_reloc_ok;
1055           else
1056             {
1057               if (int_rel.r_type != MIPS_R_REFHI)
1058                 r = _bfd_relocate_contents (howto, input_bfd, relocation,
1059                                             (contents
1060                                              + int_rel.r_vaddr
1061                                              - input_section->vma));
1062               else
1063                 {
1064                   mips_relocate_refhi (&int_rel, &reflo_int_rel,
1065                                        input_bfd, input_section, contents,
1066                                        relocation);
1067                   r = bfd_reloc_ok;
1068                 }
1069             }
1070
1071           /* Adjust the reloc address.  */
1072           int_rel.r_vaddr += (input_section->output_section->vma
1073                               + input_section->output_offset
1074                               - input_section->vma);
1075
1076           /* Save the changed reloc information.  */
1077           mips_ecoff_swap_reloc_out (input_bfd, &int_rel, (PTR) ext_rel);
1078         }
1079       else
1080         {
1081           /* We are producing a final executable.  */
1082           if (int_rel.r_extern)
1083             {
1084               /* This is a reloc against a symbol.  */
1085               if (h->root.type == bfd_link_hash_defined)
1086                 {
1087                   asection *hsec;
1088
1089                   hsec = h->root.u.def.section;
1090                   relocation = (h->root.u.def.value
1091                                 + hsec->output_section->vma
1092                                 + hsec->output_offset);
1093                 }
1094               else
1095                 {
1096                   if (! ((*info->callbacks->undefined_symbol)
1097                          (info, h->root.root.string, input_bfd,
1098                           input_section,
1099                           int_rel.r_vaddr - input_section->vma)))
1100                     return false;
1101                   relocation = 0;
1102                 }
1103             }
1104           else
1105             {
1106               /* This is a reloc against a section.  */
1107               relocation = (s->output_section->vma
1108                             + s->output_offset
1109                             - s->vma);
1110
1111               /* Adjust a PC relative relocation by removing the
1112                  reference to the original source section.  */
1113               if (howto->pc_relative)
1114                 relocation += input_section->vma;
1115             }
1116
1117           if (int_rel.r_type != MIPS_R_REFHI)
1118             r = _bfd_final_link_relocate (howto,
1119                                           input_bfd,
1120                                           input_section,
1121                                           contents,
1122                                           int_rel.r_vaddr - input_section->vma,
1123                                           relocation,
1124                                           addend);
1125           else
1126             {
1127               mips_relocate_refhi (&int_rel, &reflo_int_rel, input_bfd,
1128                                    input_section, contents, relocation);
1129               r = bfd_reloc_ok;
1130             }
1131         }
1132
1133       if (r != bfd_reloc_ok)
1134         {
1135           switch (r)
1136             {
1137             default:
1138             case bfd_reloc_outofrange:
1139               abort ();
1140             case bfd_reloc_overflow:
1141               {
1142                 const char *name;
1143
1144                 if (int_rel.r_extern)
1145                   name = h->root.root.string;
1146                 else
1147                   name = bfd_section_name (input_bfd, s);
1148                 if (! ((*info->callbacks->reloc_overflow)
1149                        (info, name, howto->name, (bfd_vma) 0,
1150                         input_bfd, input_section,
1151                         int_rel.r_vaddr - input_section->vma)))
1152                   return false;
1153               }
1154               break;
1155             }
1156         }
1157     }
1158
1159   return true;
1160 }
1161 \f
1162 /* This is the ECOFF backend structure.  The backend field of the
1163    target vector points to this.  */
1164
1165 static const struct ecoff_backend_data mips_ecoff_backend_data =
1166 {
1167   /* COFF backend structure.  */
1168   {
1169     (void (*) PARAMS ((bfd *,PTR,int,int,PTR))) bfd_void, /* aux_in */
1170     (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
1171     (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
1172     (unsigned (*) PARAMS ((bfd *,PTR,int,int,PTR))) bfd_void, /* aux_out */
1173     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
1174     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
1175     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
1176     mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
1177     mips_ecoff_swap_scnhdr_out,
1178     FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, true,
1179     mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
1180     mips_ecoff_swap_scnhdr_in, mips_ecoff_bad_format_hook,
1181     ecoff_set_arch_mach_hook, ecoff_mkobject_hook,
1182     ecoff_styp_to_sec_flags, ecoff_make_section_hook, ecoff_set_alignment_hook,
1183     ecoff_slurp_symbol_table, NULL, NULL
1184   },
1185   /* Supported architecture.  */
1186   bfd_arch_mips,
1187   /* Initial portion of armap string.  */
1188   "__________",
1189   /* The page boundary used to align sections in a demand-paged
1190      executable file.  E.g., 0x1000.  */
1191   0x1000,
1192   /* True if the .rdata section is part of the text segment, as on the
1193      Alpha.  False if .rdata is part of the data segment, as on the
1194      MIPS.  */
1195   false,
1196   /* Bitsize of constructor entries.  */
1197   32,
1198   /* Reloc to use for constructor entries.  */
1199   &mips_howto_table[MIPS_R_REFWORD],
1200   {
1201     /* Symbol table magic number.  */
1202     magicSym,
1203     /* Alignment of debugging information.  E.g., 4.  */
1204     4,
1205     /* Sizes of external symbolic information.  */
1206     sizeof (struct hdr_ext),
1207     sizeof (struct dnr_ext),
1208     sizeof (struct pdr_ext),
1209     sizeof (struct sym_ext),
1210     sizeof (struct opt_ext),
1211     sizeof (struct fdr_ext),
1212     sizeof (struct rfd_ext),
1213     sizeof (struct ext_ext),
1214     /* Functions to swap in external symbolic data.  */
1215     ecoff_swap_hdr_in,
1216     ecoff_swap_dnr_in,
1217     ecoff_swap_pdr_in,
1218     ecoff_swap_sym_in,
1219     ecoff_swap_opt_in,
1220     ecoff_swap_fdr_in,
1221     ecoff_swap_rfd_in,
1222     ecoff_swap_ext_in,
1223     /* Functions to swap out external symbolic data.  */
1224     ecoff_swap_hdr_out,
1225     ecoff_swap_dnr_out,
1226     ecoff_swap_pdr_out,
1227     ecoff_swap_sym_out,
1228     ecoff_swap_opt_out,
1229     ecoff_swap_fdr_out,
1230     ecoff_swap_rfd_out,
1231     ecoff_swap_ext_out
1232   },
1233   /* External reloc size.  */
1234   RELSZ,
1235   /* Reloc swapping functions.  */
1236   mips_ecoff_swap_reloc_in,
1237   mips_ecoff_swap_reloc_out,
1238   /* Backend reloc tweaking.  */
1239   mips_adjust_reloc_in,
1240   mips_adjust_reloc_out,
1241   /* Relocate section contents while linking.  */
1242   mips_relocate_section
1243 };
1244
1245 /* Looking up a reloc type is MIPS specific.  */
1246 #define ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
1247
1248 /* Getting relocated section contents is generic.  */
1249 #define ecoff_bfd_get_relocated_section_contents \
1250   bfd_generic_get_relocated_section_contents
1251
1252 /* Core file support is usually traditional (but note that Irix uses
1253    irix-core.c).  */
1254 #define ecoff_core_file_p _bfd_dummy_target
1255 #define ecoff_core_file_failing_command _bfd_dummy_core_file_failing_command
1256 #define ecoff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
1257 #define ecoff_core_file_matches_executable_p \
1258   _bfd_dummy_core_file_matches_executable_p
1259
1260 bfd_target ecoff_little_vec =
1261 {
1262   "ecoff-littlemips",           /* name */
1263   bfd_target_ecoff_flavour,
1264   false,                        /* data byte order is little */
1265   false,                        /* header byte order is little */
1266
1267   (HAS_RELOC | EXEC_P |         /* object flags */
1268    HAS_LINENO | HAS_DEBUG |
1269    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1270
1271   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect
1272                                                             flags */
1273   0,                            /* leading underscore */
1274   ' ',                          /* ar_pad_char */
1275   15,                           /* ar_max_namelen */
1276   4,                            /* minimum alignment power */
1277   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1278      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1279      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1280   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1281      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1282      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
1283
1284   {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1285      ecoff_archive_p, _bfd_dummy_target},
1286   {bfd_false, ecoff_mkobject,  /* bfd_set_format */
1287      _bfd_generic_mkarchive, bfd_false},
1288   {bfd_false, ecoff_write_object_contents, /* bfd_write_contents */
1289      _bfd_write_archive_contents, bfd_false},
1290   JUMP_TABLE (ecoff),
1291   (PTR) &mips_ecoff_backend_data
1292 };
1293
1294 bfd_target ecoff_big_vec =
1295 {
1296   "ecoff-bigmips",              /* name */
1297   bfd_target_ecoff_flavour,
1298   true,                         /* data byte order is big */
1299   true,                         /* header byte order is big */
1300
1301   (HAS_RELOC | EXEC_P |         /* object flags */
1302    HAS_LINENO | HAS_DEBUG |
1303    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1304
1305   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect flags */
1306   0,                            /* leading underscore */
1307   ' ',                          /* ar_pad_char */
1308   15,                           /* ar_max_namelen */
1309   4,                            /* minimum alignment power */
1310   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1311      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1312      bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1313   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1314      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1315      bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1316  {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1317     ecoff_archive_p, ecoff_core_file_p},
1318  {bfd_false, ecoff_mkobject, /* bfd_set_format */
1319     _bfd_generic_mkarchive, bfd_false},
1320  {bfd_false, ecoff_write_object_contents, /* bfd_write_contents */
1321     _bfd_write_archive_contents, bfd_false},
1322   JUMP_TABLE(ecoff),
1323   (PTR) &mips_ecoff_backend_data
1324   /* Note that there is another bfd_target just above this one.  If
1325      you are adding initializers here, you should be adding them there
1326      as well.  */
1327 };