Automatic date update in version.in
[deliverable/binutils-gdb.git] / bfd / coff-i386.c
index 30c81885d4caa775a320eab567166b6421884905..803c28fcafcf04faa67a031b80eac5d282249902 100644 (file)
@@ -1,7 +1,5 @@
 /* BFD back-end for Intel 386 COFF files.
 /* BFD back-end for Intel 386 COFF files.
-   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2007, 2008
-   Free Software Foundation, Inc.
+   Copyright (C) 1990-2016 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
    Written by Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
 
 #include "libcoff.h"
 
 
 #include "libcoff.h"
 
-static bfd_reloc_status_type coff_i386_reloc
-  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
 static reloc_howto_type *coff_i386_rtype_to_howto
 static reloc_howto_type *coff_i386_rtype_to_howto
-  PARAMS ((bfd *, asection *, struct internal_reloc *,
-          struct coff_link_hash_entry *, struct internal_syment *,
-          bfd_vma *));
+  (bfd *, asection *, struct internal_reloc *,
+   struct coff_link_hash_entry *, struct internal_syment *,
+   bfd_vma *);
 static reloc_howto_type *coff_i386_reloc_type_lookup
 static reloc_howto_type *coff_i386_reloc_type_lookup
-  PARAMS ((bfd *, bfd_reloc_code_real_type));
+  (bfd *, bfd_reloc_code_real_type);
 
 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
 /* The page size is a guess based on ELF.  */
 
 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
 /* The page size is a guess based on ELF.  */
@@ -67,15 +63,13 @@ static reloc_howto_type *coff_i386_reloc_type_lookup
    reloc type to make any required adjustments.  */
 
 static bfd_reloc_status_type
    reloc type to make any required adjustments.  */
 
 static bfd_reloc_status_type
-coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
-                error_message)
-     bfd *abfd;
-     arelent *reloc_entry;
-     asymbol *symbol;
-     PTR data;
-     asection *input_section ATTRIBUTE_UNUSED;
-     bfd *output_bfd;
-     char **error_message ATTRIBUTE_UNUSED;
+coff_i386_reloc (bfd *abfd,
+                arelent *reloc_entry,
+                asymbol *symbol,
+                void * data,
+                asection *input_section ATTRIBUTE_UNUSED,
+                bfd *output_bfd,
+                char **error_message ATTRIBUTE_UNUSED)
 {
   symvalue diff;
 
 {
   symvalue diff;
 
@@ -145,41 +139,41 @@ coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
 #define DOIT(x) \
   x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
 
 #define DOIT(x) \
   x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
 
-    if (diff != 0)
-      {
-       reloc_howto_type *howto = reloc_entry->howto;
-       unsigned char *addr = (unsigned char *) data + reloc_entry->address;
+  if (diff != 0)
+    {
+      reloc_howto_type *howto = reloc_entry->howto;
+      unsigned char *addr = (unsigned char *) data + reloc_entry->address;
+
+      switch (howto->size)
+       {
+       case 0:
+         {
+           char x = bfd_get_8 (abfd, addr);
+           DOIT (x);
+           bfd_put_8 (abfd, x, addr);
+         }
+         break;
 
 
-       switch (howto->size)
+       case 1:
          {
          {
-         case 0:
-           {
-             char x = bfd_get_8 (abfd, addr);
-             DOIT (x);
-             bfd_put_8 (abfd, x, addr);
-           }
-           break;
-
-         case 1:
-           {
-             short x = bfd_get_16 (abfd, addr);
-             DOIT (x);
-             bfd_put_16 (abfd, (bfd_vma) x, addr);
-           }
-           break;
-
-         case 2:
-           {
-             long x = bfd_get_32 (abfd, addr);
-             DOIT (x);
-             bfd_put_32 (abfd, (bfd_vma) x, addr);
-           }
-           break;
-
-         default:
-           abort ();
+           short x = bfd_get_16 (abfd, addr);
+           DOIT (x);
+           bfd_put_16 (abfd, (bfd_vma) x, addr);
          }
          }
-      }
+         break;
+
+       case 2:
+         {
+           long x = bfd_get_32 (abfd, addr);
+           DOIT (x);
+           bfd_put_32 (abfd, (bfd_vma) x, addr);
+         }
+         break;
+
+       default:
+         abort ();
+       }
+    }
 
   /* Now let bfd_perform_relocation finish everything up.  */
   return bfd_reloc_continue;
 
   /* Now let bfd_perform_relocation finish everything up.  */
   return bfd_reloc_continue;
@@ -189,13 +183,11 @@ coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
 /* Return TRUE if this relocation should appear in the output .reloc
    section.  */
 
 /* Return TRUE if this relocation should appear in the output .reloc
    section.  */
 
-static bfd_boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *));
-
-static bfd_boolean in_reloc_p (abfd, howto)
-     bfd * abfd ATTRIBUTE_UNUSED;
-     reloc_howto_type *howto;
+static bfd_boolean in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED,
+                              reloc_howto_type *howto)
 {
 {
-  return ! howto->pc_relative && howto->type != R_IMAGEBASE;
+  return ! howto->pc_relative && howto->type != R_IMAGEBASE
+        && howto->type != R_SECREL32;
 }
 #endif /* COFF_WITH_PE */
 
 }
 #endif /* COFF_WITH_PE */
 
