* elf.c (assign_file_positions_for_segments): Set next_file_pos even
[deliverable/binutils-gdb.git] / bfd / coff-i386.c
index f083ae15a0f134b2ba97f4bff5c2d02794f86b77..65700b6038b201384be878eb30cf14459e095ba6 100644 (file)
@@ -1,6 +1,6 @@
 /* BFD back-end for Intel 386 COFF files.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002
+   2000, 2001, 2002, 2003, 2004
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -56,7 +56,7 @@ static reloc_howto_type *coff_i386_reloc_type_lookup
    section for a reference to a common symbol is the value itself plus
    any desired offset.  Ian Taylor, Cygnus Support.  */
 
-/* If we are producing relocateable output, we need to do some
+/* If we are producing relocatable output, we need to do some
    adjustments to the object file that are not done by the
    bfd_perform_relocation function.  This function is called by every
    reloc type to make any required adjustments.  */
@@ -103,7 +103,7 @@ coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
     {
       /* For some reason bfd_perform_relocation always effectively
         ignores the addend for a COFF target when producing
-        relocateable output.  This seems to be always wrong for 386
+        relocatable output.  This seems to be always wrong for 386
         COFF, so we handle the addend here instead.  */
 #ifdef COFF_WITH_PE
       if (output_bfd == (bfd *) NULL)
@@ -234,7 +234,24 @@ static reloc_howto_type howto_table[] =
   EMPTY_HOWTO (010),
   EMPTY_HOWTO (011),
   EMPTY_HOWTO (012),
+#ifdef COFF_WITH_PE
+  /* 32-bit longword section relative relocation (013).  */
+  HOWTO (R_SECREL32,           /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield, /* complain_on_overflow */
+        coff_i386_reloc,       /* special_function */
+        "secrel32",            /* name */
+        TRUE,                  /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
+        TRUE),                 /* pcrel_offset */
+#else
   EMPTY_HOWTO (013),
+#endif
   EMPTY_HOWTO (014),
   EMPTY_HOWTO (015),
   EMPTY_HOWTO (016),
@@ -386,7 +403,7 @@ static reloc_howto_type howto_table[] =
 
 /* The PE relocate section routine.  The only difference between this
    and the regular routine is that we don't want to do anything for a
-   relocateable link.  */
+   relocatable link.  */
 
 static bfd_boolean coff_pe_i386_relocate_section
   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
@@ -405,7 +422,7 @@ coff_pe_i386_relocate_section (output_bfd, info, input_bfd,
      struct internal_syment *syms;
      asection **sections;
 {
-  if (info->relocateable)
+  if (info->relocatable)
     return TRUE;
 
   return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
@@ -470,7 +487,7 @@ coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
 
 #ifndef COFF_WITH_PE
   /* If the output symbol is common (in which case this must be a
-     relocateable link), we need to add in the final size of the
+     relocatable link), we need to add in the final size of the
      common symbol.  */
   if (h != NULL && h->root.type == bfd_link_hash_common)
     *addendp += h->root.u.c.size;
@@ -497,6 +514,30 @@ coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
     {
       *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
     }
+
+  if (rel->r_type == R_SECREL32)
+    {
+      bfd_vma osect_vma;
+
+      if (h && (h->type == bfd_link_hash_defined
+               || h->type == bfd_link_hash_defweak))
+       osect_vma = h->root.u.def.section->output_section->vma;
+      else
+       {
+         asection *sec;
+         int i;
+
+         /* Sigh, the only way to get the section to offset against
+            is to find it the hard way.  */
+
+         for (sec = abfd->sections, i = 1; i < sym->n_scnum; i++)
+           sec = sec->next;
+
+         osect_vma = sec->output_section->vma;
+       }
+
+      *addendp -= osect_vma;
+    }
 #endif
 
   return howto;
@@ -525,6 +566,10 @@ coff_i386_reloc_type_lookup (abfd, code)
       return howto_table + R_RELBYTE;
     case BFD_RELOC_8_PCREL:
       return howto_table + R_PCRBYTE;
+#ifdef COFF_WITH_PE
+    case BFD_RELOC_32_SECREL:
+      return howto_table + R_SECREL32;
+#endif
     default:
       BFD_FAIL ();
       return 0;
This page took 0.024927 seconds and 4 git commands to generate.