* Many files: Changes to avoid gcc warnings: Add ATTRIBUTE_UNUSED
[deliverable/binutils-gdb.git] / bfd / coff-i386.c
index 04de7514a007c0bba9e2b01c3e0787976944e54a..b3fdc4ad29b014989e1cacbca23781d33f9f0d6c 100644 (file)
@@ -1,5 +1,6 @@
 /* BFD back-end for Intel 386 COFF files.
-   Copyright 1990, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+   Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+   Free Software Foundation, Inc.
    Written by Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -30,6 +31,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "coff/pe.h"
 #endif
 
+#ifdef COFF_GO32_EXE
+#include "coff/go32exe.h"
+#endif
+
 #include "libcoff.h"
 
 static bfd_reloc_status_type coff_i386_reloc 
@@ -61,9 +66,9 @@ coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
      arelent *reloc_entry;
      asymbol *symbol;
      PTR data;
-     asection *input_section;
+     asection *input_section ATTRIBUTE_UNUSED;
      bfd *output_bfd;
-     char **error_message;
+     char **error_message ATTRIBUTE_UNUSED;
 {
   symvalue diff;
 
@@ -72,6 +77,7 @@ coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
 
   if (bfd_is_com_section (symbol->section))
     {
+#ifndef COFF_WITH_PE
       /* We are relocating a common symbol.  The current value in the
         object file is ORIG + OFFSET, where ORIG is the value of the
         common symbol as seen by the object file when it was compiled
@@ -84,6 +90,10 @@ coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
         the common symbol which we are going to put in the final
         object file.  NEW is symbol->value.  */
       diff = symbol->value + reloc_entry->addend;
+#else
+      /* In PE mode, we do not offset the common symbol.  */
+      diff = reloc_entry->addend;
+#endif
     }
   else
     {
@@ -148,7 +158,7 @@ coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
    appear in the output .reloc section. */
 
 static boolean in_reloc_p(abfd, howto)
-     bfd * abfd;
+     bfd * abfd ATTRIBUTE_UNUSED;
      reloc_howto_type *howto;
 {
   return ! howto->pc_relative && howto->type != R_IMAGEBASE;
@@ -161,12 +171,12 @@ static boolean in_reloc_p(abfd, howto)
 
 static reloc_howto_type howto_table[] = 
 {
-  {0},
-  {1},
-  {2},
-  {3},
-  {4},
-  {5},
+  EMPTY_HOWTO (0),
+  EMPTY_HOWTO (1),
+  EMPTY_HOWTO (2),
+  EMPTY_HOWTO (3),
+  EMPTY_HOWTO (4),
+  EMPTY_HOWTO (5),
   HOWTO (R_DIR32,               /* type */                                 
         0,                     /* rightshift */                           
         2,                     /* size (0 = byte, 1 = short, 2 = long) */ 
@@ -194,13 +204,13 @@ static reloc_howto_type howto_table[] =
         0xffffffff,            /* src_mask */                             
         0xffffffff,            /* dst_mask */                             
         false),                /* pcrel_offset */
-  {010},
-  {011},
-  {012},
-  {013},
-  {014},
-  {015},
-  {016},
+  EMPTY_HOWTO (010),
+  EMPTY_HOWTO (011),
+  EMPTY_HOWTO (012),
+  EMPTY_HOWTO (013),
+  EMPTY_HOWTO (014),
+  EMPTY_HOWTO (015),
+  EMPTY_HOWTO (016),
   HOWTO (R_RELBYTE,            /* type */                                 
         0,                     /* rightshift */                           
         0,                     /* size (0 = byte, 1 = short, 2 = long) */ 
@@ -328,12 +338,54 @@ static reloc_howto_type howto_table[] =
       cache_ptr->addend += asect->vma;                         \
   }
 
-/* We use the special COFF backend linker.  */
+/* We use the special COFF backend linker.  For normal i386 COFF, we
+   can use the generic relocate_section routine.  For PE, we need our
+   own routine.  */
+
+#ifndef COFF_WITH_PE
+
 #define coff_relocate_section _bfd_coff_generic_relocate_section
 
+#else /* COFF_WITH_PE */
+
+/* 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.  */
+
+static boolean coff_pe_i386_relocate_section
+  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+          struct internal_reloc *, struct internal_syment *, asection **));
+
+static boolean
+coff_pe_i386_relocate_section (output_bfd, info, input_bfd,
+                              input_section, contents, relocs, syms,
+                              sections)
+     bfd *output_bfd;
+     struct bfd_link_info *info;
+     bfd *input_bfd;
+     asection *input_section;
+     bfd_byte *contents;
+     struct internal_reloc *relocs;
+     struct internal_syment *syms;
+     asection **sections;
+{
+  if (info->relocateable)
+    return true;
+
+  return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
+                                            input_section, contents,
+                                            relocs, syms, sections);
+}
+
+#define coff_relocate_section coff_pe_i386_relocate_section
+
+#endif /* COFF_WITH_PE */
+
+/* Convert an rtype to howto for the COFF backend linker.  */
+
 static reloc_howto_type *
 coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      asection *sec;
      struct internal_reloc *rel;
      struct coff_link_hash_entry *h;
