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