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