This commit was generated by cvs2svn to track changes on a CVS vendor
[platform/upstream/binutils.git] / bfd / coff-mips.c
1 /* BFD back-end for MIPS Extended-Coff files.
2    Copyright 1990, 91, 92, 93, 94, 95, 96, 1997 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 bfd_reloc_status_type mips_relhi_reloc PARAMS ((bfd *abfd,
76                                                        arelent *reloc,
77                                                        asymbol *symbol,
78                                                        PTR data,
79                                                        asection *section,
80                                                        bfd *output_bfd,
81                                                        char **error));
82 static bfd_reloc_status_type mips_rello_reloc PARAMS ((bfd *abfd,
83                                                        arelent *reloc,
84                                                        asymbol *symbol,
85                                                        PTR data,
86                                                        asection *section,
87                                                        bfd *output_bfd,
88                                                        char **error));
89 static bfd_reloc_status_type mips_switch_reloc PARAMS ((bfd *abfd,
90                                                         arelent *reloc,
91                                                         asymbol *symbol,
92                                                         PTR data,
93                                                         asection *section,
94                                                         bfd *output_bfd,
95                                                         char **error));
96 static void mips_relocate_hi PARAMS ((struct internal_reloc *refhi,
97                                       struct internal_reloc *reflo,
98                                       bfd *input_bfd,
99                                       asection *input_section,
100                                       bfd_byte *contents,
101                                       size_t adjust,
102                                       bfd_vma relocation,
103                                       boolean pcrel));
104 static boolean mips_relocate_section PARAMS ((bfd *, struct bfd_link_info *,
105                                               bfd *, asection *,
106                                               bfd_byte *, PTR));
107 static boolean mips_read_relocs PARAMS ((bfd *, asection *));
108 static boolean mips_relax_section PARAMS ((bfd *, asection *,
109                                            struct bfd_link_info *,
110                                            boolean *));
111 static boolean mips_relax_pcrel16 PARAMS ((struct bfd_link_info *, bfd *,
112                                            asection *,
113                                            struct ecoff_link_hash_entry *,
114                                            bfd_byte *, bfd_vma));
115 static reloc_howto_type *mips_bfd_reloc_type_lookup
116   PARAMS ((bfd *, bfd_reloc_code_real_type));
117
118 \f
119 /* ECOFF has COFF sections, but the debugging information is stored in
120    a completely different format.  ECOFF targets use some of the
121    swapping routines from coffswap.h, and some of the generic COFF
122    routines in coffgen.c, but, unlike the real COFF targets, do not
123    use coffcode.h itself.
124
125    Get the generic COFF swapping routines, except for the reloc,
126    symbol, and lineno ones.  Give them ECOFF names.  */
127 #define MIPSECOFF
128 #define NO_COFF_RELOCS
129 #define NO_COFF_SYMBOLS
130 #define NO_COFF_LINENOS
131 #define coff_swap_filehdr_in mips_ecoff_swap_filehdr_in
132 #define coff_swap_filehdr_out mips_ecoff_swap_filehdr_out
133 #define coff_swap_aouthdr_in mips_ecoff_swap_aouthdr_in
134 #define coff_swap_aouthdr_out mips_ecoff_swap_aouthdr_out
135 #define coff_swap_scnhdr_in mips_ecoff_swap_scnhdr_in
136 #define coff_swap_scnhdr_out mips_ecoff_swap_scnhdr_out
137 #include "coffswap.h"
138
139 /* Get the ECOFF swapping routines.  */
140 #define ECOFF_32
141 #include "ecoffswap.h"
142 \f
143 /* How to process the various relocs types.  */
144
145 static reloc_howto_type mips_howto_table[] =
146 {
147   /* Reloc type 0 is ignored.  The reloc reading code ensures that
148      this is a reference to the .abs section, which will cause
149      bfd_perform_relocation to do nothing.  */
150   HOWTO (MIPS_R_IGNORE, /* type */
151          0,                     /* rightshift */
152          0,                     /* size (0 = byte, 1 = short, 2 = long) */
153          8,                     /* bitsize */
154          false,                 /* pc_relative */
155          0,                     /* bitpos */
156          complain_overflow_dont, /* complain_on_overflow */
157          0,                     /* special_function */
158          "IGNORE",              /* name */
159          false,                 /* partial_inplace */
160          0,                     /* src_mask */
161          0,                     /* dst_mask */
162          false),                /* pcrel_offset */
163
164   /* A 16 bit reference to a symbol, normally from a data section.  */
165   HOWTO (MIPS_R_REFHALF,        /* type */
166          0,                     /* rightshift */
167          1,                     /* size (0 = byte, 1 = short, 2 = long) */
168          16,                    /* bitsize */
169          false,                 /* pc_relative */
170          0,                     /* bitpos */
171          complain_overflow_bitfield, /* complain_on_overflow */
172          mips_generic_reloc,    /* special_function */
173          "REFHALF",             /* name */
174          true,                  /* partial_inplace */
175          0xffff,                /* src_mask */
176          0xffff,                /* dst_mask */
177          false),                /* pcrel_offset */
178
179   /* A 32 bit reference to a symbol, normally from a data section.  */
180   HOWTO (MIPS_R_REFWORD,        /* type */
181          0,                     /* rightshift */
182          2,                     /* size (0 = byte, 1 = short, 2 = long) */
183          32,                    /* bitsize */
184          false,                 /* pc_relative */
185          0,                     /* bitpos */
186          complain_overflow_bitfield, /* complain_on_overflow */
187          mips_generic_reloc,    /* special_function */
188          "REFWORD",             /* name */
189          true,                  /* partial_inplace */
190          0xffffffff,            /* src_mask */
191          0xffffffff,            /* dst_mask */
192          false),                /* pcrel_offset */
193
194   /* A 26 bit absolute jump address.  */
195   HOWTO (MIPS_R_JMPADDR,        /* type */
196          2,                     /* rightshift */
197          2,                     /* size (0 = byte, 1 = short, 2 = long) */
198          26,                    /* bitsize */
199          false,                 /* pc_relative */
200          0,                     /* bitpos */
201          complain_overflow_dont, /* complain_on_overflow */
202                                 /* This needs complex overflow
203                                    detection, because the upper four
204                                    bits must match the PC.  */
205          mips_generic_reloc,    /* special_function */
206          "JMPADDR",             /* name */
207          true,                  /* partial_inplace */
208          0x3ffffff,             /* src_mask */
209          0x3ffffff,             /* dst_mask */
210          false),                /* pcrel_offset */
211
212   /* The high 16 bits of a symbol value.  Handled by the function
213      mips_refhi_reloc.  */
214   HOWTO (MIPS_R_REFHI,          /* type */
215          16,                    /* rightshift */
216          2,                     /* size (0 = byte, 1 = short, 2 = long) */
217          16,                    /* bitsize */
218          false,                 /* pc_relative */
219          0,                     /* bitpos */
220          complain_overflow_bitfield, /* complain_on_overflow */
221          mips_refhi_reloc,      /* special_function */
222          "REFHI",               /* name */
223          true,                  /* partial_inplace */
224          0xffff,                /* src_mask */
225          0xffff,                /* dst_mask */
226          false),                /* pcrel_offset */
227
228   /* The low 16 bits of a symbol value.  */
229   HOWTO (MIPS_R_REFLO,          /* type */
230          0,                     /* rightshift */
231          2,                     /* size (0 = byte, 1 = short, 2 = long) */
232          16,                    /* bitsize */
233          false,                 /* pc_relative */
234          0,                     /* bitpos */
235          complain_overflow_dont, /* complain_on_overflow */
236          mips_reflo_reloc,      /* special_function */
237          "REFLO",               /* name */
238          true,                  /* partial_inplace */
239          0xffff,                /* src_mask */
240          0xffff,                /* dst_mask */
241          false),                /* pcrel_offset */
242
243   /* A reference to an offset from the gp register.  Handled by the
244      function mips_gprel_reloc.  */
245   HOWTO (MIPS_R_GPREL,          /* type */
246          0,                     /* rightshift */
247          2,                     /* size (0 = byte, 1 = short, 2 = long) */
248          16,                    /* bitsize */
249          false,                 /* pc_relative */
250          0,                     /* bitpos */
251          complain_overflow_signed, /* complain_on_overflow */
252          mips_gprel_reloc,      /* special_function */
253          "GPREL",               /* name */
254          true,                  /* partial_inplace */
255          0xffff,                /* src_mask */
256          0xffff,                /* dst_mask */
257          false),                /* pcrel_offset */
258
259   /* A reference to a literal using an offset from the gp register.
260      Handled by the function mips_gprel_reloc.  */
261   HOWTO (MIPS_R_LITERAL,        /* type */
262          0,                     /* rightshift */
263          2,                     /* size (0 = byte, 1 = short, 2 = long) */
264          16,                    /* bitsize */
265          false,                 /* pc_relative */
266          0,                     /* bitpos */
267          complain_overflow_signed, /* complain_on_overflow */
268          mips_gprel_reloc,      /* special_function */
269          "LITERAL",             /* name */
270          true,                  /* partial_inplace */
271          0xffff,                /* src_mask */
272          0xffff,                /* dst_mask */
273          false),                /* pcrel_offset */
274
275   { 8 },
276   { 9 },
277   { 10 },
278   { 11 },
279
280   /* This reloc is a Cygnus extension used when generating position
281      independent code for embedded systems.  It represents a 16 bit PC
282      relative reloc rightshifted twice as used in the MIPS branch
283      instructions.  */
284   HOWTO (MIPS_R_PCREL16,        /* type */
285          2,                     /* rightshift */
286          2,                     /* size (0 = byte, 1 = short, 2 = long) */
287          16,                    /* bitsize */
288          true,                  /* pc_relative */
289          0,                     /* bitpos */
290          complain_overflow_signed, /* complain_on_overflow */
291          mips_generic_reloc,    /* special_function */
292          "PCREL16",             /* name */
293          true,                  /* partial_inplace */
294          0xffff,                /* src_mask */
295          0xffff,                /* dst_mask */
296          true),                 /* pcrel_offset */
297
298   /* This reloc is a Cygnus extension used when generating position
299      independent code for embedded systems.  It represents the high 16
300      bits of a PC relative reloc.  The next reloc must be
301      MIPS_R_RELLO, and the addend is formed from the addends of the
302      two instructions, just as in MIPS_R_REFHI and MIPS_R_REFLO.  The
303      final value is actually PC relative to the location of the
304      MIPS_R_RELLO reloc, not the MIPS_R_RELHI reloc.  */
305   HOWTO (MIPS_R_RELHI,          /* type */
306          16,                    /* rightshift */
307          2,                     /* size (0 = byte, 1 = short, 2 = long) */
308          16,                    /* bitsize */
309          true,                  /* pc_relative */
310          0,                     /* bitpos */
311          complain_overflow_bitfield, /* complain_on_overflow */
312          mips_relhi_reloc,      /* special_function */
313          "RELHI",               /* name */
314          true,                  /* partial_inplace */
315          0xffff,                /* src_mask */
316          0xffff,                /* dst_mask */
317          true),                 /* pcrel_offset */
318
319   /* This reloc is a Cygnus extension used when generating position
320      independent code for embedded systems.  It represents the low 16
321      bits of a PC relative reloc.  */
322   HOWTO (MIPS_R_RELLO,          /* type */
323          0,                     /* rightshift */
324          2,                     /* size (0 = byte, 1 = short, 2 = long) */
325          16,                    /* bitsize */
326          true,                  /* pc_relative */
327          0,                     /* bitpos */
328          complain_overflow_dont, /* complain_on_overflow */
329          mips_rello_reloc,      /* special_function */
330          "RELLO",               /* name */
331          true,                  /* partial_inplace */
332          0xffff,                /* src_mask */
333          0xffff,                /* dst_mask */
334          true),                 /* pcrel_offset */
335
336   { 15 },
337   { 16 },
338   { 17 },
339   { 18 },
340   { 19 },
341   { 20 },
342   { 21 },
343
344   /* This reloc is a Cygnus extension used when generating position
345      independent code for embedded systems.  It represents an entry in
346      a switch table, which is the difference between two symbols in
347      the .text section.  The symndx is actually the offset from the
348      reloc address to the subtrahend.  See include/coff/mips.h for
349      more details.  */
350   HOWTO (MIPS_R_SWITCH,         /* type */
351          0,                     /* rightshift */
352          2,                     /* size (0 = byte, 1 = short, 2 = long) */
353          32,                    /* bitsize */
354          true,                  /* pc_relative */
355          0,                     /* bitpos */
356          complain_overflow_dont, /* complain_on_overflow */
357          mips_switch_reloc,     /* special_function */
358          "SWITCH",              /* name */
359          true,                  /* partial_inplace */
360          0xffffffff,            /* src_mask */
361          0xffffffff,            /* dst_mask */
362          true)                  /* pcrel_offset */
363 };
364
365 /* When the linker is doing relaxing, it may change a external PCREL16
366    reloc.  This typically represents an instruction like
367        bal foo
368    We change it to
369        .set  noreorder
370        bal   $L1
371        lui   $at,%hi(foo - $L1)
372      $L1:
373        addiu $at,%lo(foo - $L1)
374        addu  $at,$at,$31
375        jalr  $at
376    PCREL16_EXPANSION_ADJUSTMENT is the number of bytes this changes the
377    instruction by.  */
378
379 #define PCREL16_EXPANSION_ADJUSTMENT (4 * 4)
380 \f
381 /* See whether the magic number matches.  */
382
383 static boolean
384 mips_ecoff_bad_format_hook (abfd, filehdr)
385      bfd *abfd;
386      PTR filehdr;
387 {
388   struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
389
390   switch (internal_f->f_magic)
391     {
392     case MIPS_MAGIC_1:
393       /* I don't know what endianness this implies.  */
394       return true;
395
396     case MIPS_MAGIC_BIG:
397     case MIPS_MAGIC_BIG2:
398     case MIPS_MAGIC_BIG3:
399       return bfd_big_endian (abfd);
400
401     case MIPS_MAGIC_LITTLE:
402     case MIPS_MAGIC_LITTLE2:
403     case MIPS_MAGIC_LITTLE3:
404       return bfd_little_endian (abfd);
405
406     default:
407       return false;
408     }
409 }
410 \f
411 /* Reloc handling.  MIPS ECOFF relocs are packed into 8 bytes in
412    external form.  They use a bit which indicates whether the symbol
413    is external.  */
414
415 /* Swap a reloc in.  */
416
417 static void
418 mips_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
419      bfd *abfd;
420      PTR ext_ptr;
421      struct internal_reloc *intern;
422 {
423   const RELOC *ext = (RELOC *) ext_ptr;
424
425   intern->r_vaddr = bfd_h_get_32 (abfd, (bfd_byte *) ext->r_vaddr);
426   if (bfd_header_big_endian (abfd))
427     {
428       intern->r_symndx = (((int) ext->r_bits[0]
429                            << RELOC_BITS0_SYMNDX_SH_LEFT_BIG)
430                           | ((int) ext->r_bits[1]
431                              << RELOC_BITS1_SYMNDX_SH_LEFT_BIG)
432                           | ((int) ext->r_bits[2]
433                              << RELOC_BITS2_SYMNDX_SH_LEFT_BIG));
434       intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_BIG)
435                         >> RELOC_BITS3_TYPE_SH_BIG);
436       intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_BIG) != 0;
437     }
438   else
439     {
440       intern->r_symndx = (((int) ext->r_bits[0]
441                            << RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE)
442                           | ((int) ext->r_bits[1]
443                              << RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE)
444                           | ((int) ext->r_bits[2]
445                              << RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE));
446       intern->r_type = (((ext->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
447                          >> RELOC_BITS3_TYPE_SH_LITTLE)
448                         | ((ext->r_bits[3] & RELOC_BITS3_TYPEHI_LITTLE)
449                            << RELOC_BITS3_TYPEHI_SH_LITTLE));
450       intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0;
451     }
452
453   /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or
454      MIPS_R_RELLO reloc, r_symndx is actually the offset from the
455      reloc address to the base of the difference (see
456      include/coff/mips.h for more details).  We copy symndx into the
457      r_offset field so as not to confuse ecoff_slurp_reloc_table in
458      ecoff.c.  In adjust_reloc_in we then copy r_offset into the reloc
459      addend.  */
460   if (intern->r_type == MIPS_R_SWITCH
461       || (! intern->r_extern
462           && (intern->r_type == MIPS_R_RELLO
463               || intern->r_type == MIPS_R_RELHI)))
464     {
465       BFD_ASSERT (! intern->r_extern);
466       intern->r_offset = intern->r_symndx;
467       if (intern->r_offset & 0x800000)
468         intern->r_offset -= 0x1000000;
469       intern->r_symndx = RELOC_SECTION_TEXT;
470     }
471 }
472
473 /* Swap a reloc out.  */
474
475 static void
476 mips_ecoff_swap_reloc_out (abfd, intern, dst)
477      bfd *abfd;
478      const struct internal_reloc *intern;
479      PTR dst;
480 {
481   RELOC *ext = (RELOC *) dst;
482   long r_symndx;
483
484   BFD_ASSERT (intern->r_extern
485               || (intern->r_symndx >= 0 && intern->r_symndx <= 12));
486
487   /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELLO or
488      MIPS_R_RELHI reloc, we actually want to write the contents of
489      r_offset out as the symbol index.  This undoes the change made by
490      mips_ecoff_swap_reloc_in.  */
491   if (intern->r_type != MIPS_R_SWITCH
492       && (intern->r_extern
493           || (intern->r_type != MIPS_R_RELHI
494               && intern->r_type != MIPS_R_RELLO)))
495     r_symndx = intern->r_symndx;
496   else
497     {
498       BFD_ASSERT (intern->r_symndx == RELOC_SECTION_TEXT);
499       r_symndx = intern->r_offset & 0xffffff;
500     }
501
502   bfd_h_put_32 (abfd, intern->r_vaddr, (bfd_byte *) ext->r_vaddr);
503   if (bfd_header_big_endian (abfd))
504     {
505       ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_BIG;
506       ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_BIG;
507       ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_BIG;
508       ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_BIG)
509                          & RELOC_BITS3_TYPE_BIG)
510                         | (intern->r_extern ? RELOC_BITS3_EXTERN_BIG : 0));
511     }
512   else
513     {
514       ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE;
515       ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE;
516       ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE;
517       ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_LITTLE)
518                          & RELOC_BITS3_TYPE_LITTLE)
519                         | ((intern->r_type >> RELOC_BITS3_TYPEHI_SH_LITTLE
520                             & RELOC_BITS3_TYPEHI_LITTLE))
521                         | (intern->r_extern ? RELOC_BITS3_EXTERN_LITTLE : 0));
522     }
523 }
524
525 /* Finish canonicalizing a reloc.  Part of this is generic to all
526    ECOFF targets, and that part is in ecoff.c.  The rest is done in
527    this backend routine.  It must fill in the howto field.  */
528
529 static void
530 mips_adjust_reloc_in (abfd, intern, rptr)
531      bfd *abfd;
532      const struct internal_reloc *intern;
533      arelent *rptr;
534 {
535   if (intern->r_type > MIPS_R_SWITCH)
536     abort ();
537
538   if (! intern->r_extern
539       && (intern->r_type == MIPS_R_GPREL
540           || intern->r_type == MIPS_R_LITERAL))
541     rptr->addend += ecoff_data (abfd)->gp;
542
543   /* If the type is MIPS_R_IGNORE, make sure this is a reference to
544      the absolute section so that the reloc is ignored.  */
545   if (intern->r_type == MIPS_R_IGNORE)
546     rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
547
548   /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or
549      MIPS_R_RELLO reloc, we want the addend field of the BFD relocto
550      hold the value which was originally in the symndx field of the
551      internal MIPS ECOFF reloc.  This value was copied into
552      intern->r_offset by mips_swap_reloc_in, and here we copy it into
553      the addend field.  */
554   if (intern->r_type == MIPS_R_SWITCH
555       || (! intern->r_extern
556           && (intern->r_type == MIPS_R_RELHI
557               || intern->r_type == MIPS_R_RELLO)))
558     rptr->addend = intern->r_offset;
559
560   rptr->howto = &ecoff_backend (abfd)->howto_table[intern->r_type];
561 }
562
563 /* Make any adjustments needed to a reloc before writing it out.  None
564    are needed for MIPS.  */
565
566 static void
567 mips_adjust_reloc_out (abfd, rel, intern)
568      bfd *abfd;
569      const arelent *rel;
570      struct internal_reloc *intern;
571 {
572   /* For a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or
573      MIPS_R_RELLO reloc, we must copy rel->addend into
574      intern->r_offset.  This will then be written out as the symbol
575      index by mips_ecoff_swap_reloc_out.  This operation parallels the
576      action of mips_adjust_reloc_in.  */
577   if (intern->r_type == MIPS_R_SWITCH
578       || (! intern->r_extern
579           && (intern->r_type == MIPS_R_RELHI
580               || intern->r_type == MIPS_R_RELLO)))
581     intern->r_offset = rel->addend;
582 }
583
584 /* ECOFF relocs are either against external symbols, or against
585    sections.  If we are producing relocateable output, and the reloc
586    is against an external symbol, and nothing has given us any
587    additional addend, the resulting reloc will also be against the
588    same symbol.  In such a case, we don't want to change anything
589    about the way the reloc is handled, since it will all be done at
590    final link time.  Rather than put special case code into
591    bfd_perform_relocation, all the reloc types use this howto
592    function.  It just short circuits the reloc if producing
593    relocateable output against an external symbol.  */
594
595 static bfd_reloc_status_type
596 mips_generic_reloc (abfd,
597                     reloc_entry,
598                     symbol,
599                     data,
600                     input_section,
601                     output_bfd,
602                     error_message)
603      bfd *abfd;
604      arelent *reloc_entry;
605      asymbol *symbol;
606      PTR data;
607      asection *input_section;
608      bfd *output_bfd;
609      char **error_message;
610 {
611   if (output_bfd != (bfd *) NULL
612       && (symbol->flags & BSF_SECTION_SYM) == 0
613       && reloc_entry->addend == 0)
614     {
615       reloc_entry->address += input_section->output_offset;
616       return bfd_reloc_ok;
617     }
618
619   return bfd_reloc_continue;
620 }
621
622 /* Do a REFHI relocation.  This has to be done in combination with a
623    REFLO reloc, because there is a carry from the REFLO to the REFHI.
624    Here we just save the information we need; we do the actual
625    relocation when we see the REFLO.  MIPS ECOFF requires that the
626    REFLO immediately follow the REFHI.  As a GNU extension, we permit
627    an arbitrary number of HI relocs to be associated with a single LO
628    reloc.  This extension permits gcc to output the HI and LO relocs
629    itself.  */
630
631 struct mips_hi
632 {
633   struct mips_hi *next;
634   bfd_byte *addr;
635   bfd_vma addend;
636 };
637
638 /* FIXME: This should not be a static variable.  */
639
640 static struct mips_hi *mips_refhi_list;
641
642 static bfd_reloc_status_type
643 mips_refhi_reloc (abfd,
644                   reloc_entry,
645                   symbol,
646                   data,
647                   input_section,
648                   output_bfd,
649                   error_message)
650      bfd *abfd;
651      arelent *reloc_entry;
652      asymbol *symbol;
653      PTR data;
654      asection *input_section;
655      bfd *output_bfd;
656      char **error_message;
657 {
658   bfd_reloc_status_type ret;
659   bfd_vma relocation;
660   struct mips_hi *n;
661
662   /* If we're relocating, and this an external symbol, we don't want
663      to change anything.  */
664   if (output_bfd != (bfd *) NULL
665       && (symbol->flags & BSF_SECTION_SYM) == 0
666       && reloc_entry->addend == 0)
667     {
668       reloc_entry->address += input_section->output_offset;
669       return bfd_reloc_ok;
670     }
671
672   ret = bfd_reloc_ok;
673   if (bfd_is_und_section (symbol->section)
674       && output_bfd == (bfd *) NULL)
675     ret = bfd_reloc_undefined;
676
677   if (bfd_is_com_section (symbol->section))
678     relocation = 0;
679   else
680     relocation = symbol->value;
681
682   relocation += symbol->section->output_section->vma;
683   relocation += symbol->section->output_offset;
684   relocation += reloc_entry->addend;
685
686   if (reloc_entry->address > input_section->_cooked_size)
687     return bfd_reloc_outofrange;
688
689   /* Save the information, and let REFLO do the actual relocation.  */
690   n = (struct mips_hi *) bfd_malloc (sizeof *n);
691   if (n == NULL)
692     return bfd_reloc_outofrange;
693   n->addr = (bfd_byte *) data + reloc_entry->address;
694   n->addend = relocation;
695   n->next = mips_refhi_list;
696   mips_refhi_list = n;
697
698   if (output_bfd != (bfd *) NULL)
699     reloc_entry->address += input_section->output_offset;
700
701   return ret;
702 }
703
704 /* Do a REFLO relocation.  This is a straightforward 16 bit inplace
705    relocation; this function exists in order to do the REFHI
706    relocation described above.  */
707
708 static bfd_reloc_status_type
709 mips_reflo_reloc (abfd,
710                   reloc_entry,
711                   symbol,
712                   data,
713                   input_section,
714                   output_bfd,
715                   error_message)
716      bfd *abfd;
717      arelent *reloc_entry;
718      asymbol *symbol;
719      PTR data;
720      asection *input_section;
721      bfd *output_bfd;
722      char **error_message;
723 {
724   if (mips_refhi_list != NULL)
725     {
726       struct mips_hi *l;
727
728       l = mips_refhi_list;
729       while (l != NULL)
730         {
731           unsigned long insn;
732           unsigned long val;
733           unsigned long vallo;
734           struct mips_hi *next;
735
736           /* Do the REFHI relocation.  Note that we actually don't
737              need to know anything about the REFLO itself, except
738              where to find the low 16 bits of the addend needed by the
739              REFHI.  */
740           insn = bfd_get_32 (abfd, l->addr);
741           vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
742                    & 0xffff);
743           val = ((insn & 0xffff) << 16) + vallo;
744           val += l->addend;
745
746           /* The low order 16 bits are always treated as a signed
747              value.  Therefore, a negative value in the low order bits
748              requires an adjustment in the high order bits.  We need
749              to make this adjustment in two ways: once for the bits we
750              took from the data, and once for the bits we are putting
751              back in to the data.  */
752           if ((vallo & 0x8000) != 0)
753             val -= 0x10000;
754           if ((val & 0x8000) != 0)
755             val += 0x10000;
756
757           insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
758           bfd_put_32 (abfd, insn, l->addr);
759
760           next = l->next;
761           free (l);
762           l = next;
763         }
764
765       mips_refhi_list = NULL;
766     }
767
768   /* Now do the REFLO reloc in the usual way.  */
769   return mips_generic_reloc (abfd, reloc_entry, symbol, data,
770                               input_section, output_bfd, error_message);
771 }
772
773 /* Do a GPREL relocation.  This is a 16 bit value which must become
774    the offset from the gp register.  */
775
776 static bfd_reloc_status_type
777 mips_gprel_reloc (abfd,
778                   reloc_entry,
779                   symbol,
780                   data,
781                   input_section,
782                   output_bfd,
783                   error_message)
784      bfd *abfd;
785      arelent *reloc_entry;
786      asymbol *symbol;
787      PTR data;
788      asection *input_section;
789      bfd *output_bfd;
790      char **error_message;
791 {
792   boolean relocateable;
793   bfd_vma gp;
794   bfd_vma relocation;
795   unsigned long val;
796   unsigned long insn;
797
798   /* If we're relocating, and this is an external symbol with no
799      addend, we don't want to change anything.  We will only have an
800      addend if this is a newly created reloc, not read from an ECOFF
801      file.  */
802   if (output_bfd != (bfd *) NULL
803       && (symbol->flags & BSF_SECTION_SYM) == 0
804       && reloc_entry->addend == 0)
805     {
806       reloc_entry->address += input_section->output_offset;
807       return bfd_reloc_ok;
808     }
809
810   if (output_bfd != (bfd *) NULL)
811     relocateable = true;
812   else
813     {
814       relocateable = false;
815       output_bfd = symbol->section->output_section->owner;
816     }
817
818   if (bfd_is_und_section (symbol->section)
819       && relocateable == false)
820     return bfd_reloc_undefined;
821
822   /* We have to figure out the gp value, so that we can adjust the
823      symbol value correctly.  We look up the symbol _gp in the output
824      BFD.  If we can't find it, we're stuck.  We cache it in the ECOFF
825      target data.  We don't need to adjust the symbol value for an
826      external symbol if we are producing relocateable output.  */
827   gp = _bfd_get_gp_value (output_bfd);
828   if (gp == 0
829       && (relocateable == false
830           || (symbol->flags & BSF_SECTION_SYM) != 0))
831     {
832       if (relocateable != false)
833         {
834           /* Make up a value.  */
835           gp = symbol->section->output_section->vma + 0x4000;
836           _bfd_set_gp_value (output_bfd, gp);
837         }
838       else
839         {
840           unsigned int count;
841           asymbol **sym;
842           unsigned int i;
843
844           count = bfd_get_symcount (output_bfd);
845           sym = bfd_get_outsymbols (output_bfd);
846
847           if (sym == (asymbol **) NULL)
848             i = count;
849           else
850             {
851               for (i = 0; i < count; i++, sym++)
852                 {
853                   register CONST char *name;
854
855                   name = bfd_asymbol_name (*sym);
856                   if (*name == '_' && strcmp (name, "_gp") == 0)
857                     {
858                       gp = bfd_asymbol_value (*sym);
859                       _bfd_set_gp_value (output_bfd, gp);
860                       break;
861                     }
862                 }
863             }
864
865           if (i >= count)
866             {
867               /* Only get the error once.  */
868               gp = 4;
869               _bfd_set_gp_value (output_bfd, gp);
870               *error_message =
871                 (char *) "GP relative relocation when _gp not defined";
872               return bfd_reloc_dangerous;
873             }
874         }
875     }
876
877   if (bfd_is_com_section (symbol->section))
878     relocation = 0;
879   else
880     relocation = symbol->value;
881
882   relocation += symbol->section->output_section->vma;
883   relocation += symbol->section->output_offset;
884
885   if (reloc_entry->address > input_section->_cooked_size)
886     return bfd_reloc_outofrange;
887
888   insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
889
890   /* Set val to the offset into the section or symbol.  */
891   val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;
892   if (val & 0x8000)
893     val -= 0x10000;
894
895   /* Adjust val for the final section location and GP value.  If we
896      are producing relocateable output, we don't want to do this for
897      an external symbol.  */
898   if (relocateable == false
899       || (symbol->flags & BSF_SECTION_SYM) != 0)
900     val += relocation - gp;
901
902   insn = (insn &~ 0xffff) | (val & 0xffff);
903   bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
904
905   if (relocateable != false)
906     reloc_entry->address += input_section->output_offset;
907
908   /* Make sure it fit in 16 bits.  */
909   if (val >= 0x8000 && val < 0xffff8000)
910     return bfd_reloc_overflow;
911
912   return bfd_reloc_ok;
913 }
914
915 /* Do a RELHI relocation.  We do this in conjunction with a RELLO
916    reloc, just as REFHI and REFLO are done together.  RELHI and RELLO
917    are Cygnus extensions used when generating position independent
918    code for embedded systems.  */
919
920 /* FIXME: This should not be a static variable.  */
921
922 static struct mips_hi *mips_relhi_list;
923
924 static bfd_reloc_status_type
925 mips_relhi_reloc (abfd,
926                   reloc_entry,
927                   symbol,
928                   data,
929                   input_section,
930                   output_bfd,
931                   error_message)
932      bfd *abfd;
933      arelent *reloc_entry;
934      asymbol *symbol;
935      PTR data;
936      asection *input_section;
937      bfd *output_bfd;
938      char **error_message;
939 {
940   bfd_reloc_status_type ret;
941   bfd_vma relocation;
942   struct mips_hi *n;
943
944   /* If this is a reloc against a section symbol, then it is correct
945      in the object file.  The only time we want to change this case is
946      when we are relaxing, and that is handled entirely by
947      mips_relocate_section and never calls this function.  */
948   if ((symbol->flags & BSF_SECTION_SYM) != 0)
949     {
950       if (output_bfd != (bfd *) NULL)
951         reloc_entry->address += input_section->output_offset;
952       return bfd_reloc_ok;
953     }
954
955   /* This is an external symbol.  If we're relocating, we don't want
956      to change anything.  */
957   if (output_bfd != (bfd *) NULL)
958     {
959       reloc_entry->address += input_section->output_offset;
960       return bfd_reloc_ok;
961     }
962
963   ret = bfd_reloc_ok;
964   if (bfd_is_und_section (symbol->section)
965       && output_bfd == (bfd *) NULL)
966     ret = bfd_reloc_undefined;
967
968   if (bfd_is_com_section (symbol->section))
969     relocation = 0;
970   else
971     relocation = symbol->value;
972
973   relocation += symbol->section->output_section->vma;
974   relocation += symbol->section->output_offset;
975   relocation += reloc_entry->addend;
976
977   if (reloc_entry->address > input_section->_cooked_size)
978     return bfd_reloc_outofrange;
979
980   /* Save the information, and let RELLO do the actual relocation.  */
981   n = (struct mips_hi *) bfd_malloc (sizeof *n);
982   if (n == NULL)
983     return bfd_reloc_outofrange;
984   n->addr = (bfd_byte *) data + reloc_entry->address;
985   n->addend = relocation;
986   n->next = mips_relhi_list;
987   mips_relhi_list = n;
988
989   if (output_bfd != (bfd *) NULL)
990     reloc_entry->address += input_section->output_offset;
991
992   return ret;
993 }
994
995 /* Do a RELLO relocation.  This is a straightforward 16 bit PC
996    relative relocation; this function exists in order to do the RELHI
997    relocation described above.  */
998
999 static bfd_reloc_status_type
1000 mips_rello_reloc (abfd,
1001                   reloc_entry,
1002                   symbol,
1003                   data,
1004                   input_section,
1005                   output_bfd,
1006                   error_message)
1007      bfd *abfd;
1008      arelent *reloc_entry;
1009      asymbol *symbol;
1010      PTR data;
1011      asection *input_section;
1012      bfd *output_bfd;
1013      char **error_message;
1014 {
1015   if (mips_relhi_list != NULL)
1016     {
1017       struct mips_hi *l;
1018
1019       l = mips_relhi_list;
1020       while (l != NULL)
1021         {
1022           unsigned long insn;
1023           unsigned long val;
1024           unsigned long vallo;
1025           struct mips_hi *next;
1026
1027           /* Do the RELHI relocation.  Note that we actually don't
1028              need to know anything about the RELLO itself, except
1029              where to find the low 16 bits of the addend needed by the
1030              RELHI.  */
1031           insn = bfd_get_32 (abfd, l->addr);
1032           vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
1033                    & 0xffff);
1034           val = ((insn & 0xffff) << 16) + vallo;
1035           val += l->addend;
1036
1037           /* If the symbol is defined, make val PC relative.  If the
1038              symbol is not defined we don't want to do this, because
1039              we don't want the value in the object file to incorporate
1040              the address of the reloc.  */
1041           if (! bfd_is_und_section (bfd_get_section (symbol))
1042               && ! bfd_is_com_section (bfd_get_section (symbol)))
1043             val -= (input_section->output_section->vma
1044                     + input_section->output_offset
1045                     + reloc_entry->address);
1046
1047           /* The low order 16 bits are always treated as a signed
1048              value.  Therefore, a negative value in the low order bits
1049              requires an adjustment in the high order bits.  We need
1050              to make this adjustment in two ways: once for the bits we
1051              took from the data, and once for the bits we are putting
1052              back in to the data.  */
1053           if ((vallo & 0x8000) != 0)
1054             val -= 0x10000;
1055           if ((val & 0x8000) != 0)
1056             val += 0x10000;
1057
1058           insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
1059           bfd_put_32 (abfd, insn, l->addr);
1060
1061           next = l->next;
1062           free (l);
1063           l = next;
1064         }
1065
1066       mips_relhi_list = NULL;
1067     }
1068
1069   /* If this is a reloc against a section symbol, then it is correct
1070      in the object file.  The only time we want to change this case is
1071      when we are relaxing, and that is handled entirely by
1072      mips_relocate_section and never calls this function.  */
1073   if ((symbol->flags & BSF_SECTION_SYM) != 0)
1074     {
1075       if (output_bfd != (bfd *) NULL)
1076         reloc_entry->address += input_section->output_offset;
1077       return bfd_reloc_ok;
1078     }
1079
1080   /* bfd_perform_relocation does not handle pcrel_offset relocations
1081      correctly when generating a relocateable file, so handle them
1082      directly here.  */
1083   if (output_bfd != (bfd *) NULL)
1084     {
1085       reloc_entry->address += input_section->output_offset;
1086       return bfd_reloc_ok;
1087     }
1088
1089   /* Now do the RELLO reloc in the usual way.  */
1090   return mips_generic_reloc (abfd, reloc_entry, symbol, data,
1091                               input_section, output_bfd, error_message);
1092 }
1093
1094 /* This is the special function for the MIPS_R_SWITCH reloc.  This
1095    special reloc is normally correct in the object file, and only
1096    requires special handling when relaxing.  We don't want
1097    bfd_perform_relocation to tamper with it at all.  */
1098
1099 /*ARGSUSED*/
1100 static bfd_reloc_status_type
1101 mips_switch_reloc (abfd,
1102                    reloc_entry,
1103                    symbol,
1104                    data,
1105                    input_section,
1106                    output_bfd,
1107                    error_message)
1108      bfd *abfd;
1109      arelent *reloc_entry;
1110      asymbol *symbol;
1111      PTR data;
1112      asection *input_section;
1113      bfd *output_bfd;
1114      char **error_message;
1115 {
1116   return bfd_reloc_ok;
1117 }
1118
1119 /* Get the howto structure for a generic reloc type.  */
1120
1121 static reloc_howto_type *
1122 mips_bfd_reloc_type_lookup (abfd, code)
1123      bfd *abfd;
1124      bfd_reloc_code_real_type code;
1125 {
1126   int mips_type;
1127
1128   switch (code)
1129     {
1130     case BFD_RELOC_16:
1131       mips_type = MIPS_R_REFHALF;
1132       break;
1133     case BFD_RELOC_32:
1134     case BFD_RELOC_CTOR:
1135       mips_type = MIPS_R_REFWORD;
1136       break;
1137     case BFD_RELOC_MIPS_JMP:
1138       mips_type = MIPS_R_JMPADDR;
1139       break;
1140     case BFD_RELOC_HI16_S:
1141       mips_type = MIPS_R_REFHI;
1142       break;
1143     case BFD_RELOC_LO16:
1144       mips_type = MIPS_R_REFLO;
1145       break;
1146     case BFD_RELOC_MIPS_GPREL:
1147       mips_type = MIPS_R_GPREL;
1148       break;
1149     case BFD_RELOC_MIPS_LITERAL:
1150       mips_type = MIPS_R_LITERAL;
1151       break;
1152     case BFD_RELOC_16_PCREL_S2:
1153       mips_type = MIPS_R_PCREL16;
1154       break;
1155     case BFD_RELOC_PCREL_HI16_S:
1156       mips_type = MIPS_R_RELHI;
1157       break;
1158     case BFD_RELOC_PCREL_LO16:
1159       mips_type = MIPS_R_RELLO;
1160       break;
1161     case BFD_RELOC_GPREL32:
1162       mips_type = MIPS_R_SWITCH;
1163       break;
1164     default:
1165       return (reloc_howto_type *) NULL;
1166     }
1167
1168   return &ecoff_backend (abfd)->howto_table[mips_type];
1169 }
1170 \f
1171 /* A helper routine for mips_relocate_section which handles the REFHI
1172    and RELHI relocations.  The REFHI relocation must be followed by a
1173    REFLO relocation (and RELHI by a RELLO), and the addend used is
1174    formed from the addends of both instructions.  */
1175
1176 static void
1177 mips_relocate_hi (refhi, reflo, input_bfd, input_section, contents, adjust,
1178                   relocation, pcrel)
1179      struct internal_reloc *refhi;
1180      struct internal_reloc *reflo;
1181      bfd *input_bfd;
1182      asection *input_section;
1183      bfd_byte *contents;
1184      size_t adjust;
1185      bfd_vma relocation;
1186      boolean pcrel;
1187 {
1188   unsigned long insn;
1189   unsigned long val;
1190   unsigned long vallo;
1191
1192   insn = bfd_get_32 (input_bfd,
1193                      contents + adjust + refhi->r_vaddr - input_section->vma);
1194   vallo = (bfd_get_32 (input_bfd,
1195                        contents + adjust + reflo->r_vaddr - input_section->vma)
1196            & 0xffff);
1197   val = ((insn & 0xffff) << 16) + vallo;
1198   val += relocation;
1199
1200   /* The low order 16 bits are always treated as a signed value.
1201      Therefore, a negative value in the low order bits requires an
1202      adjustment in the high order bits.  We need to make this
1203      adjustment in two ways: once for the bits we took from the data,
1204      and once for the bits we are putting back in to the data.  */
1205   if ((vallo & 0x8000) != 0)
1206     val -= 0x10000;
1207
1208   if (pcrel)
1209     val -= (input_section->output_section->vma
1210             + input_section->output_offset
1211             + (reflo->r_vaddr - input_section->vma + adjust));
1212
1213   if ((val & 0x8000) != 0)
1214     val += 0x10000;
1215
1216   insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
1217   bfd_put_32 (input_bfd, (bfd_vma) insn,
1218               contents + adjust + refhi->r_vaddr - input_section->vma);
1219 }
1220
1221 /* Relocate a section while linking a MIPS ECOFF file.  */
1222
1223 static boolean
1224 mips_relocate_section (output_bfd, info, input_bfd, input_section,
1225                        contents, external_relocs)
1226      bfd *output_bfd;
1227      struct bfd_link_info *info;
1228      bfd *input_bfd;
1229      asection *input_section;
1230      bfd_byte *contents;
1231      PTR external_relocs;
1232 {
1233   asection **symndx_to_section;
1234   struct ecoff_link_hash_entry **sym_hashes;
1235   bfd_vma gp;
1236   boolean gp_undefined;
1237   size_t adjust;
1238   long *offsets;
1239   struct external_reloc *ext_rel;
1240   struct external_reloc *ext_rel_end;
1241   unsigned int i;
1242   boolean got_lo;
1243   struct internal_reloc lo_int_rel;
1244
1245   BFD_ASSERT (input_bfd->xvec->byteorder
1246               == output_bfd->xvec->byteorder);
1247
1248   /* We keep a table mapping the symndx found in an internal reloc to
1249      the appropriate section.  This is faster than looking up the
1250      section by name each time.  */
1251   symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
1252   if (symndx_to_section == (asection **) NULL)
1253     {
1254       symndx_to_section = ((asection **)
1255                            bfd_alloc (input_bfd,
1256                                       (NUM_RELOC_SECTIONS
1257                                        * sizeof (asection *))));
1258       if (!symndx_to_section)
1259         return false;
1260
1261       symndx_to_section[RELOC_SECTION_NONE] = NULL;
1262       symndx_to_section[RELOC_SECTION_TEXT] =
1263         bfd_get_section_by_name (input_bfd, ".text");
1264       symndx_to_section[RELOC_SECTION_RDATA] =
1265         bfd_get_section_by_name (input_bfd, ".rdata");
1266       symndx_to_section[RELOC_SECTION_DATA] =
1267         bfd_get_section_by_name (input_bfd, ".data");
1268       symndx_to_section[RELOC_SECTION_SDATA] =
1269         bfd_get_section_by_name (input_bfd, ".sdata");
1270       symndx_to_section[RELOC_SECTION_SBSS] =
1271         bfd_get_section_by_name (input_bfd, ".sbss");
1272       symndx_to_section[RELOC_SECTION_BSS] =
1273         bfd_get_section_by_name (input_bfd, ".bss");
1274       symndx_to_section[RELOC_SECTION_INIT] =
1275         bfd_get_section_by_name (input_bfd, ".init");
1276       symndx_to_section[RELOC_SECTION_LIT8] =
1277         bfd_get_section_by_name (input_bfd, ".lit8");
1278       symndx_to_section[RELOC_SECTION_LIT4] =
1279         bfd_get_section_by_name (input_bfd, ".lit4");
1280       symndx_to_section[RELOC_SECTION_XDATA] = NULL;
1281       symndx_to_section[RELOC_SECTION_PDATA] = NULL;
1282       symndx_to_section[RELOC_SECTION_FINI] =
1283         bfd_get_section_by_name (input_bfd, ".fini");
1284       symndx_to_section[RELOC_SECTION_LITA] = NULL;
1285       symndx_to_section[RELOC_SECTION_ABS] = NULL;
1286
1287       ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
1288     }
1289
1290   sym_hashes = ecoff_data (input_bfd)->sym_hashes;
1291
1292   gp = _bfd_get_gp_value (output_bfd);
1293   if (gp == 0)
1294     gp_undefined = true;
1295   else
1296     gp_undefined = false;
1297
1298   got_lo = false;
1299
1300   adjust = 0;
1301
1302   if (ecoff_section_data (input_bfd, input_section) == NULL)
1303     offsets = NULL;
1304   else
1305     offsets = ecoff_section_data (input_bfd, input_section)->offsets;
1306
1307   ext_rel = (struct external_reloc *) external_relocs;
1308   ext_rel_end = ext_rel + input_section->reloc_count;
1309   for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
1310     {
1311       struct internal_reloc int_rel;
1312       boolean use_lo;
1313       bfd_vma addend;
1314       reloc_howto_type *howto;
1315       struct ecoff_link_hash_entry *h = NULL;
1316       asection *s = NULL;
1317       bfd_vma relocation;
1318       bfd_reloc_status_type r;
1319
1320       if (! got_lo)
1321         mips_ecoff_swap_reloc_in (input_bfd, (PTR) ext_rel, &int_rel);
1322       else
1323         {
1324           int_rel = lo_int_rel;
1325           got_lo = false;
1326         }
1327
1328       BFD_ASSERT (int_rel.r_type < ecoff_backend (abfd)->howto_table_size);
1329
1330       /* The REFHI and RELHI relocs requires special handling.  they
1331          must be followed by a REFLO or RELLO reloc, respectively, and
1332          the addend is formed from both relocs.  */
1333       if (int_rel.r_type == MIPS_R_REFHI
1334           || int_rel.r_type == MIPS_R_RELHI)
1335         {
1336           struct external_reloc *lo_ext_rel;
1337
1338           /* As a GNU extension, permit an arbitrary number of REFHI
1339              or RELHI relocs before the REFLO or RELLO reloc.  This
1340              permits gcc to emit the HI and LO relocs itself.  */
1341           for (lo_ext_rel = ext_rel + 1;
1342                lo_ext_rel < ext_rel_end;
1343                lo_ext_rel++)
1344             {
1345               mips_ecoff_swap_reloc_in (input_bfd, (PTR) lo_ext_rel,
1346                                         &lo_int_rel);
1347               if (lo_int_rel.r_type != int_rel.r_type)
1348                 break;
1349             }
1350
1351           if (lo_ext_rel < ext_rel_end
1352               && (lo_int_rel.r_type
1353                   == (int_rel.r_type == MIPS_R_REFHI
1354                       ? MIPS_R_REFLO
1355                       : MIPS_R_RELLO))
1356               && int_rel.r_extern == lo_int_rel.r_extern
1357               && int_rel.r_symndx == lo_int_rel.r_symndx)
1358             {
1359               use_lo = true;
1360               if (lo_ext_rel == ext_rel + 1)
1361                 got_lo = true;
1362             }
1363         }
1364
1365       howto = &ecoff_backend (abfd)->howto_table[int_rel.r_type];
1366
1367       /* The SWITCH reloc must be handled specially.  This reloc is
1368          marks the location of a difference between two portions of an
1369          object file.  The symbol index does not reference a symbol,
1370          but is actually the offset from the reloc to the subtrahend
1371          of the difference.  This reloc is correct in the object file,
1372          and needs no further adjustment, unless we are relaxing.  If
1373          we are relaxing, we may have to add in an offset.  Since no
1374          symbols are involved in this reloc, we handle it completely
1375          here.  */
1376       if (int_rel.r_type == MIPS_R_SWITCH)
1377         {
1378           if (offsets != NULL
1379               && offsets[i] != 0)
1380             {
1381               r = _bfd_relocate_contents (howto, input_bfd,
1382                                           (bfd_vma) offsets[i],
1383                                           (contents
1384                                            + adjust
1385                                            + int_rel.r_vaddr
1386                                            - input_section->vma));
1387               BFD_ASSERT (r == bfd_reloc_ok);
1388             }
1389
1390           continue;
1391         }
1392
1393       if (int_rel.r_extern)
1394         {
1395           h = sym_hashes[int_rel.r_symndx];
1396           /* If h is NULL, that means that there is a reloc against an
1397              external symbol which we thought was just a debugging
1398              symbol.  This should not happen.  */
1399           if (h == (struct ecoff_link_hash_entry *) NULL)
1400             abort ();
1401         }
1402       else
1403         {
1404           if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS)
1405             s = NULL;
1406           else
1407             s = symndx_to_section[int_rel.r_symndx];
1408
1409           if (s == (asection *) NULL)
1410             abort ();
1411         }
1412
1413       /* The GPREL reloc uses an addend: the difference in the GP
1414          values.  */
1415       if (int_rel.r_type != MIPS_R_GPREL
1416           && int_rel.r_type != MIPS_R_LITERAL)
1417         addend = 0;
1418       else
1419         {
1420           if (gp_undefined)
1421             {
1422               if (! ((*info->callbacks->reloc_dangerous)
1423                      (info, "GP relative relocation when GP not defined",
1424                       input_bfd, input_section,
1425                       int_rel.r_vaddr - input_section->vma)))
1426                 return false;
1427               /* Only give the error once per link.  */
1428               gp = 4;
1429               _bfd_set_gp_value (output_bfd, gp);
1430               gp_undefined = false;
1431             }
1432           if (! int_rel.r_extern)
1433             {
1434               /* This is a relocation against a section.  The current
1435                  addend in the instruction is the difference between
1436                  INPUT_SECTION->vma and the GP value of INPUT_BFD.  We
1437                  must change this to be the difference between the
1438                  final definition (which will end up in RELOCATION)
1439                  and the GP value of OUTPUT_BFD (which is in GP).  */
1440               addend = ecoff_data (input_bfd)->gp - gp;
1441             }
1442           else if (! info->relocateable
1443                    || h->root.type == bfd_link_hash_defined
1444                    || h->root.type == bfd_link_hash_defweak)
1445             {
1446               /* This is a relocation against a defined symbol.  The
1447                  current addend in the instruction is simply the
1448                  desired offset into the symbol (normally zero).  We
1449                  are going to change this into a relocation against a
1450                  defined symbol, so we want the instruction to hold
1451                  the difference between the final definition of the
1452                  symbol (which will end up in RELOCATION) and the GP
1453                  value of OUTPUT_BFD (which is in GP).  */
1454               addend = - gp;
1455             }
1456           else
1457             {
1458               /* This is a relocation against an undefined or common
1459                  symbol.  The current addend in the instruction is
1460                  simply the desired offset into the symbol (normally
1461                  zero).  We are generating relocateable output, and we
1462                  aren't going to define this symbol, so we just leave
1463                  the instruction alone.  */
1464               addend = 0;
1465             }
1466         }
1467
1468       /* If we are relaxing, mips_relax_section may have set
1469          offsets[i] to some value.  A value of 1 means we must expand
1470          a PC relative branch into a multi-instruction of sequence,
1471          and any other value is an addend.  */
1472       if (offsets != NULL
1473           && offsets[i] != 0)
1474         {
1475           BFD_ASSERT (! info->relocateable);
1476           BFD_ASSERT (int_rel.r_type == MIPS_R_PCREL16
1477                       || int_rel.r_type == MIPS_R_RELHI
1478                       || int_rel.r_type == MIPS_R_RELLO);
1479           if (offsets[i] != 1)
1480             addend += offsets[i];
1481           else
1482             {
1483               bfd_byte *here;
1484
1485               BFD_ASSERT (int_rel.r_extern
1486                           && int_rel.r_type == MIPS_R_PCREL16);
1487
1488               /* Move the rest of the instructions up.  */
1489               here = (contents
1490                       + adjust
1491                       + int_rel.r_vaddr
1492                       - input_section->vma);
1493               memmove (here + PCREL16_EXPANSION_ADJUSTMENT, here,
1494                        (size_t) (input_section->_raw_size
1495                                  - (int_rel.r_vaddr - input_section->vma)));
1496                        
1497               /* Generate the new instructions.  */
1498               if (! mips_relax_pcrel16 (info, input_bfd, input_section,
1499                                         h, here,
1500                                         (input_section->output_section->vma
1501                                          + input_section->output_offset
1502                                          + (int_rel.r_vaddr
1503                                             - input_section->vma)
1504                                          + adjust)))
1505                 return false;
1506
1507               /* We must adjust everything else up a notch.  */
1508               adjust += PCREL16_EXPANSION_ADJUSTMENT;
1509
1510               /* mips_relax_pcrel16 handles all the details of this
1511                  relocation.  */
1512               continue;
1513             }
1514         }
1515
1516       /* If we are relaxing, and this is a reloc against the .text
1517          segment, we may need to adjust it if some branches have been
1518          expanded.  The reloc types which are likely to occur in the
1519          .text section are handled efficiently by mips_relax_section,
1520          and thus do not need to be handled here.  */
1521       if (ecoff_data (input_bfd)->debug_info.adjust != NULL
1522           && ! int_rel.r_extern
1523           && int_rel.r_symndx == RELOC_SECTION_TEXT
1524           && (strcmp (bfd_get_section_name (input_bfd, input_section),
1525                       ".text") != 0
1526               || (int_rel.r_type != MIPS_R_PCREL16
1527                   && int_rel.r_type != MIPS_R_SWITCH
1528                   && int_rel.r_type != MIPS_R_RELHI
1529                   && int_rel.r_type != MIPS_R_RELLO)))
1530         {
1531           bfd_vma adr;
1532           struct ecoff_value_adjust *a;
1533
1534           /* We need to get the addend so that we know whether we need
1535              to adjust the address.  */
1536           BFD_ASSERT (int_rel.r_type == MIPS_R_REFWORD);
1537
1538           adr = bfd_get_32 (input_bfd,
1539                             (contents
1540                              + adjust
1541                              + int_rel.r_vaddr
1542                              - input_section->vma));
1543
1544           for (a = ecoff_data (input_bfd)->debug_info.adjust;
1545                a != (struct ecoff_value_adjust *) NULL;
1546                a = a->next)
1547             {
1548               if (adr >= a->start && adr < a->end)
1549                 addend += a->adjust;
1550             }
1551         }
1552
1553       if (info->relocateable)
1554         {
1555           /* We are generating relocateable output, and must convert
1556              the existing reloc.  */
1557           if (int_rel.r_extern)
1558             {
1559               if ((h->root.type == bfd_link_hash_defined
1560                    || h->root.type == bfd_link_hash_defweak)
1561                   && ! bfd_is_abs_section (h->root.u.def.section))
1562                 {
1563                   const char *name;
1564
1565                   /* This symbol is defined in the output.  Convert
1566                      the reloc from being against the symbol to being
1567                      against the section.  */
1568
1569                   /* Clear the r_extern bit.  */
1570                   int_rel.r_extern = 0;
1571
1572                   /* Compute a new r_symndx value.  */
1573                   s = h->root.u.def.section;
1574                   name = bfd_get_section_name (output_bfd,
1575                                                s->output_section);
1576
1577                   int_rel.r_symndx = -1;
1578                   switch (name[1])
1579                     {
1580                     case 'b':
1581                       if (strcmp (name, ".bss") == 0)
1582                         int_rel.r_symndx = RELOC_SECTION_BSS;
1583                       break;
1584                     case 'd':
1585                       if (strcmp (name, ".data") == 0)
1586                         int_rel.r_symndx = RELOC_SECTION_DATA;
1587                       break;
1588                     case 'f':
1589                       if (strcmp (name, ".fini") == 0)
1590                         int_rel.r_symndx = RELOC_SECTION_FINI;
1591                       break;
1592                     case 'i':
1593                       if (strcmp (name, ".init") == 0)
1594                         int_rel.r_symndx = RELOC_SECTION_INIT;
1595                       break;
1596                     case 'l':
1597                       if (strcmp (name, ".lit8") == 0)
1598                         int_rel.r_symndx = RELOC_SECTION_LIT8;
1599                       else if (strcmp (name, ".lit4") == 0)
1600                         int_rel.r_symndx = RELOC_SECTION_LIT4;
1601                       break;
1602                     case 'r':
1603                       if (strcmp (name, ".rdata") == 0)
1604                         int_rel.r_symndx = RELOC_SECTION_RDATA;
1605                       break;
1606                     case 's':
1607                       if (strcmp (name, ".sdata") == 0)
1608                         int_rel.r_symndx = RELOC_SECTION_SDATA;
1609                       else if (strcmp (name, ".sbss") == 0)
1610                         int_rel.r_symndx = RELOC_SECTION_SBSS;
1611                       break;
1612                     case 't':
1613                       if (strcmp (name, ".text") == 0)
1614                         int_rel.r_symndx = RELOC_SECTION_TEXT;
1615                       break;
1616                     }
1617                       
1618                   if (int_rel.r_symndx == -1)
1619                     abort ();
1620
1621                   /* Add the section VMA and the symbol value.  */
1622                   relocation = (h->root.u.def.value
1623                                 + s->output_section->vma
1624                                 + s->output_offset);
1625
1626                   /* For a PC relative relocation, the object file
1627                      currently holds just the addend.  We must adjust
1628                      by the address to get the right value.  */
1629                   if (howto->pc_relative)
1630                     {
1631                       relocation -= int_rel.r_vaddr - input_section->vma;
1632
1633                       /* If we are converting a RELHI or RELLO reloc
1634                          from being against an external symbol to
1635                          being against a section, we must put a
1636                          special value into the r_offset field.  This
1637                          value is the old addend.  The r_offset for
1638                          both the RELHI and RELLO relocs are the same,
1639                          and we set both when we see RELHI.  */
1640                       if (int_rel.r_type == MIPS_R_RELHI)
1641                         {
1642                           long addhi, addlo;
1643
1644                           addhi = bfd_get_32 (input_bfd,
1645                                               (contents
1646                                                + adjust
1647                                                + int_rel.r_vaddr
1648                                                - input_section->vma));
1649                           addhi &= 0xffff;
1650                           if (addhi & 0x8000)
1651                             addhi -= 0x10000;
1652                           addhi <<= 16;
1653
1654                           if (! use_lo)
1655                             addlo = 0;
1656                           else
1657                             {
1658                               addlo = bfd_get_32 (input_bfd,
1659                                                   (contents
1660                                                    + adjust
1661                                                    + lo_int_rel.r_vaddr
1662                                                    - input_section->vma));
1663                               addlo &= 0xffff;
1664                               if (addlo & 0x8000)
1665                                 addlo -= 0x10000;
1666
1667                               lo_int_rel.r_offset = addhi + addlo;
1668                             }
1669
1670                           int_rel.r_offset = addhi + addlo;
1671                         }
1672                     }
1673
1674                   h = NULL;
1675                 }
1676               else
1677                 {
1678                   /* Change the symndx value to the right one for the
1679                      output BFD.  */
1680                   int_rel.r_symndx = h->indx;
1681                   if (int_rel.r_symndx == -1)
1682                     {
1683                       /* This symbol is not being written out.  */
1684                       if (! ((*info->callbacks->unattached_reloc)
1685                              (info, h->root.root.string, input_bfd,
1686                               input_section,
1687                               int_rel.r_vaddr - input_section->vma)))
1688                         return false;
1689                       int_rel.r_symndx = 0;
1690                     }
1691                   relocation = 0;
1692                 }
1693             }
1694           else
1695             {
1696               /* This is a relocation against a section.  Adjust the
1697                  value by the amount the section moved.  */
1698               relocation = (s->output_section->vma
1699                             + s->output_offset
1700                             - s->vma);
1701             }
1702
1703           relocation += addend;
1704           addend = 0;
1705
1706           /* Adjust a PC relative relocation by removing the reference
1707              to the original address in the section and including the
1708              reference to the new address.  However, external RELHI
1709              and RELLO relocs are PC relative, but don't include any
1710              reference to the address.  The addend is merely an
1711              addend.  */
1712           if (howto->pc_relative
1713               && (! int_rel.r_extern
1714                   || (int_rel.r_type != MIPS_R_RELHI
1715                       && int_rel.r_type != MIPS_R_RELLO)))
1716             relocation -= (input_section->output_section->vma
1717                            + input_section->output_offset
1718                            - input_section->vma);
1719
1720           /* Adjust the contents.  */
1721           if (relocation == 0)
1722             r = bfd_reloc_ok;
1723           else
1724             {
1725               if (int_rel.r_type != MIPS_R_REFHI
1726                   && int_rel.r_type != MIPS_R_RELHI)
1727                 r = _bfd_relocate_contents (howto, input_bfd, relocation,
1728                                             (contents
1729                                              + adjust
1730                                              + int_rel.r_vaddr
1731                                              - input_section->vma));
1732               else
1733                 {
1734                   mips_relocate_hi (&int_rel,
1735                                     use_lo ? &lo_int_rel : NULL,
1736                                     input_bfd, input_section, contents,
1737                                     adjust, relocation,
1738                                     int_rel.r_type == MIPS_R_RELHI);
1739                   r = bfd_reloc_ok;
1740                 }
1741             }
1742
1743           /* Adjust the reloc address.  */
1744           int_rel.r_vaddr += (input_section->output_section->vma
1745                               + input_section->output_offset
1746                               - input_section->vma);
1747
1748           /* Save the changed reloc information.  */
1749           mips_ecoff_swap_reloc_out (input_bfd, &int_rel, (PTR) ext_rel);
1750         }
1751       else
1752         {
1753           /* We are producing a final executable.  */
1754           if (int_rel.r_extern)
1755             {
1756               /* This is a reloc against a symbol.  */
1757               if (h->root.type == bfd_link_hash_defined
1758                   || h->root.type == bfd_link_hash_defweak)
1759                 {
1760                   asection *hsec;
1761
1762                   hsec = h->root.u.def.section;
1763                   relocation = (h->root.u.def.value
1764                                 + hsec->output_section->vma
1765                                 + hsec->output_offset);
1766                 }
1767               else
1768                 {
1769                   if (! ((*info->callbacks->undefined_symbol)
1770                          (info, h->root.root.string, input_bfd,
1771                           input_section,
1772                           int_rel.r_vaddr - input_section->vma)))
1773                     return false;
1774                   relocation = 0;
1775                 }
1776             }
1777           else
1778             {
1779               /* This is a reloc against a section.  */
1780               relocation = (s->output_section->vma
1781                             + s->output_offset
1782                             - s->vma);
1783
1784               /* A PC relative reloc is already correct in the object
1785                  file.  Make it look like a pcrel_offset relocation by
1786                  adding in the start address.  */
1787               if (howto->pc_relative)
1788                 {
1789                   if (int_rel.r_type != MIPS_R_RELHI || ! use_lo)
1790                     relocation += int_rel.r_vaddr + adjust;
1791                   else
1792                     relocation += lo_int_rel.r_vaddr + adjust;
1793                 }
1794             }
1795
1796           if (int_rel.r_type != MIPS_R_REFHI
1797               && int_rel.r_type != MIPS_R_RELHI)
1798             r = _bfd_final_link_relocate (howto,
1799                                           input_bfd,
1800                                           input_section,
1801                                           contents,
1802                                           (int_rel.r_vaddr
1803                                            - input_section->vma
1804                                            + adjust),
1805                                           relocation,
1806                                           addend);
1807           else
1808             {
1809               mips_relocate_hi (&int_rel,
1810                                 use_lo ? &lo_int_rel : NULL,
1811                                 input_bfd, input_section, contents, adjust,
1812                                 relocation,
1813                                 int_rel.r_type == MIPS_R_RELHI);
1814               r = bfd_reloc_ok;
1815             }
1816         }
1817
1818       /* MIPS_R_JMPADDR requires peculiar overflow detection.  The
1819          instruction provides a 28 bit address (the two lower bits are
1820          implicit zeroes) which is combined with the upper four bits
1821          of the instruction address.  */
1822       if (r == bfd_reloc_ok
1823           && int_rel.r_type == MIPS_R_JMPADDR
1824           && (((relocation
1825                 + addend
1826                 + (int_rel.r_extern ? 0 : s->vma))
1827                & 0xf0000000)
1828               != ((input_section->output_section->vma
1829                    + input_section->output_offset
1830                    + (int_rel.r_vaddr - input_section->vma)
1831                    + adjust)
1832                   & 0xf0000000)))
1833         r = bfd_reloc_overflow;
1834
1835       if (r != bfd_reloc_ok)
1836         {
1837           switch (r)
1838             {
1839             default:
1840             case bfd_reloc_outofrange:
1841               abort ();
1842             case bfd_reloc_overflow:
1843               {
1844                 const char *name;
1845
1846                 if (int_rel.r_extern)
1847                   name = h->root.root.string;
1848                 else
1849                   name = bfd_section_name (input_bfd, s);
1850                 if (! ((*info->callbacks->reloc_overflow)
1851                        (info, name, howto->name, (bfd_vma) 0,
1852                         input_bfd, input_section,
1853                         int_rel.r_vaddr - input_section->vma)))
1854                   return false;
1855               }
1856               break;
1857             }
1858         }
1859     }
1860
1861   return true;
1862 }
1863 \f
1864 /* Read in the relocs for a section.  */
1865
1866 static boolean
1867 mips_read_relocs (abfd, sec)
1868      bfd *abfd;
1869      asection *sec;
1870 {
1871   struct ecoff_section_tdata *section_tdata;
1872
1873   section_tdata = ecoff_section_data (abfd, sec);
1874   if (section_tdata == (struct ecoff_section_tdata *) NULL)
1875     {
1876       sec->used_by_bfd =
1877         (PTR) bfd_alloc (abfd, sizeof (struct ecoff_section_tdata));
1878       if (sec->used_by_bfd == NULL)
1879         return false;
1880
1881       section_tdata = ecoff_section_data (abfd, sec);
1882       section_tdata->external_relocs = NULL;
1883       section_tdata->contents = NULL;
1884       section_tdata->offsets = NULL;
1885     }
1886
1887   if (section_tdata->external_relocs == NULL)
1888     {
1889       bfd_size_type external_relocs_size;
1890
1891       external_relocs_size = (ecoff_backend (abfd)->external_reloc_size
1892                               * sec->reloc_count);
1893
1894       section_tdata->external_relocs =
1895         (PTR) bfd_alloc (abfd, external_relocs_size);
1896       if (section_tdata->external_relocs == NULL && external_relocs_size != 0)
1897         return false;
1898
1899       if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0
1900           || (bfd_read (section_tdata->external_relocs, 1,
1901                         external_relocs_size, abfd)
1902               != external_relocs_size))
1903         return false;
1904     }
1905
1906   return true;
1907 }
1908
1909 /* Relax a section when linking a MIPS ECOFF file.  This is used for
1910    embedded PIC code, which always uses PC relative branches which
1911    only have an 18 bit range on MIPS.  If a branch is not in range, we
1912    generate a long instruction sequence to compensate.  Each time we
1913    find a branch to expand, we have to check all the others again to
1914    make sure they are still in range.  This is slow, but it only has
1915    to be done when -relax is passed to the linker.
1916
1917    This routine figures out which branches need to expand; the actual
1918    expansion is done in mips_relocate_section when the section
1919    contents are relocated.  The information is stored in the offsets
1920    field of the ecoff_section_tdata structure.  An offset of 1 means
1921    that the branch must be expanded into a multi-instruction PC
1922    relative branch (such an offset will only occur for a PC relative
1923    branch to an external symbol).  Any other offset must be a multiple
1924    of four, and is the amount to change the branch by (such an offset
1925    will only occur for a PC relative branch within the same section).
1926
1927    We do not modify the section relocs or contents themselves so that
1928    if memory usage becomes an issue we can discard them and read them
1929    again.  The only information we must save in memory between this
1930    routine and the mips_relocate_section routine is the table of
1931    offsets.  */
1932
1933 static boolean
1934 mips_relax_section (abfd, sec, info, again)
1935      bfd *abfd;
1936      asection *sec;
1937      struct bfd_link_info *info;
1938      boolean *again;
1939 {
1940   struct ecoff_section_tdata *section_tdata;
1941   bfd_byte *contents = NULL;
1942   long *offsets;
1943   struct external_reloc *ext_rel;
1944   struct external_reloc *ext_rel_end;
1945   unsigned int i;
1946
1947   /* Assume we are not going to need another pass.  */
1948   *again = false;
1949
1950   /* If we are not generating an ECOFF file, this is much too
1951      confusing to deal with.  */
1952   if (info->hash->creator->flavour != bfd_get_flavour (abfd))
1953     return true;
1954
1955   /* If there are no relocs, there is nothing to do.  */
1956   if (sec->reloc_count == 0)
1957     return true;
1958
1959   /* We are only interested in PC relative relocs, and why would there
1960      ever be one from anything but the .text section?  */
1961   if (strcmp (bfd_get_section_name (abfd, sec), ".text") != 0)
1962     return true;
1963
1964   /* Read in the relocs, if we haven't already got them.  */
1965   section_tdata = ecoff_section_data (abfd, sec);
1966   if (section_tdata == (struct ecoff_section_tdata *) NULL
1967       || section_tdata->external_relocs == NULL)
1968     {
1969       if (! mips_read_relocs (abfd, sec))
1970         goto error_return;
1971       section_tdata = ecoff_section_data (abfd, sec);
1972     }
1973
1974   if (sec->_cooked_size == 0)
1975     {
1976       /* We must initialize _cooked_size only the first time we are
1977          called.  */
1978       sec->_cooked_size = sec->_raw_size;
1979     }
1980
1981   contents = section_tdata->contents;
1982   offsets = section_tdata->offsets;
1983
1984   /* Look for any external PC relative relocs.  Internal PC relative
1985      relocs are already correct in the object file, so they certainly
1986      can not overflow.  */
1987   ext_rel = (struct external_reloc *) section_tdata->external_relocs;
1988   ext_rel_end = ext_rel + sec->reloc_count;
1989   for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
1990     {
1991       struct internal_reloc int_rel;
1992       struct ecoff_link_hash_entry *h;
1993       asection *hsec;
1994       bfd_signed_vma relocation;
1995       struct external_reloc *adj_ext_rel;
1996       unsigned int adj_i;
1997       unsigned long ext_count;
1998       struct ecoff_link_hash_entry **adj_h_ptr;
1999       struct ecoff_link_hash_entry **adj_h_ptr_end;
2000       struct ecoff_value_adjust *adjust;
2001
2002       /* If we have already expanded this reloc, we certainly don't
2003          need to do it again.  */
2004       if (offsets != (long *) NULL && offsets[i] == 1)
2005         continue;
2006
2007       /* Quickly check that this reloc is external PCREL16.  */
2008       if (bfd_header_big_endian (abfd))
2009         {
2010           if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_BIG) == 0
2011               || (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_BIG)
2012                    >> RELOC_BITS3_TYPE_SH_BIG)
2013                   != MIPS_R_PCREL16))
2014             continue;
2015         }
2016       else
2017         {
2018           if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) == 0
2019               || (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
2020                    >> RELOC_BITS3_TYPE_SH_LITTLE)
2021                   != MIPS_R_PCREL16))
2022             continue;
2023         }
2024
2025       mips_ecoff_swap_reloc_in (abfd, (PTR) ext_rel, &int_rel);
2026
2027       h = ecoff_data (abfd)->sym_hashes[int_rel.r_symndx];
2028       if (h == (struct ecoff_link_hash_entry *) NULL)
2029         abort ();
2030
2031       if (h->root.type != bfd_link_hash_defined
2032           && h->root.type != bfd_link_hash_defweak)
2033         {
2034           /* Just ignore undefined symbols.  These will presumably
2035              generate an error later in the link.  */
2036           continue;
2037         }
2038
2039       /* Get the value of the symbol.  */
2040       hsec = h->root.u.def.section;
2041       relocation = (h->root.u.def.value
2042                     + hsec->output_section->vma
2043                     + hsec->output_offset);
2044
2045       /* Subtract out the current address.  */
2046       relocation -= (sec->output_section->vma
2047                      + sec->output_offset
2048                      + (int_rel.r_vaddr - sec->vma));
2049
2050       /* The addend is stored in the object file.  In the normal case
2051          of ``bal symbol'', the addend will be -4.  It will only be
2052          different in the case of ``bal symbol+constant''.  To avoid
2053          always reading in the section contents, we don't check the
2054          addend in the object file (we could easily check the contents
2055          if we happen to have already read them in, but I fear that
2056          this could be confusing).  This means we will screw up if
2057          there is a branch to a symbol that is in range, but added to
2058          a constant which puts it out of range; in such a case the
2059          link will fail with a reloc overflow error.  Since the
2060          compiler will never generate such code, it should be easy
2061          enough to work around it by changing the assembly code in the
2062          source file.  */
2063       relocation -= 4;
2064
2065       /* Now RELOCATION is the number we want to put in the object
2066          file.  See whether it fits.  */
2067       if (relocation >= -0x20000 && relocation < 0x20000)
2068         continue;
2069
2070       /* Now that we know this reloc needs work, which will rarely
2071          happen, go ahead and grab the section contents.  */
2072       if (contents == (bfd_byte *) NULL)
2073         {
2074           if (info->keep_memory)
2075             contents = (bfd_byte *) bfd_alloc (abfd, sec->_raw_size);
2076           else
2077             contents = (bfd_byte *) bfd_malloc ((size_t) sec->_raw_size);
2078           if (contents == (bfd_byte *) NULL)
2079             goto error_return;
2080           if (! bfd_get_section_contents (abfd, sec, (PTR) contents,
2081                                           (file_ptr) 0, sec->_raw_size))
2082             goto error_return;
2083           if (info->keep_memory)
2084             section_tdata->contents = contents;
2085         }
2086
2087       /* We only support changing the bal instruction.  It would be
2088          possible to handle other PC relative branches, but some of
2089          them (the conditional branches) would require a different
2090          length instruction sequence which would complicate both this
2091          routine and mips_relax_pcrel16.  It could be written if
2092          somebody felt it were important.  Ignoring this reloc will
2093          presumably cause a reloc overflow error later on.  */
2094       if (bfd_get_32 (abfd, contents + int_rel.r_vaddr - sec->vma)
2095           != 0x0411ffff) /* bgezal $0,. == bal . */
2096         continue;
2097
2098       /* Bother.  We need to expand this reloc, and we will need to
2099          make another relaxation pass since this change may put other
2100          relocs out of range.  We need to examine the local branches
2101          and we need to allocate memory to hold the offsets we must
2102          add to them.  We also need to adjust the values of all
2103          symbols in the object file following this location.  */
2104
2105       sec->_cooked_size += PCREL16_EXPANSION_ADJUSTMENT;
2106       *again = true;
2107
2108       if (offsets == (long *) NULL)
2109         {
2110           size_t size;
2111
2112           size = sec->reloc_count * sizeof (long);
2113           offsets = (long *) bfd_alloc (abfd, size);
2114           if (offsets == (long *) NULL)
2115             goto error_return;
2116           memset (offsets, 0, size);
2117           section_tdata->offsets = offsets;
2118         }
2119
2120       offsets[i] = 1;
2121
2122       /* Now look for all PC relative references that cross this reloc
2123          and adjust their offsets.  */
2124       adj_ext_rel = (struct external_reloc *) section_tdata->external_relocs;
2125       for (adj_i = 0; adj_ext_rel < ext_rel_end; adj_ext_rel++, adj_i++)
2126         {
2127           struct internal_reloc adj_int_rel;
2128           bfd_vma start, stop;
2129           int change;
2130
2131           mips_ecoff_swap_reloc_in (abfd, (PTR) adj_ext_rel, &adj_int_rel);
2132
2133           if (adj_int_rel.r_type == MIPS_R_PCREL16)
2134             {
2135               unsigned long insn;
2136
2137               /* We only care about local references.  External ones
2138                  will be relocated correctly anyhow.  */
2139               if (adj_int_rel.r_extern)
2140                 continue;
2141
2142               /* We are only interested in a PC relative reloc within
2143                  this section.  FIXME: Cross section PC relative
2144                  relocs may not be handled correctly; does anybody
2145                  care?  */
2146               if (adj_int_rel.r_symndx != RELOC_SECTION_TEXT)
2147                 continue;
2148
2149               start = adj_int_rel.r_vaddr;
2150
2151               insn = bfd_get_32 (abfd,
2152                                  contents + adj_int_rel.r_vaddr - sec->vma);
2153
2154               stop = (insn & 0xffff) << 2;
2155               if ((stop & 0x20000) != 0)
2156                 stop -= 0x40000;
2157               stop += adj_int_rel.r_vaddr + 4;
2158             }
2159           else if (adj_int_rel.r_type == MIPS_R_RELHI)
2160             {
2161               struct internal_reloc rello;
2162               long addhi, addlo;
2163
2164               /* The next reloc must be MIPS_R_RELLO, and we handle
2165                  them together.  */
2166               BFD_ASSERT (adj_ext_rel + 1 < ext_rel_end);
2167
2168               mips_ecoff_swap_reloc_in (abfd, (PTR) (adj_ext_rel + 1), &rello);
2169
2170               BFD_ASSERT (rello.r_type == MIPS_R_RELLO);
2171               
2172               addhi = bfd_get_32 (abfd,
2173                                    contents + adj_int_rel.r_vaddr - sec->vma);
2174               addhi &= 0xffff;
2175               if (addhi & 0x8000)
2176                 addhi -= 0x10000;
2177               addhi <<= 16;
2178
2179               addlo = bfd_get_32 (abfd, contents + rello.r_vaddr - sec->vma);
2180               addlo &= 0xffff;
2181               if (addlo & 0x8000)
2182                 addlo -= 0x10000;
2183
2184               if (adj_int_rel.r_extern)
2185                 {
2186                   /* The value we want here is
2187                        sym - RELLOaddr + addend
2188                      which we can express as
2189                        sym - (RELLOaddr - addend)
2190                      Therefore if we are expanding the area between
2191                      RELLOaddr and RELLOaddr - addend we must adjust
2192                      the addend.  This is admittedly ambiguous, since
2193                      we might mean (sym + addend) - RELLOaddr, but in
2194                      practice we don't, and there is no way to handle
2195                      that case correctly since at this point we have
2196                      no idea whether any reloc is being expanded
2197                      between sym and sym + addend.  */
2198                   start = rello.r_vaddr - (addhi + addlo);
2199                   stop = rello.r_vaddr;
2200                 }
2201               else
2202                 {
2203                   /* An internal RELHI/RELLO pair represents the
2204                      difference between two addresses, $LC0 - foo.
2205                      The symndx value is actually the difference
2206                      between the reloc address and $LC0.  This lets us
2207                      compute $LC0, and, by considering the addend,
2208                      foo.  If the reloc we are expanding falls between
2209                      those two relocs, we must adjust the addend.  At
2210                      this point, the symndx value is actually in the
2211                      r_offset field, where it was put by
2212                      mips_ecoff_swap_reloc_in.  */
2213                   start = rello.r_vaddr - adj_int_rel.r_offset;
2214                   stop = start + addhi + addlo;
2215                 }
2216             }
2217           else if (adj_int_rel.r_type == MIPS_R_SWITCH)
2218             {
2219               /* A MIPS_R_SWITCH reloc represents a word of the form
2220                    .word $L3-$LS12
2221                  The value in the object file is correct, assuming the
2222                  original value of $L3.  The symndx value is actually
2223                  the difference between the reloc address and $LS12.
2224                  This lets us compute the original value of $LS12 as
2225                    vaddr - symndx
2226                  and the original value of $L3 as
2227                    vaddr - symndx + addend
2228                  where addend is the value from the object file.  At
2229                  this point, the symndx value is actually found in the
2230                  r_offset field, since it was moved by
2231                  mips_ecoff_swap_reloc_in.  */
2232               start = adj_int_rel.r_vaddr - adj_int_rel.r_offset;
2233               stop = start + bfd_get_32 (abfd,
2234                                          (contents
2235                                           + adj_int_rel.r_vaddr
2236                                           - sec->vma));
2237             }
2238           else
2239             continue;
2240
2241           /* If the range expressed by this reloc, which is the
2242              distance between START and STOP crosses the reloc we are
2243              expanding, we must adjust the offset.  The sign of the
2244              adjustment depends upon the direction in which the range
2245              crosses the reloc being expanded.  */
2246           if (start <= int_rel.r_vaddr && stop > int_rel.r_vaddr)
2247             change = PCREL16_EXPANSION_ADJUSTMENT;
2248           else if (start > int_rel.r_vaddr && stop <= int_rel.r_vaddr)
2249             change = - PCREL16_EXPANSION_ADJUSTMENT;
2250           else
2251             change = 0;
2252
2253           offsets[adj_i] += change;
2254
2255           if (adj_int_rel.r_type == MIPS_R_RELHI)
2256             {
2257               adj_ext_rel++;
2258               adj_i++;
2259               offsets[adj_i] += change;
2260             }
2261         }
2262
2263       /* Find all symbols in this section defined by this object file
2264          and adjust their values.  Note that we decide whether to
2265          adjust the value based on the value stored in the ECOFF EXTR
2266          structure, because the value stored in the hash table may
2267          have been changed by an earlier expanded reloc and thus may
2268          no longer correctly indicate whether the symbol is before or
2269          after the expanded reloc.  */
2270       ext_count = ecoff_data (abfd)->debug_info.symbolic_header.iextMax;
2271       adj_h_ptr = ecoff_data (abfd)->sym_hashes;
2272       adj_h_ptr_end = adj_h_ptr + ext_count;
2273       for (; adj_h_ptr < adj_h_ptr_end; adj_h_ptr++)
2274         {
2275           struct ecoff_link_hash_entry *adj_h;
2276
2277           adj_h = *adj_h_ptr;
2278           if (adj_h != (struct ecoff_link_hash_entry *) NULL
2279               && (adj_h->root.type == bfd_link_hash_defined
2280                   || adj_h->root.type == bfd_link_hash_defweak)
2281               && adj_h->root.u.def.section == sec
2282               && adj_h->esym.asym.value > int_rel.r_vaddr)
2283             adj_h->root.u.def.value += PCREL16_EXPANSION_ADJUSTMENT;
2284         }
2285
2286       /* Add an entry to the symbol value adjust list.  This is used
2287          by bfd_ecoff_debug_accumulate to adjust the values of
2288          internal symbols and FDR's.  */
2289       adjust = ((struct ecoff_value_adjust *)
2290                 bfd_alloc (abfd, sizeof (struct ecoff_value_adjust)));
2291       if (adjust == (struct ecoff_value_adjust *) NULL)
2292         goto error_return;
2293
2294       adjust->start = int_rel.r_vaddr;
2295       adjust->end = sec->vma + sec->_raw_size;
2296       adjust->adjust = PCREL16_EXPANSION_ADJUSTMENT;
2297
2298       adjust->next = ecoff_data (abfd)->debug_info.adjust;
2299       ecoff_data (abfd)->debug_info.adjust = adjust;
2300     }
2301
2302   if (contents != (bfd_byte *) NULL && ! info->keep_memory)
2303     free (contents);
2304
2305   return true;
2306
2307  error_return:
2308   if (contents != (bfd_byte *) NULL && ! info->keep_memory)
2309     free (contents);
2310   return false;
2311 }
2312
2313 /* This routine is called from mips_relocate_section when a PC
2314    relative reloc must be expanded into the five instruction sequence.
2315    It handles all the details of the expansion, including resolving
2316    the reloc.  */
2317
2318 static boolean
2319 mips_relax_pcrel16 (info, input_bfd, input_section, h, location, address)
2320      struct bfd_link_info *info;
2321      bfd *input_bfd;
2322      asection *input_section;
2323      struct ecoff_link_hash_entry *h;
2324      bfd_byte *location;
2325      bfd_vma address;
2326 {
2327   bfd_vma relocation;
2328
2329   /* 0x0411ffff is bgezal $0,. == bal .  */
2330   BFD_ASSERT (bfd_get_32 (input_bfd, location) == 0x0411ffff);
2331
2332   /* We need to compute the distance between the symbol and the
2333      current address plus eight.  */
2334   relocation = (h->root.u.def.value
2335                 + h->root.u.def.section->output_section->vma
2336                 + h->root.u.def.section->output_offset);
2337   relocation -= address + 8;
2338
2339   /* If the lower half is negative, increment the upper 16 half.  */
2340   if ((relocation & 0x8000) != 0)
2341     relocation += 0x10000;
2342
2343   bfd_put_32 (input_bfd, 0x04110001, location); /* bal .+8 */
2344   bfd_put_32 (input_bfd,
2345               0x3c010000 | ((relocation >> 16) & 0xffff), /* lui $at,XX */
2346               location + 4);
2347   bfd_put_32 (input_bfd,
2348               0x24210000 | (relocation & 0xffff), /* addiu $at,$at,XX */
2349               location + 8);
2350   bfd_put_32 (input_bfd, 0x003f0821, location + 12); /* addu $at,$at,$ra */
2351   bfd_put_32 (input_bfd, 0x0020f809, location + 16); /* jalr $at */
2352
2353   return true;
2354 }
2355
2356 /* Given a .sdata section and a .rel.sdata in-memory section, store
2357    relocation information into the .rel.sdata section which can be
2358    used at runtime to relocate the section.  This is called by the
2359    linker when the --embedded-relocs switch is used.  This is called
2360    after the add_symbols entry point has been called for all the
2361    objects, and before the final_link entry point is called.  This
2362    function presumes that the object was compiled using
2363    -membedded-pic.  */
2364
2365 boolean
2366 bfd_mips_ecoff_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
2367      bfd *abfd;
2368      struct bfd_link_info *info;
2369      asection *datasec;
2370      asection *relsec;
2371      char **errmsg;
2372 {
2373   struct ecoff_link_hash_entry **sym_hashes;
2374   struct ecoff_section_tdata *section_tdata;
2375   struct external_reloc *ext_rel;
2376   struct external_reloc *ext_rel_end;
2377   bfd_byte *p;
2378
2379   BFD_ASSERT (! info->relocateable);
2380
2381   *errmsg = NULL;
2382
2383   if (datasec->reloc_count == 0)
2384     return true;
2385
2386   sym_hashes = ecoff_data (abfd)->sym_hashes;
2387
2388   if (! mips_read_relocs (abfd, datasec))
2389     return false;
2390
2391   relsec->contents = (bfd_byte *) bfd_alloc (abfd, datasec->reloc_count * 4);
2392   if (relsec->contents == NULL)
2393     return false;
2394
2395   p = relsec->contents;
2396
2397   section_tdata = ecoff_section_data (abfd, datasec);
2398   ext_rel = (struct external_reloc *) section_tdata->external_relocs;
2399   ext_rel_end = ext_rel + datasec->reloc_count;
2400   for (; ext_rel < ext_rel_end; ext_rel++, p += 4)
2401     {
2402       struct internal_reloc int_rel;
2403       boolean text_relative;
2404
2405       mips_ecoff_swap_reloc_in (abfd, (PTR) ext_rel, &int_rel);
2406
2407       /* We are going to write a four byte word into the runtime reloc
2408          section.  The word will be the address in the data section
2409          which must be relocated.  This must be on a word boundary,
2410          which means the lower two bits must be zero.  We use the
2411          least significant bit to indicate how the value in the data
2412          section must be relocated.  A 0 means that the value is
2413          relative to the text section, while a 1 indicates that the
2414          value is relative to the data section.  Given that we are
2415          assuming the code was compiled using -membedded-pic, there
2416          should not be any other possibilities.  */
2417
2418       /* We can only relocate REFWORD relocs at run time.  */
2419       if (int_rel.r_type != MIPS_R_REFWORD)
2420         {
2421           *errmsg = "unsupported reloc type";
2422           bfd_set_error (bfd_error_bad_value);
2423           return false;
2424         }
2425
2426       if (int_rel.r_extern)
2427         {
2428           struct ecoff_link_hash_entry *h;
2429
2430           h = sym_hashes[int_rel.r_symndx];
2431           /* If h is NULL, that means that there is a reloc against an
2432              external symbol which we thought was just a debugging
2433              symbol.  This should not happen.  */
2434           if (h == (struct ecoff_link_hash_entry *) NULL)
2435             abort ();
2436           if ((h->root.type == bfd_link_hash_defined
2437                || h->root.type == bfd_link_hash_defweak)
2438               && (h->root.u.def.section->flags & SEC_CODE) != 0)
2439             text_relative = true;
2440           else
2441             text_relative = false;
2442         }
2443       else
2444         {
2445           switch (int_rel.r_symndx)
2446             {
2447             case RELOC_SECTION_TEXT:
2448               text_relative = true;
2449               break;
2450             case RELOC_SECTION_SDATA:
2451             case RELOC_SECTION_SBSS:
2452             case RELOC_SECTION_LIT8:
2453               text_relative = false;
2454               break;
2455             default:
2456               /* No other sections should appear in -membedded-pic
2457                  code.  */
2458               *errmsg = "reloc against unsupported section";
2459               bfd_set_error (bfd_error_bad_value);
2460               return false;
2461             }
2462         }
2463
2464       if ((int_rel.r_offset & 3) != 0)
2465         {
2466           *errmsg = "reloc not properly aligned";
2467           bfd_set_error (bfd_error_bad_value);
2468           return false;
2469         }
2470
2471       bfd_put_32 (abfd,
2472                   (int_rel.r_vaddr - datasec->vma + datasec->output_offset
2473                    + (text_relative ? 0 : 1)),
2474                   p);
2475     }
2476
2477   return true;
2478 }
2479 \f
2480 /* This is the ECOFF backend structure.  The backend field of the
2481    target vector points to this.  */
2482
2483 static const struct ecoff_backend_data mips_ecoff_backend_data =
2484 {
2485   /* COFF backend structure.  */
2486   {
2487     (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */
2488     (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
2489     (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
2490     (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/
2491     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
2492     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
2493     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
2494     mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
2495     mips_ecoff_swap_scnhdr_out,
2496     FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, true, false, 4,
2497     mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
2498     mips_ecoff_swap_scnhdr_in, NULL,
2499     mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
2500     _bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
2501     _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
2502     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
2503   },
2504   /* Supported architecture.  */
2505   bfd_arch_mips,
2506   /* Initial portion of armap string.  */
2507   "__________",
2508   /* The page boundary used to align sections in a demand-paged
2509      executable file.  E.g., 0x1000.  */
2510   0x1000,
2511   /* True if the .rdata section is part of the text segment, as on the
2512      Alpha.  False if .rdata is part of the data segment, as on the
2513      MIPS.  */
2514   false,
2515   /* Bitsize of constructor entries.  */
2516   32,
2517   /* Reloc to use for constructor entries.  */
2518   &mips_howto_table[MIPS_R_REFWORD],
2519   {
2520     /* Symbol table magic number.  */
2521     magicSym,
2522     /* Alignment of debugging information.  E.g., 4.  */
2523     4,
2524     /* Sizes of external symbolic information.  */
2525     sizeof (struct hdr_ext),
2526     sizeof (struct dnr_ext),
2527     sizeof (struct pdr_ext),
2528     sizeof (struct sym_ext),
2529     sizeof (struct opt_ext),
2530     sizeof (struct fdr_ext),
2531     sizeof (struct rfd_ext),
2532     sizeof (struct ext_ext),
2533     /* Functions to swap in external symbolic data.  */
2534     ecoff_swap_hdr_in,
2535     ecoff_swap_dnr_in,
2536     ecoff_swap_pdr_in,
2537     ecoff_swap_sym_in,
2538     ecoff_swap_opt_in,
2539     ecoff_swap_fdr_in,
2540     ecoff_swap_rfd_in,
2541     ecoff_swap_ext_in,
2542     _bfd_ecoff_swap_tir_in,
2543     _bfd_ecoff_swap_rndx_in,
2544     /* Functions to swap out external symbolic data.  */
2545     ecoff_swap_hdr_out,
2546     ecoff_swap_dnr_out,
2547     ecoff_swap_pdr_out,
2548     ecoff_swap_sym_out,
2549     ecoff_swap_opt_out,
2550     ecoff_swap_fdr_out,
2551     ecoff_swap_rfd_out,
2552     ecoff_swap_ext_out,
2553     _bfd_ecoff_swap_tir_out,
2554     _bfd_ecoff_swap_rndx_out,
2555     /* Function to read in symbolic data.  */
2556     _bfd_ecoff_slurp_symbolic_info
2557   },
2558   /* External reloc size.  */
2559   RELSZ,
2560   /* Howto reloc table.  */
2561   mips_howto_table,
2562   /* Howto reloc table size.  */
2563   sizeof mips_howto_table / sizeof mips_howto_table[0],
2564   /* Does this backend implement the LITERALSLEAZY reloc?  */
2565   false,
2566   /* Reloc swapping functions.  */
2567   mips_ecoff_swap_reloc_in,
2568   mips_ecoff_swap_reloc_out,
2569   /* Backend reloc tweaking.  */
2570   mips_adjust_reloc_in,
2571   mips_adjust_reloc_out,
2572   /* Relocate section contents while linking.  */
2573   mips_relocate_section,
2574   /* Do final adjustments to filehdr and aouthdr.  */
2575   NULL,
2576   /* Read an element from an archive at a given file position.  */
2577   _bfd_get_elt_at_filepos
2578 };
2579
2580 /* Looking up a reloc type is MIPS specific.  */
2581 #define _bfd_ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
2582
2583 /* Getting relocated section contents is generic.  */
2584 #define _bfd_ecoff_bfd_get_relocated_section_contents \
2585   bfd_generic_get_relocated_section_contents
2586
2587 /* Handling file windows is generic.  */
2588 #define _bfd_ecoff_get_section_contents_in_window \
2589   _bfd_generic_get_section_contents_in_window
2590
2591 /* Relaxing sections is MIPS specific.  */
2592 #define _bfd_ecoff_bfd_relax_section mips_relax_section
2593
2594 const bfd_target ecoff_little_vec =
2595 {
2596   "ecoff-littlemips",           /* name */
2597   bfd_target_ecoff_flavour,
2598   BFD_ENDIAN_LITTLE,            /* data byte order is little */
2599   BFD_ENDIAN_LITTLE,            /* header byte order is little */
2600
2601   (HAS_RELOC | EXEC_P |         /* object flags */
2602    HAS_LINENO | HAS_DEBUG |
2603    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
2604
2605   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
2606   0,                            /* leading underscore */
2607   ' ',                          /* ar_pad_char */
2608   15,                           /* ar_max_namelen */
2609   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2610      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2611      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
2612   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2613      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2614      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
2615
2616   {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
2617      _bfd_ecoff_archive_p, _bfd_dummy_target},
2618   {bfd_false, _bfd_ecoff_mkobject,  /* bfd_set_format */
2619      _bfd_generic_mkarchive, bfd_false},
2620   {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
2621      _bfd_write_archive_contents, bfd_false},
2622
2623      BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
2624      BFD_JUMP_TABLE_COPY (_bfd_ecoff),
2625      BFD_JUMP_TABLE_CORE (_bfd_nocore),
2626      BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
2627      BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
2628      BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
2629      BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
2630      BFD_JUMP_TABLE_LINK (_bfd_ecoff),
2631      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2632
2633   (PTR) &mips_ecoff_backend_data
2634 };
2635
2636 const bfd_target ecoff_big_vec =
2637 {
2638   "ecoff-bigmips",              /* name */
2639   bfd_target_ecoff_flavour,
2640   BFD_ENDIAN_BIG,               /* data byte order is big */
2641   BFD_ENDIAN_BIG,               /* header byte order is big */
2642
2643   (HAS_RELOC | EXEC_P |         /* object flags */
2644    HAS_LINENO | HAS_DEBUG |
2645    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
2646
2647   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
2648   0,                            /* leading underscore */
2649   ' ',                          /* ar_pad_char */
2650   15,                           /* ar_max_namelen */
2651   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
2652      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
2653      bfd_getb16, bfd_getb_signed_16, bfd_putb16,
2654   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
2655      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
2656      bfd_getb16, bfd_getb_signed_16, bfd_putb16,
2657  {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
2658     _bfd_ecoff_archive_p, _bfd_dummy_target},
2659  {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
2660     _bfd_generic_mkarchive, bfd_false},
2661  {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
2662     _bfd_write_archive_contents, bfd_false},
2663
2664      BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
2665      BFD_JUMP_TABLE_COPY (_bfd_ecoff),
2666      BFD_JUMP_TABLE_CORE (_bfd_nocore),
2667      BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
2668      BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
2669      BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
2670      BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
2671      BFD_JUMP_TABLE_LINK (_bfd_ecoff),
2672      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2673
2674   (PTR) &mips_ecoff_backend_data
2675 };
2676
2677 const bfd_target ecoff_biglittle_vec =
2678 {
2679   "ecoff-biglittlemips",                /* name */
2680   bfd_target_ecoff_flavour,
2681   BFD_ENDIAN_LITTLE,            /* data byte order is little */
2682   BFD_ENDIAN_BIG,               /* header byte order is big */
2683
2684   (HAS_RELOC | EXEC_P |         /* object flags */
2685    HAS_LINENO | HAS_DEBUG |
2686    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
2687
2688   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
2689   0,                            /* leading underscore */
2690   ' ',                          /* ar_pad_char */
2691   15,                           /* ar_max_namelen */
2692   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2693      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2694      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
2695   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
2696      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
2697      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
2698
2699   {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
2700      _bfd_ecoff_archive_p, _bfd_dummy_target},
2701   {bfd_false, _bfd_ecoff_mkobject,  /* bfd_set_format */
2702      _bfd_generic_mkarchive, bfd_false},
2703   {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
2704      _bfd_write_archive_contents, bfd_false},
2705
2706      BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
2707      BFD_JUMP_TABLE_COPY (_bfd_ecoff),
2708      BFD_JUMP_TABLE_CORE (_bfd_nocore),
2709      BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
2710      BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
2711      BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
2712      BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
2713      BFD_JUMP_TABLE_LINK (_bfd_ecoff),
2714      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2715
2716   (PTR) &mips_ecoff_backend_data
2717 };