Automatic date update in version.in
[external/binutils.git] / bfd / coff-mips.c
1 /* BFD back-end for MIPS Extended-Coff files.
2    Copyright (C) 1990-2017 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 3 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., 51 Franklin Street - Fifth Floor, Boston,
21    MA 02110-1301, USA.  */
22
23 #include "sysdep.h"
24 #include "bfd.h"
25 #include "bfdlink.h"
26 #include "libbfd.h"
27 #include "coff/internal.h"
28 #include "coff/sym.h"
29 #include "coff/symconst.h"
30 #include "coff/ecoff.h"
31 #include "coff/mips.h"
32 #include "libcoff.h"
33 #include "libecoff.h"
34 \f
35 /* Prototypes for static functions.  */
36 static bfd_reloc_status_type
37 mips_generic_reloc
38   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
39 static bfd_reloc_status_type
40 mips_refhi_reloc
41   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
42 static bfd_reloc_status_type
43 mips_reflo_reloc
44   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
45 static bfd_reloc_status_type
46 mips_gprel_reloc
47   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
48
49 \f
50 /* ECOFF has COFF sections, but the debugging information is stored in
51    a completely different format.  ECOFF targets use some of the
52    swapping routines from coffswap.h, and some of the generic COFF
53    routines in coffgen.c, but, unlike the real COFF targets, do not
54    use coffcode.h itself.
55
56    Get the generic COFF swapping routines, except for the reloc,
57    symbol, and lineno ones.  Give them ECOFF names.  */
58 #define MIPSECOFF
59 #define NO_COFF_RELOCS
60 #define NO_COFF_SYMBOLS
61 #define NO_COFF_LINENOS
62 #define coff_swap_filehdr_in  mips_ecoff_swap_filehdr_in
63 #define coff_swap_filehdr_out mips_ecoff_swap_filehdr_out
64 #define coff_swap_aouthdr_in  mips_ecoff_swap_aouthdr_in
65 #define coff_swap_aouthdr_out mips_ecoff_swap_aouthdr_out
66 #define coff_swap_scnhdr_in   mips_ecoff_swap_scnhdr_in
67 #define coff_swap_scnhdr_out  mips_ecoff_swap_scnhdr_out
68
69 #include "coffswap.h"
70
71 /* Get the ECOFF swapping routines.  */
72 #define ECOFF_32
73 #include "ecoffswap.h"
74 \f
75 /* How to process the various relocs types.  */
76
77 static reloc_howto_type mips_howto_table[] =
78 {
79   /* Reloc type 0 is ignored.  The reloc reading code ensures that
80      this is a reference to the .abs section, which will cause
81      bfd_perform_relocation to do nothing.  */
82   HOWTO (MIPS_R_IGNORE, /* type */
83          0,                     /* rightshift */
84          0,                     /* size (0 = byte, 1 = short, 2 = long) */
85          8,                     /* bitsize */
86          FALSE,                 /* pc_relative */
87          0,                     /* bitpos */
88          complain_overflow_dont, /* complain_on_overflow */
89          0,                     /* special_function */
90          "IGNORE",              /* name */
91          FALSE,                 /* partial_inplace */
92          0,                     /* src_mask */
93          0,                     /* dst_mask */
94          FALSE),                /* pcrel_offset */
95
96   /* A 16 bit reference to a symbol, normally from a data section.  */
97   HOWTO (MIPS_R_REFHALF,        /* type */
98          0,                     /* rightshift */
99          1,                     /* size (0 = byte, 1 = short, 2 = long) */
100          16,                    /* bitsize */
101          FALSE,                 /* pc_relative */
102          0,                     /* bitpos */
103          complain_overflow_bitfield, /* complain_on_overflow */
104          mips_generic_reloc,    /* special_function */
105          "REFHALF",             /* name */
106          TRUE,                  /* partial_inplace */
107          0xffff,                /* src_mask */
108          0xffff,                /* dst_mask */
109          FALSE),                /* pcrel_offset */
110
111   /* A 32 bit reference to a symbol, normally from a data section.  */
112   HOWTO (MIPS_R_REFWORD,        /* type */
113          0,                     /* rightshift */
114          2,                     /* size (0 = byte, 1 = short, 2 = long) */
115          32,                    /* bitsize */
116          FALSE,                 /* pc_relative */
117          0,                     /* bitpos */
118          complain_overflow_bitfield, /* complain_on_overflow */
119          mips_generic_reloc,    /* special_function */
120          "REFWORD",             /* name */
121          TRUE,                  /* partial_inplace */
122          0xffffffff,            /* src_mask */
123          0xffffffff,            /* dst_mask */
124          FALSE),                /* pcrel_offset */
125
126   /* A 26 bit absolute jump address.  */
127   HOWTO (MIPS_R_JMPADDR,        /* type */
128          2,                     /* rightshift */
129          2,                     /* size (0 = byte, 1 = short, 2 = long) */
130          26,                    /* bitsize */
131          FALSE,                 /* pc_relative */
132          0,                     /* bitpos */
133          complain_overflow_dont, /* complain_on_overflow */
134                                 /* This needs complex overflow
135                                    detection, because the upper four
136                                    bits must match the PC.  */
137          mips_generic_reloc,    /* special_function */
138          "JMPADDR",             /* name */
139          TRUE,                  /* partial_inplace */
140          0x3ffffff,             /* src_mask */
141          0x3ffffff,             /* dst_mask */
142          FALSE),                /* pcrel_offset */
143
144   /* The high 16 bits of a symbol value.  Handled by the function
145      mips_refhi_reloc.  */
146   HOWTO (MIPS_R_REFHI,          /* type */
147          16,                    /* rightshift */
148          2,                     /* size (0 = byte, 1 = short, 2 = long) */
149          16,                    /* bitsize */
150          FALSE,                 /* pc_relative */
151          0,                     /* bitpos */
152          complain_overflow_bitfield, /* complain_on_overflow */
153          mips_refhi_reloc,      /* special_function */
154          "REFHI",               /* name */
155          TRUE,                  /* partial_inplace */
156          0xffff,                /* src_mask */
157          0xffff,                /* dst_mask */
158          FALSE),                /* pcrel_offset */
159
160   /* The low 16 bits of a symbol value.  */
161   HOWTO (MIPS_R_REFLO,          /* type */
162          0,                     /* rightshift */
163          2,                     /* size (0 = byte, 1 = short, 2 = long) */
164          16,                    /* bitsize */
165          FALSE,                 /* pc_relative */
166          0,                     /* bitpos */
167          complain_overflow_dont, /* complain_on_overflow */
168          mips_reflo_reloc,      /* special_function */
169          "REFLO",               /* name */
170          TRUE,                  /* partial_inplace */
171          0xffff,                /* src_mask */
172          0xffff,                /* dst_mask */
173          FALSE),                /* pcrel_offset */
174
175   /* A reference to an offset from the gp register.  Handled by the
176      function mips_gprel_reloc.  */
177   HOWTO (MIPS_R_GPREL,          /* type */
178          0,                     /* rightshift */
179          2,                     /* size (0 = byte, 1 = short, 2 = long) */
180          16,                    /* bitsize */
181          FALSE,                 /* pc_relative */
182          0,                     /* bitpos */
183          complain_overflow_signed, /* complain_on_overflow */
184          mips_gprel_reloc,      /* special_function */
185          "GPREL",               /* name */
186          TRUE,                  /* partial_inplace */
187          0xffff,                /* src_mask */
188          0xffff,                /* dst_mask */
189          FALSE),                /* pcrel_offset */
190
191   /* A reference to a literal using an offset from the gp register.
192      Handled by the function mips_gprel_reloc.  */
193   HOWTO (MIPS_R_LITERAL,        /* type */
194          0,                     /* rightshift */
195          2,                     /* size (0 = byte, 1 = short, 2 = long) */
196          16,                    /* bitsize */
197          FALSE,                 /* pc_relative */
198          0,                     /* bitpos */
199          complain_overflow_signed, /* complain_on_overflow */
200          mips_gprel_reloc,      /* special_function */
201          "LITERAL",             /* name */
202          TRUE,                  /* partial_inplace */
203          0xffff,                /* src_mask */
204          0xffff,                /* dst_mask */
205          FALSE),                /* pcrel_offset */
206
207   EMPTY_HOWTO (8),
208   EMPTY_HOWTO (9),
209   EMPTY_HOWTO (10),
210   EMPTY_HOWTO (11),
211
212   /* FIXME: This relocation is used (internally only) to represent branches
213      when assembling.  It should never appear in output files, and
214      be removed.  (It used to be used for embedded-PIC support.)  */
215   HOWTO (MIPS_R_PCREL16,        /* type */
216          2,                     /* rightshift */
217          2,                     /* size (0 = byte, 1 = short, 2 = long) */
218          16,                    /* bitsize */
219          TRUE,                  /* pc_relative */
220          0,                     /* bitpos */
221          complain_overflow_signed, /* complain_on_overflow */
222          mips_generic_reloc,    /* special_function */
223          "PCREL16",             /* name */
224          TRUE,                  /* partial_inplace */
225          0xffff,                /* src_mask */
226          0xffff,                /* dst_mask */
227          TRUE),                 /* pcrel_offset */
228 };
229
230 #define MIPS_HOWTO_COUNT \
231   (sizeof mips_howto_table / sizeof mips_howto_table[0])
232 \f
233 /* See whether the magic number matches.  */
234
235 static bfd_boolean
236 mips_ecoff_bad_format_hook (bfd * abfd, void * filehdr)
237 {
238   struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
239
240   switch (internal_f->f_magic)
241     {
242     case MIPS_MAGIC_1:
243       /* I don't know what endianness this implies.  */
244       return TRUE;
245
246     case MIPS_MAGIC_BIG:
247     case MIPS_MAGIC_BIG2:
248     case MIPS_MAGIC_BIG3:
249       return bfd_big_endian (abfd);
250
251     case MIPS_MAGIC_LITTLE:
252     case MIPS_MAGIC_LITTLE2:
253     case MIPS_MAGIC_LITTLE3:
254       return bfd_little_endian (abfd);
255
256     default:
257       return FALSE;
258     }
259 }
260 \f
261 /* Reloc handling.  MIPS ECOFF relocs are packed into 8 bytes in
262    external form.  They use a bit which indicates whether the symbol
263    is external.  */
264
265 /* Swap a reloc in.  */
266
267 static void
268 mips_ecoff_swap_reloc_in (bfd *  abfd,
269                           void * ext_ptr,
270                           struct internal_reloc *intern)
271 {
272   const RELOC *ext = (RELOC *) ext_ptr;
273
274   intern->r_vaddr = H_GET_32 (abfd, ext->r_vaddr);
275   if (bfd_header_big_endian (abfd))
276     {
277       intern->r_symndx = (((int) ext->r_bits[0]
278                            << RELOC_BITS0_SYMNDX_SH_LEFT_BIG)
279                           | ((int) ext->r_bits[1]
280                              << RELOC_BITS1_SYMNDX_SH_LEFT_BIG)
281                           | ((int) ext->r_bits[2]
282                              << RELOC_BITS2_SYMNDX_SH_LEFT_BIG));
283       intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_BIG)
284                         >> RELOC_BITS3_TYPE_SH_BIG);
285       intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_BIG) != 0;
286     }
287   else
288     {
289       intern->r_symndx = (((int) ext->r_bits[0]
290                            << RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE)
291                           | ((int) ext->r_bits[1]
292                              << RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE)
293                           | ((int) ext->r_bits[2]
294                              << RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE));
295       intern->r_type = (((ext->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
296                          >> RELOC_BITS3_TYPE_SH_LITTLE)
297                         | ((ext->r_bits[3] & RELOC_BITS3_TYPEHI_LITTLE)
298                            << RELOC_BITS3_TYPEHI_SH_LITTLE));
299       intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0;
300     }
301 }
302
303 /* Swap a reloc out.  */
304
305 static void
306 mips_ecoff_swap_reloc_out (bfd * abfd,
307                            const struct internal_reloc * intern,
308                            void * dst)
309 {
310   RELOC *ext = (RELOC *) dst;
311   long r_symndx;
312
313   BFD_ASSERT (intern->r_extern
314               || (intern->r_symndx >= 0 && intern->r_symndx <= 12));
315
316   r_symndx = intern->r_symndx;
317
318   H_PUT_32 (abfd, intern->r_vaddr, ext->r_vaddr);
319   if (bfd_header_big_endian (abfd))
320     {
321       ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_BIG;
322       ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_BIG;
323       ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_BIG;
324       ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_BIG)
325                          & RELOC_BITS3_TYPE_BIG)
326                         | (intern->r_extern ? RELOC_BITS3_EXTERN_BIG : 0));
327     }
328   else
329     {
330       ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE;
331       ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE;
332       ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE;
333       ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_LITTLE)
334                          & RELOC_BITS3_TYPE_LITTLE)
335                         | ((intern->r_type >> RELOC_BITS3_TYPEHI_SH_LITTLE
336                             & RELOC_BITS3_TYPEHI_LITTLE))
337                         | (intern->r_extern ? RELOC_BITS3_EXTERN_LITTLE : 0));
338     }
339 }
340
341 /* Finish canonicalizing a reloc.  Part of this is generic to all
342    ECOFF targets, and that part is in ecoff.c.  The rest is done in
343    this backend routine.  It must fill in the howto field.  */
344
345 static void
346 mips_adjust_reloc_in (bfd *abfd,
347                       const struct internal_reloc *intern,
348                       arelent *rptr)
349 {
350   if (intern->r_type > MIPS_R_PCREL16)
351     abort ();
352
353   if (! intern->r_extern
354       && (intern->r_type == MIPS_R_GPREL
355           || intern->r_type == MIPS_R_LITERAL))
356     rptr->addend += ecoff_data (abfd)->gp;
357
358   /* If the type is MIPS_R_IGNORE, make sure this is a reference to
359      the absolute section so that the reloc is ignored.  */
360   if (intern->r_type == MIPS_R_IGNORE)
361     rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
362
363   rptr->howto = &mips_howto_table[intern->r_type];
364 }
365
366 /* Make any adjustments needed to a reloc before writing it out.  None
367    are needed for MIPS.  */
368
369 static void
370 mips_adjust_reloc_out (bfd *abfd ATTRIBUTE_UNUSED,
371                        const arelent *rel ATTRIBUTE_UNUSED,
372                        struct internal_reloc *intern ATTRIBUTE_UNUSED)
373 {
374 }
375
376 /* ECOFF relocs are either against external symbols, or against
377    sections.  If we are producing relocatable output, and the reloc
378    is against an external symbol, and nothing has given us any
379    additional addend, the resulting reloc will also be against the
380    same symbol.  In such a case, we don't want to change anything
381    about the way the reloc is handled, since it will all be done at
382    final link time.  Rather than put special case code into
383    bfd_perform_relocation, all the reloc types use this howto
384    function.  It just short circuits the reloc if producing
385    relocatable output against an external symbol.  */
386
387 static bfd_reloc_status_type
388 mips_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED,
389                     arelent *reloc_entry,
390                     asymbol *symbol,
391                     void * data ATTRIBUTE_UNUSED,
392                     asection *input_section,
393                     bfd *output_bfd,
394                     char **error_message ATTRIBUTE_UNUSED)
395 {
396   if (output_bfd != (bfd *) NULL
397       && (symbol->flags & BSF_SECTION_SYM) == 0
398       && reloc_entry->addend == 0)
399     {
400       reloc_entry->address += input_section->output_offset;
401       return bfd_reloc_ok;
402     }
403
404   return bfd_reloc_continue;
405 }
406
407 /* Do a REFHI relocation.  This has to be done in combination with a
408    REFLO reloc, because there is a carry from the REFLO to the REFHI.
409    Here we just save the information we need; we do the actual
410    relocation when we see the REFLO.  MIPS ECOFF requires that the
411    REFLO immediately follow the REFHI.  As a GNU extension, we permit
412    an arbitrary number of HI relocs to be associated with a single LO
413    reloc.  This extension permits gcc to output the HI and LO relocs
414    itself.  */
415
416 struct mips_hi
417 {
418   struct mips_hi *next;
419   bfd_byte *addr;
420   bfd_vma addend;
421 };
422
423 /* FIXME: This should not be a static variable.  */
424
425 static struct mips_hi *mips_refhi_list;
426
427 static bfd_reloc_status_type
428 mips_refhi_reloc (bfd *abfd ATTRIBUTE_UNUSED,
429                   arelent *reloc_entry,
430                   asymbol *symbol,
431                   void * data,
432                   asection *input_section,
433                   bfd *output_bfd,
434                   char **error_message ATTRIBUTE_UNUSED)
435 {
436   bfd_reloc_status_type ret;
437   bfd_vma relocation;
438   struct mips_hi *n;
439
440   /* If we're relocating, and this an external symbol, we don't want
441      to change anything.  */
442   if (output_bfd != (bfd *) NULL
443       && (symbol->flags & BSF_SECTION_SYM) == 0
444       && reloc_entry->addend == 0)
445     {
446       reloc_entry->address += input_section->output_offset;
447       return bfd_reloc_ok;
448     }
449
450   ret = bfd_reloc_ok;
451   if (bfd_is_und_section (symbol->section)
452       && output_bfd == (bfd *) NULL)
453     ret = bfd_reloc_undefined;
454
455   if (bfd_is_com_section (symbol->section))
456     relocation = 0;
457   else
458     relocation = symbol->value;
459
460   relocation += symbol->section->output_section->vma;
461   relocation += symbol->section->output_offset;
462   relocation += reloc_entry->addend;
463
464   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
465     return bfd_reloc_outofrange;
466
467   /* Save the information, and let REFLO do the actual relocation.  */
468   n = (struct mips_hi *) bfd_malloc ((bfd_size_type) sizeof *n);
469   if (n == NULL)
470     return bfd_reloc_outofrange;
471   n->addr = (bfd_byte *) data + reloc_entry->address;
472   n->addend = relocation;
473   n->next = mips_refhi_list;
474   mips_refhi_list = n;
475
476   if (output_bfd != (bfd *) NULL)
477     reloc_entry->address += input_section->output_offset;
478
479   return ret;
480 }
481
482 /* Do a REFLO relocation.  This is a straightforward 16 bit inplace
483    relocation; this function exists in order to do the REFHI
484    relocation described above.  */
485
486 static bfd_reloc_status_type
487 mips_reflo_reloc (bfd *abfd ATTRIBUTE_UNUSED,
488                   arelent *reloc_entry,
489                   asymbol *symbol,
490                   void * data,
491                   asection *input_section,
492                   bfd *output_bfd,
493                   char **error_message ATTRIBUTE_UNUSED)
494 {
495   if (mips_refhi_list != NULL)
496     {
497       struct mips_hi *l;
498
499       l = mips_refhi_list;
500       while (l != NULL)
501         {
502           unsigned long insn;
503           unsigned long val;
504           unsigned long vallo;
505           struct mips_hi *next;
506
507           /* Do the REFHI relocation.  Note that we actually don't
508              need to know anything about the REFLO itself, except
509              where to find the low 16 bits of the addend needed by the
510              REFHI.  */
511           insn = bfd_get_32 (abfd, l->addr);
512           vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
513                    & 0xffff);
514           val = ((insn & 0xffff) << 16) + vallo;
515           val += l->addend;
516
517           /* The low order 16 bits are always treated as a signed
518              value.  Therefore, a negative value in the low order bits
519              requires an adjustment in the high order bits.  We need
520              to make this adjustment in two ways: once for the bits we
521              took from the data, and once for the bits we are putting
522              back in to the data.  */
523           if ((vallo & 0x8000) != 0)
524             val -= 0x10000;
525           if ((val & 0x8000) != 0)
526             val += 0x10000;
527
528           insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
529           bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
530
531           next = l->next;
532           free (l);
533           l = next;
534         }
535
536       mips_refhi_list = NULL;
537     }
538
539   /* Now do the REFLO reloc in the usual way.  */
540   return mips_generic_reloc (abfd, reloc_entry, symbol, data,
541                               input_section, output_bfd, error_message);
542 }
543
544 /* Do a GPREL relocation.  This is a 16 bit value which must become
545    the offset from the gp register.  */
546
547 static bfd_reloc_status_type
548 mips_gprel_reloc (bfd *abfd ATTRIBUTE_UNUSED,
549                   arelent *reloc_entry,
550                   asymbol *symbol,
551                   void * data,
552                   asection *input_section,
553                   bfd *output_bfd,
554                   char **error_message ATTRIBUTE_UNUSED)
555 {
556   bfd_boolean relocatable;
557   bfd_vma gp;
558   bfd_vma relocation;
559   unsigned long val;
560   unsigned long insn;
561
562   /* If we're relocating, and this is an external symbol with no
563      addend, we don't want to change anything.  We will only have an
564      addend if this is a newly created reloc, not read from an ECOFF
565      file.  */
566   if (output_bfd != (bfd *) NULL
567       && (symbol->flags & BSF_SECTION_SYM) == 0
568       && reloc_entry->addend == 0)
569     {
570       reloc_entry->address += input_section->output_offset;
571       return bfd_reloc_ok;
572     }
573
574   if (output_bfd != (bfd *) NULL)
575     relocatable = TRUE;
576   else
577     {
578       relocatable = FALSE;
579       output_bfd = symbol->section->output_section->owner;
580     }
581
582   if (bfd_is_und_section (symbol->section) && ! relocatable)
583     return bfd_reloc_undefined;
584
585   /* We have to figure out the gp value, so that we can adjust the
586      symbol value correctly.  We look up the symbol _gp in the output
587      BFD.  If we can't find it, we're stuck.  We cache it in the ECOFF
588      target data.  We don't need to adjust the symbol value for an
589      external symbol if we are producing relocatable output.  */
590   gp = _bfd_get_gp_value (output_bfd);
591   if (gp == 0
592       && (! relocatable
593           || (symbol->flags & BSF_SECTION_SYM) != 0))
594     {
595       if (relocatable)
596         {
597           /* Make up a value.  */
598           gp = symbol->section->output_section->vma + 0x4000;
599           _bfd_set_gp_value (output_bfd, gp);
600         }
601       else
602         {
603           unsigned int count;
604           asymbol **sym;
605           unsigned int i;
606
607           count = bfd_get_symcount (output_bfd);
608           sym = bfd_get_outsymbols (output_bfd);
609
610           if (sym == (asymbol **) NULL)
611             i = count;
612           else
613             {
614               for (i = 0; i < count; i++, sym++)
615                 {
616                   register const char *name;
617
618                   name = bfd_asymbol_name (*sym);
619                   if (*name == '_' && strcmp (name, "_gp") == 0)
620                     {
621                       gp = bfd_asymbol_value (*sym);
622                       _bfd_set_gp_value (output_bfd, gp);
623                       break;
624                     }
625                 }
626             }
627
628           if (i >= count)
629             {
630               /* Only get the error once.  */
631               gp = 4;
632               _bfd_set_gp_value (output_bfd, gp);
633               *error_message =
634                 (char *) _("GP relative relocation when _gp not defined");
635               return bfd_reloc_dangerous;
636             }
637         }
638     }
639
640   if (bfd_is_com_section (symbol->section))
641     relocation = 0;
642   else
643     relocation = symbol->value;
644
645   relocation += symbol->section->output_section->vma;
646   relocation += symbol->section->output_offset;
647
648   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
649     return bfd_reloc_outofrange;
650
651   insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
652
653   /* Set val to the offset into the section or symbol.  */
654   val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;
655   if (val & 0x8000)
656     val -= 0x10000;
657
658   /* Adjust val for the final section location and GP value.  If we
659      are producing relocatable output, we don't want to do this for
660      an external symbol.  */
661   if (! relocatable
662       || (symbol->flags & BSF_SECTION_SYM) != 0)
663     val += relocation - gp;
664
665   insn = (insn &~ (unsigned) 0xffff) | (val & 0xffff);
666   bfd_put_32 (abfd, (bfd_vma) insn, (bfd_byte *) data + reloc_entry->address);
667
668   if (relocatable)
669     reloc_entry->address += input_section->output_offset;
670
671   /* Make sure it fit in 16 bits.  */
672   if ((long) val >= 0x8000 || (long) val < -0x8000)
673     return bfd_reloc_overflow;
674
675   return bfd_reloc_ok;
676 }
677
678 /* Get the howto structure for a generic reloc type.  */
679
680 static reloc_howto_type *
681 mips_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
682                             bfd_reloc_code_real_type code)
683 {
684   int mips_type;
685
686   switch (code)
687     {
688     case BFD_RELOC_16:
689       mips_type = MIPS_R_REFHALF;
690       break;
691     case BFD_RELOC_32:
692     case BFD_RELOC_CTOR:
693       mips_type = MIPS_R_REFWORD;
694       break;
695     case BFD_RELOC_MIPS_JMP:
696       mips_type = MIPS_R_JMPADDR;
697       break;
698     case BFD_RELOC_HI16_S:
699       mips_type = MIPS_R_REFHI;
700       break;
701     case BFD_RELOC_LO16:
702       mips_type = MIPS_R_REFLO;
703       break;
704     case BFD_RELOC_GPREL16:
705       mips_type = MIPS_R_GPREL;
706       break;
707     case BFD_RELOC_MIPS_LITERAL:
708       mips_type = MIPS_R_LITERAL;
709       break;
710     case BFD_RELOC_16_PCREL_S2:
711       mips_type = MIPS_R_PCREL16;
712       break;
713     default:
714       return (reloc_howto_type *) NULL;
715     }
716
717   return &mips_howto_table[mips_type];
718 }
719
720 static reloc_howto_type *
721 mips_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
722                             const char *r_name)
723 {
724   unsigned int i;
725
726   for (i = 0;
727        i < sizeof (mips_howto_table) / sizeof (mips_howto_table[0]);
728        i++)
729     if (mips_howto_table[i].name != NULL
730         && strcasecmp (mips_howto_table[i].name, r_name) == 0)
731       return &mips_howto_table[i];
732
733   return NULL;
734 }
735 \f
736 /* A helper routine for mips_relocate_section which handles the REFHI
737    relocations.  The REFHI relocation must be followed by a REFLO
738    relocation, and the addend used is formed from the addends of both
739    instructions.  */
740
741 static void
742 mips_relocate_hi (struct internal_reloc *refhi,
743                   struct internal_reloc *reflo,
744                   bfd *input_bfd,
745                   asection *input_section,
746                   bfd_byte *contents,
747                   bfd_vma relocation)
748 {
749   unsigned long insn;
750   unsigned long val;
751   unsigned long vallo;
752
753   if (refhi == NULL)
754     return;
755
756   insn = bfd_get_32 (input_bfd,
757                      contents + refhi->r_vaddr - input_section->vma);
758   if (reflo == NULL)
759     vallo = 0;
760   else
761     vallo = (bfd_get_32 (input_bfd,
762                          contents + reflo->r_vaddr - input_section->vma)
763              & 0xffff);
764
765   val = ((insn & 0xffff) << 16) + vallo;
766   val += relocation;
767
768   /* The low order 16 bits are always treated as a signed value.
769      Therefore, a negative value in the low order bits requires an
770      adjustment in the high order bits.  We need to make this
771      adjustment in two ways: once for the bits we took from the data,
772      and once for the bits we are putting back in to the data.  */
773   if ((vallo & 0x8000) != 0)
774     val -= 0x10000;
775
776   if ((val & 0x8000) != 0)
777     val += 0x10000;
778
779   insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
780   bfd_put_32 (input_bfd, (bfd_vma) insn,
781               contents + refhi->r_vaddr - input_section->vma);
782 }
783
784 /* Relocate a section while linking a MIPS ECOFF file.  */
785
786 static bfd_boolean
787 mips_relocate_section (bfd *output_bfd,
788                        struct bfd_link_info *info,
789                        bfd *input_bfd,
790                        asection *input_section,
791                        bfd_byte *contents,
792                        void * external_relocs)
793 {
794   asection **symndx_to_section;
795   struct ecoff_link_hash_entry **sym_hashes;
796   bfd_vma gp;
797   bfd_boolean gp_undefined;
798   struct external_reloc *ext_rel;
799   struct external_reloc *ext_rel_end;
800   unsigned int i;
801   bfd_boolean got_lo;
802   struct internal_reloc lo_int_rel;
803   bfd_size_type amt;
804
805   BFD_ASSERT (input_bfd->xvec->byteorder
806               == output_bfd->xvec->byteorder);
807
808   /* We keep a table mapping the symndx found in an internal reloc to
809      the appropriate section.  This is faster than looking up the
810      section by name each time.  */
811   symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
812   if (symndx_to_section == (asection **) NULL)
813     {
814       amt = NUM_RELOC_SECTIONS * sizeof (asection *);
815       symndx_to_section = (asection **) bfd_alloc (input_bfd, amt);
816       if (!symndx_to_section)
817         return FALSE;
818
819       symndx_to_section[RELOC_SECTION_NONE] = NULL;
820       symndx_to_section[RELOC_SECTION_TEXT] =
821         bfd_get_section_by_name (input_bfd, ".text");
822       symndx_to_section[RELOC_SECTION_RDATA] =
823         bfd_get_section_by_name (input_bfd, ".rdata");
824       symndx_to_section[RELOC_SECTION_DATA] =
825         bfd_get_section_by_name (input_bfd, ".data");
826       symndx_to_section[RELOC_SECTION_SDATA] =
827         bfd_get_section_by_name (input_bfd, ".sdata");
828       symndx_to_section[RELOC_SECTION_SBSS] =
829         bfd_get_section_by_name (input_bfd, ".sbss");
830       symndx_to_section[RELOC_SECTION_BSS] =
831         bfd_get_section_by_name (input_bfd, ".bss");
832       symndx_to_section[RELOC_SECTION_INIT] =
833         bfd_get_section_by_name (input_bfd, ".init");
834       symndx_to_section[RELOC_SECTION_LIT8] =
835         bfd_get_section_by_name (input_bfd, ".lit8");
836       symndx_to_section[RELOC_SECTION_LIT4] =
837         bfd_get_section_by_name (input_bfd, ".lit4");
838       symndx_to_section[RELOC_SECTION_XDATA] = NULL;
839       symndx_to_section[RELOC_SECTION_PDATA] = NULL;
840       symndx_to_section[RELOC_SECTION_FINI] =
841         bfd_get_section_by_name (input_bfd, ".fini");
842       symndx_to_section[RELOC_SECTION_LITA] = NULL;
843       symndx_to_section[RELOC_SECTION_ABS] = NULL;
844
845       ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
846     }
847
848   sym_hashes = ecoff_data (input_bfd)->sym_hashes;
849
850   gp = _bfd_get_gp_value (output_bfd);
851   if (gp == 0)
852     gp_undefined = TRUE;
853   else
854     gp_undefined = FALSE;
855
856   got_lo = FALSE;
857
858   ext_rel = (struct external_reloc *) external_relocs;
859   ext_rel_end = ext_rel + input_section->reloc_count;
860   for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
861     {
862       struct internal_reloc int_rel;
863       bfd_boolean use_lo = FALSE;
864       bfd_vma addend;
865       reloc_howto_type *howto;
866       struct ecoff_link_hash_entry *h = NULL;
867       asection *s = NULL;
868       bfd_vma relocation;
869       bfd_reloc_status_type r;
870
871       if (! got_lo)
872         mips_ecoff_swap_reloc_in (input_bfd, ext_rel, &int_rel);
873       else
874         {
875           int_rel = lo_int_rel;
876           got_lo = FALSE;
877         }
878
879       BFD_ASSERT (int_rel.r_type
880                   < sizeof mips_howto_table / sizeof mips_howto_table[0]);
881
882       /* The REFHI reloc requires special handling.  It must be followed
883          by a REFLO reloc, and the addend is formed from both relocs.  */
884       if (int_rel.r_type == MIPS_R_REFHI)
885         {
886           struct external_reloc *lo_ext_rel;
887
888           /* As a GNU extension, permit an arbitrary number of REFHI
889              relocs before the REFLO reloc.  This permits gcc to emit
890              the HI and LO relocs itself.  */
891           for (lo_ext_rel = ext_rel + 1;
892                lo_ext_rel < ext_rel_end;
893                lo_ext_rel++)
894             {
895               mips_ecoff_swap_reloc_in (input_bfd, lo_ext_rel,
896                                         &lo_int_rel);
897               if (lo_int_rel.r_type != int_rel.r_type)
898                 break;
899             }
900
901           if (lo_ext_rel < ext_rel_end
902               && lo_int_rel.r_type == MIPS_R_REFLO
903               && int_rel.r_extern == lo_int_rel.r_extern
904               && int_rel.r_symndx == lo_int_rel.r_symndx)
905             {
906               use_lo = TRUE;
907               if (lo_ext_rel == ext_rel + 1)
908                 got_lo = TRUE;
909             }
910         }
911
912       howto = &mips_howto_table[int_rel.r_type];
913
914       if (int_rel.r_extern)
915         {
916           h = sym_hashes[int_rel.r_symndx];
917           /* If h is NULL, that means that there is a reloc against an
918              external symbol which we thought was just a debugging
919              symbol.  This should not happen.  */
920           if (h == (struct ecoff_link_hash_entry *) NULL)
921             abort ();
922         }
923       else
924         {
925           if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS)
926             s = NULL;
927           else
928             s = symndx_to_section[int_rel.r_symndx];
929
930           if (s == (asection *) NULL)
931             abort ();
932         }
933
934       /* The GPREL reloc uses an addend: the difference in the GP
935          values.  */
936       if (int_rel.r_type != MIPS_R_GPREL
937           && int_rel.r_type != MIPS_R_LITERAL)
938         addend = 0;
939       else
940         {
941           if (gp_undefined)
942             {
943               (*info->callbacks->reloc_dangerous)
944                 (info, _("GP relative relocation used when GP not defined"),
945                  input_bfd, input_section,
946                  int_rel.r_vaddr - input_section->vma);
947               /* Only give the error once per link.  */
948               gp = 4;
949               _bfd_set_gp_value (output_bfd, gp);
950               gp_undefined = FALSE;
951             }
952           if (! int_rel.r_extern)
953             {
954               /* This is a relocation against a section.  The current
955                  addend in the instruction is the difference between
956                  INPUT_SECTION->vma and the GP value of INPUT_BFD.  We
957                  must change this to be the difference between the
958                  final definition (which will end up in RELOCATION)
959                  and the GP value of OUTPUT_BFD (which is in GP).  */
960               addend = ecoff_data (input_bfd)->gp - gp;
961             }
962           else if (! bfd_link_relocatable (info)
963                    || h->root.type == bfd_link_hash_defined
964                    || h->root.type == bfd_link_hash_defweak)
965             {
966               /* This is a relocation against a defined symbol.  The
967                  current addend in the instruction is simply the
968                  desired offset into the symbol (normally zero).  We
969                  are going to change this into a relocation against a
970                  defined symbol, so we want the instruction to hold
971                  the difference between the final definition of the
972                  symbol (which will end up in RELOCATION) and the GP
973                  value of OUTPUT_BFD (which is in GP).  */
974               addend = - gp;
975             }
976           else
977             {
978               /* This is a relocation against an undefined or common
979                  symbol.  The current addend in the instruction is
980                  simply the desired offset into the symbol (normally
981                  zero).  We are generating relocatable output, and we
982                  aren't going to define this symbol, so we just leave
983                  the instruction alone.  */
984               addend = 0;
985             }
986         }
987
988       if (bfd_link_relocatable (info))
989         {
990           /* We are generating relocatable output, and must convert
991              the existing reloc.  */
992           if (int_rel.r_extern)
993             {
994               if ((h->root.type == bfd_link_hash_defined
995                    || h->root.type == bfd_link_hash_defweak)
996                   && ! bfd_is_abs_section (h->root.u.def.section))
997                 {
998                   const char *name;
999
1000                   /* This symbol is defined in the output.  Convert
1001                      the reloc from being against the symbol to being
1002                      against the section.  */
1003
1004                   /* Clear the r_extern bit.  */
1005                   int_rel.r_extern = 0;
1006
1007                   /* Compute a new r_symndx value.  */
1008                   s = h->root.u.def.section;
1009                   name = bfd_get_section_name (output_bfd,
1010                                                s->output_section);
1011
1012                   int_rel.r_symndx = -1;
1013                   switch (name[1])
1014                     {
1015                     case 'b':
1016                       if (strcmp (name, ".bss") == 0)
1017                         int_rel.r_symndx = RELOC_SECTION_BSS;
1018                       break;
1019                     case 'd':
1020                       if (strcmp (name, ".data") == 0)
1021                         int_rel.r_symndx = RELOC_SECTION_DATA;
1022                       break;
1023                     case 'f':
1024                       if (strcmp (name, ".fini") == 0)
1025                         int_rel.r_symndx = RELOC_SECTION_FINI;
1026                       break;
1027                     case 'i':
1028                       if (strcmp (name, ".init") == 0)
1029                         int_rel.r_symndx = RELOC_SECTION_INIT;
1030                       break;
1031                     case 'l':
1032                       if (strcmp (name, ".lit8") == 0)
1033                         int_rel.r_symndx = RELOC_SECTION_LIT8;
1034                       else if (strcmp (name, ".lit4") == 0)
1035                         int_rel.r_symndx = RELOC_SECTION_LIT4;
1036                       break;
1037                     case 'r':
1038                       if (strcmp (name, ".rdata") == 0)
1039                         int_rel.r_symndx = RELOC_SECTION_RDATA;
1040                       break;
1041                     case 's':
1042                       if (strcmp (name, ".sdata") == 0)
1043                         int_rel.r_symndx = RELOC_SECTION_SDATA;
1044                       else if (strcmp (name, ".sbss") == 0)
1045                         int_rel.r_symndx = RELOC_SECTION_SBSS;
1046                       break;
1047                     case 't':
1048                       if (strcmp (name, ".text") == 0)
1049                         int_rel.r_symndx = RELOC_SECTION_TEXT;
1050                       break;
1051                     }
1052
1053                   if (int_rel.r_symndx == -1)
1054                     abort ();
1055
1056                   /* Add the section VMA and the symbol value.  */
1057                   relocation = (h->root.u.def.value
1058                                 + s->output_section->vma
1059                                 + s->output_offset);
1060
1061                   /* For a PC relative relocation, the object file
1062                      currently holds just the addend.  We must adjust
1063                      by the address to get the right value.  */
1064                   if (howto->pc_relative)
1065                     relocation -= int_rel.r_vaddr - input_section->vma;
1066
1067                   h = NULL;
1068                 }
1069               else
1070                 {
1071                   /* Change the symndx value to the right one for the
1072                      output BFD.  */
1073                   int_rel.r_symndx = h->indx;
1074                   if (int_rel.r_symndx == -1)
1075                     {
1076                       /* This symbol is not being written out.  */
1077                       (*info->callbacks->unattached_reloc)
1078                         (info, h->root.root.string, input_bfd, input_section,
1079                          int_rel.r_vaddr - input_section->vma);
1080                       int_rel.r_symndx = 0;
1081                     }
1082                   relocation = 0;
1083                 }
1084             }
1085           else
1086             {
1087               /* This is a relocation against a section.  Adjust the
1088                  value by the amount the section moved.  */
1089               relocation = (s->output_section->vma
1090                             + s->output_offset
1091                             - s->vma);
1092             }
1093
1094           relocation += addend;
1095           addend = 0;
1096
1097           /* Adjust a PC relative relocation by removing the reference
1098              to the original address in the section and including the
1099              reference to the new address.  */
1100           if (howto->pc_relative)
1101             relocation -= (input_section->output_section->vma
1102                            + input_section->output_offset
1103                            - input_section->vma);
1104
1105           /* Adjust the contents.  */
1106           if (relocation == 0)
1107             r = bfd_reloc_ok;
1108           else
1109             {
1110               if (int_rel.r_type != MIPS_R_REFHI)
1111                 r = _bfd_relocate_contents (howto, input_bfd, relocation,
1112                                             (contents
1113                                              + int_rel.r_vaddr
1114                                              - input_section->vma));
1115               else
1116                 {
1117                   mips_relocate_hi (&int_rel,
1118                                     use_lo ? &lo_int_rel : NULL,
1119                                     input_bfd, input_section, contents,
1120                                     relocation);
1121                   r = bfd_reloc_ok;
1122                 }
1123             }
1124
1125           /* Adjust the reloc address.  */
1126           int_rel.r_vaddr += (input_section->output_section->vma
1127                               + input_section->output_offset
1128                               - input_section->vma);
1129
1130           /* Save the changed reloc information.  */
1131           mips_ecoff_swap_reloc_out (input_bfd, &int_rel, ext_rel);
1132         }
1133       else
1134         {
1135           /* We are producing a final executable.  */
1136           if (int_rel.r_extern)
1137             {
1138               /* This is a reloc against a symbol.  */
1139               if (h->root.type == bfd_link_hash_defined
1140                   || h->root.type == bfd_link_hash_defweak)
1141                 {
1142                   asection *hsec;
1143
1144                   hsec = h->root.u.def.section;
1145                   relocation = (h->root.u.def.value
1146                                 + hsec->output_section->vma
1147                                 + hsec->output_offset);
1148                 }
1149               else
1150                 {
1151                   (*info->callbacks->undefined_symbol)
1152                     (info, h->root.root.string, input_bfd, input_section,
1153                      int_rel.r_vaddr - input_section->vma, TRUE);
1154                   relocation = 0;
1155                 }
1156             }
1157           else
1158             {
1159               /* This is a reloc against a section.  */
1160               relocation = (s->output_section->vma
1161                             + s->output_offset
1162                             - s->vma);
1163
1164               /* A PC relative reloc is already correct in the object
1165                  file.  Make it look like a pcrel_offset relocation by
1166                  adding in the start address.  */
1167               if (howto->pc_relative)
1168                 relocation += int_rel.r_vaddr;
1169             }
1170
1171           if (int_rel.r_type != MIPS_R_REFHI)
1172             r = _bfd_final_link_relocate (howto,
1173                                           input_bfd,
1174                                           input_section,
1175                                           contents,
1176                                           (int_rel.r_vaddr
1177                                            - input_section->vma),
1178                                           relocation,
1179                                           addend);
1180           else
1181             {
1182               mips_relocate_hi (&int_rel,
1183                                 use_lo ? &lo_int_rel : NULL,
1184                                 input_bfd, input_section, contents,
1185                                 relocation);
1186               r = bfd_reloc_ok;
1187             }
1188         }
1189
1190       /* MIPS_R_JMPADDR requires peculiar overflow detection.  The
1191          instruction provides a 28 bit address (the two lower bits are
1192          implicit zeroes) which is combined with the upper four bits
1193          of the instruction address.  */
1194       if (r == bfd_reloc_ok
1195           && int_rel.r_type == MIPS_R_JMPADDR
1196           && (((relocation
1197                 + addend
1198                 + (int_rel.r_extern ? 0 : s->vma))
1199                & 0xf0000000)
1200               != ((input_section->output_section->vma
1201                    + input_section->output_offset
1202                    + (int_rel.r_vaddr - input_section->vma))
1203                   & 0xf0000000)))
1204         r = bfd_reloc_overflow;
1205
1206       if (r != bfd_reloc_ok)
1207         {
1208           switch (r)
1209             {
1210             default:
1211             case bfd_reloc_outofrange:
1212               abort ();
1213             case bfd_reloc_overflow:
1214               {
1215                 const char *name;
1216
1217                 if (int_rel.r_extern)
1218                   name = NULL;
1219                 else
1220                   name = bfd_section_name (input_bfd, s);
1221                 (*info->callbacks->reloc_overflow)
1222                   (info, (h ? &h->root : NULL), name, howto->name,
1223                    (bfd_vma) 0, input_bfd, input_section,
1224                    int_rel.r_vaddr - input_section->vma);
1225               }
1226               break;
1227             }
1228         }
1229     }
1230
1231   return TRUE;
1232 }
1233 \f
1234 /* This is the ECOFF backend structure.  The backend field of the
1235    target vector points to this.  */
1236
1237 static const struct ecoff_backend_data mips_ecoff_backend_data =
1238 {
1239   /* COFF backend structure.  */
1240   {
1241     (void (*) (bfd *,void *,int,int,int,int,void *)) bfd_void, /* aux_in */
1242     (void (*) (bfd *,void *,void *)) bfd_void, /* sym_in */
1243     (void (*) (bfd *,void *,void *)) bfd_void, /* lineno_in */
1244     (unsigned (*) (bfd *,void *,int,int,int,int,void *)) bfd_void,/*aux_out*/
1245     (unsigned (*) (bfd *,void *,void *)) bfd_void, /* sym_out */
1246     (unsigned (*) (bfd *,void *,void *)) bfd_void, /* lineno_out */
1247     (unsigned (*) (bfd *,void *,void *)) bfd_void, /* reloc_out */
1248     mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
1249     mips_ecoff_swap_scnhdr_out,
1250     FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, TRUE,
1251     ECOFF_NO_LONG_SECTION_NAMES, 4, FALSE, 2, 32768,
1252     mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
1253     mips_ecoff_swap_scnhdr_in, NULL,
1254     mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
1255     _bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
1256     _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
1257     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1258     NULL, NULL, NULL
1259   },
1260   /* Supported architecture.  */
1261   bfd_arch_mips,
1262   /* Initial portion of armap string.  */
1263   "__________",
1264   /* The page boundary used to align sections in a demand-paged
1265      executable file.  E.g., 0x1000.  */
1266   0x1000,
1267   /* TRUE if the .rdata section is part of the text segment, as on the
1268      Alpha.  FALSE if .rdata is part of the data segment, as on the
1269      MIPS.  */
1270   FALSE,
1271   /* Bitsize of constructor entries.  */
1272   32,
1273   /* Reloc to use for constructor entries.  */
1274   &mips_howto_table[MIPS_R_REFWORD],
1275   {
1276     /* Symbol table magic number.  */
1277     magicSym,
1278     /* Alignment of debugging information.  E.g., 4.  */
1279     4,
1280     /* Sizes of external symbolic information.  */
1281     sizeof (struct hdr_ext),
1282     sizeof (struct dnr_ext),
1283     sizeof (struct pdr_ext),
1284     sizeof (struct sym_ext),
1285     sizeof (struct opt_ext),
1286     sizeof (struct fdr_ext),
1287     sizeof (struct rfd_ext),
1288     sizeof (struct ext_ext),
1289     /* Functions to swap in external symbolic data.  */
1290     ecoff_swap_hdr_in,
1291     ecoff_swap_dnr_in,
1292     ecoff_swap_pdr_in,
1293     ecoff_swap_sym_in,
1294     ecoff_swap_opt_in,
1295     ecoff_swap_fdr_in,
1296     ecoff_swap_rfd_in,
1297     ecoff_swap_ext_in,
1298     _bfd_ecoff_swap_tir_in,
1299     _bfd_ecoff_swap_rndx_in,
1300     /* Functions to swap out external symbolic data.  */
1301     ecoff_swap_hdr_out,
1302     ecoff_swap_dnr_out,
1303     ecoff_swap_pdr_out,
1304     ecoff_swap_sym_out,
1305     ecoff_swap_opt_out,
1306     ecoff_swap_fdr_out,
1307     ecoff_swap_rfd_out,
1308     ecoff_swap_ext_out,
1309     _bfd_ecoff_swap_tir_out,
1310     _bfd_ecoff_swap_rndx_out,
1311     /* Function to read in symbolic data.  */
1312     _bfd_ecoff_slurp_symbolic_info
1313   },
1314   /* External reloc size.  */
1315   RELSZ,
1316   /* Reloc swapping functions.  */
1317   mips_ecoff_swap_reloc_in,
1318   mips_ecoff_swap_reloc_out,
1319   /* Backend reloc tweaking.  */
1320   mips_adjust_reloc_in,
1321   mips_adjust_reloc_out,
1322   /* Relocate section contents while linking.  */
1323   mips_relocate_section,
1324   /* Do final adjustments to filehdr and aouthdr.  */
1325   NULL,
1326   /* Read an element from an archive at a given file position.  */
1327   _bfd_get_elt_at_filepos
1328 };
1329
1330 /* Looking up a reloc type is MIPS specific.  */
1331 #define _bfd_ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
1332 #define _bfd_ecoff_bfd_reloc_name_lookup mips_bfd_reloc_name_lookup
1333
1334 /* Getting relocated section contents is generic.  */
1335 #define _bfd_ecoff_bfd_get_relocated_section_contents \
1336   bfd_generic_get_relocated_section_contents
1337
1338 /* Handling file windows is generic.  */
1339 #define _bfd_ecoff_get_section_contents_in_window \
1340   _bfd_generic_get_section_contents_in_window
1341
1342 /* Relaxing sections is MIPS specific.  */
1343 #define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
1344
1345 /* GC of sections is not done.  */
1346 #define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
1347
1348 /* Input section flags is not implemented.  */
1349 #define _bfd_ecoff_bfd_lookup_section_flags bfd_generic_lookup_section_flags
1350
1351 /* Merging of sections is not done.  */
1352 #define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections
1353
1354 #define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section
1355 #define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
1356 #define _bfd_ecoff_section_already_linked \
1357   _bfd_coff_section_already_linked
1358 #define _bfd_ecoff_bfd_define_common_symbol bfd_generic_define_common_symbol
1359 #define _bfd_ecoff_bfd_define_start_stop bfd_generic_define_start_stop
1360 #define _bfd_ecoff_set_reloc _bfd_generic_set_reloc
1361
1362 extern const bfd_target mips_ecoff_be_vec;
1363
1364 const bfd_target mips_ecoff_le_vec =
1365 {
1366   "ecoff-littlemips",           /* name */
1367   bfd_target_ecoff_flavour,
1368   BFD_ENDIAN_LITTLE,            /* data byte order is little */
1369   BFD_ENDIAN_LITTLE,            /* header byte order is little */
1370
1371   (HAS_RELOC | EXEC_P |         /* object flags */
1372    HAS_LINENO | HAS_DEBUG |
1373    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1374
1375   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1376   0,                            /* leading underscore */
1377   ' ',                          /* ar_pad_char */
1378   15,                           /* ar_max_namelen */
1379   0,                            /* match priority.  */
1380   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1381      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1382      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1383   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1384      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1385      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
1386
1387   {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1388      bfd_generic_archive_p, _bfd_dummy_target},
1389   {bfd_false, _bfd_ecoff_mkobject,  /* bfd_set_format */
1390      _bfd_generic_mkarchive, bfd_false},
1391   {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
1392      _bfd_write_archive_contents, bfd_false},
1393
1394      BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
1395      BFD_JUMP_TABLE_COPY (_bfd_ecoff),
1396      BFD_JUMP_TABLE_CORE (_bfd_nocore),
1397      BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
1398      BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
1399      BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
1400      BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
1401      BFD_JUMP_TABLE_LINK (_bfd_ecoff),
1402      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1403
1404   & mips_ecoff_be_vec,
1405
1406   & mips_ecoff_backend_data
1407 };
1408
1409 const bfd_target mips_ecoff_be_vec =
1410 {
1411   "ecoff-bigmips",              /* name */
1412   bfd_target_ecoff_flavour,
1413   BFD_ENDIAN_BIG,               /* data byte order is big */
1414   BFD_ENDIAN_BIG,               /* header byte order is big */
1415
1416   (HAS_RELOC | EXEC_P |         /* object flags */
1417    HAS_LINENO | HAS_DEBUG |
1418    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1419
1420   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1421   0,                            /* leading underscore */
1422   ' ',                          /* ar_pad_char */
1423   15,                           /* ar_max_namelen */
1424   0,                            /* match priority.  */
1425   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1426      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1427      bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1428   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1429      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1430      bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1431  {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1432     bfd_generic_archive_p, _bfd_dummy_target},
1433  {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
1434     _bfd_generic_mkarchive, bfd_false},
1435  {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
1436     _bfd_write_archive_contents, bfd_false},
1437
1438      BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
1439      BFD_JUMP_TABLE_COPY (_bfd_ecoff),
1440      BFD_JUMP_TABLE_CORE (_bfd_nocore),
1441      BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
1442      BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
1443      BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
1444      BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
1445      BFD_JUMP_TABLE_LINK (_bfd_ecoff),
1446      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1447
1448   & mips_ecoff_le_vec,
1449
1450   & mips_ecoff_backend_data
1451 };
1452
1453 const bfd_target mips_ecoff_bele_vec =
1454 {
1455   "ecoff-biglittlemips",                /* name */
1456   bfd_target_ecoff_flavour,
1457   BFD_ENDIAN_LITTLE,            /* data byte order is little */
1458   BFD_ENDIAN_BIG,               /* header byte order is big */
1459
1460   (HAS_RELOC | EXEC_P |         /* object flags */
1461    HAS_LINENO | HAS_DEBUG |
1462    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1463
1464   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
1465   0,                            /* leading underscore */
1466   ' ',                          /* ar_pad_char */
1467   15,                           /* ar_max_namelen */
1468   0,                            /* match priority.  */
1469   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1470      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1471      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1472   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1473      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1474      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
1475
1476   {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
1477      bfd_generic_archive_p, _bfd_dummy_target},
1478   {bfd_false, _bfd_ecoff_mkobject,  /* bfd_set_format */
1479      _bfd_generic_mkarchive, bfd_false},
1480   {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
1481      _bfd_write_archive_contents, bfd_false},
1482
1483      BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
1484      BFD_JUMP_TABLE_COPY (_bfd_ecoff),
1485      BFD_JUMP_TABLE_CORE (_bfd_nocore),
1486      BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
1487      BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
1488      BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
1489      BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
1490      BFD_JUMP_TABLE_LINK (_bfd_ecoff),
1491      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1492
1493   NULL,
1494
1495   & mips_ecoff_backend_data
1496 };