@@ -348,16 +340,18 @@ static reloc_howto_type howto_table[] =
         PCRELOFFSET)           /* pcrel_offset */
 };
 
         PCRELOFFSET)           /* pcrel_offset */
 };
 
+#define NUM_HOWTOS (sizeof (howto_table) / sizeof (howto_table[0]))
+
 /* Turn a howto into a reloc  nunmber */
 
 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
 #define BADMAG(x) I386BADMAG(x)
 #define I386 1                 /* Customize coffcode.h */
 
 /* Turn a howto into a reloc  nunmber */
 
 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
 #define BADMAG(x) I386BADMAG(x)
 #define I386 1                 /* Customize coffcode.h */
 
-#define RTYPE2HOWTO(cache_ptr, dst)                                    \
-  ((cache_ptr)->howto =                                                        \
-   ((dst)->r_type < sizeof (howto_table) / sizeof (howto_table[0])     \
-    ? howto_table + (dst)->r_type                                      \
+#define RTYPE2HOWTO(cache_ptr, dst)                            \
+  ((cache_ptr)->howto =                                                \
+   ((dst)->r_type < NUM_HOWTOS                                 \
+    ? howto_table + (dst)->r_type                              \
     : NULL))
 
 /* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
     : NULL))
 
 /* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
@@ -385,7 +379,7 @@ static reloc_howto_type howto_table[] =
       coffsym = (obj_symbols (abfd)                            \
                 + (cache_ptr->sym_ptr_ptr - symbols));         \
     else if (ptr)                                              \
       coffsym = (obj_symbols (abfd)                            \
                 + (cache_ptr->sym_ptr_ptr - symbols));         \
     else if (ptr)                                              \
-      coffsym = coff_symbol_from (abfd, ptr);                  \
+      coffsym = coff_symbol_from (ptr);                                \
     if (coffsym != (coff_symbol_type *) NULL                   \
        && coffsym->native->u.syment.n_scnum == 0)              \
       cache_ptr->addend = - coffsym->native->u.syment.n_value; \
     if (coffsym != (coff_symbol_type *) NULL                   \
        && coffsym->native->u.syment.n_scnum == 0)              \
       cache_ptr->addend = - coffsym->native->u.syment.n_value; \
@@ -394,7 +388,8 @@ static reloc_howto_type howto_table[] =
       cache_ptr->addend = - (ptr->section->vma + ptr->value);  \
     else                                                       \
       cache_ptr->addend = 0;                                   \
       cache_ptr->addend = - (ptr->section->vma + ptr->value);  \
     else                                                       \
       cache_ptr->addend = 0;                                   \
-    if (ptr && howto_table[reloc.r_type].pc_relative)          \
+    if (ptr && reloc.r_type < NUM_HOWTOS                       \
+       && howto_table[reloc.r_type].pc_relative)               \
       cache_ptr->addend += asect->vma;                         \
   }
 
       cache_ptr->addend += asect->vma;                         \
   }
 
@@ -412,24 +407,17 @@ static reloc_howto_type howto_table[] =
    and the regular routine is that we don't want to do anything for a
    relocatable link.  */
 
    and the regular routine is that we don't want to do anything for a
    relocatable link.  */
 
-static bfd_boolean coff_pe_i386_relocate_section
-  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
-          struct internal_reloc *, struct internal_syment *, asection **));
-
 static bfd_boolean
 static bfd_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;
