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