2000-12-14 Kazu Hirata <kazu@hxi.com>
[deliverable/binutils-gdb.git] / bfd / coff-i386.c
index c5afe656f1ad97cb8ae22bf0747139b46853e38d..83d67c4a87586597d7befd1b1e2231c4387b8878 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD back-end for Intel 386 COFF files.
-   Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+   Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -45,7 +45,6 @@ static reloc_howto_type *coff_i386_rtype_to_howto
           bfd_vma *));
 static reloc_howto_type *coff_i386_reloc_type_lookup
   PARAMS ((bfd *, bfd_reloc_code_real_type));
-static const bfd_target *i3coff_object_p PARAMS ((bfd *));
 
 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
 /* The page size is a guess based on ELF.  */
@@ -74,8 +73,10 @@ coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
 {
   symvalue diff;
 
+#ifndef COFF_WITH_PE
   if (output_bfd == (bfd *) NULL)
     return bfd_reloc_continue;
+#endif
 
   if (bfd_is_com_section (symbol->section))
     {
@@ -103,7 +104,26 @@ coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
         ignores the addend for a COFF target when producing
         relocateable output.  This seems to be always wrong for 386
         COFF, so we handle the addend here instead.  */
-      diff = reloc_entry->addend;
+#ifdef COFF_WITH_PE
+      if (output_bfd == (bfd *) NULL)
+       {
+         reloc_howto_type *howto = reloc_entry->howto;
+
+         /* Although PC relative relocations are very similar between
+            PE and non-PE formats, but they are off by 1 << howto->size
+            bytes. For the external relocation, PE is very different
+            from others. See md_apply_fix3 () in gas/config/tc-i386.c.
+            When we link PE and non-PE object files together to
+            generate a non-PE executable, we have to compensate it
+            here.  */
+         if (howto->pc_relative == true && howto->pcrel_offset == true)
+           diff = -(1 << howto->size);
+         else
+           diff = -reloc_entry->addend;
+       }
+      else
+#endif
+       diff = reloc_entry->addend;
     }
 
 #ifdef COFF_WITH_PE
@@ -156,19 +176,17 @@ coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
 }
 
 #ifdef COFF_WITH_PE
-
 /* Return true if this relocation should appear in the output .reloc
    section.  */
 
 static boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *));
 
 static boolean in_reloc_p (abfd, howto)
-     bfd *abfd ATTRIBUTE_UNUSED;
+     bfd * abfd ATTRIBUTE_UNUSED;
      reloc_howto_type *howto;
 {
   return ! howto->pc_relative && howto->type != R_IMAGEBASE;
 }
-
 #endif /* COFF_WITH_PE */
 
 #ifndef PCRELOFFSET
@@ -576,7 +594,7 @@ const bfd_target
      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
 
-/* Note that we allow an object file to be treated as a core file as well. */
+/* Note that we allow an object file to be treated as a core file as well.  */
     {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
        bfd_generic_archive_p, coff_object_p},
     {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
This page took 0.026079 seconds and 4 git commands to generate.