+coff_pe_i386_relocate_section (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->relocatable)
+  if (bfd_link_relocatable (info))
     return TRUE;
 
   return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
     return TRUE;
 
   return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
@@ -444,17 +432,16 @@ coff_pe_i386_relocate_section (output_bfd, info, input_bfd,
 /* Convert an rtype to howto for the COFF backend linker.  */
 
 static reloc_howto_type *
 /* 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 ATTRIBUTE_UNUSED;
-     asection *sec;
-     struct internal_reloc *rel;
-     struct coff_link_hash_entry *h;
-     struct internal_syment *sym;
-     bfd_vma *addendp;
+coff_i386_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+                         asection *sec,
+                         struct internal_reloc *rel,
+                         struct coff_link_hash_entry *h,
+                         struct internal_syment *sym,
+                         bfd_vma *addendp)
 {
   reloc_howto_type *howto;
 
 {
   reloc_howto_type *howto;
 
-  if (rel->r_type >= sizeof (howto_table) / sizeof (howto_table[0]))
+  if (rel->r_type >= NUM_HOWTOS)
     {
       bfd_set_error (bfd_error_bad_value);
       return NULL;
     {
       bfd_set_error (bfd_error_bad_value);
       return NULL;
@@ -522,26 +509,31 @@ coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
       *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
     }
 
       *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
     }
 
-  BFD_ASSERT (sym != NULL);
+  /* PR 17099 - Absolute R_PCRLONG relocations do not need a symbol.  */
+  if (rel->r_type == R_PCRLONG && sym == NULL)
+    *addendp -= rel->r_vaddr;
+  else
+    BFD_ASSERT (sym != NULL);
+
   if (rel->r_type == R_SECREL32 && sym != NULL)
     {
       bfd_vma osect_vma;
 
   if (rel->r_type == R_SECREL32 && sym != NULL)
     {
       bfd_vma osect_vma;
 
-      if (h && (h->type == bfd_link_hash_defined
-               || h->type == bfd_link_hash_defweak))
+      if (h && (h->root.type == bfd_link_hash_defined
+               || h->root.type == bfd_link_hash_defweak))
        osect_vma = h->root.u.def.section->output_section->vma;
       else
        {
        osect_vma = h->root.u.def.section->output_section->vma;
       else
        {
-         asection *sec;
+         asection *s;
          int i;
 
          /* Sigh, the only way to get the section to offset against
             is to find it the hard way.  */
 
          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;
+         for (s = abfd->sections, i = 1; i < sym->n_scnum; i++)
+           s = s->next;
 
 
-         osect_vma = sec->output_section->vma;
+         osect_vma = s->output_section->vma;
        }
 
       *addendp -= osect_vma;
        }
 
       *addendp -= osect_vma;
@@ -555,9 +547,8 @@ coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
 #define coff_bfd_reloc_name_lookup coff_i386_reloc_name_lookup
 
 static reloc_howto_type *
 #define coff_bfd_reloc_name_lookup coff_i386_reloc_name_lookup
 
 static reloc_howto_type *
-coff_i386_reloc_type_lookup (abfd, code)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     bfd_reloc_code_real_type code;
+coff_i386_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                            bfd_reloc_code_real_type code)
 {
   switch (code)
     {
 {
   switch (code)
     {
@@ -591,7 +582,7 @@ coff_i386_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 {
   unsigned int i;
 
 {
   unsigned int i;
 
-  for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++)
+  for (i = 0; i < NUM_HOWTOS; i++)
     if (howto_table[i].name != NULL
        && strcasecmp (howto_table[i].name, r_name) == 0)
       return &howto_table[i];
     if (howto_table[i].name != NULL
        && strcasecmp (howto_table[i].name, r_name) == 0)
       return &howto_table[i];
@@ -607,13 +598,8 @@ coff_i386_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    a leading dot for local labels, so if TARGET_UNDERSCORE is defined
    we treat all symbols starting with L as local.  */
 
    a leading dot for local labels, so if TARGET_UNDERSCORE is defined
    we treat all symbols starting with L as local.  */
 
-static bfd_boolean coff_i386_is_local_label_name
-  PARAMS ((bfd *, const char *));
-
 static bfd_boolean
 static bfd_boolean
-coff_i386_is_local_label_name (abfd, name)
-     bfd *abfd;
-     const char *name;
+coff_i386_is_local_label_name (bfd *abfd, const char *name)
 {
   if (name[0] == 'L')
     return TRUE;
 {
   if (name[0] == 'L')
     return TRUE;
@@ -631,7 +617,7 @@ const bfd_target
 #ifdef TARGET_SYM
   TARGET_SYM =
 #else
 #ifdef TARGET_SYM
   TARGET_SYM =
 #else
-  i386coff_vec =
+  i386_coff_vec =
 #endif
 {
 #ifdef TARGET_NAME
 #endif
 {
 #ifdef TARGET_NAME
@@ -645,13 +631,13 @@ const bfd_target
 
   (HAS_RELOC | EXEC_P |                /* object flags */
    HAS_LINENO | HAS_DEBUG |
 
   (HAS_RELOC | EXEC_P |                /* object flags */
    HAS_LINENO | HAS_DEBUG |
-   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS ),
 
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
 #ifdef COFF_WITH_PE
 
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
 #ifdef COFF_WITH_PE
-   | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY
+   | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING
 #endif
 #endif
-   | SEC_CODE | SEC_DATA),
+   | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
 
 #ifdef TARGET_UNDERSCORE
   TARGET_UNDERSCORE,           /* leading underscore */
 
 #ifdef TARGET_UNDERSCORE
   TARGET_UNDERSCORE,           /* leading underscore */
@@ -660,6 +646,7 @@ const bfd_target
 #endif
   '/',                         /* ar_pad_char */
   15,                          /* ar_max_namelen */
 #endif
   '/',                         /* ar_pad_char */
   15,                          /* ar_max_namelen */
+  0,                           /* match priority.  */
 
   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
 
   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
@@ -669,8 +656,13 @@ const bfd_target
      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.  */
      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.  */
-    {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
-       bfd_generic_archive_p, coff_object_p},
+    /* bfd_check_format */
+#ifdef COFF_CHECK_FORMAT
+    {_bfd_dummy_target, COFF_CHECK_FORMAT,
+       bfd_generic_archive_p, COFF_CHECK_FORMAT},
+#else
+    {_bfd_dummy_target, coff_object_p, bfd_generic_archive_p, coff_object_p},
+#endif
     {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
        bfd_false},
     {bfd_false, coff_write_object_contents, /* bfd_write_contents */
     {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
        bfd_false},
     {bfd_false, coff_write_object_contents, /* bfd_write_contents */
This page took 0.028801 seconds and 4 git commands to generate.