1 /* BFD back-end for MIPS Extended-Coff files.
2    Copyright (C) 1990-2021 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 	 0,			/* size (0 = byte, 1 = short, 2 = long) */
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 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
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 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
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 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
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 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
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 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
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 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
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 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
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 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
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     abort ();
355 
356   if (! intern->r_extern
357       && (intern->r_type == MIPS_R_GPREL
358 	  || intern->r_type == MIPS_R_LITERAL))
359     rptr->addend += ecoff_data (abfd)->gp;
360 
361   /* If the type is MIPS_R_IGNORE, make sure this is a reference to
362      the absolute section so that the reloc is ignored.  */
363   if (intern->r_type == MIPS_R_IGNORE)
364     rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
365 
366   rptr->howto = &mips_howto_table[intern->r_type];
367 }
368 
369 /* Make any adjustments needed to a reloc before writing it out.  None
370    are needed for MIPS.  */
371 
372 static void
mips_adjust_reloc_out(bfd * abfd ATTRIBUTE_UNUSED,const arelent * rel ATTRIBUTE_UNUSED,struct internal_reloc * intern ATTRIBUTE_UNUSED)373 mips_adjust_reloc_out (bfd *abfd ATTRIBUTE_UNUSED,
374 		       const arelent *rel ATTRIBUTE_UNUSED,
375 		       struct internal_reloc *intern ATTRIBUTE_UNUSED)
376 {
377 }
378 
379 /* ECOFF relocs are either against external symbols, or against
380    sections.  If we are producing relocatable output, and the reloc
381    is against an external symbol, and nothing has given us any
382    additional addend, the resulting reloc will also be against the
383    same symbol.  In such a case, we don't want to change anything
384    about the way the reloc is handled, since it will all be done at
385    final link time.  Rather than put special case code into
386    bfd_perform_relocation, all the reloc types use this howto
387    function.  It just short circuits the reloc if producing
388    relocatable output against an external symbol.  */
389 
390 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)391 mips_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED,
392 		    arelent *reloc_entry,
393 		    asymbol *symbol,
394 		    void * data ATTRIBUTE_UNUSED,
395 		    asection *input_section,
396 		    bfd *output_bfd,
397 		    char **error_message ATTRIBUTE_UNUSED)
398 {
399   if (output_bfd != (bfd *) NULL
400       && (symbol->flags & BSF_SECTION_SYM) == 0
401       && reloc_entry->addend == 0)
402     {
403       reloc_entry->address += input_section->output_offset;
404       return bfd_reloc_ok;
405     }
406 
407   return bfd_reloc_continue;
408 }
409 
410 /* Do a REFHI relocation.  This has to be done in combination with a
411    REFLO reloc, because there is a carry from the REFLO to the REFHI.
412    Here we just save the information we need; we do the actual
413    relocation when we see the REFLO.  MIPS ECOFF requires that the
414    REFLO immediately follow the REFHI.  As a GNU extension, we permit
415    an arbitrary number of HI relocs to be associated with a single LO
416    reloc.  This extension permits gcc to output the HI and LO relocs
417    itself.  */
418 
419 struct mips_hi
420 {
421   struct mips_hi *next;
422   bfd_byte *addr;
423   bfd_vma addend;
424 };
425 
426 /* FIXME: This should not be a static variable.  */
427 
428 static struct mips_hi *mips_refhi_list;
429 
430 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)431 mips_refhi_reloc (bfd *abfd ATTRIBUTE_UNUSED,
432 		  arelent *reloc_entry,
433 		  asymbol *symbol,
434 		  void * data,
435 		  asection *input_section,
436 		  bfd *output_bfd,
437 		  char **error_message ATTRIBUTE_UNUSED)
438 {
439   bfd_reloc_status_type ret;
440   bfd_vma relocation;
441   struct mips_hi *n;
442 
443   /* If we're relocating, and this an external symbol, we don't want
444      to change anything.  */
445   if (output_bfd != (bfd *) NULL
446       && (symbol->flags & BSF_SECTION_SYM) == 0
447       && reloc_entry->addend == 0)
448     {
449       reloc_entry->address += input_section->output_offset;
450       return bfd_reloc_ok;
451     }
452 
453   ret = bfd_reloc_ok;
454   if (bfd_is_und_section (symbol->section)
455       && output_bfd == (bfd *) NULL)
456     ret = bfd_reloc_undefined;
457 
458   if (bfd_is_com_section (symbol->section))
459     relocation = 0;
460   else
461     relocation = symbol->value;
462 
463   relocation += symbol->section->output_section->vma;
464   relocation += symbol->section->output_offset;
465   relocation += reloc_entry->addend;
466 
467   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
468     return bfd_reloc_outofrange;
469 
470   /* Save the information, and let REFLO do the actual relocation.  */
471   n = (struct mips_hi *) bfd_malloc ((bfd_size_type) sizeof *n);
472   if (n == NULL)
473     return bfd_reloc_outofrange;
474   n->addr = (bfd_byte *) data + reloc_entry->address;
475   n->addend = relocation;
476   n->next = mips_refhi_list;
477   mips_refhi_list = n;
478 
479   if (output_bfd != (bfd *) NULL)
480     reloc_entry->address += input_section->output_offset;
481 
482   return ret;
483 }
484 
485 /* Do a REFLO relocation.  This is a straightforward 16 bit inplace
486    relocation; this function exists in order to do the REFHI
487    relocation described above.  */
488 
489 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)490 mips_reflo_reloc (bfd *abfd,
491 		  arelent *reloc_entry,
492 		  asymbol *symbol,
493 		  void * data,
494 		  asection *input_section,
495 		  bfd *output_bfd,
496 		  char **error_message)
497 {
498   if (mips_refhi_list != NULL)
499     {
500       struct mips_hi *l;
501 
502       l = mips_refhi_list;
503       while (l != NULL)
504 	{
505 	  unsigned long insn;
506 	  unsigned long val;
507 	  unsigned long vallo;
508 	  struct mips_hi *next;
509 	  bfd_size_type octets = (reloc_entry->address
510 				  * OCTETS_PER_BYTE (abfd, input_section));
511 	  bfd_byte *loc = (bfd_byte *) data + octets;
512 
513 	  if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
514 					  input_section, octets))
515 	    return bfd_reloc_outofrange;
516 
517 	  /* Do the REFHI relocation.  Note that we actually don't
518 	     need to know anything about the REFLO itself, except
519 	     where to find the low 16 bits of the addend needed by the
520 	     REFHI.  */
521 	  insn = bfd_get_32 (abfd, l->addr);
522 	  vallo = bfd_get_32 (abfd, loc) & 0xffff;
523 	  val = ((insn & 0xffff) << 16) + vallo;
524 	  val += l->addend;
525 
526 	  /* The low order 16 bits are always treated as a signed
527 	     value.  Therefore, a negative value in the low order bits
528 	     requires an adjustment in the high order bits.  We need
529 	     to make this adjustment in two ways: once for the bits we
530 	     took from the data, and once for the bits we are putting
531 	     back in to the data.  */
532 	  if ((vallo & 0x8000) != 0)
533 	    val -= 0x10000;
534 	  if ((val & 0x8000) != 0)
535 	    val += 0x10000;
536 
537 	  insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
538 	  bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
539 
540 	  next = l->next;
541 	  free (l);
542 	  l = next;
543 	}
544 
545       mips_refhi_list = NULL;
546     }
547 
548   /* Now do the REFLO reloc in the usual way.  */
549   return mips_generic_reloc (abfd, reloc_entry, symbol, data,
550 			     input_section, output_bfd, error_message);
551 }
552 
553 /* Do a GPREL relocation.  This is a 16 bit value which must become
554    the offset from the gp register.  */
555 
556 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)557 mips_gprel_reloc (bfd *abfd ATTRIBUTE_UNUSED,
558 		  arelent *reloc_entry,
559 		  asymbol *symbol,
560 		  void * data,
561 		  asection *input_section,
562 		  bfd *output_bfd,
563 		  char **error_message ATTRIBUTE_UNUSED)
564 {
565   bool relocatable;
566   bfd_vma gp;
567   bfd_vma relocation;
568   unsigned long val;
569   unsigned long insn;
570 
571   /* If we're relocating, and this is an external symbol with no
572      addend, we don't want to change anything.  We will only have an
573      addend if this is a newly created reloc, not read from an ECOFF
574      file.  */
575   if (output_bfd != (bfd *) NULL
576       && (symbol->flags & BSF_SECTION_SYM) == 0
577       && reloc_entry->addend == 0)
578     {
579       reloc_entry->address += input_section->output_offset;
580       return bfd_reloc_ok;
581     }
582 
583   if (output_bfd != (bfd *) NULL)
584     relocatable = true;
585   else
586     {
587       relocatable = false;
588       output_bfd = symbol->section->output_section->owner;
589     }
590 
591   if (bfd_is_und_section (symbol->section) && ! relocatable)
592     return bfd_reloc_undefined;
593 
594   /* We have to figure out the gp value, so that we can adjust the
595      symbol value correctly.  We look up the symbol _gp in the output
596      BFD.  If we can't find it, we're stuck.  We cache it in the ECOFF
597      target data.  We don't need to adjust the symbol value for an
598      external symbol if we are producing relocatable output.  */
599   gp = _bfd_get_gp_value (output_bfd);
600   if (gp == 0
601       && (! relocatable
602 	  || (symbol->flags & BSF_SECTION_SYM) != 0))
603     {
604       if (relocatable)
605 	{
606 	  /* Make up a value.  */
607 	  gp = symbol->section->output_section->vma + 0x4000;
608 	  _bfd_set_gp_value (output_bfd, gp);
609 	}
610       else
611 	{
612 	  unsigned int count;
613 	  asymbol **sym;
614 	  unsigned int i;
615 
616 	  count = bfd_get_symcount (output_bfd);
617 	  sym = bfd_get_outsymbols (output_bfd);
618 
619 	  if (sym == (asymbol **) NULL)
620 	    i = count;
621 	  else
622 	    {
623 	      for (i = 0; i < count; i++, sym++)
624 		{
625 		  register const char *name;
626 
627 		  name = bfd_asymbol_name (*sym);
628 		  if (*name == '_' && strcmp (name, "_gp") == 0)
629 		    {
630 		      gp = bfd_asymbol_value (*sym);
631 		      _bfd_set_gp_value (output_bfd, gp);
632 		      break;
633 		    }
634 		}
635 	    }
636 
637 	  if (i >= count)
638 	    {
639 	      /* Only get the error once.  */
640 	      gp = 4;
641 	      _bfd_set_gp_value (output_bfd, gp);
642 	      *error_message =
643 		(char *) _("GP relative relocation when _gp not defined");
644 	      return bfd_reloc_dangerous;
645 	    }
646 	}
647     }
648 
649   if (bfd_is_com_section (symbol->section))
650     relocation = 0;
651   else
652     relocation = symbol->value;
653 
654   relocation += symbol->section->output_section->vma;
655   relocation += symbol->section->output_offset;
656 
657   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
658     return bfd_reloc_outofrange;
659 
660   insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
661 
662   /* Set val to the offset into the section or symbol.  */
663   val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;
664   if (val & 0x8000)
665     val -= 0x10000;
666 
667   /* Adjust val for the final section location and GP value.  If we
668      are producing relocatable output, we don't want to do this for
669      an external symbol.  */
670   if (! relocatable
671       || (symbol->flags & BSF_SECTION_SYM) != 0)
672     val += relocation - gp;
673 
674   insn = (insn &~ (unsigned) 0xffff) | (val & 0xffff);
675   bfd_put_32 (abfd, (bfd_vma) insn, (bfd_byte *) data + reloc_entry->address);
676 
677   if (relocatable)
678     reloc_entry->address += input_section->output_offset;
679 
680   /* Make sure it fit in 16 bits.  */
681   if ((long) val >= 0x8000 || (long) val < -0x8000)
682     return bfd_reloc_overflow;
683 
684   return bfd_reloc_ok;
685 }
686 
687 /* Get the howto structure for a generic reloc type.  */
688 
689 static reloc_howto_type *
mips_bfd_reloc_type_lookup(bfd * abfd ATTRIBUTE_UNUSED,bfd_reloc_code_real_type code)690 mips_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
691 			    bfd_reloc_code_real_type code)
692 {
693   int mips_type;
694 
695   switch (code)
696     {
697     case BFD_RELOC_16:
698       mips_type = MIPS_R_REFHALF;
699       break;
700     case BFD_RELOC_32:
701     case BFD_RELOC_CTOR:
702       mips_type = MIPS_R_REFWORD;
703       break;
704     case BFD_RELOC_MIPS_JMP:
705       mips_type = MIPS_R_JMPADDR;
706       break;
707     case BFD_RELOC_HI16_S:
708       mips_type = MIPS_R_REFHI;
709       break;
710     case BFD_RELOC_LO16:
711       mips_type = MIPS_R_REFLO;
712       break;
713     case BFD_RELOC_GPREL16:
714       mips_type = MIPS_R_GPREL;
715       break;
716     case BFD_RELOC_MIPS_LITERAL:
717       mips_type = MIPS_R_LITERAL;
718       break;
719     case BFD_RELOC_16_PCREL_S2:
720       mips_type = MIPS_R_PCREL16;
721       break;
722     default:
723       return (reloc_howto_type *) NULL;
724     }
725 
726   return &mips_howto_table[mips_type];
727 }
728 
729 static reloc_howto_type *
mips_bfd_reloc_name_lookup(bfd * abfd ATTRIBUTE_UNUSED,const char * r_name)730 mips_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
731 			    const char *r_name)
732 {
733   unsigned int i;
734 
735   for (i = 0;
736        i < sizeof (mips_howto_table) / sizeof (mips_howto_table[0]);
737        i++)
738     if (mips_howto_table[i].name != NULL
739 	&& strcasecmp (mips_howto_table[i].name, r_name) == 0)
740       return &mips_howto_table[i];
741 
742   return NULL;
743 }
744 
745 /* A helper routine for mips_relocate_section which handles the REFHI
746    relocations.  The REFHI relocation must be followed by a REFLO
747    relocation, and the addend used is formed from the addends of both
748    instructions.  */
749 
750 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)751 mips_relocate_hi (struct internal_reloc *refhi,
752 		  struct internal_reloc *reflo,
753 		  bfd *input_bfd,
754 		  asection *input_section,
755 		  bfd_byte *contents,
756 		  bfd_vma relocation)
757 {
758   unsigned long insn;
759   unsigned long val;
760   unsigned long vallo;
761 
762   if (refhi == NULL)
763     return;
764 
765   insn = bfd_get_32 (input_bfd,
766 		     contents + refhi->r_vaddr - input_section->vma);
767   if (reflo == NULL)
768     vallo = 0;
769   else
770     vallo = (bfd_get_32 (input_bfd,
771 			 contents + reflo->r_vaddr - input_section->vma)
772 	     & 0xffff);
773 
774   val = ((insn & 0xffff) << 16) + vallo;
775   val += relocation;
776 
777   /* The low order 16 bits are always treated as a signed value.
778      Therefore, a negative value in the low order bits requires an
779      adjustment in the high order bits.  We need to make this
780      adjustment in two ways: once for the bits we took from the data,
781      and once for the bits we are putting back in to the data.  */
782   if ((vallo & 0x8000) != 0)
783     val -= 0x10000;
784 
785   if ((val & 0x8000) != 0)
786     val += 0x10000;
787 
788   insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
789   bfd_put_32 (input_bfd, (bfd_vma) insn,
790 	      contents + refhi->r_vaddr - input_section->vma);
791 }
792 
793 /* Relocate a section while linking a MIPS ECOFF file.  */
794 
795 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)796 mips_relocate_section (bfd *output_bfd,
797 		       struct bfd_link_info *info,
798 		       bfd *input_bfd,
799 		       asection *input_section,
800 		       bfd_byte *contents,
801 		       void * external_relocs)
802 {
803   asection **symndx_to_section;
804   struct ecoff_link_hash_entry **sym_hashes;
805   bfd_vma gp;
806   bool gp_undefined;
807   struct external_reloc *ext_rel;
808   struct external_reloc *ext_rel_end;
809   unsigned int i;
810   bool got_lo;
811   struct internal_reloc lo_int_rel;
812   bfd_size_type amt;
813 
814   BFD_ASSERT (input_bfd->xvec->byteorder
815 	      == output_bfd->xvec->byteorder);
816 
817   /* We keep a table mapping the symndx found in an internal reloc to
818      the appropriate section.  This is faster than looking up the
819      section by name each time.  */
820   symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
821   if (symndx_to_section == (asection **) NULL)
822     {
823       amt = NUM_RELOC_SECTIONS * sizeof (asection *);
824       symndx_to_section = (asection **) bfd_alloc (input_bfd, amt);
825       if (!symndx_to_section)
826 	return false;
827 
828       symndx_to_section[RELOC_SECTION_NONE] = NULL;
829       symndx_to_section[RELOC_SECTION_TEXT] =
830 	bfd_get_section_by_name (input_bfd, ".text");
831       symndx_to_section[RELOC_SECTION_RDATA] =
832 	bfd_get_section_by_name (input_bfd, ".rdata");
833       symndx_to_section[RELOC_SECTION_DATA] =
834 	bfd_get_section_by_name (input_bfd, ".data");
835       symndx_to_section[RELOC_SECTION_SDATA] =
836 	bfd_get_section_by_name (input_bfd, ".sdata");
837       symndx_to_section[RELOC_SECTION_SBSS] =
838 	bfd_get_section_by_name (input_bfd, ".sbss");
839       symndx_to_section[RELOC_SECTION_BSS] =
840 	bfd_get_section_by_name (input_bfd, ".bss");
841       symndx_to_section[RELOC_SECTION_INIT] =
842 	bfd_get_section_by_name (input_bfd, ".init");
843       symndx_to_section[RELOC_SECTION_LIT8] =
844 	bfd_get_section_by_name (input_bfd, ".lit8");
845       symndx_to_section[RELOC_SECTION_LIT4] =
846 	bfd_get_section_by_name (input_bfd, ".lit4");
847       symndx_to_section[RELOC_SECTION_XDATA] = NULL;
848       symndx_to_section[RELOC_SECTION_PDATA] = NULL;
849       symndx_to_section[RELOC_SECTION_FINI] =
850 	bfd_get_section_by_name (input_bfd, ".fini");
851       symndx_to_section[RELOC_SECTION_LITA] = NULL;
852       symndx_to_section[RELOC_SECTION_ABS] = NULL;
853 
854       ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
855     }
856 
857   sym_hashes = ecoff_data (input_bfd)->sym_hashes;
858 
859   gp = _bfd_get_gp_value (output_bfd);
860   if (gp == 0)
861     gp_undefined = true;
862   else
863     gp_undefined = false;
864 
865   got_lo = false;
866 
867   ext_rel = (struct external_reloc *) external_relocs;
868   ext_rel_end = ext_rel + input_section->reloc_count;
869   for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
870     {
871       struct internal_reloc int_rel;
872       bool use_lo = false;
873       bfd_vma addend;
874       reloc_howto_type *howto;
875       struct ecoff_link_hash_entry *h = NULL;
876       asection *s = NULL;
877       bfd_vma relocation;
878       bfd_reloc_status_type r;
879 
880       if (! got_lo)
881 	mips_ecoff_swap_reloc_in (input_bfd, ext_rel, &int_rel);
882       else
883 	{
884 	  int_rel = lo_int_rel;
885 	  got_lo = false;
886 	}
887 
888       BFD_ASSERT (int_rel.r_type
889 		  < sizeof mips_howto_table / sizeof mips_howto_table[0]);
890 
891       /* The REFHI reloc requires special handling.  It must be followed
892 	 by a REFLO reloc, and the addend is formed from both relocs.  */
893       if (int_rel.r_type == MIPS_R_REFHI)
894 	{
895 	  struct external_reloc *lo_ext_rel;
896 
897 	  /* As a GNU extension, permit an arbitrary number of REFHI
898 	     relocs before the REFLO reloc.  This permits gcc to emit
899 	     the HI and LO relocs itself.  */
900 	  for (lo_ext_rel = ext_rel + 1;
901 	       lo_ext_rel < ext_rel_end;
902 	       lo_ext_rel++)
903 	    {
904 	      mips_ecoff_swap_reloc_in (input_bfd, lo_ext_rel,
905 					&lo_int_rel);
906 	      if (lo_int_rel.r_type != int_rel.r_type)
907 		break;
908 	    }
909 
910 	  if (lo_ext_rel < ext_rel_end
911 	      && lo_int_rel.r_type == MIPS_R_REFLO
912 	      && int_rel.r_extern == lo_int_rel.r_extern
913 	      && int_rel.r_symndx == lo_int_rel.r_symndx)
914 	    {
915 	      use_lo = true;
916 	      if (lo_ext_rel == ext_rel + 1)
917 		got_lo = true;
918 	    }
919 	}
920 
921       howto = &mips_howto_table[int_rel.r_type];
922 
923       if (int_rel.r_extern)
924 	{
925 	  h = sym_hashes[int_rel.r_symndx];
926 	  /* If h is NULL, that means that there is a reloc against an
927 	     external symbol which we thought was just a debugging
928 	     symbol.  This should not happen.  */
929 	  if (h == (struct ecoff_link_hash_entry *) NULL)
930 	    abort ();
931 	}
932       else
933 	{
934 	  if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS)
935 	    s = NULL;
936 	  else
937 	    s = symndx_to_section[int_rel.r_symndx];
938 
939 	  if (s == (asection *) NULL)
940 	    abort ();
941 	}
942 
943       /* The GPREL reloc uses an addend: the difference in the GP
944 	 values.  */
945       if (int_rel.r_type != MIPS_R_GPREL
946 	  && int_rel.r_type != MIPS_R_LITERAL)
947 	addend = 0;
948       else
949 	{
950 	  if (gp_undefined)
951 	    {
952 	      (*info->callbacks->reloc_dangerous)
953 		(info, _("GP relative relocation used when GP not defined"),
954 		 input_bfd, input_section,
955 		 int_rel.r_vaddr - input_section->vma);
956 	      /* Only give the error once per link.  */
957 	      gp = 4;
958 	      _bfd_set_gp_value (output_bfd, gp);
959 	      gp_undefined = false;
960 	    }
961 	  if (! int_rel.r_extern)
962 	    {
963 	      /* This is a relocation against a section.  The current
964 		 addend in the instruction is the difference between
965 		 INPUT_SECTION->vma and the GP value of INPUT_BFD.  We
966 		 must change this to be the difference between the
967 		 final definition (which will end up in RELOCATION)
968 		 and the GP value of OUTPUT_BFD (which is in GP).  */
969 	      addend = ecoff_data (input_bfd)->gp - gp;
970 	    }
971 	  else if (! bfd_link_relocatable (info)
972 		   || h->root.type == bfd_link_hash_defined
973 		   || h->root.type == bfd_link_hash_defweak)
974 	    {
975 	      /* This is a relocation against a defined symbol.  The
976 		 current addend in the instruction is simply the
977 		 desired offset into the symbol (normally zero).  We
978 		 are going to change this into a relocation against a
979 		 defined symbol, so we want the instruction to hold
980 		 the difference between the final definition of the
981 		 symbol (which will end up in RELOCATION) and the GP
982 		 value of OUTPUT_BFD (which is in GP).  */
983 	      addend = - gp;
984 	    }
985 	  else
986 	    {
987 	      /* This is a relocation against an undefined or common
988 		 symbol.  The current addend in the instruction is
989 		 simply the desired offset into the symbol (normally
990 		 zero).  We are generating relocatable output, and we
991 		 aren't going to define this symbol, so we just leave
992 		 the instruction alone.  */
993 	      addend = 0;
994 	    }
995 	}
996 
997       if (bfd_link_relocatable (info))
998 	{
999 	  /* We are generating relocatable output, and must convert
1000 	     the existing reloc.  */
1001 	  if (int_rel.r_extern)
1002 	    {
1003 	      if ((h->root.type == bfd_link_hash_defined
1004 		   || h->root.type == bfd_link_hash_defweak)
1005 		  && ! bfd_is_abs_section (h->root.u.def.section))
1006 		{
1007 		  const char *name;
1008 
1009 		  /* This symbol is defined in the output.  Convert
1010 		     the reloc from being against the symbol to being
1011 		     against the section.  */
1012 
1013 		  /* Clear the r_extern bit.  */
1014 		  int_rel.r_extern = 0;
1015 
1016 		  /* Compute a new r_symndx value.  */
1017 		  s = h->root.u.def.section;
1018 		  name = bfd_section_name (s->output_section);
1019 
1020 		  int_rel.r_symndx = -1;
1021 		  switch (name[1])
1022 		    {
1023 		    case 'b':
1024 		      if (strcmp (name, ".bss") == 0)
1025 			int_rel.r_symndx = RELOC_SECTION_BSS;
1026 		      break;
1027 		    case 'd':
1028 		      if (strcmp (name, ".data") == 0)
1029 			int_rel.r_symndx = RELOC_SECTION_DATA;
1030 		      break;
1031 		    case 'f':
1032 		      if (strcmp (name, ".fini") == 0)
1033 			int_rel.r_symndx = RELOC_SECTION_FINI;
1034 		      break;
1035 		    case 'i':
1036 		      if (strcmp (name, ".init") == 0)
1037 			int_rel.r_symndx = RELOC_SECTION_INIT;
1038 		      break;
1039 		    case 'l':
1040 		      if (strcmp (name, ".lit8") == 0)
1041 			int_rel.r_symndx = RELOC_SECTION_LIT8;
1042 		      else if (strcmp (name, ".lit4") == 0)
1043 			int_rel.r_symndx = RELOC_SECTION_LIT4;
1044 		      break;
1045 		    case 'r':
1046 		      if (strcmp (name, ".rdata") == 0)
1047 			int_rel.r_symndx = RELOC_SECTION_RDATA;
1048 		      break;
1049 		    case 's':
1050 		      if (strcmp (name, ".sdata") == 0)
1051 			int_rel.r_symndx = RELOC_SECTION_SDATA;
1052 		      else if (strcmp (name, ".sbss") == 0)
1053 			int_rel.r_symndx = RELOC_SECTION_SBSS;
1054 		      break;
1055 		    case 't':
1056 		      if (strcmp (name, ".text") == 0)
1057 			int_rel.r_symndx = RELOC_SECTION_TEXT;
1058 		      break;
1059 		    }
1060 
1061 		  if (int_rel.r_symndx == -1)
1062 		    abort ();
1063 
1064 		  /* Add the section VMA and the symbol value.  */
1065 		  relocation = (h->root.u.def.value
1066 				+ s->output_section->vma
1067 				+ s->output_offset);
1068 
1069 		  /* For a PC relative relocation, the object file
1070 		     currently holds just the addend.  We must adjust
1071 		     by the address to get the right value.  */
1072 		  if (howto->pc_relative)
1073 		    relocation -= int_rel.r_vaddr - input_section->vma;
1074 
1075 		  h = NULL;
1076 		}
1077 	      else
1078 		{
1079 		  /* Change the symndx value to the right one for the
1080 		     output BFD.  */
1081 		  int_rel.r_symndx = h->indx;
1082 		  if (int_rel.r_symndx == -1)
1083 		    {
1084 		      /* This symbol is not being written out.  */
1085 		      (*info->callbacks->unattached_reloc)
1086 			(info, h->root.root.string, input_bfd, input_section,
1087 			 int_rel.r_vaddr - input_section->vma);
1088 		      int_rel.r_symndx = 0;
1089 		    }
1090 		  relocation = 0;
1091 		}
1092 	    }
1093 	  else
1094 	    {
1095 	      /* This is a relocation against a section.  Adjust the
1096 		 value by the amount the section moved.  */
1097 	      relocation = (s->output_section->vma
1098 			    + s->output_offset
1099 			    - s->vma);
1100 	    }
1101 
1102 	  relocation += addend;
1103 	  addend = 0;
1104 
1105 	  /* Adjust a PC relative relocation by removing the reference
1106 	     to the original address in the section and including the
1107 	     reference to the new address.  */
1108 	  if (howto->pc_relative)
1109 	    relocation -= (input_section->output_section->vma
1110 			   + input_section->output_offset
1111 			   - input_section->vma);
1112 
1113 	  /* Adjust the contents.  */
1114 	  if (relocation == 0)
1115 	    r = bfd_reloc_ok;
1116 	  else
1117 	    {
1118 	      if (int_rel.r_type != MIPS_R_REFHI)
1119 		r = _bfd_relocate_contents (howto, input_bfd, relocation,
1120 					    (contents
1121 					     + int_rel.r_vaddr
1122 					     - input_section->vma));
1123 	      else
1124 		{
1125 		  mips_relocate_hi (&int_rel,
1126 				    use_lo ? &lo_int_rel : NULL,
1127 				    input_bfd, input_section, contents,
1128 				    relocation);
1129 		  r = bfd_reloc_ok;
1130 		}
1131 	    }
1132 
1133 	  /* Adjust the reloc address.  */
1134 	  int_rel.r_vaddr += (input_section->output_section->vma
1135 			      + input_section->output_offset
1136 			      - input_section->vma);
1137 
1138 	  /* Save the changed reloc information.  */
1139 	  mips_ecoff_swap_reloc_out (input_bfd, &int_rel, ext_rel);
1140 	}
1141       else
1142 	{
1143 	  /* We are producing a final executable.  */
1144 	  if (int_rel.r_extern)
1145 	    {
1146 	      /* This is a reloc against a symbol.  */
1147 	      if (h->root.type == bfd_link_hash_defined
1148 		  || h->root.type == bfd_link_hash_defweak)
1149 		{
1150 		  asection *hsec;
1151 
1152 		  hsec = h->root.u.def.section;
1153 		  relocation = (h->root.u.def.value
1154 				+ hsec->output_section->vma
1155 				+ hsec->output_offset);
1156 		}
1157 	      else
1158 		{
1159 		  (*info->callbacks->undefined_symbol)
1160 		    (info, h->root.root.string, input_bfd, input_section,
1161 		     int_rel.r_vaddr - input_section->vma, true);
1162 		  relocation = 0;
1163 		}
1164 	    }
1165 	  else
1166 	    {
1167 	      /* This is a reloc against a section.  */
1168 	      relocation = (s->output_section->vma
1169 			    + s->output_offset
1170 			    - s->vma);
1171 
1172 	      /* A PC relative reloc is already correct in the object
1173 		 file.  Make it look like a pcrel_offset relocation by
1174 		 adding in the start address.  */
1175 	      if (howto->pc_relative)
1176 		relocation += int_rel.r_vaddr;
1177 	    }
1178 
1179 	  if (int_rel.r_type != MIPS_R_REFHI)
1180 	    r = _bfd_final_link_relocate (howto,
1181 					  input_bfd,
1182 					  input_section,
1183 					  contents,
1184 					  (int_rel.r_vaddr
1185 					   - input_section->vma),
1186 					  relocation,
1187 					  addend);
1188 	  else
1189 	    {
1190 	      mips_relocate_hi (&int_rel,
1191 				use_lo ? &lo_int_rel : NULL,
1192 				input_bfd, input_section, contents,
1193 				relocation);
1194 	      r = bfd_reloc_ok;
1195 	    }
1196 	}
1197 
1198       /* MIPS_R_JMPADDR requires peculiar overflow detection.  The
1199 	 instruction provides a 28 bit address (the two lower bits are
1200 	 implicit zeroes) which is combined with the upper four bits
1201 	 of the instruction address.  */
1202       if (r == bfd_reloc_ok
1203 	  && int_rel.r_type == MIPS_R_JMPADDR
1204 	  && (((relocation
1205 		+ addend
1206 		+ (int_rel.r_extern ? 0 : s->vma))
1207 	       & 0xf0000000)
1208 	      != ((input_section->output_section->vma
1209 		   + input_section->output_offset
1210 		   + (int_rel.r_vaddr - input_section->vma))
1211 		  & 0xf0000000)))
1212 	r = bfd_reloc_overflow;
1213 
1214       if (r != bfd_reloc_ok)
1215 	{
1216 	  switch (r)
1217 	    {
1218 	    default:
1219 	    case bfd_reloc_outofrange:
1220 	      abort ();
1221 	    case bfd_reloc_overflow:
1222 	      {
1223 		const char *name;
1224 
1225 		if (int_rel.r_extern)
1226 		  name = NULL;
1227 		else
1228 		  name = bfd_section_name (s);
1229 		(*info->callbacks->reloc_overflow)
1230 		  (info, (h ? &h->root : NULL), name, howto->name,
1231 		   (bfd_vma) 0, input_bfd, input_section,
1232 		   int_rel.r_vaddr - input_section->vma);
1233 	      }
1234 	      break;
1235 	    }
1236 	}
1237     }
1238 
1239   return true;
1240 }
1241 
1242 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)1243 mips_ecoff_swap_coff_aux_in (bfd *abfd ATTRIBUTE_UNUSED,
1244 			     void *ext1 ATTRIBUTE_UNUSED,
1245 			     int type ATTRIBUTE_UNUSED,
1246 			     int in_class ATTRIBUTE_UNUSED,
1247 			     int indx ATTRIBUTE_UNUSED,
1248 			     int numaux ATTRIBUTE_UNUSED,
1249 			     void *in1 ATTRIBUTE_UNUSED)
1250 {
1251 }
1252 
1253 static void
mips_ecoff_swap_coff_sym_in(bfd * abfd ATTRIBUTE_UNUSED,void * ext1 ATTRIBUTE_UNUSED,void * in1 ATTRIBUTE_UNUSED)1254 mips_ecoff_swap_coff_sym_in (bfd *abfd ATTRIBUTE_UNUSED,
1255 			     void *ext1 ATTRIBUTE_UNUSED,
1256 			     void *in1 ATTRIBUTE_UNUSED)
1257 {
1258 }
1259 
1260 static void
mips_ecoff_swap_coff_lineno_in(bfd * abfd ATTRIBUTE_UNUSED,void * ext1 ATTRIBUTE_UNUSED,void * in1 ATTRIBUTE_UNUSED)1261 mips_ecoff_swap_coff_lineno_in (bfd *abfd ATTRIBUTE_UNUSED,
1262 				void *ext1 ATTRIBUTE_UNUSED,
1263 				void *in1 ATTRIBUTE_UNUSED)
1264 {
1265 }
1266 
1267 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)1268 mips_ecoff_swap_coff_aux_out (bfd *abfd ATTRIBUTE_UNUSED,
1269 			      void *inp ATTRIBUTE_UNUSED,
1270 			      int type ATTRIBUTE_UNUSED,
1271 			      int in_class ATTRIBUTE_UNUSED,
1272 			      int indx ATTRIBUTE_UNUSED,
1273 			      int numaux ATTRIBUTE_UNUSED,
1274 			      void *extp ATTRIBUTE_UNUSED)
1275 {
1276   return 0;
1277 }
1278 
1279 static unsigned int
mips_ecoff_swap_coff_sym_out(bfd * abfd ATTRIBUTE_UNUSED,void * inp ATTRIBUTE_UNUSED,void * extp ATTRIBUTE_UNUSED)1280 mips_ecoff_swap_coff_sym_out (bfd *abfd ATTRIBUTE_UNUSED,
1281 			      void *inp ATTRIBUTE_UNUSED,
1282 			      void *extp ATTRIBUTE_UNUSED)
1283 {
1284   return 0;
1285 }
1286 
1287 static unsigned int
mips_ecoff_swap_coff_lineno_out(bfd * abfd ATTRIBUTE_UNUSED,void * inp ATTRIBUTE_UNUSED,void * extp ATTRIBUTE_UNUSED)1288 mips_ecoff_swap_coff_lineno_out (bfd *abfd ATTRIBUTE_UNUSED,
1289 				 void *inp ATTRIBUTE_UNUSED,
1290 				 void *extp ATTRIBUTE_UNUSED)
1291 {
1292   return 0;
1293 }
1294 
1295 static unsigned int
mips_ecoff_swap_coff_reloc_out(bfd * abfd ATTRIBUTE_UNUSED,void * inp ATTRIBUTE_UNUSED,void * extp ATTRIBUTE_UNUSED)1296 mips_ecoff_swap_coff_reloc_out (bfd *abfd ATTRIBUTE_UNUSED,
1297 				void *inp ATTRIBUTE_UNUSED,
1298 				void *extp ATTRIBUTE_UNUSED)
1299 {
1300   return 0;
1301 }
1302 
1303 /* This is the ECOFF backend structure.  The backend field of the
1304    target vector points to this.  */
1305 
1306 static const struct ecoff_backend_data mips_ecoff_backend_data =
1307 {
1308   /* COFF backend structure.  */
1309   {
1310     mips_ecoff_swap_coff_aux_in, mips_ecoff_swap_coff_sym_in,
1311     mips_ecoff_swap_coff_lineno_in, mips_ecoff_swap_coff_aux_out,
1312     mips_ecoff_swap_coff_sym_out, mips_ecoff_swap_coff_lineno_out,
1313     mips_ecoff_swap_coff_reloc_out,
1314     mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
1315     mips_ecoff_swap_scnhdr_out,
1316     FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, true,
1317     ECOFF_NO_LONG_SECTION_NAMES, 4, false, 2, 32768,
1318     mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
1319     mips_ecoff_swap_scnhdr_in, NULL,
1320     mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
1321     _bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
1322     _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
1323     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1324     NULL, NULL, NULL
1325   },
1326   /* Supported architecture.  */
1327   bfd_arch_mips,
1328   /* Initial portion of armap string.  */
1329   "__________",
1330   /* The page boundary used to align sections in a demand-paged
1331      executable file.  E.g., 0x1000.  */
1332   0x1000,
1333   /* TRUE if the .rdata section is part of the text segment, as on the
1334      Alpha.  FALSE if .rdata is part of the data segment, as on the
1335      MIPS.  */
1336   false,
1337   /* Bitsize of constructor entries.  */
1338   32,
1339   /* Reloc to use for constructor entries.  */
1340   &mips_howto_table[MIPS_R_REFWORD],
1341   {
1342     /* Symbol table magic number.  */
1343     magicSym,
1344     /* Alignment of debugging information.  E.g., 4.  */
1345     4,
1346     /* Sizes of external symbolic information.  */
1347     sizeof (struct hdr_ext),
1348     sizeof (struct dnr_ext),
1349     sizeof (struct pdr_ext),
1350     sizeof (struct sym_ext),
1351     sizeof (struct opt_ext),
1352     sizeof (struct fdr_ext),
1353     sizeof (struct rfd_ext),
1354     sizeof (struct ext_ext),
1355     /* Functions to swap in external symbolic data.  */
1356     ecoff_swap_hdr_in,
1357     ecoff_swap_dnr_in,
1358     ecoff_swap_pdr_in,
1359     ecoff_swap_sym_in,
1360     ecoff_swap_opt_in,
1361     ecoff_swap_fdr_in,
1362     ecoff_swap_rfd_in,
1363     ecoff_swap_ext_in,
1364     _bfd_ecoff_swap_tir_in,
1365     _bfd_ecoff_swap_rndx_in,
1366     /* Functions to swap out external symbolic data.  */
1367     ecoff_swap_hdr_out,
1368     ecoff_swap_dnr_out,
1369     ecoff_swap_pdr_out,
1370     ecoff_swap_sym_out,
1371     ecoff_swap_opt_out,
1372     ecoff_swap_fdr_out,
1373     ecoff_swap_rfd_out,
1374     ecoff_swap_ext_out,
1375     _bfd_ecoff_swap_tir_out,
1376     _bfd_ecoff_swap_rndx_out,
1377     /* Function to read in symbolic data.  */
1378     _bfd_ecoff_slurp_symbolic_info
1379   },
1380   /* External reloc size.  */
1381   RELSZ,
1382   /* Reloc swapping functions.  */
1383   mips_ecoff_swap_reloc_in,
1384   mips_ecoff_swap_reloc_out,
1385   /* Backend reloc tweaking.  */
1386   mips_adjust_reloc_in,
1387   mips_adjust_reloc_out,
1388   /* Relocate section contents while linking.  */
1389   mips_relocate_section,
1390   /* Do final adjustments to filehdr and aouthdr.  */
1391   NULL,
1392   /* Read an element from an archive at a given file position.  */
1393   _bfd_get_elt_at_filepos
1394 };
1395 
1396 /* Looking up a reloc type is MIPS specific.  */
1397 #define _bfd_ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
1398 #define _bfd_ecoff_bfd_reloc_name_lookup mips_bfd_reloc_name_lookup
1399 
1400 /* Getting relocated section contents is generic.  */
1401 #define _bfd_ecoff_bfd_get_relocated_section_contents \
1402   bfd_generic_get_relocated_section_contents
1403 
1404 /* Handling file windows is generic.  */
1405 #define _bfd_ecoff_get_section_contents_in_window \
1406   _bfd_generic_get_section_contents_in_window
1407 
1408 /* Relaxing sections is MIPS specific.  */
1409 #define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
1410 
1411 /* GC of sections is not done.  */
1412 #define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
1413 
1414 /* Input section flags is not implemented.  */
1415 #define _bfd_ecoff_bfd_lookup_section_flags bfd_generic_lookup_section_flags
1416 
1417 /* Merging of sections is not done.  */
1418 #define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections
1419 
1420 #define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section
1421 #define _bfd_ecoff_bfd_group_name bfd_generic_group_name
1422 #define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
1423 #define _bfd_ecoff_section_already_linked \
1424   _bfd_coff_section_already_linked
1425 #define _bfd_ecoff_bfd_define_common_symbol bfd_generic_define_common_symbol
1426 #define _bfd_ecoff_bfd_link_hide_symbol _bfd_generic_link_hide_symbol
1427 #define _bfd_ecoff_bfd_define_start_stop bfd_generic_define_start_stop
1428 #define _bfd_ecoff_set_reloc _bfd_generic_set_reloc
1429 
1430 extern const bfd_target mips_ecoff_be_vec;
1431 
1432 const bfd_target mips_ecoff_le_vec =
1433 {
1434   "ecoff-littlemips",		/* name */
1435   bfd_target_ecoff_flavour,
1436   BFD_ENDIAN_LITTLE,		/* data byte order is little */
1437   BFD_ENDIAN_LITTLE,		/* header byte order is little */
1438 
1439   (HAS_RELOC | EXEC_P		/* object flags */
1440    | HAS_LINENO | HAS_DEBUG
1441    | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1442 
1443   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE
1444    | SEC_DATA | SEC_SMALL_DATA),
1445   0,				/* leading underscore */
1446   ' ',				/* ar_pad_char */
1447   15,				/* ar_max_namelen */
1448   0,				/* match priority.  */
1449   TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
1450   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1451      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1452      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1453   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1454      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1455      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
1456 
1457   {				/* bfd_check_format */
1458     _bfd_dummy_target,
1459     coff_object_p,
1460     bfd_generic_archive_p,
1461     _bfd_dummy_target
1462   },
1463   {				/* bfd_set_format */
1464     _bfd_bool_bfd_false_error,
1465     _bfd_ecoff_mkobject,
1466     _bfd_generic_mkarchive,
1467     _bfd_bool_bfd_false_error
1468   },
1469   {				/* bfd_write_contents */
1470     _bfd_bool_bfd_false_error,
1471     _bfd_ecoff_write_object_contents,
1472     _bfd_write_archive_contents,
1473     _bfd_bool_bfd_false_error
1474   },
1475 
1476   BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
1477   BFD_JUMP_TABLE_COPY (_bfd_ecoff),
1478   BFD_JUMP_TABLE_CORE (_bfd_nocore),
1479   BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
1480   BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
1481   BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
1482   BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
1483   BFD_JUMP_TABLE_LINK (_bfd_ecoff),
1484   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1485 
1486   &mips_ecoff_be_vec,
1487 
1488   &mips_ecoff_backend_data
1489 };
1490 
1491 const bfd_target mips_ecoff_be_vec =
1492 {
1493   "ecoff-bigmips",		/* name */
1494   bfd_target_ecoff_flavour,
1495   BFD_ENDIAN_BIG,		/* data byte order is big */
1496   BFD_ENDIAN_BIG,		/* header byte order is big */
1497 
1498   (HAS_RELOC | EXEC_P		/* object flags */
1499    | HAS_LINENO | HAS_DEBUG
1500    | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1501 
1502   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE
1503    | SEC_DATA | SEC_SMALL_DATA),
1504   0,				/* leading underscore */
1505   ' ',				/* ar_pad_char */
1506   15,				/* ar_max_namelen */
1507   0,				/* match priority.  */
1508   TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
1509   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1510      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1511      bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1512   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1513      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1514      bfd_getb16, bfd_getb_signed_16, bfd_putb16,
1515 
1516   {				/* bfd_check_format */
1517     _bfd_dummy_target,
1518     coff_object_p,
1519     bfd_generic_archive_p,
1520     _bfd_dummy_target
1521   },
1522   {				/* bfd_set_format */
1523     _bfd_bool_bfd_false_error,
1524     _bfd_ecoff_mkobject,
1525     _bfd_generic_mkarchive,
1526     _bfd_bool_bfd_false_error
1527   },
1528   {				/* bfd_write_contents */
1529     _bfd_bool_bfd_false_error,
1530     _bfd_ecoff_write_object_contents,
1531     _bfd_write_archive_contents,
1532     _bfd_bool_bfd_false_error
1533   },
1534 
1535   BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
1536   BFD_JUMP_TABLE_COPY (_bfd_ecoff),
1537   BFD_JUMP_TABLE_CORE (_bfd_nocore),
1538   BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
1539   BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
1540   BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
1541   BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
1542   BFD_JUMP_TABLE_LINK (_bfd_ecoff),
1543   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1544 
1545   &mips_ecoff_le_vec,
1546 
1547   &mips_ecoff_backend_data
1548 };
1549 
1550 const bfd_target mips_ecoff_bele_vec =
1551 {
1552   "ecoff-biglittlemips",		/* name */
1553   bfd_target_ecoff_flavour,
1554   BFD_ENDIAN_LITTLE,		/* data byte order is little */
1555   BFD_ENDIAN_BIG,		/* header byte order is big */
1556 
1557   (HAS_RELOC | EXEC_P		/* object flags */
1558    | HAS_LINENO | HAS_DEBUG
1559    | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1560 
1561   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE
1562    | SEC_DATA | SEC_SMALL_DATA),
1563   0,				/* leading underscore */
1564   ' ',				/* ar_pad_char */
1565   15,				/* ar_max_namelen */
1566   0,				/* match priority.  */
1567   TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
1568   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1569      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1570      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1571   bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1572      bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1573      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
1574 
1575   {				/* bfd_check_format */
1576     _bfd_dummy_target,
1577     coff_object_p,
1578     bfd_generic_archive_p,
1579     _bfd_dummy_target
1580   },
1581   {				/* bfd_set_format */
1582     _bfd_bool_bfd_false_error,
1583     _bfd_ecoff_mkobject,
1584     _bfd_generic_mkarchive,
1585     _bfd_bool_bfd_false_error
1586   },
1587   {				/* bfd_write_contents */
1588     _bfd_bool_bfd_false_error,
1589     _bfd_ecoff_write_object_contents,
1590     _bfd_write_archive_contents,
1591     _bfd_bool_bfd_false_error
1592   },
1593 
1594   BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
1595   BFD_JUMP_TABLE_COPY (_bfd_ecoff),
1596   BFD_JUMP_TABLE_CORE (_bfd_nocore),
1597   BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
1598   BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
1599   BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
1600   BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
1601   BFD_JUMP_TABLE_LINK (_bfd_ecoff),
1602   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1603 
1604   NULL,
1605 
1606   &mips_ecoff_backend_data
1607 };
1608