@@ -362,28 +414,40 @@ coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
  
       BFD_ASSERT (h != NULL);
 
-
 #ifndef COFF_WITH_PE
-      /* I think we *do* want to bypass this.  If we don't, I have seen some data
-        parameters get the wrong relcation address.  If I link two versions
-        with and without this section bypassed and then do a binary comparison,
-        the addresses which are different can be looked up in the map.  The 
-        case in which this section has been bypassed has addresses which correspond
-        to values I can find in the map */
+      /* I think we *do* want to bypass this.  If we don't, I have
+        seen some data parameters get the wrong relocation address.
+        If I link two versions with and without this section bypassed
+        and then do a binary comparison, the addresses which are
+        different can be looked up in the map.  The case in which
+        this section has been bypassed has addresses which correspond
+        to values I can find in the map.  */
       *addendp -= sym->n_value;
 #endif
     }
 
+#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
      common symbol.  */
   if (h != NULL && h->root.type == bfd_link_hash_common) 
     *addendp += h->root.u.c.size;
-
+#endif
 
 #ifdef COFF_WITH_PE
   if (howto->pc_relative)
-    *addendp -= 4;
+    {
+      *addendp -= 4;
+
+      /* If the symbol is defined, then the generic code is going to
+         add back the symbol value in order to cancel out an
+         adjustment it made to the addend.  However, we set the addend
+         to 0 at the start of this function.  We need to adjust here,
+         to avoid the adjustment the generic code will make.  FIXME:
+         This is getting a bit hackish.  */
+      if (sym != NULL && sym->n_scnum != 0)
+       *addendp -= sym->n_value;
+    }
 
   if (rel->r_type == R_IMAGEBASE)
     {
@@ -400,7 +464,7 @@ coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
 
 static reloc_howto_type *
 coff_i386_reloc_type_lookup (abfd, code)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      bfd_reloc_code_real_type code;
 {
   switch (code)
@@ -417,9 +481,30 @@ coff_i386_reloc_type_lookup (abfd, code)
     }
 }
 
+#define coff_rtype_to_howto coff_i386_rtype_to_howto
 
+#ifdef TARGET_UNDERSCORE
 
-#define coff_rtype_to_howto coff_i386_rtype_to_howto
+/* If i386 gcc uses underscores for symbol names, then it does not use
+   a leading dot for local labels, so if TARGET_UNDERSCORE is defined
+   we treat all symbols starting with L as local.  */
+
+static boolean coff_i386_is_local_label_name PARAMS ((bfd *, const char *));
+
+static boolean
+coff_i386_is_local_label_name (abfd, name)
+     bfd *abfd;
+     const char *name;
+{
+  if (name[0] == 'L')
+    return true;
+
+  return _bfd_coff_is_local_label_name (abfd, name);
+}
+
+#define coff_bfd_is_local_label_name coff_i386_is_local_label_name
+
+#endif /* TARGET_UNDERSCORE */
 
 #include "coffcode.h"
 
@@ -507,9 +592,11 @@ const bfd_target
    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
 
 #ifndef COFF_WITH_PE
-  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
+   | SEC_CODE | SEC_DATA),
 #else
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
+   | SEC_CODE | SEC_DATA
    | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
 #endif
 
This page took 0.034442 seconds and 4 git commands to generate.