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