1 /* BFD back-end for MIPS Extended-Coff files.
2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3 Original version by Per Bothner.
4 Full support added by Ian Lance Taylor, ian@cygnus.com.
6 This file is part of BFD, the Binary File Descriptor library.
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 2 of the License, or
11 (at your option) any later version.
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
26 #include "coff/internal.h"
28 #include "coff/symconst.h"
29 #include "coff/ecoff.h"
30 #include "coff/mips.h"
34 /* Prototypes for static functions. */
36 static boolean mips_ecoff_bad_format_hook
PARAMS ((bfd
*abfd
, PTR filehdr
));
37 static void mips_ecoff_swap_reloc_in
PARAMS ((bfd
*, PTR
,
38 struct internal_reloc
*));
39 static void mips_ecoff_swap_reloc_out
PARAMS ((bfd
*,
40 const struct internal_reloc
*,
42 static void mips_adjust_reloc_in
PARAMS ((bfd
*,
43 const struct internal_reloc
*,
45 static void mips_adjust_reloc_out
PARAMS ((bfd
*, const arelent
*,
46 struct internal_reloc
*));
47 static bfd_reloc_status_type mips_generic_reloc
PARAMS ((bfd
*abfd
,
54 static bfd_reloc_status_type mips_refhi_reloc
PARAMS ((bfd
*abfd
,
61 static bfd_reloc_status_type mips_reflo_reloc
PARAMS ((bfd
*abfd
,
68 static bfd_reloc_status_type mips_gprel_reloc
PARAMS ((bfd
*abfd
,
75 static void mips_relocate_refhi
PARAMS ((struct internal_reloc
*refhi
,
76 struct internal_reloc
*reflo
,
78 asection
*input_section
,
81 static boolean mips_relocate_section
PARAMS ((bfd
*, struct bfd_link_info
*,
85 /* ECOFF has COFF sections, but the debugging information is stored in
86 a completely different format. ECOFF targets use some of the
87 swapping routines from coffswap.h, and some of the generic COFF
88 routines in coffgen.c, but, unlike the real COFF targets, do not
89 use coffcode.h itself.
91 Get the generic COFF swapping routines, except for the reloc,
92 symbol, and lineno ones. Give them ECOFF names. */
94 #define NO_COFF_RELOCS
95 #define NO_COFF_SYMBOLS
96 #define NO_COFF_LINENOS
97 #define coff_swap_filehdr_in mips_ecoff_swap_filehdr_in
98 #define coff_swap_filehdr_out mips_ecoff_swap_filehdr_out
99 #define coff_swap_aouthdr_in mips_ecoff_swap_aouthdr_in
100 #define coff_swap_aouthdr_out mips_ecoff_swap_aouthdr_out
101 #define coff_swap_scnhdr_in mips_ecoff_swap_scnhdr_in
102 #define coff_swap_scnhdr_out mips_ecoff_swap_scnhdr_out
103 #include "coffswap.h"
105 /* Get the ECOFF swapping routines. */
107 #include "ecoffswap.h"
109 /* How to process the various relocs types. */
111 static reloc_howto_type mips_howto_table
[] =
113 /* Reloc type 0 is ignored. The reloc reading code ensures that
114 this is a reference to the .abs section, which will cause
115 bfd_perform_relocation to do nothing. */
116 HOWTO (MIPS_R_IGNORE
, /* type */
118 0, /* size (0 = byte, 1 = short, 2 = long) */
120 false, /* pc_relative */
122 complain_overflow_dont
, /* complain_on_overflow */
123 0, /* special_function */
125 false, /* partial_inplace */
128 false), /* pcrel_offset */
130 /* A 16 bit reference to a symbol, normally from a data section. */
131 HOWTO (MIPS_R_REFHALF
, /* type */
133 1, /* size (0 = byte, 1 = short, 2 = long) */
135 false, /* pc_relative */
137 complain_overflow_bitfield
, /* complain_on_overflow */
138 mips_generic_reloc
, /* special_function */
139 "REFHALF", /* name */
140 true, /* partial_inplace */
141 0xffff, /* src_mask */
142 0xffff, /* dst_mask */
143 false), /* pcrel_offset */
145 /* A 32 bit reference to a symbol, normally from a data section. */
146 HOWTO (MIPS_R_REFWORD
, /* type */
148 2, /* size (0 = byte, 1 = short, 2 = long) */
150 false, /* pc_relative */
152 complain_overflow_bitfield
, /* complain_on_overflow */
153 mips_generic_reloc
, /* special_function */
154 "REFWORD", /* name */
155 true, /* partial_inplace */
156 0xffffffff, /* src_mask */
157 0xffffffff, /* dst_mask */
158 false), /* pcrel_offset */
160 /* A 26 bit absolute jump address. */
161 HOWTO (MIPS_R_JMPADDR
, /* type */
163 2, /* size (0 = byte, 1 = short, 2 = long) */
165 false, /* pc_relative */
167 complain_overflow_dont
, /* complain_on_overflow */
168 /* This needs complex overflow
169 detection, because the upper four
170 bits must match the PC. */
171 mips_generic_reloc
, /* special_function */
172 "JMPADDR", /* name */
173 true, /* partial_inplace */
174 0x3ffffff, /* src_mask */
175 0x3ffffff, /* dst_mask */
176 false), /* pcrel_offset */
178 /* The high 16 bits of a symbol value. Handled by the function
180 HOWTO (MIPS_R_REFHI
, /* type */
182 2, /* size (0 = byte, 1 = short, 2 = long) */
184 false, /* pc_relative */
186 complain_overflow_bitfield
, /* complain_on_overflow */
187 mips_refhi_reloc
, /* special_function */
189 true, /* partial_inplace */
190 0xffff, /* src_mask */
191 0xffff, /* dst_mask */
192 false), /* pcrel_offset */
194 /* The low 16 bits of a symbol value. */
195 HOWTO (MIPS_R_REFLO
, /* type */
197 2, /* size (0 = byte, 1 = short, 2 = long) */
199 false, /* pc_relative */
201 complain_overflow_dont
, /* complain_on_overflow */
202 mips_reflo_reloc
, /* special_function */
204 true, /* partial_inplace */
205 0xffff, /* src_mask */
206 0xffff, /* dst_mask */
207 false), /* pcrel_offset */
209 /* A reference to an offset from the gp register. Handled by the
210 function mips_gprel_reloc. */
211 HOWTO (MIPS_R_GPREL
, /* type */
213 2, /* size (0 = byte, 1 = short, 2 = long) */
215 false, /* pc_relative */
217 complain_overflow_signed
, /* complain_on_overflow */
218 mips_gprel_reloc
, /* special_function */
220 true, /* partial_inplace */
221 0xffff, /* src_mask */
222 0xffff, /* dst_mask */
223 false), /* pcrel_offset */
225 /* A reference to a literal using an offset from the gp register.
226 Handled by the function mips_gprel_reloc. */
227 HOWTO (MIPS_R_LITERAL
, /* type */
229 2, /* size (0 = byte, 1 = short, 2 = long) */
231 false, /* pc_relative */
233 complain_overflow_signed
, /* complain_on_overflow */
234 mips_gprel_reloc
, /* special_function */
235 "LITERAL", /* name */
236 true, /* partial_inplace */
237 0xffff, /* src_mask */
238 0xffff, /* dst_mask */
239 false) /* pcrel_offset */
242 #define MIPS_HOWTO_COUNT \
243 (sizeof mips_howto_table / sizeof mips_howto_table[0])
245 /* See whether the magic number matches. */
248 mips_ecoff_bad_format_hook (abfd
, filehdr
)
252 struct internal_filehdr
*internal_f
= (struct internal_filehdr
*) filehdr
;
254 switch (internal_f
->f_magic
)
257 /* I don't know what endianness this implies. */
261 case MIPS_MAGIC_BIG2
:
262 case MIPS_MAGIC_BIG3
:
263 return abfd
->xvec
->byteorder_big_p
;
265 case MIPS_MAGIC_LITTLE
:
266 case MIPS_MAGIC_LITTLE2
:
267 case MIPS_MAGIC_LITTLE3
:
268 return abfd
->xvec
->byteorder_big_p
== false;
275 /* Reloc handling. MIPS ECOFF relocs are packed into 8 bytes in
276 external form. They use a bit which indicates whether the symbol
279 /* Swap a reloc in. */
282 mips_ecoff_swap_reloc_in (abfd
, ext_ptr
, intern
)
285 struct internal_reloc
*intern
;
287 const RELOC
*ext
= (RELOC
*) ext_ptr
;
289 intern
->r_vaddr
= bfd_h_get_32 (abfd
, (bfd_byte
*) ext
->r_vaddr
);
290 if (abfd
->xvec
->header_byteorder_big_p
!= false)
292 intern
->r_symndx
= (((int) ext
->r_bits
[0]
293 << RELOC_BITS0_SYMNDX_SH_LEFT_BIG
)
294 | ((int) ext
->r_bits
[1]
295 << RELOC_BITS1_SYMNDX_SH_LEFT_BIG
)
296 | ((int) ext
->r_bits
[2]
297 << RELOC_BITS2_SYMNDX_SH_LEFT_BIG
));
298 intern
->r_type
= ((ext
->r_bits
[3] & RELOC_BITS3_TYPE_BIG
)
299 >> RELOC_BITS3_TYPE_SH_BIG
);
300 intern
->r_extern
= (ext
->r_bits
[3] & RELOC_BITS3_EXTERN_BIG
) != 0;
304 intern
->r_symndx
= (((int) ext
->r_bits
[0]
305 << RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE
)
306 | ((int) ext
->r_bits
[1]
307 << RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE
)
308 | ((int) ext
->r_bits
[2]
309 << RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE
));
310 intern
->r_type
= ((ext
->r_bits
[3] & RELOC_BITS3_TYPE_LITTLE
)
311 >> RELOC_BITS3_TYPE_SH_LITTLE
);
312 intern
->r_extern
= (ext
->r_bits
[3] & RELOC_BITS3_EXTERN_LITTLE
) != 0;
316 /* Swap a reloc out. */
319 mips_ecoff_swap_reloc_out (abfd
, intern
, dst
)
321 const struct internal_reloc
*intern
;
324 RELOC
*ext
= (RELOC
*) dst
;
326 BFD_ASSERT (intern
->r_extern
327 || (intern
->r_symndx
>= 0 && intern
->r_symndx
<= 12));
329 bfd_h_put_32 (abfd
, intern
->r_vaddr
, (bfd_byte
*) ext
->r_vaddr
);
330 if (abfd
->xvec
->header_byteorder_big_p
!= false)
332 ext
->r_bits
[0] = intern
->r_symndx
>> RELOC_BITS0_SYMNDX_SH_LEFT_BIG
;
333 ext
->r_bits
[1] = intern
->r_symndx
>> RELOC_BITS1_SYMNDX_SH_LEFT_BIG
;
334 ext
->r_bits
[2] = intern
->r_symndx
>> RELOC_BITS2_SYMNDX_SH_LEFT_BIG
;
335 ext
->r_bits
[3] = (((intern
->r_type
<< RELOC_BITS3_TYPE_SH_BIG
)
336 & RELOC_BITS3_TYPE_BIG
)
337 | (intern
->r_extern
? RELOC_BITS3_EXTERN_BIG
: 0));
341 ext
->r_bits
[0] = intern
->r_symndx
>> RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE
;
342 ext
->r_bits
[1] = intern
->r_symndx
>> RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE
;
343 ext
->r_bits
[2] = intern
->r_symndx
>> RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE
;
344 ext
->r_bits
[3] = (((intern
->r_type
<< RELOC_BITS3_TYPE_SH_LITTLE
)
345 & RELOC_BITS3_TYPE_LITTLE
)
346 | (intern
->r_extern
? RELOC_BITS3_EXTERN_LITTLE
: 0));
350 /* Finish canonicalizing a reloc. Part of this is generic to all
351 ECOFF targets, and that part is in ecoff.c. The rest is done in
352 this backend routine. It must fill in the howto field. */
355 mips_adjust_reloc_in (abfd
, intern
, rptr
)
357 const struct internal_reloc
*intern
;
360 if (intern
->r_type
> MIPS_R_LITERAL
)
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
;
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
.symbol_ptr_ptr
;
373 rptr
->howto
= &mips_howto_table
[intern
->r_type
];
376 /* Make any adjustments needed to a reloc before writing it out. None
377 are needed for MIPS. */
380 mips_adjust_reloc_out (abfd
, rel
, intern
)
383 struct internal_reloc
*intern
;
387 /* ECOFF relocs are either against external symbols, or against
388 sections. If we are producing relocateable output, and the reloc
389 is against an external symbol, and nothing has given us any
390 additional addend, the resulting reloc will also be against the
391 same symbol. In such a case, we don't want to change anything
392 about the way the reloc is handled, since it will all be done at
393 final link time. Rather than put special case code into
394 bfd_perform_relocation, all the reloc types use this howto
395 function. It just short circuits the reloc if producing
396 relocateable output against an external symbol. */
398 static bfd_reloc_status_type
399 mips_generic_reloc (abfd
,
407 arelent
*reloc_entry
;
410 asection
*input_section
;
412 char **error_message
;
414 if (output_bfd
!= (bfd
*) NULL
415 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
416 && reloc_entry
->addend
== 0)
418 reloc_entry
->address
+= input_section
->output_offset
;
422 return bfd_reloc_continue
;
425 /* Do a REFHI relocation. This has to be done in combination with a
426 REFLO reloc, because there is a carry from the REFLO to the REFHI.
427 Here we just save the information we need; we do the actual
428 relocation when we see the REFLO. MIPS ECOFF requires that the
429 REFLO immediately follow the REFHI, so this ought to work. */
431 static bfd_byte
*mips_refhi_addr
;
432 static bfd_vma mips_refhi_addend
;
434 static bfd_reloc_status_type
435 mips_refhi_reloc (abfd
,
443 arelent
*reloc_entry
;
446 asection
*input_section
;
448 char **error_message
;
450 bfd_reloc_status_type ret
;
453 /* If we're relocating, and this an external symbol, we don't want
454 to change anything. */
455 if (output_bfd
!= (bfd
*) NULL
456 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
457 && reloc_entry
->addend
== 0)
459 reloc_entry
->address
+= input_section
->output_offset
;
464 if (symbol
->section
== &bfd_und_section
465 && output_bfd
== (bfd
*) NULL
)
466 ret
= bfd_reloc_undefined
;
468 if (bfd_is_com_section (symbol
->section
))
471 relocation
= symbol
->value
;
473 relocation
+= symbol
->section
->output_section
->vma
;
474 relocation
+= symbol
->section
->output_offset
;
475 relocation
+= reloc_entry
->addend
;
477 if (reloc_entry
->address
> input_section
->_cooked_size
)
478 return bfd_reloc_outofrange
;
480 /* Save the information, and let REFLO do the actual relocation. */
481 mips_refhi_addr
= (bfd_byte
*) data
+ reloc_entry
->address
;
482 mips_refhi_addend
= relocation
;
484 if (output_bfd
!= (bfd
*) NULL
)
485 reloc_entry
->address
+= input_section
->output_offset
;
490 /* Do a REFLO relocation. This is a straightforward 16 bit inplace
491 relocation; this function exists in order to do the REFHI
492 relocation described above. */
494 static bfd_reloc_status_type
495 mips_reflo_reloc (abfd
,
503 arelent
*reloc_entry
;
506 asection
*input_section
;
508 char **error_message
;
510 if (mips_refhi_addr
!= (bfd_byte
*) NULL
)
516 /* Do the REFHI relocation. Note that we actually don't need to
517 know anything about the REFLO itself, except where to find
518 the low 16 bits of the addend needed by the REFHI. */
519 insn
= bfd_get_32 (abfd
, mips_refhi_addr
);
520 vallo
= (bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
)
522 val
= ((insn
& 0xffff) << 16) + vallo
;
523 val
+= mips_refhi_addend
;
525 /* The low order 16 bits are always treated as a signed value.
526 Therefore, a negative value in the low order bits requires an
527 adjustment in the high order bits. We need to make this
528 adjustment in two ways: once for the bits we took from the
529 data, and once for the bits we are putting back in to the
531 if ((vallo
& 0x8000) != 0)
533 if ((val
& 0x8000) != 0)
536 insn
= (insn
&~ 0xffff) | ((val
>> 16) & 0xffff);
537 bfd_put_32 (abfd
, insn
, mips_refhi_addr
);
539 mips_refhi_addr
= (bfd_byte
*) NULL
;
542 /* Now do the REFLO reloc in the usual way. */
543 return mips_generic_reloc (abfd
, reloc_entry
, symbol
, data
,
544 input_section
, output_bfd
, error_message
);
547 /* Do a GPREL relocation. This is a 16 bit value which must become
548 the offset from the gp register. */
550 static bfd_reloc_status_type
551 mips_gprel_reloc (abfd
,
559 arelent
*reloc_entry
;
562 asection
*input_section
;
564 char **error_message
;
566 boolean relocateable
;
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
575 if (output_bfd
!= (bfd
*) NULL
576 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
577 && reloc_entry
->addend
== 0)
579 reloc_entry
->address
+= input_section
->output_offset
;
583 if (output_bfd
!= (bfd
*) NULL
)
587 relocateable
= false;
588 output_bfd
= symbol
->section
->output_section
->owner
;
591 if (symbol
->section
== &bfd_und_section
592 && relocateable
== false)
593 return bfd_reloc_undefined
;
595 /* We have to figure out the gp value, so that we can adjust the
596 symbol value correctly. We look up the symbol _gp in the output
597 BFD. If we can't find it, we're stuck. We cache it in the ECOFF
598 target data. We don't need to adjust the symbol value for an
599 external symbol if we are producing relocateable output. */
600 if (ecoff_data (output_bfd
)->gp
== 0
601 && (relocateable
== false
602 || (symbol
->flags
& BSF_SECTION_SYM
) != 0))
604 if (relocateable
!= false)
606 /* Make up a value. */
607 ecoff_data (output_bfd
)->gp
=
608 symbol
->section
->output_section
->vma
+ 0x4000;
616 count
= bfd_get_symcount (output_bfd
);
617 sym
= bfd_get_outsymbols (output_bfd
);
619 if (sym
== (asymbol
**) NULL
)
623 for (i
= 0; i
< count
; i
++, sym
++)
625 register CONST
char *name
;
627 name
= bfd_asymbol_name (*sym
);
628 if (*name
== '_' && strcmp (name
, "_gp") == 0)
630 ecoff_data (output_bfd
)->gp
= bfd_asymbol_value (*sym
);
638 /* Only get the error once. */
639 ecoff_data (output_bfd
)->gp
= 4;
641 (char *) "GP relative relocation when _gp not defined";
642 return bfd_reloc_dangerous
;
647 if (bfd_is_com_section (symbol
->section
))
650 relocation
= symbol
->value
;
652 relocation
+= symbol
->section
->output_section
->vma
;
653 relocation
+= symbol
->section
->output_offset
;
655 if (reloc_entry
->address
> input_section
->_cooked_size
)
656 return bfd_reloc_outofrange
;
658 insn
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
);
660 /* Set val to the offset into the section or symbol. */
661 val
= ((insn
& 0xffff) + reloc_entry
->addend
) & 0xffff;
665 /* Adjust val for the final section location and GP value. If we
666 are producing relocateable output, we don't want to do this for
667 an external symbol. */
668 if (relocateable
== false
669 || (symbol
->flags
& BSF_SECTION_SYM
) != 0)
670 val
+= relocation
- ecoff_data (output_bfd
)->gp
;
672 insn
= (insn
&~ 0xffff) | (val
& 0xffff);
673 bfd_put_32 (abfd
, insn
, (bfd_byte
*) data
+ reloc_entry
->address
);
675 if (relocateable
!= false)
676 reloc_entry
->address
+= input_section
->output_offset
;
678 /* Make sure it fit in 16 bits. */
679 if (val
>= 0x8000 && val
< 0xffff8000)
680 return bfd_reloc_overflow
;
685 /* Get the howto structure for a generic reloc type. */
687 static CONST
struct reloc_howto_struct
*
688 mips_bfd_reloc_type_lookup (abfd
, code
)
690 bfd_reloc_code_real_type code
;
697 mips_type
= MIPS_R_REFHALF
;
701 mips_type
= MIPS_R_REFWORD
;
703 case BFD_RELOC_MIPS_JMP
:
704 mips_type
= MIPS_R_JMPADDR
;
706 case BFD_RELOC_HI16_S
:
707 mips_type
= MIPS_R_REFHI
;
710 mips_type
= MIPS_R_REFLO
;
712 case BFD_RELOC_MIPS_GPREL
:
713 mips_type
= MIPS_R_GPREL
;
715 case BFD_RELOC_MIPS_LITERAL
:
716 mips_type
= MIPS_R_LITERAL
;
719 return (CONST
struct reloc_howto_struct
*) NULL
;
722 return &mips_howto_table
[mips_type
];
725 /* A helper routine for mips_relocate_section which handles the REFHI
726 relocation. The REFHI relocation must be followed by a REFLO
727 relocation, and the addend used is formed from the addends of both
731 mips_relocate_refhi (refhi
, reflo
, input_bfd
, input_section
, contents
,
733 struct internal_reloc
*refhi
;
734 struct internal_reloc
*reflo
;
736 asection
*input_section
;
744 insn
= bfd_get_32 (input_bfd
,
745 contents
+ refhi
->r_vaddr
- input_section
->vma
);
746 vallo
= (bfd_get_32 (input_bfd
,
747 contents
+ reflo
->r_vaddr
- input_section
->vma
)
749 val
= ((insn
& 0xffff) << 16) + vallo
;
752 /* The low order 16 bits are always treated as a signed value.
753 Therefore, a negative value in the low order bits requires an
754 adjustment in the high order bits. We need to make this
755 adjustment in two ways: once for the bits we took from the data,
756 and once for the bits we are putting back in to the data. */
757 if ((vallo
& 0x8000) != 0)
759 if ((val
& 0x8000) != 0)
762 insn
= (insn
&~ 0xffff) | ((val
>> 16) & 0xffff);
763 bfd_put_32 (input_bfd
, (bfd_vma
) insn
,
764 contents
+ refhi
->r_vaddr
- input_section
->vma
);
767 /* Relocate a section while linking a MIPS ECOFF file. */
770 mips_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
771 contents
, external_relocs
)
773 struct bfd_link_info
*info
;
775 asection
*input_section
;
779 asection
**symndx_to_section
;
780 struct ecoff_link_hash_entry
**sym_hashes
;
782 boolean gp_undefined
;
783 struct external_reloc
*ext_rel
;
784 struct external_reloc
*ext_rel_end
;
787 BFD_ASSERT (input_bfd
->xvec
->header_byteorder_big_p
788 == output_bfd
->xvec
->header_byteorder_big_p
);
790 /* We keep a table mapping the symndx found in an internal reloc to
791 the appropriate section. This is faster than looking up the
792 section by name each time. */
793 symndx_to_section
= ecoff_data (input_bfd
)->symndx_to_section
;
794 if (symndx_to_section
== (asection
**) NULL
)
796 symndx_to_section
= ((asection
**)
797 bfd_alloc (input_bfd
,
799 * sizeof (asection
*))));
800 if (!symndx_to_section
)
802 bfd_set_error (bfd_error_no_memory
);
806 symndx_to_section
[RELOC_SECTION_NONE
] = NULL
;
807 symndx_to_section
[RELOC_SECTION_TEXT
] =
808 bfd_get_section_by_name (input_bfd
, ".text");
809 symndx_to_section
[RELOC_SECTION_RDATA
] =
810 bfd_get_section_by_name (input_bfd
, ".rdata");
811 symndx_to_section
[RELOC_SECTION_DATA
] =
812 bfd_get_section_by_name (input_bfd
, ".data");
813 symndx_to_section
[RELOC_SECTION_SDATA
] =
814 bfd_get_section_by_name (input_bfd
, ".sdata");
815 symndx_to_section
[RELOC_SECTION_SBSS
] =
816 bfd_get_section_by_name (input_bfd
, ".sbss");
817 symndx_to_section
[RELOC_SECTION_BSS
] =
818 bfd_get_section_by_name (input_bfd
, ".bss");
819 symndx_to_section
[RELOC_SECTION_INIT
] =
820 bfd_get_section_by_name (input_bfd
, ".init");
821 symndx_to_section
[RELOC_SECTION_LIT8
] =
822 bfd_get_section_by_name (input_bfd
, ".lit8");
823 symndx_to_section
[RELOC_SECTION_LIT4
] =
824 bfd_get_section_by_name (input_bfd
, ".lit4");
825 symndx_to_section
[RELOC_SECTION_XDATA
] = NULL
;
826 symndx_to_section
[RELOC_SECTION_PDATA
] = NULL
;
827 symndx_to_section
[RELOC_SECTION_FINI
] =
828 bfd_get_section_by_name (input_bfd
, ".fini");
829 symndx_to_section
[RELOC_SECTION_LITA
] = NULL
;
830 symndx_to_section
[RELOC_SECTION_ABS
] = NULL
;
832 ecoff_data (input_bfd
)->symndx_to_section
= symndx_to_section
;
835 sym_hashes
= ecoff_data (input_bfd
)->sym_hashes
;
837 gp
= ecoff_data (output_bfd
)->gp
;
841 gp_undefined
= false;
845 ext_rel
= (struct external_reloc
*) external_relocs
;
846 ext_rel_end
= ext_rel
+ input_section
->reloc_count
;
847 for (; ext_rel
< ext_rel_end
; ext_rel
++)
849 struct internal_reloc int_rel
;
850 struct internal_reloc reflo_int_rel
;
852 reloc_howto_type
*howto
;
853 struct ecoff_link_hash_entry
*h
= NULL
;
856 bfd_reloc_status_type r
;
859 mips_ecoff_swap_reloc_in (input_bfd
, (PTR
) ext_rel
, &int_rel
);
862 int_rel
= reflo_int_rel
;
866 BFD_ASSERT (int_rel
.r_type
867 < sizeof mips_howto_table
/ sizeof mips_howto_table
[0]);
869 /* The REFHI reloc requires special handling. It must be
870 followed by a REFLO reloc, and the addend is formed from both
872 if (int_rel
.r_type
== MIPS_R_REFHI
)
874 BFD_ASSERT ((ext_rel
+ 1) < ext_rel_end
);
875 mips_ecoff_swap_reloc_in (input_bfd
, (PTR
) (ext_rel
+ 1),
877 BFD_ASSERT (reflo_int_rel
.r_type
== MIPS_R_REFLO
878 && int_rel
.r_extern
== reflo_int_rel
.r_extern
879 && int_rel
.r_symndx
== reflo_int_rel
.r_symndx
);
883 howto
= &mips_howto_table
[int_rel
.r_type
];
885 if (int_rel
.r_extern
)
887 h
= sym_hashes
[int_rel
.r_symndx
];
888 /* If h is NULL, that means that there is a reloc against an
889 external symbol which we thought was just a debugging
890 symbol. This should not happen. */
891 if (h
== (struct ecoff_link_hash_entry
*) NULL
)
896 if (int_rel
.r_symndx
< 0 || int_rel
.r_symndx
>= NUM_RELOC_SECTIONS
)
899 s
= symndx_to_section
[int_rel
.r_symndx
];
901 if (s
== (asection
*) NULL
)
905 /* The GPREL reloc uses an addend: the difference in the GP
907 if (int_rel
.r_type
!= MIPS_R_GPREL
908 && int_rel
.r_type
!= MIPS_R_LITERAL
)
914 if (! ((*info
->callbacks
->reloc_dangerous
)
915 (info
, "GP relative relocation when GP not defined",
916 input_bfd
, input_section
,
917 int_rel
.r_vaddr
- input_section
->vma
)))
919 /* Only give the error once per link. */
920 ecoff_data (output_bfd
)->gp
= gp
= 4;
921 gp_undefined
= false;
923 if (! int_rel
.r_extern
)
925 /* This is a relocation against a section. The current
926 addend in the instruction is the difference between
927 INPUT_SECTION->vma and the GP value of INPUT_BFD. We
928 must change this to be the difference between the
929 final definition (which will end up in RELOCATION)
930 and the GP value of OUTPUT_BFD (which is in GP). */
931 addend
= ecoff_data (input_bfd
)->gp
- gp
;
933 else if (! info
->relocateable
934 || h
->root
.type
== bfd_link_hash_defined
)
936 /* This is a relocation against an undefined or common
937 symbol. The current addend in the instruction is
938 simply the desired offset into the symbol (normally
939 zero). We are going to change this into a relocation
940 against a defined symbol, so we want the instruction
941 to hold the difference between the final definition
942 of the symbol (which will end up in RELOCATION) and
943 the GP value of OUTPUT_BFD (which is in GP). */
948 /* This is a relocation against an undefined or common
949 symbol. The current addend in the instruction is
950 simply the desired offset into the symbol (normally
951 zero). We are generating relocateable output, and we
952 aren't going to define this symbol, so we just leave
953 the instruction alone. */
958 if (info
->relocateable
)
960 /* We are generating relocateable output, and must convert
961 the existing reloc. */
962 if (int_rel
.r_extern
)
964 if (h
->root
.type
== bfd_link_hash_defined
)
969 /* This symbol is defined in the output. Convert
970 the reloc from being against the symbol to being
971 against the section. */
973 /* Clear the r_extern bit. */
974 int_rel
.r_extern
= 0;
976 /* Compute a new r_symndx value. */
977 hsec
= h
->root
.u
.def
.section
;
978 name
= bfd_get_section_name (output_bfd
,
979 hsec
->output_section
);
981 int_rel
.r_symndx
= -1;
985 if (strcmp (name
, ".bss") == 0)
986 int_rel
.r_symndx
= RELOC_SECTION_BSS
;
989 if (strcmp (name
, ".data") == 0)
990 int_rel
.r_symndx
= RELOC_SECTION_DATA
;
993 if (strcmp (name
, ".fini") == 0)
994 int_rel
.r_symndx
= RELOC_SECTION_FINI
;
997 if (strcmp (name
, ".init") == 0)
998 int_rel
.r_symndx
= RELOC_SECTION_INIT
;
1001 if (strcmp (name
, ".lit8") == 0)
1002 int_rel
.r_symndx
= RELOC_SECTION_LIT8
;
1003 else if (strcmp (name
, ".lit4") == 0)
1004 int_rel
.r_symndx
= RELOC_SECTION_LIT4
;
1007 if (strcmp (name
, ".rdata") == 0)
1008 int_rel
.r_symndx
= RELOC_SECTION_RDATA
;
1011 if (strcmp (name
, ".sdata") == 0)
1012 int_rel
.r_symndx
= RELOC_SECTION_SDATA
;
1013 else if (strcmp (name
, ".sbss") == 0)
1014 int_rel
.r_symndx
= RELOC_SECTION_SBSS
;
1017 if (strcmp (name
, ".text") == 0)
1018 int_rel
.r_symndx
= RELOC_SECTION_TEXT
;
1022 if (int_rel
.r_symndx
== -1)
1025 /* Add the section VMA and the symbol value. */
1026 relocation
= (h
->root
.u
.def
.value
1027 + hsec
->output_section
->vma
1028 + hsec
->output_offset
);
1032 /* Change the symndx value to the right one for the
1034 int_rel
.r_symndx
= h
->indx
;
1035 if (int_rel
.r_symndx
== -1)
1037 /* This symbol is not being written out. */
1038 if (! ((*info
->callbacks
->unattached_reloc
)
1039 (info
, h
->root
.root
.string
, input_bfd
,
1041 int_rel
.r_vaddr
- input_section
->vma
)))
1043 int_rel
.r_symndx
= 0;
1050 /* This is a relocation against a section. Adjust the
1051 value by the amount the section moved. */
1052 relocation
= (s
->output_section
->vma
1057 relocation
+= addend
;
1059 /* Adjust the contents. */
1060 if (relocation
== 0)
1064 if (int_rel
.r_type
!= MIPS_R_REFHI
)
1065 r
= _bfd_relocate_contents (howto
, input_bfd
, relocation
,
1068 - input_section
->vma
));
1071 mips_relocate_refhi (&int_rel
, &reflo_int_rel
,
1072 input_bfd
, input_section
, contents
,
1078 /* Adjust the reloc address. */
1079 int_rel
.r_vaddr
+= (input_section
->output_section
->vma
1080 + input_section
->output_offset
1081 - input_section
->vma
);
1083 /* Save the changed reloc information. */
1084 mips_ecoff_swap_reloc_out (input_bfd
, &int_rel
, (PTR
) ext_rel
);
1088 /* We are producing a final executable. */
1089 if (int_rel
.r_extern
)
1091 /* This is a reloc against a symbol. */
1092 if (h
->root
.type
== bfd_link_hash_defined
)
1096 hsec
= h
->root
.u
.def
.section
;
1097 relocation
= (h
->root
.u
.def
.value
1098 + hsec
->output_section
->vma
1099 + hsec
->output_offset
);
1103 if (! ((*info
->callbacks
->undefined_symbol
)
1104 (info
, h
->root
.root
.string
, input_bfd
,
1106 int_rel
.r_vaddr
- input_section
->vma
)))
1113 /* This is a reloc against a section. */
1114 relocation
= (s
->output_section
->vma
1118 /* Adjust a PC relative relocation by removing the
1119 reference to the original source section. */
1120 if (howto
->pc_relative
)
1121 relocation
+= input_section
->vma
;
1124 if (int_rel
.r_type
!= MIPS_R_REFHI
)
1125 r
= _bfd_final_link_relocate (howto
,
1129 int_rel
.r_vaddr
- input_section
->vma
,
1134 mips_relocate_refhi (&int_rel
, &reflo_int_rel
, input_bfd
,
1135 input_section
, contents
, relocation
);
1140 if (r
!= bfd_reloc_ok
)
1145 case bfd_reloc_outofrange
:
1147 case bfd_reloc_overflow
:
1151 if (int_rel
.r_extern
)
1152 name
= h
->root
.root
.string
;
1154 name
= bfd_section_name (input_bfd
, s
);
1155 if (! ((*info
->callbacks
->reloc_overflow
)
1156 (info
, name
, howto
->name
, (bfd_vma
) 0,
1157 input_bfd
, input_section
,
1158 int_rel
.r_vaddr
- input_section
->vma
)))
1169 /* This is the ECOFF backend structure. The backend field of the
1170 target vector points to this. */
1172 static const struct ecoff_backend_data mips_ecoff_backend_data
=
1174 /* COFF backend structure. */
1176 (void (*) PARAMS ((bfd
*,PTR
,int,int,int,int,PTR
))) bfd_void
, /* aux_in */
1177 (void (*) PARAMS ((bfd
*,PTR
,PTR
))) bfd_void
, /* sym_in */
1178 (void (*) PARAMS ((bfd
*,PTR
,PTR
))) bfd_void
, /* lineno_in */
1179 (unsigned (*) PARAMS ((bfd
*,PTR
,int,int,int,int,PTR
)))bfd_void
,/*aux_out*/
1180 (unsigned (*) PARAMS ((bfd
*,PTR
,PTR
))) bfd_void
, /* sym_out */
1181 (unsigned (*) PARAMS ((bfd
*,PTR
,PTR
))) bfd_void
, /* lineno_out */
1182 (unsigned (*) PARAMS ((bfd
*,PTR
,PTR
))) bfd_void
, /* reloc_out */
1183 mips_ecoff_swap_filehdr_out
, mips_ecoff_swap_aouthdr_out
,
1184 mips_ecoff_swap_scnhdr_out
,
1185 FILHSZ
, AOUTSZ
, SCNHSZ
, 0, 0, 0, true,
1186 mips_ecoff_swap_filehdr_in
, mips_ecoff_swap_aouthdr_in
,
1187 mips_ecoff_swap_scnhdr_in
, mips_ecoff_bad_format_hook
,
1188 ecoff_set_arch_mach_hook
, ecoff_mkobject_hook
,
1189 ecoff_styp_to_sec_flags
, ecoff_make_section_hook
, ecoff_set_alignment_hook
,
1190 ecoff_slurp_symbol_table
, NULL
, NULL
1192 /* Supported architecture. */
1194 /* Initial portion of armap string. */
1196 /* The page boundary used to align sections in a demand-paged
1197 executable file. E.g., 0x1000. */
1199 /* True if the .rdata section is part of the text segment, as on the
1200 Alpha. False if .rdata is part of the data segment, as on the
1203 /* Bitsize of constructor entries. */
1205 /* Reloc to use for constructor entries. */
1206 &mips_howto_table
[MIPS_R_REFWORD
],
1208 /* Symbol table magic number. */
1210 /* Alignment of debugging information. E.g., 4. */
1212 /* Sizes of external symbolic information. */
1213 sizeof (struct hdr_ext
),
1214 sizeof (struct dnr_ext
),
1215 sizeof (struct pdr_ext
),
1216 sizeof (struct sym_ext
),
1217 sizeof (struct opt_ext
),
1218 sizeof (struct fdr_ext
),
1219 sizeof (struct rfd_ext
),
1220 sizeof (struct ext_ext
),
1221 /* Functions to swap in external symbolic data. */
1230 /* Functions to swap out external symbolic data. */
1240 /* External reloc size. */
1242 /* Reloc swapping functions. */
1243 mips_ecoff_swap_reloc_in
,
1244 mips_ecoff_swap_reloc_out
,
1245 /* Backend reloc tweaking. */
1246 mips_adjust_reloc_in
,
1247 mips_adjust_reloc_out
,
1248 /* Relocate section contents while linking. */
1249 mips_relocate_section
1252 /* Looking up a reloc type is MIPS specific. */
1253 #define ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
1255 /* Getting relocated section contents is generic. */
1256 #define ecoff_bfd_get_relocated_section_contents \
1257 bfd_generic_get_relocated_section_contents
1259 /* Core file support is usually traditional (but note that Irix uses
1261 #define ecoff_core_file_p _bfd_dummy_target
1262 #define ecoff_core_file_failing_command _bfd_dummy_core_file_failing_command
1263 #define ecoff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
1264 #define ecoff_core_file_matches_executable_p \
1265 _bfd_dummy_core_file_matches_executable_p
1267 bfd_target ecoff_little_vec
=
1269 "ecoff-littlemips", /* name */
1270 bfd_target_ecoff_flavour
,
1271 false, /* data byte order is little */
1272 false, /* header byte order is little */
1274 (HAS_RELOC
| EXEC_P
| /* object flags */
1275 HAS_LINENO
| HAS_DEBUG
|
1276 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| D_PAGED
),
1278 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* sect
1280 0, /* leading underscore */
1281 ' ', /* ar_pad_char */
1282 15, /* ar_max_namelen */
1283 4, /* minimum alignment power */
1284 bfd_getl64
, bfd_getl_signed_64
, bfd_putl64
,
1285 bfd_getl32
, bfd_getl_signed_32
, bfd_putl32
,
1286 bfd_getl16
, bfd_getl_signed_16
, bfd_putl16
, /* data */
1287 bfd_getl64
, bfd_getl_signed_64
, bfd_putl64
,
1288 bfd_getl32
, bfd_getl_signed_32
, bfd_putl32
,
1289 bfd_getl16
, bfd_getl_signed_16
, bfd_putl16
, /* hdrs */
1291 {_bfd_dummy_target
, coff_object_p
, /* bfd_check_format */
1292 ecoff_archive_p
, _bfd_dummy_target
},
1293 {bfd_false
, ecoff_mkobject
, /* bfd_set_format */
1294 _bfd_generic_mkarchive
, bfd_false
},
1295 {bfd_false
, ecoff_write_object_contents
, /* bfd_write_contents */
1296 _bfd_write_archive_contents
, bfd_false
},
1298 (PTR
) &mips_ecoff_backend_data
1301 bfd_target ecoff_big_vec
=
1303 "ecoff-bigmips", /* name */
1304 bfd_target_ecoff_flavour
,
1305 true, /* data byte order is big */
1306 true, /* header byte order is big */
1308 (HAS_RELOC
| EXEC_P
| /* object flags */
1309 HAS_LINENO
| HAS_DEBUG
|
1310 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| D_PAGED
),
1312 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* sect flags */
1313 0, /* leading underscore */
1314 ' ', /* ar_pad_char */
1315 15, /* ar_max_namelen */
1316 4, /* minimum alignment power */
1317 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
1318 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
1319 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
,
1320 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
1321 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
1322 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
,
1323 {_bfd_dummy_target
, coff_object_p
, /* bfd_check_format */
1324 ecoff_archive_p
, ecoff_core_file_p
},
1325 {bfd_false
, ecoff_mkobject
, /* bfd_set_format */
1326 _bfd_generic_mkarchive
, bfd_false
},
1327 {bfd_false
, ecoff_write_object_contents
, /* bfd_write_contents */
1328 _bfd_write_archive_contents
, bfd_false
},
1330 (PTR
) &mips_ecoff_backend_data
1331 /* Note that there is another bfd_target just above this one. If
1332 you are adding initializers here, you should be adding them there