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