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