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