* targets.c (bfd_target): Remove unused align_power_min field.
[platform/upstream/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 abfd->xvec->byteorder_big_p;
400
401     case MIPS_MAGIC_LITTLE:
402     case MIPS_MAGIC_LITTLE2:
403     case MIPS_MAGIC_LITTLE3:
404       return abfd->xvec->byteorder_big_p == false;
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 (abfd->xvec->header_byteorder_big_p != false)
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 (abfd->xvec->header_byteorder_big_p != false)
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_big_p
1194               == output_bfd->xvec->header_byteorder_big_p);
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         {
1208           bfd_set_error (bfd_error_no_memory);
1209           return false;
1210         }
1211
1212       symndx_to_section[RELOC_SECTION_NONE] = NULL;
1213       symndx_to_section[RELOC_SECTION_TEXT] =
1214         bfd_get_section_by_name (input_bfd, ".text");
1215       symndx_to_section[RELOC_SECTION_RDATA] =
1216         bfd_get_section_by_name (input_bfd, ".rdata");
1217       symndx_to_section[RELOC_SECTION_DATA] =
1218         bfd_get_section_by_name (input_bfd, ".data");
1219       symndx_to_section[RELOC_SECTION_SDATA] =
1220         bfd_get_section_by_name (input_bfd, ".sdata");
1221       symndx_to_section[RELOC_SECTION_SBSS] =
1222         bfd_get_section_by_name (input_bfd, ".sbss");
1223       symndx_to_section[RELOC_SECTION_BSS] =
1224         bfd_get_section_by_name (input_bfd, ".bss");
1225       symndx_to_section[RELOC_SECTION_INIT] =
1226         bfd_get_section_by_name (input_bfd, ".init");
1227       symndx_to_section[RELOC_SECTION_LIT8] =
1228         bfd_get_section_by_name (input_bfd, ".lit8");
1229       symndx_to_section[RELOC_SECTION_LIT4] =
1230         bfd_get_section_by_name (input_bfd, ".lit4");
1231       symndx_to_section[RELOC_SECTION_XDATA] = NULL;
1232       symndx_to_section[RELOC_SECTION_PDATA] = NULL;
1233       symndx_to_section[RELOC_SECTION_FINI] =
1234         bfd_get_section_by_name (input_bfd, ".fini");
1235       symndx_to_section[RELOC_SECTION_LITA] = NULL;
1236       symndx_to_section[RELOC_SECTION_ABS] = NULL;
1237
1238       ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
1239     }
1240
1241   sym_hashes = ecoff_data (input_bfd)->sym_hashes;
1242
1243   gp = ecoff_data (output_bfd)->gp;
1244   if (gp == 0)
1245     gp_undefined = true;
1246   else
1247     gp_undefined = false;
1248
1249   got_lo = false;
1250
1251   adjust = 0;
1252
1253   if (ecoff_section_data (input_bfd, input_section) == NULL)
1254     offsets = NULL;
1255   else
1256     offsets = ecoff_section_data (input_bfd, input_section)->offsets;
1257
1258   ext_rel = (struct external_reloc *) external_relocs;
1259   ext_rel_end = ext_rel + input_section->reloc_count;
1260   for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
1261     {
1262       struct internal_reloc int_rel;
1263       bfd_vma addend;
1264       reloc_howto_type *howto;
1265       struct ecoff_link_hash_entry *h = NULL;
1266       asection *s = NULL;
1267       bfd_vma relocation;
1268       bfd_reloc_status_type r;
1269
1270       if (! got_lo)
1271         mips_ecoff_swap_reloc_in (input_bfd, (PTR) ext_rel, &int_rel);
1272       else
1273         {
1274           int_rel = lo_int_rel;
1275           got_lo = false;
1276         }
1277
1278       BFD_ASSERT (int_rel.r_type
1279                   < sizeof mips_howto_table / sizeof mips_howto_table[0]);
1280
1281       /* The REFHI and RELHI relocs requires special handling.  they
1282          must be followed by a REFLO or RELLO reloc, respectively, and
1283          the addend is formed from both relocs.  */
1284       if (int_rel.r_type == MIPS_R_REFHI
1285           || int_rel.r_type == MIPS_R_RELHI)
1286         {
1287           BFD_ASSERT ((ext_rel + 1) < ext_rel_end);
1288           mips_ecoff_swap_reloc_in (input_bfd, (PTR) (ext_rel + 1),
1289                                     &lo_int_rel);
1290           BFD_ASSERT ((lo_int_rel.r_type
1291                        == (int_rel.r_type == MIPS_R_REFHI
1292                            ? MIPS_R_REFLO
1293                            : MIPS_R_RELLO))
1294                       && int_rel.r_extern == lo_int_rel.r_extern
1295                       && int_rel.r_symndx == lo_int_rel.r_symndx);
1296           got_lo = true;
1297         }
1298
1299       howto = &mips_howto_table[int_rel.r_type];
1300
1301       /* The SWITCH reloc must be handled specially.  This reloc is
1302          marks the location of a difference between two portions of an
1303          object file.  The symbol index does not reference a symbol,
1304          but is actually the offset from the reloc to the subtrahend
1305          of the difference.  This reloc is correct in the object file,
1306          and needs no further adjustment, unless we are relaxing.  If
1307          we are relaxing, we may have to add in an offset.  Since no
1308          symbols are involved in this reloc, we handle it completely
1309          here.  */
1310       if (int_rel.r_type == MIPS_R_SWITCH)
1311         {
1312           if (offsets != NULL
1313               && offsets[i] != 0)
1314             {
1315               r = _bfd_relocate_contents (howto, input_bfd,
1316                                           (bfd_vma) offsets[i],
1317                                           (contents
1318                                            + adjust
1319                                            + int_rel.r_vaddr
1320                                            - input_section->vma));
1321               BFD_ASSERT (r == bfd_reloc_ok);
1322             }
1323
1324           continue;
1325         }
1326
1327       if (int_rel.r_extern)
1328         {
1329           h = sym_hashes[int_rel.r_symndx];
1330           /* If h is NULL, that means that there is a reloc against an
1331              external symbol which we thought was just a debugging
1332              symbol.  This should not happen.  */
1333           if (h == (struct ecoff_link_hash_entry *) NULL)
1334             abort ();
1335         }
1336       else
1337         {
1338           if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS)
1339             s = NULL;
1340           else
1341             s = symndx_to_section[int_rel.r_symndx];
1342
1343           if (s == (asection *) NULL)
1344             abort ();
1345         }
1346
1347       /* The GPREL reloc uses an addend: the difference in the GP
1348          values.  */
1349       if (int_rel.r_type != MIPS_R_GPREL
1350           && int_rel.r_type != MIPS_R_LITERAL)
1351         addend = 0;
1352       else
1353         {
1354           if (gp_undefined)
1355             {
1356               if (! ((*info->callbacks->reloc_dangerous)
1357                      (info, "GP relative relocation when GP not defined",
1358                       input_bfd, input_section,
1359                       int_rel.r_vaddr - input_section->vma)))
1360                 return false;
1361               /* Only give the error once per link.  */
1362               ecoff_data (output_bfd)->gp = gp = 4;
1363               gp_undefined = false;
1364             }
1365           if (! int_rel.r_extern)
1366             {
1367               /* This is a relocation against a section.  The current
1368                  addend in the instruction is the difference between
1369                  INPUT_SECTION->vma and the GP value of INPUT_BFD.  We
1370                  must change this to be the difference between the
1371                  final definition (which will end up in RELOCATION)
1372                  and the GP value of OUTPUT_BFD (which is in GP).  */
1373               addend = ecoff_data (input_bfd)->gp - gp;
1374             }
1375           else if (! info->relocateable
1376                    || h->root.type == bfd_link_hash_defined
1377                    || h->root.type == bfd_link_hash_defweak)
1378             {
1379               /* This is a relocation against a defined symbol.  The
1380                  current addend in the instruction is simply the
1381                  desired offset into the symbol (normally zero).  We
1382                  are going to change this into a relocation against a
1383                  defined symbol, so we want the instruction to hold
1384                  the difference between the final definition of the
1385                  symbol (which will end up in RELOCATION) and the GP
1386                  value of OUTPUT_BFD (which is in GP).  */
1387               addend = - gp;
1388             }
1389           else
1390             {
1391               /* This is a relocation against an undefined or common
1392                  symbol.  The current addend in the instruction is
1393                  simply the desired offset into the symbol (normally
1394                  zero).  We are generating relocateable output, and we
1395                  aren't going to define this symbol, so we just leave
1396                  the instruction alone.  */
1397               addend = 0;
1398             }
1399         }
1400
1401       /* If we are relaxing, mips_relax_section may have set
1402          offsets[i] to some value.  A value of 1 means we must expand
1403          a PC relative branch into a multi-instruction of sequence,
1404          and any other value is an addend.  */
1405       if (offsets != NULL
1406           && offsets[i] != 0)
1407         {
1408           BFD_ASSERT (! info->relocateable);
1409           BFD_ASSERT (int_rel.r_type == MIPS_R_PCREL16
1410                       || int_rel.r_type == MIPS_R_RELHI
1411                       || int_rel.r_type == MIPS_R_RELLO);
1412           if (offsets[i] != 1)
1413             addend += offsets[i];
1414           else
1415             {
1416               bfd_byte *here;
1417
1418               BFD_ASSERT (int_rel.r_extern
1419                           && int_rel.r_type == MIPS_R_PCREL16);
1420
1421               /* Move the rest of the instructions up.  */
1422               here = (contents
1423                       + adjust
1424                       + int_rel.r_vaddr
1425                       - input_section->vma);
1426               memmove (here + PCREL16_EXPANSION_ADJUSTMENT, here,
1427                        (size_t) (input_section->_raw_size
1428                                  - (int_rel.r_vaddr - input_section->vma)));
1429                        
1430               /* Generate the new instructions.  */
1431               if (! mips_relax_pcrel16 (info, input_bfd, input_section,
1432                                         h, here,
1433                                         (input_section->output_section->vma
1434                                          + input_section->output_offset
1435                                          + (int_rel.r_vaddr
1436                                             - input_section->vma)
1437                                          + adjust)))
1438                 return false;
1439
1440               /* We must adjust everything else up a notch.  */
1441               adjust += PCREL16_EXPANSION_ADJUSTMENT;
1442
1443               /* mips_relax_pcrel16 handles all the details of this
1444                  relocation.  */
1445               continue;
1446             }
1447         }
1448
1449       /* If we are relaxing, and this is a reloc against the .text
1450          segment, we may need to adjust it if some branches have been
1451          expanded.  The reloc types which are likely to occur in the
1452          .text section are handled efficiently by mips_relax_section,
1453          and thus do not need to be handled here.  */
1454       if (ecoff_data (input_bfd)->debug_info.adjust != NULL
1455           && ! int_rel.r_extern
1456           && int_rel.r_symndx == RELOC_SECTION_TEXT
1457           && (strcmp (bfd_get_section_name (input_bfd, input_section),
1458                       ".text") != 0
1459               || (int_rel.r_type != MIPS_R_PCREL16
1460                   && int_rel.r_type != MIPS_R_SWITCH
1461                   && int_rel.r_type != MIPS_R_RELHI
1462                   && int_rel.r_type != MIPS_R_RELLO)))
1463         {
1464           bfd_vma adr;
1465           struct ecoff_value_adjust *a;
1466
1467           /* We need to get the addend so that we know whether we need
1468              to adjust the address.  */
1469           BFD_ASSERT (int_rel.r_type == MIPS_R_REFWORD);
1470
1471           adr = bfd_get_32 (input_bfd,
1472                             (contents
1473                              + adjust
1474                              + int_rel.r_vaddr
1475                              - input_section->vma));
1476
1477           for (a = ecoff_data (input_bfd)->debug_info.adjust;
1478                a != (struct ecoff_value_adjust *) NULL;
1479                a = a->next)
1480             {
1481               if (adr >= a->start && adr < a->end)
1482                 addend += a->adjust;
1483             }
1484         }
1485
1486       if (info->relocateable)
1487         {
1488           /* We are generating relocateable output, and must convert
1489              the existing reloc.  */
1490           if (int_rel.r_extern)
1491             {
1492               if ((h->root.type == bfd_link_hash_defined
1493                    || h->root.type == bfd_link_hash_defweak)
1494                   && ! bfd_is_abs_section (h->root.u.def.section))
1495                 {
1496                   const char *name;
1497
1498                   /* This symbol is defined in the output.  Convert
1499                      the reloc from being against the symbol to being
1500                      against the section.  */
1501
1502                   /* Clear the r_extern bit.  */
1503                   int_rel.r_extern = 0;
1504
1505                   /* Compute a new r_symndx value.  */
1506                   s = h->root.u.def.section;
1507                   name = bfd_get_section_name (output_bfd,
1508                                                s->output_section);
1509
1510                   int_rel.r_symndx = -1;
1511                   switch (name[1])
1512                     {
1513                     case 'b':
1514                       if (strcmp (name, ".bss") == 0)
1515                         int_rel.r_symndx = RELOC_SECTION_BSS;
1516                       break;
1517                     case 'd':
1518                       if (strcmp (name, ".data") == 0)
1519                         int_rel.r_symndx = RELOC_SECTION_DATA;
1520                       break;
1521                     case 'f':
1522                       if (strcmp (name, ".fini") == 0)
1523                         int_rel.r_symndx = RELOC_SECTION_FINI;
1524                       break;
1525                     case 'i':
1526                       if (strcmp (name, ".init") == 0)
1527                         int_rel.r_symndx = RELOC_SECTION_INIT;
1528                       break;
1529                     case 'l':
1530                       if (strcmp (name, ".lit8") == 0)
1531                         int_rel.r_symndx = RELOC_SECTION_LIT8;
1532                       else if (strcmp (name, ".lit4") == 0)
1533                         int_rel.r_symndx = RELOC_SECTION_LIT4;
1534                       break;
1535                     case 'r':
1536                       if (strcmp (name, ".rdata") == 0)
1537                         int_rel.r_symndx = RELOC_SECTION_RDATA;
1538                       break;
1539                     case 's':
1540                       if (strcmp (name, ".sdata") == 0)
1541                         int_rel.r_symndx = RELOC_SECTION_SDATA;
1542                       else if (strcmp (name, ".sbss") == 0)
1543                         int_rel.r_symndx = RELOC_SECTION_SBSS;
1544                       break;
1545                     case 't':
1546                       if (strcmp (name, ".text") == 0)
1547                         int_rel.r_symndx = RELOC_SECTION_TEXT;
1548                       break;
1549                     }
1550                       
1551                   if (int_rel.r_symndx == -1)
1552                     abort ();
1553
1554                   /* Add the section VMA and the symbol value.  */
1555                   relocation = (h->root.u.def.value
1556                                 + s->output_section->vma
1557                                 + s->output_offset);
1558
1559                   /* For a PC relative relocation, the object file
1560                      currently holds just the addend.  We must adjust
1561                      by the address to get the right value.  */
1562                   if (howto->pc_relative)
1563                     {
1564                       relocation -= int_rel.r_vaddr - input_section->vma;
1565
1566                       /* If we are converting a RELHI or RELLO reloc
1567                          from being against an external symbol to
1568                          being against a section, we must put a
1569                          special value into the r_offset field.  This
1570                          value is the old addend.  The r_offset for
1571                          both the RELOHI and RELLO relocs are the
1572                          same, and we set both when we see RELHI.  */
1573                       if (int_rel.r_type == MIPS_R_RELHI)
1574                         {
1575                           long addhi, addlo;
1576
1577                           addhi = bfd_get_32 (input_bfd,
1578                                               (contents
1579                                                + adjust
1580                                                + int_rel.r_vaddr
1581                                                - input_section->vma));
1582                           addhi &= 0xffff;
1583                           if (addhi & 0x8000)
1584                             addhi -= 0x10000;
1585                           addhi <<= 16;
1586
1587                           addlo = bfd_get_32 (input_bfd,
1588                                               (contents
1589                                                + adjust
1590                                                + lo_int_rel.r_vaddr
1591                                                - input_section->vma));
1592                           addlo &= 0xffff;
1593                           if (addlo & 0x8000)
1594                             addlo -= 0x10000;
1595
1596                           int_rel.r_offset = addhi + addlo;
1597                           lo_int_rel.r_offset = int_rel.r_offset;
1598                         }
1599                     }
1600
1601                   h = NULL;
1602                 }
1603               else
1604                 {
1605                   /* Change the symndx value to the right one for the
1606                      output BFD.  */
1607                   int_rel.r_symndx = h->indx;
1608                   if (int_rel.r_symndx == -1)
1609                     {
1610                       /* This symbol is not being written out.  */
1611                       if (! ((*info->callbacks->unattached_reloc)
1612                              (info, h->root.root.string, input_bfd,
1613                               input_section,
1614                               int_rel.r_vaddr - input_section->vma)))
1615                         return false;
1616                       int_rel.r_symndx = 0;
1617                     }
1618                   relocation = 0;
1619                 }
1620             }
1621           else
1622             {
1623               /* This is a relocation against a section.  Adjust the
1624                  value by the amount the section moved.  */
1625               relocation = (s->output_section->vma
1626                             + s->output_offset
1627                             - s->vma);
1628             }
1629
1630           relocation += addend;
1631           addend = 0;
1632
1633           /* Adjust a PC relative relocation by removing the reference
1634              to the original address in the section and including the
1635              reference to the new address.  However, external RELHI
1636              and RELLO relocs are PC relative, but don't include any
1637              reference to the address.  The addend is merely an
1638              addend.  */
1639           if (howto->pc_relative
1640               && (! int_rel.r_extern
1641                   || (int_rel.r_type != MIPS_R_RELHI
1642                       && int_rel.r_type != MIPS_R_RELLO)))
1643             relocation -= (input_section->output_section->vma
1644                            + input_section->output_offset
1645                            - input_section->vma);
1646
1647           /* Adjust the contents.  */
1648           if (relocation == 0)
1649             r = bfd_reloc_ok;
1650           else
1651             {
1652               if (int_rel.r_type != MIPS_R_REFHI
1653                   && int_rel.r_type != MIPS_R_RELHI)
1654                 r = _bfd_relocate_contents (howto, input_bfd, relocation,
1655                                             (contents
1656                                              + adjust
1657                                              + int_rel.r_vaddr
1658                                              - input_section->vma));
1659               else
1660                 {
1661                   mips_relocate_hi (&int_rel, &lo_int_rel,
1662                                     input_bfd, input_section, contents,
1663                                     adjust, relocation,
1664                                     int_rel.r_type == MIPS_R_RELHI);
1665                   r = bfd_reloc_ok;
1666                 }
1667             }
1668
1669           /* Adjust the reloc address.  */
1670           int_rel.r_vaddr += (input_section->output_section->vma
1671                               + input_section->output_offset
1672                               - input_section->vma);
1673
1674           /* Save the changed reloc information.  */
1675           mips_ecoff_swap_reloc_out (input_bfd, &int_rel, (PTR) ext_rel);
1676         }
1677       else
1678         {
1679           /* We are producing a final executable.  */
1680           if (int_rel.r_extern)
1681             {
1682               /* This is a reloc against a symbol.  */
1683               if (h->root.type == bfd_link_hash_defined
1684                   || h->root.type == bfd_link_hash_defweak)
1685                 {
1686                   asection *hsec;
1687
1688                   hsec = h->root.u.def.section;
1689                   relocation = (h->root.u.def.value
1690                                 + hsec->output_section->vma
1691                                 + hsec->output_offset);
1692                 }
1693               else
1694                 {
1695                   if (! ((*info->callbacks->undefined_symbol)
1696                          (info, h->root.root.string, input_bfd,
1697                           input_section,
1698                           int_rel.r_vaddr - input_section->vma)))
1699                     return false;
1700                   relocation = 0;
1701                 }
1702             }
1703           else
1704             {
1705               /* This is a reloc against a section.  */
1706               relocation = (s->output_section->vma
1707                             + s->output_offset
1708                             - s->vma);
1709
1710               /* A PC relative reloc is already correct in the object
1711                  file.  Make it look like a pcrel_offset relocation by
1712                  adding in the start address.  */
1713               if (howto->pc_relative)
1714                 {
1715                   if (int_rel.r_type != MIPS_R_RELHI)
1716                     relocation += int_rel.r_vaddr + adjust;
1717                   else
1718                     relocation += lo_int_rel.r_vaddr + adjust;
1719                 }
1720             }
1721
1722           if (int_rel.r_type != MIPS_R_REFHI
1723               && int_rel.r_type != MIPS_R_RELHI)
1724             r = _bfd_final_link_relocate (howto,
1725                                           input_bfd,
1726                                           input_section,
1727                                           contents,
1728                                           (int_rel.r_vaddr
1729                                            - input_section->vma
1730                                            + adjust),
1731                                           relocation,
1732                                           addend);
1733           else
1734             {
1735               mips_relocate_hi (&int_rel, &lo_int_rel, input_bfd,
1736                                 input_section, contents, adjust,
1737                                 relocation,
1738                                 int_rel.r_type == MIPS_R_RELHI);
1739               r = bfd_reloc_ok;
1740             }
1741         }
1742
1743       /* MIPS_R_JMPADDR requires peculiar overflow detection.  The
1744          instruction provides a 28 bit address (the two lower bits are
1745          implicit zeroes) which is combined with the upper four bits
1746          of the instruction address.  */
1747       if (r == bfd_reloc_ok
1748           && int_rel.r_type == MIPS_R_JMPADDR
1749           && (((relocation
1750                 + addend
1751                 + (int_rel.r_extern ? 0 : s->vma))
1752                & 0xf0000000)
1753               != ((input_section->output_section->vma
1754                    + input_section->output_offset
1755                    + (int_rel.r_vaddr - input_section->vma)
1756                    + adjust)
1757                   & 0xf0000000)))
1758         r = bfd_reloc_overflow;
1759
1760       if (r != bfd_reloc_ok)
1761         {
1762           switch (r)
1763             {
1764             default:
1765             case bfd_reloc_outofrange:
1766               abort ();
1767             case bfd_reloc_overflow:
1768               {
1769                 const char *name;
1770
1771                 if (int_rel.r_extern)
1772                   name = h->root.root.string;
1773                 else
1774                   name = bfd_section_name (input_bfd, s);
1775                 if (! ((*info->callbacks->reloc_overflow)
1776                        (info, name, howto->name, (bfd_vma) 0,
1777                         input_bfd, input_section,
1778                         int_rel.r_vaddr - input_section->vma)))
1779                   return false;
1780               }
1781               break;
1782             }
1783         }
1784     }
1785
1786   return true;
1787 }
1788 \f
1789 /* Read in the relocs for a section.  */
1790
1791 static boolean
1792 mips_read_relocs (abfd, sec)
1793      bfd *abfd;
1794      asection *sec;
1795 {
1796   struct ecoff_section_tdata *section_tdata;
1797
1798   section_tdata = ecoff_section_data (abfd, sec);
1799   if (section_tdata == (struct ecoff_section_tdata *) NULL)
1800     {
1801       sec->used_by_bfd =
1802         (PTR) bfd_alloc_by_size_t (abfd, sizeof (struct ecoff_section_tdata));
1803       if (sec->used_by_bfd == NULL)
1804         {
1805           bfd_set_error (bfd_error_no_memory);
1806           return false;
1807         }
1808
1809       section_tdata = ecoff_section_data (abfd, sec);
1810       section_tdata->external_relocs = NULL;
1811       section_tdata->contents = NULL;
1812       section_tdata->offsets = NULL;
1813     }
1814
1815   if (section_tdata->external_relocs == NULL)
1816     {
1817       bfd_size_type external_relocs_size;
1818
1819       external_relocs_size = (ecoff_backend (abfd)->external_reloc_size
1820                               * sec->reloc_count);
1821
1822       section_tdata->external_relocs =
1823         (PTR) bfd_alloc (abfd, external_relocs_size);
1824       if (section_tdata->external_relocs == NULL && external_relocs_size != 0)
1825         {
1826           bfd_set_error (bfd_error_no_memory);
1827           return false;
1828         }
1829
1830       if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0
1831           || (bfd_read (section_tdata->external_relocs, 1,
1832                         external_relocs_size, abfd)
1833               != external_relocs_size))
1834         return false;
1835     }
1836
1837   return true;
1838 }
1839
1840 /* Relax a section when linking a MIPS ECOFF file.  This is used for
1841    embedded PIC code, which always uses PC relative branches which
1842    only have an 18 bit range on MIPS.  If a branch is not in range, we
1843    generate a long instruction sequence to compensate.  Each time we
1844    find a branch to expand, we have to check all the others again to
1845    make sure they are still in range.  This is slow, but it only has
1846    to be done when -relax is passed to the linker.
1847
1848    This routine figures out which branches need to expand; the actual
1849    expansion is done in mips_relocate_section when the section
1850    contents are relocated.  The information is stored in the offsets
1851    field of the ecoff_section_tdata structure.  An offset of 1 means
1852    that the branch must be expanded into a multi-instruction PC
1853    relative branch (such an offset will only occur for a PC relative
1854    branch to an external symbol).  Any other offset must be a multiple
1855    of four, and is the amount to change the branch by (such an offset
1856    will only occur for a PC relative branch within the same section).
1857
1858    We do not modify the section relocs or contents themselves so that
1859    if memory usage becomes an issue we can discard them and read them
1860    again.  The only information we must save in memory between this
1861    routine and the mips_relocate_section routine is the table of
1862    offsets.  */
1863
1864 static boolean
1865 mips_relax_section (abfd, sec, info, again)
1866      bfd *abfd;
1867      asection *sec;
1868      struct bfd_link_info *info;
1869      boolean *again;
1870 {
1871   struct ecoff_section_tdata *section_tdata;
1872   bfd_byte *contents = NULL;
1873   long *offsets;
1874   struct external_reloc *ext_rel;
1875   struct external_reloc *ext_rel_end;
1876   unsigned int i;
1877
1878   /* Assume we are not going to need another pass.  */
1879   *again = false;
1880
1881   /* If we are not generating an ECOFF file, this is much too
1882      confusing to deal with.  */
1883   if (info->hash->creator->flavour != bfd_get_flavour (abfd))
1884     return true;
1885
1886   /* If there are no relocs, there is nothing to do.  */
1887   if (sec->reloc_count == 0)
1888     return true;
1889
1890   /* We are only interested in PC relative relocs, and why would there
1891      ever be one from anything but the .text section?  */
1892   if (strcmp (bfd_get_section_name (abfd, sec), ".text") != 0)
1893     return true;
1894
1895   /* Read in the relocs, if we haven't already got them.  */
1896   section_tdata = ecoff_section_data (abfd, sec);
1897   if (section_tdata == (struct ecoff_section_tdata *) NULL
1898       || section_tdata->external_relocs == NULL)
1899     {
1900       if (! mips_read_relocs (abfd, sec))
1901         goto error_return;
1902       section_tdata = ecoff_section_data (abfd, sec);
1903     }
1904
1905   if (sec->_cooked_size == 0)
1906     {
1907       /* We must initialize _cooked_size only the first time we are
1908          called.  */
1909       sec->_cooked_size = sec->_raw_size;
1910     }
1911
1912   contents = section_tdata->contents;
1913   offsets = section_tdata->offsets;
1914
1915   /* Look for any external PC relative relocs.  Internal PC relative
1916      relocs are already correct in the object file, so they certainly
1917      can not overflow.  */
1918   ext_rel = (struct external_reloc *) section_tdata->external_relocs;
1919   ext_rel_end = ext_rel + sec->reloc_count;
1920   for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
1921     {
1922       struct internal_reloc int_rel;
1923       struct ecoff_link_hash_entry *h;
1924       asection *hsec;
1925       bfd_signed_vma relocation;
1926       struct external_reloc *adj_ext_rel;
1927       unsigned int adj_i;
1928       unsigned long ext_count;
1929       struct ecoff_link_hash_entry **adj_h_ptr;
1930       struct ecoff_link_hash_entry **adj_h_ptr_end;
1931       struct ecoff_value_adjust *adjust;
1932
1933       /* If we have already expanded this reloc, we certainly don't
1934          need to do it again.  */
1935       if (offsets != (long *) NULL && offsets[i] == 1)
1936         continue;
1937
1938       /* Quickly check that this reloc is external PCREL16.  */
1939       if (abfd->xvec->header_byteorder_big_p)
1940         {
1941           if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_BIG) == 0
1942               || (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_BIG)
1943                    >> RELOC_BITS3_TYPE_SH_BIG)
1944                   != MIPS_R_PCREL16))
1945             continue;
1946         }
1947       else
1948         {
1949           if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) == 0
1950               || (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
1951                    >> RELOC_BITS3_TYPE_SH_LITTLE)
1952                   != MIPS_R_PCREL16))
1953             continue;
1954         }
1955
1956       mips_ecoff_swap_reloc_in (abfd, (PTR) ext_rel, &int_rel);
1957
1958       h = ecoff_data (abfd)->sym_hashes[int_rel.r_symndx];
1959       if (h == (struct ecoff_link_hash_entry *) NULL)
1960         abort ();
1961
1962       if (h->root.type != bfd_link_hash_defined
1963           && h->root.type != bfd_link_hash_defweak)
1964         {
1965           /* Just ignore undefined symbols.  These will presumably
1966              generate an error later in the link.  */
1967           continue;
1968         }
1969
1970       /* Get the value of the symbol.  */
1971       hsec = h->root.u.def.section;
1972       relocation = (h->root.u.def.value
1973                     + hsec->output_section->vma
1974                     + hsec->output_offset);
1975
1976       /* Subtract out the current address.  */
1977       relocation -= (sec->output_section->vma
1978                      + sec->output_offset
1979                      + (int_rel.r_vaddr - sec->vma));
1980
1981       /* The addend is stored in the object file.  In the normal case
1982          of ``bal symbol'', the addend will be -4.  It will only be
1983          different in the case of ``bal symbol+constant''.  To avoid
1984          always reading in the section contents, we don't check the
1985          addend in the object file (we could easily check the contents
1986          if we happen to have already read them in, but I fear that
1987          this could be confusing).  This means we will screw up if
1988          there is a branch to a symbol that is in range, but added to
1989          a constant which puts it out of range; in such a case the
1990          link will fail with a reloc overflow error.  Since the
1991          compiler will never generate such code, it should be easy
1992          enough to work around it by changing the assembly code in the
1993          source file.  */
1994       relocation -= 4;
1995
1996       /* Now RELOCATION is the number we want to put in the object
1997          file.  See whether it fits.  */
1998       if (relocation >= -0x20000 && relocation < 0x20000)
1999         continue;
2000
2001       /* Now that we know this reloc needs work, which will rarely
2002          happen, go ahead and grab the section contents.  */
2003       if (contents == (bfd_byte *) NULL)
2004         {
2005           if (info->keep_memory)
2006             contents = (bfd_byte *) bfd_alloc (abfd, sec->_raw_size);
2007           else
2008             contents = (bfd_byte *) malloc ((size_t) sec->_raw_size);
2009           if (contents == (bfd_byte *) NULL)
2010             {
2011               bfd_set_error (bfd_error_no_memory);
2012               goto error_return;
2013             }
2014           if (! bfd_get_section_contents (abfd, sec, (PTR) contents,
2015                                           (file_ptr) 0, sec->_raw_size))
2016             goto error_return;
2017           if (info->keep_memory)
2018             section_tdata->contents = contents;
2019         }
2020
2021       /* We only support changing the bal instruction.  It would be
2022          possible to handle other PC relative branches, but some of
2023          them (the conditional branches) would require a different
2024          length instruction sequence which would complicate both this
2025          routine and mips_relax_pcrel16.  It could be written if
2026          somebody felt it were important.  Ignoring this reloc will
2027          presumably cause a reloc overflow error later on.  */
2028       if (bfd_get_32 (abfd, contents + int_rel.r_vaddr - sec->vma)
2029           != 0x0411ffff) /* bgezal $0,. == bal . */
2030         continue;
2031
2032       /* Bother.  We need to expand this reloc, and we will need to
2033          make another relaxation pass since this change may put other
2034          relocs out of range.  We need to examine the local branches
2035          and we need to allocate memory to hold the offsets we must
2036          add to them.  We also need to adjust the values of all
2037          symbols in the object file following this location.  */
2038
2039       sec->_cooked_size += PCREL16_EXPANSION_ADJUSTMENT;
2040       *again = true;
2041
2042       if (offsets == (long *) NULL)
2043         {
2044           size_t size;
2045
2046           size = sec->reloc_count * sizeof (long);
2047           offsets = (long *) bfd_alloc_by_size_t (abfd, size);
2048           if (offsets == (long *) NULL)
2049             {
2050               bfd_set_error (bfd_error_no_memory);
2051               goto error_return;
2052             }
2053           memset (offsets, 0, size);
2054           section_tdata->offsets = offsets;
2055         }
2056
2057       offsets[i] = 1;
2058
2059       /* Now look for all PC relative references that cross this reloc
2060          and adjust their offsets.  */
2061       adj_ext_rel = (struct external_reloc *) section_tdata->external_relocs;
2062       for (adj_i = 0; adj_ext_rel < ext_rel_end; adj_ext_rel++, adj_i++)
2063         {
2064           struct internal_reloc adj_int_rel;
2065           bfd_vma start, stop;
2066           int change;
2067
2068           mips_ecoff_swap_reloc_in (abfd, (PTR) adj_ext_rel, &adj_int_rel);
2069
2070           if (adj_int_rel.r_type == MIPS_R_PCREL16)
2071             {
2072               unsigned long insn;
2073
2074               /* We only care about local references.  External ones
2075                  will be relocated correctly anyhow.  */
2076               if (adj_int_rel.r_extern)
2077                 continue;
2078
2079               /* We are only interested in a PC relative reloc within
2080                  this section.  FIXME: Cross section PC relative
2081                  relocs may not be handled correctly; does anybody
2082                  care?  */
2083               if (adj_int_rel.r_symndx != RELOC_SECTION_TEXT)
2084                 continue;
2085
2086               start = adj_int_rel.r_vaddr;
2087
2088               insn = bfd_get_32 (abfd,
2089                                  contents + adj_int_rel.r_vaddr - sec->vma);
2090
2091               stop = (insn & 0xffff) << 2;
2092               if ((stop & 0x20000) != 0)
2093                 stop -= 0x40000;
2094               stop += adj_int_rel.r_vaddr + 4;
2095             }
2096           else if (adj_int_rel.r_type == MIPS_R_RELHI)
2097             {
2098               struct internal_reloc rello;
2099               long addhi, addlo;
2100
2101               /* The next reloc must be MIPS_R_RELLO, and we handle
2102                  them together.  */
2103               BFD_ASSERT (adj_ext_rel + 1 < ext_rel_end);
2104
2105               mips_ecoff_swap_reloc_in (abfd, (PTR) (adj_ext_rel + 1), &rello);
2106
2107               BFD_ASSERT (rello.r_type == MIPS_R_RELLO);
2108               
2109               addhi = bfd_get_32 (abfd,
2110                                    contents + adj_int_rel.r_vaddr - sec->vma);
2111               addhi &= 0xffff;
2112               if (addhi & 0x8000)
2113                 addhi -= 0x10000;
2114               addhi <<= 16;
2115
2116               addlo = bfd_get_32 (abfd, contents + rello.r_vaddr - sec->vma);
2117               addlo &= 0xffff;
2118               if (addlo & 0x8000)
2119                 addlo -= 0x10000;
2120
2121               if (adj_int_rel.r_extern)
2122                 {
2123                   /* The value we want here is
2124                        sym - RELLOaddr + addend
2125                      which we can express as
2126                        sym - (RELLOaddr - addend)
2127                      Therefore if we are expanding the area between
2128                      RELLOaddr and RELLOaddr - addend we must adjust
2129                      the addend.  This is admittedly ambiguous, since
2130                      we might mean (sym + addend) - RELLOaddr, but in
2131                      practice we don't, and there is no way to handle
2132                      that case correctly since at this point we have
2133                      no idea whether any reloc is being expanded
2134                      between sym and sym + addend.  */
2135                   start = rello.r_vaddr - (addhi + addlo);
2136                   stop = rello.r_vaddr;
2137                 }
2138               else
2139                 {
2140                   /* An internal RELHI/RELLO pair represents the
2141                      difference between two addresses, $LC0 - foo.
2142                      The symndx value is actually the difference
2143                      between the reloc address and $LC0.  This lets us
2144                      compute $LC0, and, by considering the addend,
2145                      foo.  If the reloc we are expanding falls between
2146                      those two relocs, we must adjust the addend.  At
2147                      this point, the symndx value is actually in the
2148                      r_offset field, where it was put by
2149                      mips_ecoff_swap_reloc_in.  */
2150                   start = rello.r_vaddr - adj_int_rel.r_offset;
2151                   stop = start + addhi + addlo;
2152                 }
2153             }
2154           else if (adj_int_rel.r_type == MIPS_R_SWITCH)
2155             {
2156               /* A MIPS_R_SWITCH reloc represents a word of the form
2157                    .word $L3-$LS12
2158                  The value in the object file is correct, assuming the
2159                  original value of $L3.  The symndx value is actually
2160                  the difference between the reloc address and $LS12.
2161                  This lets us compute the original value of $LS12 as
2162                    vaddr - symndx
2163                  and the original value of $L3 as
2164                    vaddr - symndx + addend
2165                  where addend is the value from the object file.  At
2166                  this point, the symndx value is actually found in the
2167                  r_offset field, since it was moved by
2168                  mips_ecoff_swap_reloc_in.  */
2169               start = adj_int_rel.r_vaddr - adj_int_rel.r_offset;
2170               stop = start + bfd_get_32 (abfd,
2171                                          (contents
2172                                           + adj_int_rel.r_vaddr
2173                                           - sec->vma));
2174             }
2175           else
2176             continue;
2177
2178           /* If the range expressed by this reloc, which is the
2179              distance between START and STOP crosses the reloc we are
2180              expanding, we must adjust the offset.  The sign of the
2181              adjustment depends upon the direction in which the range
2182              crosses the reloc being expanded.  */
2183           if (start <= int_rel.r_vaddr && stop > int_rel.r_vaddr)
2184             change = PCREL16_EXPANSION_ADJUSTMENT;
2185           else if (start > int_rel.r_vaddr && stop <= int_rel.r_vaddr)
2186             change = - PCREL16_EXPANSION_ADJUSTMENT;
2187           else
2188             change = 0;
2189
2190           offsets[adj_i] += change;
2191
2192           if (adj_int_rel.r_type == MIPS_R_RELHI)
2193             {
2194               adj_ext_rel++;
2195               adj_i++;
2196               offsets[adj_i] += change;
2197             }
2198         }
2199
2200       /* Find all symbols in this section defined by this object file
2201          and adjust their values.  Note that we decide whether to
2202          adjust the value based on the value stored in the ECOFF EXTR
2203          structure, because the value stored in the hash table may
2204          have been changed by an earlier expanded reloc and thus may
2205          no longer correctly indicate whether the symbol is before or
2206          after the expanded reloc.  */
2207       ext_count = ecoff_data (abfd)->debug_info.symbolic_header.iextMax;
2208       adj_h_ptr = ecoff_data (abfd)->sym_hashes;
2209       adj_h_ptr_end = adj_h_ptr + ext_count;
2210       for (; adj_h_ptr < adj_h_ptr_end; adj_h_ptr++)
2211         {
2212           struct ecoff_link_hash_entry *adj_h;
2213
2214           adj_h = *adj_h_ptr;
2215           if (adj_h != (struct ecoff_link_hash_entry *) NULL
2216               && (adj_h->root.type == bfd_link_hash_defined
2217                   || adj_h->root.type == bfd_link_hash_defweak)
2218               && adj_h->root.u.def.section == sec
2219               && adj_h->esym.asym.value > int_rel.r_vaddr)
2220             adj_h->root.u.def.value += PCREL16_EXPANSION_ADJUSTMENT;
2221         }
2222
2223       /* Add an entry to the symbol value adjust list.  This is used
2224          by bfd_ecoff_debug_accumulate to adjust the values of
2225          internal symbols and FDR's.  */
2226       adjust = ((struct ecoff_value_adjust *)
2227                 bfd_alloc (abfd, sizeof (struct ecoff_value_adjust)));
2228       if (adjust == (struct ecoff_value_adjust *) NULL)
2229         {
2230           bfd_set_error (bfd_error_no_memory);
2231           goto error_return;
2232         }
2233
2234       adjust->start = int_rel.r_vaddr;
2235       adjust->end = sec->vma + sec->_raw_size;
2236       adjust->adjust = PCREL16_EXPANSION_ADJUSTMENT;
2237
2238       adjust->next = ecoff_data (abfd)->debug_info.adjust;
2239       ecoff_data (abfd)->debug_info.adjust = adjust;
2240     }
2241
2242   if (contents != (bfd_byte *) NULL && ! info->keep_memory)
2243     free (contents);
2244
2245   return true;
2246
2247  error_return:
2248   if (contents != (bfd_byte *) NULL && ! info->keep_memory)
2249     free (contents);
2250   return false;
2251 }
2252
2253 /* This routine is called from mips_relocate_section when a PC
2254    relative reloc must be expanded into the five instruction sequence.
2255    It handles all the details of the expansion, including resolving
2256    the reloc.  */
2257
2258 static boolean
2259 mips_relax_pcrel16 (info, input_bfd, input_section, h, location, address)
2260      struct bfd_link_info *info;
2261      bfd *input_bfd;
2262      asection *input_section;
2263      struct ecoff_link_hash_entry *h;
2264      bfd_byte *location;
2265      bfd_vma address;
2266 {
2267   bfd_vma relocation;
2268
2269   /* 0x0411ffff is bgezal $0,. == bal .  */
2270   BFD_ASSERT (bfd_get_32 (input_bfd, location) == 0x0411ffff);
2271
2272   /* We need to compute the distance between the symbol and the
2273      current address plus eight.  */
2274   relocation = (h->root.u.def.value
2275                 + h->root.u.def.section->output_section->vma
2276                 + h->root.u.def.section->output_offset);
2277   relocation -= address + 8;
2278
2279   /* If the lower half is negative, increment the upper 16 half.  */
2280   if ((relocation & 0x8000) != 0)
2281     relocation += 0x10000;
2282
2283   bfd_put_32 (input_bfd, 0x04110001, location); /* bal .+8 */
2284   bfd_put_32 (input_bfd,
2285               0x3c010000 | ((relocation >> 16) & 0xffff), /* lui $at,XX */
2286               location + 4);
2287   bfd_put_32 (input_bfd,
2288               0x24210000 | (relocation & 0xffff), /* addiu $at,$at,XX */
2289               location + 8);
2290   bfd_put_32 (input_bfd, 0x003f0821, location + 12); /* addu $at,$at,$ra */
2291   bfd_put_32 (input_bfd, 0x0020f809, location + 16); /* jalr $at */
2292
2293   return true;
2294 }
2295
2296 /* Given a .sdata section and a .rel.sdata in-memory section, store
2297    relocation information into the .rel.sdata section which can be
2298    used at runtime to relocate the section.  This is called by the
2299    linker when the --embedded-relocs switch is used.  This is called
2300    after the add_symbols entry point has been called for all the
2301    objects, and before the final_link entry point is called.  This
2302    function presumes that the object was compiled using
2303    -membedded-pic.  */
2304
2305 boolean
2306 bfd_mips_ecoff_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
2307      bfd *abfd;
2308      struct bfd_link_info *info;
2309      asection *datasec;
2310      asection *relsec;
2311      char **errmsg;
2312 {
2313   struct ecoff_link_hash_entry **sym_hashes;
2314   struct ecoff_section_tdata *section_tdata;
2315   struct external_reloc *ext_rel;
2316   struct external_reloc *ext_rel_end;
2317   bfd_byte *p;
2318
2319   BFD_ASSERT (! info->relocateable);
2320
2321   *errmsg = NULL;
2322
2323   if (datasec->reloc_count == 0)
2324     return true;
2325
2326   sym_hashes = ecoff_data (abfd)->sym_hashes;
2327
2328   if (! mips_read_relocs (abfd, datasec))
2329     return false;
2330
2331   relsec->contents = (bfd_byte *) bfd_alloc (abfd, datasec->reloc_count * 4);
2332   if (relsec->contents == NULL)
2333     {
2334       bfd_set_error (bfd_error_no_memory);
2335       return false;
2336     }
2337
2338   p = relsec->contents;
2339
2340   section_tdata = ecoff_section_data (abfd, datasec);
2341   ext_rel = (struct external_reloc *) section_tdata->external_relocs;
2342   ext_rel_end = ext_rel + datasec->reloc_count;
2343   for (; ext_rel < ext_rel_end; ext_rel++, p += 4)
2344     {
2345       struct internal_reloc int_rel;
2346       boolean text_relative;
2347
2348       mips_ecoff_swap_reloc_in (abfd, (PTR) ext_rel, &int_rel);
2349
2350       /* We are going to write a four byte word into the runtime reloc
2351          section.  The word will be the address in the data section
2352          which must be relocated.  This must be on a word boundary,
2353          which means the lower two bits must be zero.  We use the
2354          least significant bit to indicate how the value in the data
2355          section must be relocated.  A 0 means that the value is
2356          relative to the text section, while a 1 indicates that the
2357          value is relative to the data section.  Given that we are
2358          assuming the code was compiled using -membedded-pic, there
2359          should not be any other possibilities.  */
2360
2361       /* We can only relocate REFWORD relocs at run time.  */
2362       if (int_rel.r_type != MIPS_R_REFWORD)
2363         {
2364           *errmsg = "unsupported reloc type";
2365           bfd_set_error (bfd_error_bad_value);
2366           return false;
2367         }
2368
2369       if (int_rel.r_extern)
2370         {
2371           struct ecoff_link_hash_entry *h;
2372
2373           h = sym_hashes[int_rel.r_symndx];
2374           /* If h is NULL, that means that there is a reloc against an
2375              external symbol which we thought was just a debugging
2376              symbol.  This should not happen.  */
2377           if (h == (struct ecoff_link_hash_entry *) NULL)
2378             abort ();
2379           if ((h->root.type == bfd_link_hash_defined
2380                || h->root.type == bfd_link_hash_defweak)
2381               && (h->root.u.def.section->flags & SEC_CODE) != 0)
2382             text_relative = true;
2383           else
2384             text_relative = false;
2385         }
2386       else
2387         {
2388           switch (int_rel.r_symndx)
2389             {
2390             case RELOC_SECTION_TEXT:
2391               text_relative = true;
2392               break;
2393             case RELOC_SECTION_SDATA:
2394             case RELOC_SECTION_SBSS:
2395             case RELOC_SECTION_LIT8:
2396               text_relative = false;
2397               break;
2398             default:
2399               /* No other sections should appear in -membedded-pic
2400                  code.  */
2401               *errmsg = "reloc against unsupported section";
2402               bfd_set_error (bfd_error_bad_value);
2403               return false;
2404             }
2405         }
2406
2407       if ((int_rel.r_offset & 3) != 0)
2408         {
2409           *errmsg = "reloc not properly aligned";
2410           bfd_set_error (bfd_error_bad_value);
2411           return false;
2412         }
2413
2414       bfd_put_32 (abfd,
2415                   (int_rel.r_vaddr - datasec->vma + datasec->output_offset
2416                    + (text_relative ? 0 : 1)),
2417                   p);
2418     }
2419
2420   return true;
2421 }
2422 \f
2423 /* This is the ECOFF backend structure.  The backend field of the
2424    target vector points to this.  */
2425
2426 static const struct ecoff_backend_data mips_ecoff_backend_data =
2427 {
2428   /* COFF backend structure.  */
2429   {
2430     (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */
2431     (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
2432     (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
2433     (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/
2434     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
2435     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
2436     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
2437     mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
2438     mips_ecoff_swap_scnhdr_out,
2439     FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, true,
2440     mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
2441     mips_ecoff_swap_scnhdr_in, NULL,
2442     mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
2443     _bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
2444     _bfd_ecoff_make_section_hook, _bfd_ecoff_set_alignment_hook,
2445     _bfd_ecoff_slurp_symbol_table,
2446     NULL, NULL, NULL, NULL, NULL, NULL, NULL
2447   },
2448   /* Supported architecture.  */
2449   bfd_arch_mips,
2450   /* Initial portion of armap string.  */
2451   "__________",
2452   /* The page boundary used to align sections in a demand-paged
2453      executable file.  E.g., 0x1000.  */
2454   0x1000,
2455   /* True if the .rdata section is part of the text segment, as on the
2456      Alpha.  False if .rdata is part of the data segment, as on the
2457      MIPS.  */
2458   false,
2459   /* Bitsize of constructor entries.  */
2460   32,
2461   /* Reloc to use for constructor entries.  */
2462   &mips_howto_table[MIPS_R_REFWORD],
2463   {
2464     /* Symbol table magic number.  */
2465     magicSym,
2466     /* Alignment of debugging information.  E.g., 4.  */
2467     4,
2468     /* Sizes of external symbolic information.  */
2469     sizeof (struct hdr_ext),
2470     sizeof (struct dnr_ext),
2471     sizeof (struct pdr_ext),
2472     sizeof (struct sym_ext),
2473     sizeof (struct opt_ext),
2474     sizeof (struct fdr_ext),
2475     sizeof (struct rfd_ext),
2476     sizeof (struct ext_ext),
2477     /* Functions to swap in external symbolic data.  */
2478     ecoff_swap_hdr_in,
2479     ecoff_swap_dnr_in,
2480     ecoff_swap_pdr_in,
2481     ecoff_swap_sym_in,
2482     ecoff_swap_opt_in,
2483     ecoff_swap_fdr_in,
2484     ecoff_swap_rfd_in,
2485     ecoff_swap_ext_in,
2486     _bfd_ecoff_swap_tir_in,
2487     _bfd_ecoff_swap_rndx_in,
2488     /* Functions to swap out external symbolic data.  */
2489     ecoff_swap_hdr_out,
2490     ecoff_swap_dnr_out,
2491     ecoff_swap_pdr_out,
2492     ecoff_swap_sym_out,
2493     ecoff_swap_opt_out,
2494     ecoff_swap_fdr_out,
2495     ecoff_swap_rfd_out,
2496     ecoff_swap_ext_out,
2497     _bfd_ecoff_swap_tir_out,
2498     _bfd_ecoff_swap_rndx_out,
2499     /* Function to read in symbolic data.  */
2500     _bfd_ecoff_slurp_symbolic_info
2501   },
2502   /* External reloc size.  */
2503   RELSZ,
2504   /* Reloc swapping functions.  */
2505   mips_ecoff_swap_reloc_in,
2506   mips_ecoff_swap_reloc_out,
2507   /* Backend reloc tweaking.  */
2508   mips_adjust_reloc_in,
2509   mips_adjust_reloc_out,
2510   /* Relocate section contents while linking.  */
2511   mips_relocate_section
2512 };
2513
2514 /* Looking up a reloc type is MIPS specific.  */
2515 #define _bfd_ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
2516
2517 /* Getting relocated section contents is generic.  */
2518 #define _bfd_ecoff_bfd_get_relocated_section_contents \
2519   bfd_generic_get_relocated_section_contents
2520
2521 /* Relaxing sections is MIPS specific.  */
2522 #define _bfd_ecoff_bfd_relax_section mips_relax_section
2523
2524 const bfd_target ecoff_little_vec =
2525 {
2526   "ecoff-littlemips",           /* name */
2527   bfd_target_ecoff_flavour,
2528   false,                        /* data byte order is little */
2529   false,                        /* header byte order is little */
2530
2531   (HAS_RELOC | EXEC_P |         /* object flags */
2532    HAS_LINENO | HAS_DEBUG |
2533    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
2534
2535   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
2536   0,                            /* leading underscore */
2537   ' ',                          /* ar_pad_char */
2538   15,                           /* ar_max_namelen */
2539   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2540      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2541      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
2542   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2543      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2544      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
2545
2546   {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
2547      _bfd_ecoff_archive_p, _bfd_dummy_target},
2548   {bfd_false, _bfd_ecoff_mkobject,  /* bfd_set_format */
2549      _bfd_generic_mkarchive, bfd_false},
2550   {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
2551      _bfd_write_archive_contents, bfd_false},
2552
2553      BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
2554      BFD_JUMP_TABLE_COPY (_bfd_ecoff),
2555      BFD_JUMP_TABLE_CORE (_bfd_nocore),
2556      BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
2557      BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
2558      BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
2559      BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
2560      BFD_JUMP_TABLE_LINK (_bfd_ecoff),
2561      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2562
2563   (PTR) &mips_ecoff_backend_data
2564 };
2565
2566 const bfd_target ecoff_big_vec =
2567 {
2568   "ecoff-bigmips",              /* name */
2569   bfd_target_ecoff_flavour,
2570   true,                         /* data byte order is big */
2571   true,                         /* header byte order is big */
2572
2573   (HAS_RELOC | EXEC_P |         /* object flags */
2574    HAS_LINENO | HAS_DEBUG |
2575    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
2576
2577   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
2578   0,                            /* leading underscore */
2579   ' ',                          /* ar_pad_char */
2580   15,                           /* ar_max_namelen */
2581   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
2582      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
2583      bfd_getb16, bfd_getb_signed_16, bfd_putb16,
2584   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
2585      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
2586      bfd_getb16, bfd_getb_signed_16, bfd_putb16,
2587  {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
2588     _bfd_ecoff_archive_p, _bfd_dummy_target},
2589  {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
2590     _bfd_generic_mkarchive, bfd_false},
2591  {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
2592     _bfd_write_archive_contents, bfd_false},
2593
2594      BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
2595      BFD_JUMP_TABLE_COPY (_bfd_ecoff),
2596      BFD_JUMP_TABLE_CORE (_bfd_nocore),
2597      BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
2598      BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
2599      BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
2600      BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
2601      BFD_JUMP_TABLE_LINK (_bfd_ecoff),
2602      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2603
2604   (PTR) &mips_ecoff_backend_data
2605 };