xref: /freebsd-11-stable/contrib/binutils/bfd/coff-mips.c (revision ce8fb931782e66cb56f7bfb4cff1ac032fc57076)
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 
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 2 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, 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 
38 static bfd_boolean mips_ecoff_bad_format_hook
39   PARAMS ((bfd *abfd, PTR filehdr));
40 static void mips_ecoff_swap_reloc_in
41   PARAMS ((bfd *, PTR, struct internal_reloc *));
42 static void mips_ecoff_swap_reloc_out
43   PARAMS ((bfd *, const struct internal_reloc *, PTR));
44 static void mips_adjust_reloc_in
45   PARAMS ((bfd *, const struct internal_reloc *, arelent *));
46 static void mips_adjust_reloc_out
47   PARAMS ((bfd *, const arelent *, struct internal_reloc *));
48 static 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));
51 static 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));
54 static 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));
57 static 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));
60 static 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));
64 static bfd_boolean mips_relocate_section
65   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, PTR));
66 static 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 
95 static 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 
253 static bfd_boolean
mips_ecoff_bad_format_hook(abfd,filehdr)254 mips_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 
287 static void
mips_ecoff_swap_reloc_in(abfd,ext_ptr,intern)288 mips_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 
326 static void
mips_ecoff_swap_reloc_out(abfd,intern,dst)327 mips_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 
367 static void
mips_adjust_reloc_in(abfd,intern,rptr)368 mips_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 
392 static void
mips_adjust_reloc_out(abfd,rel,intern)393 mips_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 
411 static bfd_reloc_status_type
mips_generic_reloc(abfd,reloc_entry,symbol,data,input_section,output_bfd,error_message)412 mips_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 
447 struct 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 
456 static struct mips_hi *mips_refhi_list;
457 
458 static bfd_reloc_status_type
mips_refhi_reloc(abfd,reloc_entry,symbol,data,input_section,output_bfd,error_message)459 mips_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 
524 static bfd_reloc_status_type
mips_reflo_reloc(abfd,reloc_entry,symbol,data,input_section,output_bfd,error_message)525 mips_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 
592 static bfd_reloc_status_type
mips_gprel_reloc(abfd,reloc_entry,symbol,data,input_section,output_bfd,error_message)593 mips_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 
732 static reloc_howto_type *
mips_bfd_reloc_type_lookup(abfd,code)733 mips_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 
773 static reloc_howto_type *
mips_bfd_reloc_name_lookup(bfd * abfd ATTRIBUTE_UNUSED,const char * r_name)774 mips_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 
794 static void
mips_relocate_hi(refhi,reflo,input_bfd,input_section,contents,relocation)795 mips_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 
841 static bfd_boolean
mips_relocate_section(output_bfd,info,input_bfd,input_section,contents,external_relocs)842 mips_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 
1300 static 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 
1418 extern const bfd_target ecoff_big_vec;
1419 
1420 const 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 
1464 const 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 
1507 const 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