[ARC] ARC_PC32 dynamic reloc incorrectly generated.
[deliverable/binutils-gdb.git] / bfd / cofflink.c
index 948b4cd0de934157b8dfcc565c139c3b48e4e1b0..aa84a3512805c8a0c65a370c3959db930fdcd5a9 100644 (file)
@@ -1,6 +1,5 @@
 /* COFF specific linker code.
 /* COFF specific linker code.
-   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005, 2006, 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1994-2017 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
    Written by Ian Lance Taylor, Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
 #include "libcoff.h"
 #include "safe-ctype.h"
 
 #include "libcoff.h"
 #include "safe-ctype.h"
 
-static bfd_boolean coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info);
-static bfd_boolean coff_link_check_archive_element (bfd *abfd, struct bfd_link_info *info, bfd_boolean *pneeded);
-static bfd_boolean coff_link_add_symbols (bfd *abfd, struct bfd_link_info *info);
+static bfd_boolean coff_link_add_object_symbols (bfd *, struct bfd_link_info *);
+static bfd_boolean coff_link_check_archive_element
+  (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, const char *,
+   bfd_boolean *);
+static bfd_boolean coff_link_add_symbols (bfd *, struct bfd_link_info *);
 
 /* Return TRUE if SYM is a weak, external symbol.  */
 #define IS_WEAK_EXTERNAL(abfd, sym)                    \
 
 /* Return TRUE if SYM is a weak, external symbol.  */
 #define IS_WEAK_EXTERNAL(abfd, sym)                    \
@@ -191,74 +192,6 @@ coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
   return TRUE;
 }
 
   return TRUE;
 }
 
-/* Look through the symbols to see if this object file should be
-   included in the link.  */
-
-static bfd_boolean
-coff_link_check_ar_symbols (bfd *abfd,
-                           struct bfd_link_info *info,
-                           bfd_boolean *pneeded,
-                           bfd **subsbfd)
-{
-  bfd_size_type symesz;
-  bfd_byte *esym;
-  bfd_byte *esym_end;
-
-  *pneeded = FALSE;
-
-  symesz = bfd_coff_symesz (abfd);
-  esym = (bfd_byte *) obj_coff_external_syms (abfd);
-  esym_end = esym + obj_raw_syment_count (abfd) * symesz;
-  while (esym < esym_end)
-    {
-      struct internal_syment sym;
-      enum coff_symbol_classification classification;
-
-      bfd_coff_swap_sym_in (abfd, esym, &sym);
-
-      classification = bfd_coff_classify_symbol (abfd, &sym);
-      if (classification == COFF_SYMBOL_GLOBAL
-         || classification == COFF_SYMBOL_COMMON)
-       {
-         const char *name;
-         char buf[SYMNMLEN + 1];
-         struct bfd_link_hash_entry *h;
-
-         /* This symbol is externally visible, and is defined by this
-             object file.  */
-         name = _bfd_coff_internal_syment_name (abfd, &sym, buf);
-         if (name == NULL)
-           return FALSE;
-         h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
-
-         /* Auto import.  */
-         if (!h
-             && info->pei386_auto_import
-             && CONST_STRNEQ (name, "__imp_"))
-           h = bfd_link_hash_lookup (info->hash, name + 6, FALSE, FALSE, TRUE);
-
-         /* We are only interested in symbols that are currently
-            undefined.  If a symbol is currently known to be common,
-            COFF linkers do not bring in an object file which defines
-            it.  */
-         if (h != (struct bfd_link_hash_entry *) NULL
-             && h->type == bfd_link_hash_undefined)
-           {
-             if (!(*info->callbacks
-                   ->add_archive_element) (info, abfd, name, subsbfd))
-               return FALSE;
-             *pneeded = TRUE;
-             return TRUE;
-           }
-       }
-
-      esym += (sym.n_numaux + 1) * symesz;
-    }
-
-  /* We do not need this object file.  */
-  return TRUE;
-}
-
 /* Check a single archive element to see if we need to include it in
    the link.  *PNEEDED is set according to whether this element is
    needed in the link or not.  This is called via
 /* Check a single archive element to see if we need to include it in
    the link.  *PNEEDED is set according to whether this element is
    needed in the link or not.  This is called via
@@ -267,41 +200,24 @@ coff_link_check_ar_symbols (bfd *abfd,
 static bfd_boolean
 coff_link_check_archive_element (bfd *abfd,
                                 struct bfd_link_info *info,
 static bfd_boolean
 coff_link_check_archive_element (bfd *abfd,
                                 struct bfd_link_info *info,
+                                struct bfd_link_hash_entry *h,
+                                const char *name,
                                 bfd_boolean *pneeded)
 {
                                 bfd_boolean *pneeded)
 {
-  bfd *oldbfd;
-  bfd_boolean needed;
-
-  if (!_bfd_coff_get_external_symbols (abfd))
-    return FALSE;
+  *pneeded = FALSE;
 
 
-  oldbfd = abfd;
-  if (!coff_link_check_ar_symbols (abfd, info, pneeded, &abfd))
-    return FALSE;
+  /* We are only interested in symbols that are currently undefined.
+     If a symbol is currently known to be common, COFF linkers do not
+     bring in an object file which defines it.  */
+  if (h->type != bfd_link_hash_undefined)
+    return TRUE;
 
 
-  needed = *pneeded;
-  if (needed)
-    {
-      /* Potentially, the add_archive_element hook may have set a
-        substitute BFD for us.  */
-      if (abfd != oldbfd)
-       {
-         if (!info->keep_memory
-             && !_bfd_coff_free_symbols (oldbfd))
-           return FALSE;
-         if (!_bfd_coff_get_external_symbols (abfd))
-           return FALSE;
-       }
-      if (!coff_link_add_symbols (abfd, info))
-       return FALSE;
-    }
+  /* Include this element?  */
+  if (!(*info->callbacks->add_archive_element) (info, abfd, name, &abfd))
+    return TRUE;
+  *pneeded = TRUE;
 
 
-  if (!info->keep_memory || !needed)
-    {
-      if (!_bfd_coff_free_symbols (abfd))
-       return FALSE;
-    }
-  return TRUE;
+  return coff_link_add_object_symbols (abfd, info);
 }
 
 /* Add all the symbols from an object file to the hash table.  */
 }
 
 /* Add all the symbols from an object file to the hash table.  */
@@ -428,8 +344,8 @@ coff_link_add_symbols (bfd *abfd,
                       & COFF_LINK_HASH_PE_SECTION_SYMBOL) == 0
                      && (*sym_hash)->root.type != bfd_link_hash_undefined
                      && (*sym_hash)->root.type != bfd_link_hash_undefweak)
                       & COFF_LINK_HASH_PE_SECTION_SYMBOL) == 0
                      && (*sym_hash)->root.type != bfd_link_hash_undefined
                      && (*sym_hash)->root.type != bfd_link_hash_undefweak)
-                   (*_bfd_error_handler)
-                     ("Warning: symbol `%s' is both section and non-section",
+                   _bfd_error_handler
+                     (_("Warning: symbol `%s' is both section and non-section"),
                       name);
 
                  addit = FALSE;
                       name);
 
                  addit = FALSE;
@@ -529,9 +445,11 @@ coff_link_add_symbols (bfd *abfd,
                          && !(DTYPE ((*sym_hash)->type) == DTYPE (sym.n_type)
                               && (BTYPE ((*sym_hash)->type) == T_NULL
                                   || BTYPE (sym.n_type) == T_NULL)))
                          && !(DTYPE ((*sym_hash)->type) == DTYPE (sym.n_type)
                               && (BTYPE ((*sym_hash)->type) == T_NULL
                                   || BTYPE (sym.n_type) == T_NULL)))
-                       (*_bfd_error_handler)
-                         (_("Warning: type of symbol `%s' changed from %d to %d in %B"),
-                          abfd, name, (*sym_hash)->type, sym.n_type);
+                       _bfd_error_handler
+                         /* xgettext: c-format */
+                         (_("Warning: type of symbol `%s' changed"
+                            " from %d to %d in %B"),
+                          name, (*sym_hash)->type, sym.n_type, abfd);
 
                      /* We don't want to change from a meaningful
                         base type to a null one, but if we know
 
                      /* We don't want to change from a meaningful
                         base type to a null one, but if we know
@@ -592,7 +510,7 @@ coff_link_add_symbols (bfd *abfd,
 
   /* If this is a non-traditional, non-relocatable link, try to
      optimize the handling of any .stab/.stabstr sections.  */
 
   /* If this is a non-traditional, non-relocatable link, try to
      optimize the handling of any .stab/.stabstr sections.  */
-  if (! info->relocatable
+  if (! bfd_link_relocatable (info)
       && ! info->traditional_format
       && bfd_get_flavour (info->output_bfd) == bfd_get_flavour (abfd)
       && (info->strip != strip_all && info->strip != strip_debugger))
       && ! info->traditional_format
       && bfd_get_flavour (info->output_bfd) == bfd_get_flavour (abfd)
       && (info->strip != strip_all && info->strip != strip_debugger))
@@ -737,7 +655,7 @@ _bfd_coff_final_link (bfd *abfd,
                  || info->strip == strip_some)
                o->lineno_count += sec->lineno_count;
 
                  || info->strip == strip_some)
                o->lineno_count += sec->lineno_count;
 
-             if (info->relocatable)
+             if (bfd_link_relocatable (info))
                o->reloc_count += sec->reloc_count;
 
              if (sec->rawsize > max_contents_size)
                o->reloc_count += sec->reloc_count;
 
              if (sec->rawsize > max_contents_size)
@@ -749,7 +667,7 @@ _bfd_coff_final_link (bfd *abfd,
              if (sec->reloc_count > max_reloc_count)
                max_reloc_count = sec->reloc_count;
            }
              if (sec->reloc_count > max_reloc_count)
                max_reloc_count = sec->reloc_count;
            }
-         else if (info->relocatable
+         else if (bfd_link_relocatable (info)
                   && (p->type == bfd_section_reloc_link_order
                       || p->type == bfd_symbol_reloc_link_order))
            ++o->reloc_count;
                   && (p->type == bfd_section_reloc_link_order
                       || p->type == bfd_symbol_reloc_link_order))
            ++o->reloc_count;
@@ -784,7 +702,7 @@ _bfd_coff_final_link (bfd *abfd,
 
   /* If doing a relocatable link, allocate space for the pointers we
      need to keep.  */
 
   /* If doing a relocatable link, allocate space for the pointers we
      need to keep.  */
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     {
       unsigned int i;
 
     {
       unsigned int i;
 
@@ -832,7 +750,7 @@ _bfd_coff_final_link (bfd *abfd,
             memory until the end of the link.  This wastes memory,
             but only when doing a relocatable link, which is not the
             common case.  */
             memory until the end of the link.  This wastes memory,
             but only when doing a relocatable link, which is not the
             common case.  */
-         BFD_ASSERT (info->relocatable);
+         BFD_ASSERT (bfd_link_relocatable (info));
          amt = o->reloc_count;
          amt *= sizeof (struct internal_reloc);
          flaginfo.section_info[o->target_index].relocs =
          amt = o->reloc_count;
          amt *= sizeof (struct internal_reloc);
          flaginfo.section_info[o->target_index].relocs =
@@ -861,7 +779,7 @@ _bfd_coff_final_link (bfd *abfd,
      the opportunity to clear the output_has_begun fields of all the
      input BFD's.  */
   max_sym_count = 0;
      the opportunity to clear the output_has_begun fields of all the
      input BFD's.  */
   max_sym_count = 0;
-  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+  for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
     {
       size_t sz;
 
     {
       size_t sz;
 
@@ -884,7 +802,7 @@ _bfd_coff_final_link (bfd *abfd,
   flaginfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
   amt = max_reloc_count * relsz;
   flaginfo.external_relocs = (bfd_byte *) bfd_malloc (amt);
   flaginfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
   amt = max_reloc_count * relsz;
   flaginfo.external_relocs = (bfd_byte *) bfd_malloc (amt);
-  if (! info->relocatable)
+  if (! bfd_link_relocatable (info))
     {
       amt = max_reloc_count * sizeof (struct internal_reloc);
       flaginfo.internal_relocs = (struct internal_reloc *) bfd_malloc (amt);
     {
       amt = max_reloc_count * sizeof (struct internal_reloc);
       flaginfo.internal_relocs = (struct internal_reloc *) bfd_malloc (amt);
@@ -896,7 +814,7 @@ _bfd_coff_final_link (bfd *abfd,
       || (flaginfo.linenos == NULL && max_lineno_count > 0)
       || (flaginfo.contents == NULL && max_contents_size > 0)
       || (flaginfo.external_relocs == NULL && max_reloc_count > 0)
       || (flaginfo.linenos == NULL && max_lineno_count > 0)
       || (flaginfo.contents == NULL && max_contents_size > 0)
       || (flaginfo.external_relocs == NULL && max_reloc_count > 0)
-      || (! info->relocatable
+      || (! bfd_link_relocatable (info)
          && flaginfo.internal_relocs == NULL
          && max_reloc_count > 0))
     goto error_return;
          && flaginfo.internal_relocs == NULL
          && max_reloc_count > 0))
     goto error_return;
@@ -946,7 +864,7 @@ _bfd_coff_final_link (bfd *abfd,
   if (flaginfo.info->strip != strip_all && flaginfo.info->discard != discard_all)
     {
       /* Add local symbols from foreign inputs.  */
   if (flaginfo.info->strip != strip_all && flaginfo.info->discard != discard_all)
     {
       /* Add local symbols from foreign inputs.  */
-      for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+      for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
        {
          unsigned int i;
 
        {
          unsigned int i;
 
@@ -957,9 +875,10 @@ _bfd_coff_final_link (bfd *abfd,
              asymbol *sym = bfd_get_outsymbols (sub) [i];
              file_ptr pos;
              struct internal_syment isym;
              asymbol *sym = bfd_get_outsymbols (sub) [i];
              file_ptr pos;
              struct internal_syment isym;
-             bfd_size_type string_size = 0;
+             union internal_auxent iaux;
+             bfd_size_type string_size = 0, indx;
              bfd_vma written = 0;
              bfd_vma written = 0;
-             bfd_boolean rewrite = FALSE;
+             bfd_boolean rewrite = FALSE, hash;
 
              if (! (sym->flags & BSF_LOCAL)
                  || (sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC
 
              if (! (sym->flags & BSF_LOCAL)
                  || (sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC
@@ -976,7 +895,7 @@ _bfd_coff_final_link (bfd *abfd,
                       == NULL))
                  || (((flaginfo.info->discard == discard_sec_merge
                        && (bfd_get_section (sym)->flags & SEC_MERGE)
                       == NULL))
                  || (((flaginfo.info->discard == discard_sec_merge
                        && (bfd_get_section (sym)->flags & SEC_MERGE)
-                       && ! flaginfo.info->relocatable)
+                       && ! bfd_link_relocatable (flaginfo.info))
                       || flaginfo.info->discard == discard_l)
                      && bfd_is_local_label_name (sub, bfd_asymbol_name(sym))))
                continue;
                       || flaginfo.info->discard == discard_l)
                      && bfd_is_local_label_name (sub, bfd_asymbol_name(sym))))
                continue;
@@ -985,23 +904,52 @@ _bfd_coff_final_link (bfd *abfd,
                                             * symesz;
              if (bfd_seek (abfd, pos, SEEK_SET) != 0)
                goto error_return;
                                             * symesz;
              if (bfd_seek (abfd, pos, SEEK_SET) != 0)
                goto error_return;
-             if (! coff_write_alien_symbol(abfd, sym, &isym, &written,
+             if (! coff_write_alien_symbol(abfd, sym, &isym, &iaux, &written,
                                            &string_size, NULL, NULL))
                goto error_return;
 
                                            &string_size, NULL, NULL))
                goto error_return;
 
-             if (string_size)
+             hash = !flaginfo.info->traditional_format;
+
+             if (string_size >= 6 && isym.n_sclass == C_FILE
+                 && ! isym._n._n_n._n_zeroes && isym.n_numaux)
                {
                {
-                 bfd_boolean hash = ! (abfd->flags & BFD_TRADITIONAL_FORMAT);
-                 bfd_size_type indx;
+                 indx = _bfd_stringtab_add (flaginfo.strtab, ".file", hash,
+                                            FALSE);
+                 if (indx == (bfd_size_type) -1)
+                   goto error_return;
+                 isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
+                 bfd_coff_swap_sym_out (abfd, &isym, flaginfo.outsyms);
+                 if (bfd_seek (abfd, pos, SEEK_SET) != 0
+                     || bfd_bwrite (flaginfo.outsyms, symesz,
+                                    abfd) != symesz)
+                   goto error_return;
+                 string_size -= 6;
+               }
 
 
+             if (string_size)
+               {
                  indx = _bfd_stringtab_add (flaginfo.strtab,
                                             bfd_asymbol_name (sym), hash,
                                             FALSE);
                  if (indx == (bfd_size_type) -1)
                    goto error_return;
                  indx = _bfd_stringtab_add (flaginfo.strtab,
                                             bfd_asymbol_name (sym), hash,
                                             FALSE);
                  if (indx == (bfd_size_type) -1)
                    goto error_return;
-                 isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
-                 bfd_coff_swap_sym_out (abfd, &isym, flaginfo.outsyms);
-                 rewrite = TRUE;
+                 if (isym.n_sclass != C_FILE)
+                   {
+                     isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
+                     bfd_coff_swap_sym_out (abfd, &isym, flaginfo.outsyms);
+                     rewrite = TRUE;
+                   }
+                 else
+                   {
+                     BFD_ASSERT (isym.n_numaux == 1);
+                     iaux.x_file.x_n.x_offset = STRING_SIZE_SIZE + indx;
+                     bfd_coff_swap_aux_out (abfd, &iaux, isym.n_type, C_FILE,
+                                            0, 1, flaginfo.outsyms + symesz);
+                     if (bfd_seek (abfd, pos + symesz, SEEK_SET) != 0
+                         || bfd_bwrite (flaginfo.outsyms + symesz, symesz,
+                                        abfd) != symesz)
+                       goto error_return;
+                   }
                }
 
              if (isym.n_sclass == C_FILE)
                }
 
              if (isym.n_sclass == C_FILE)
@@ -1116,7 +1064,7 @@ _bfd_coff_final_link (bfd *abfd,
       flaginfo.outsyms = NULL;
     }
 
       flaginfo.outsyms = NULL;
     }
 
-  if (info->relocatable && max_output_reloc_count > 0)
+  if (bfd_link_relocatable (info) && max_output_reloc_count > 0)
     {
       /* Now that we have written out all the global symbols, we know
         the symbol indices to use for relocs against them, and we can
     {
       /* Now that we have written out all the global symbols, we know
         the symbol indices to use for relocs against them, and we can
@@ -1435,8 +1383,8 @@ mark_relocs (struct coff_final_link_info *flaginfo, bfd *input_bfd)
       internal_relocs = _bfd_coff_read_internal_relocs
        (input_bfd, a, FALSE,
         flaginfo->external_relocs,
       internal_relocs = _bfd_coff_read_internal_relocs
        (input_bfd, a, FALSE,
         flaginfo->external_relocs,
-        flaginfo->info->relocatable,
-        (flaginfo->info->relocatable
+        bfd_link_relocatable (flaginfo->info),
+        (bfd_link_relocatable (flaginfo->info)
          ? (flaginfo->section_info[ a->output_section->target_index ].relocs + a->output_section->reloc_count)
          : flaginfo->internal_relocs)
        );
          ? (flaginfo->section_info[ a->output_section->target_index ].relocs + a->output_section->reloc_count)
          : flaginfo->internal_relocs)
        );
@@ -1452,7 +1400,8 @@ mark_relocs (struct coff_final_link_info *flaginfo, bfd *input_bfd)
         in the relocation table.  This will then be picked up in the
         skip/don't-skip pass.  */
       for (; irel < irelend; irel++)
         in the relocation table.  This will then be picked up in the
         skip/don't-skip pass.  */
       for (; irel < irelend; irel++)
-       flaginfo->sym_indices[ irel->r_symndx ] = -1;
+       if ((unsigned long) irel->r_symndx < obj_raw_syment_count (input_bfd))
+         flaginfo->sym_indices[irel->r_symndx] = -1;
     }
 }
 
     }
 }
 
@@ -1498,7 +1447,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
   if (! flaginfo->info->keep_memory)
     copy = TRUE;
   hash = TRUE;
   if (! flaginfo->info->keep_memory)
     copy = TRUE;
   hash = TRUE;
-  if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
+  if (flaginfo->info->traditional_format)
     hash = FALSE;
 
   if (! _bfd_coff_get_external_symbols (input_bfd))
     hash = FALSE;
 
   if (! _bfd_coff_get_external_symbols (input_bfd))
@@ -1521,7 +1470,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
      symbols that are going to be involved in the relocations.  */
   if ((   flaginfo->info->strip   != strip_none
        || flaginfo->info->discard != discard_none)
      symbols that are going to be involved in the relocations.  */
   if ((   flaginfo->info->strip   != strip_none
        || flaginfo->info->discard != discard_none)
-      && flaginfo->info->relocatable)
+      && bfd_link_relocatable (flaginfo->info))
     {
       /* Mark the symbol array as 'not-used'.  */
       memset (indexp, 0, obj_raw_syment_count (input_bfd) * sizeof * indexp);
     {
       /* Mark the symbol array as 'not-used'.  */
       memset (indexp, 0, obj_raw_syment_count (input_bfd) * sizeof * indexp);
@@ -1568,7 +1517,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
          relocation.  */
       if ((flaginfo->info->strip != strip_none
           || flaginfo->info->discard != discard_none)
          relocation.  */
       if ((flaginfo->info->strip != strip_none
           || flaginfo->info->discard != discard_none)
-         && flaginfo->info->relocatable)
+         && bfd_link_relocatable (flaginfo->info))
        dont_skip_symbol = *indexp;
       else
        dont_skip_symbol = FALSE;
        dont_skip_symbol = *indexp;
       else
        dont_skip_symbol = FALSE;
@@ -1676,7 +1625,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
       /* If this is an enum, struct, or union tag, see if we have
          already output an identical type.  */
       if (! skip
       /* If this is an enum, struct, or union tag, see if we have
          already output an identical type.  */
       if (! skip
-         && (flaginfo->output_bfd->flags & BFD_TRADITIONAL_FORMAT) == 0
+         && !flaginfo->info->traditional_format
          && (isym.n_sclass == C_ENTAG
              || isym.n_sclass == C_STRTAG
              || isym.n_sclass == C_UNTAG)
          && (isym.n_sclass == C_ENTAG
              || isym.n_sclass == C_STRTAG
              || isym.n_sclass == C_UNTAG)
@@ -2088,7 +2037,10 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
                          if (strings == NULL)
                            return FALSE;
                        }
                          if (strings == NULL)
                            return FALSE;
                        }
-                     filename = strings + auxp->x_file.x_n.x_offset;
+                     if ((bfd_size_type) auxp->x_file.x_n.x_offset >= obj_coff_strings_len (input_bfd))
+                       filename = _("<corrupt>");
+                     else
+                       filename = strings + auxp->x_file.x_n.x_offset;
                      indx = _bfd_stringtab_add (flaginfo->strtab, filename,
                                                 hash, copy);
                      if (indx == (bfd_size_type) -1)
                      indx = _bfd_stringtab_add (flaginfo->strtab, filename,
                                                 hash, copy);
                      if (indx == (bfd_size_type) -1)
@@ -2412,7 +2364,8 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
          if ((o->flags & SEC_RELOC) != 0
              && o->reloc_count != 0)
            {
          if ((o->flags & SEC_RELOC) != 0
              && o->reloc_count != 0)
            {
-             (*_bfd_error_handler)
+             _bfd_error_handler
+               /* xgettext: c-format */
                (_("%B: relocs in section `%A', but it has no contents"),
                 input_bfd, o);
              bfd_set_error (bfd_error_no_contents);
                (_("%B: relocs in section `%A', but it has no contents"),
                 input_bfd, o);
              bfd_set_error (bfd_error_no_contents);
@@ -2442,8 +2395,8 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
          target_index = o->output_section->target_index;
          internal_relocs = (_bfd_coff_read_internal_relocs
                             (input_bfd, o, FALSE, flaginfo->external_relocs,
          target_index = o->output_section->target_index;
          internal_relocs = (_bfd_coff_read_internal_relocs
                             (input_bfd, o, FALSE, flaginfo->external_relocs,
-                             flaginfo->info->relocatable,
-                             (flaginfo->info->relocatable
+                             bfd_link_relocatable (flaginfo->info),
+                             (bfd_link_relocatable (flaginfo->info)
                               ? (flaginfo->section_info[target_index].relocs
                                  + o->output_section->reloc_count)
                               : flaginfo->internal_relocs)));
                               ? (flaginfo->section_info[target_index].relocs
                                  + o->output_section->reloc_count)
                               : flaginfo->internal_relocs)));
@@ -2475,6 +2428,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
              /* Complain if definition comes from an excluded section.  */
              if (ps->flags & SEC_EXCLUDE)
                (*flaginfo->info->callbacks->einfo)
              /* Complain if definition comes from an excluded section.  */
              if (ps->flags & SEC_EXCLUDE)
                (*flaginfo->info->callbacks->einfo)
+                 /* xgettext: c-format */
                  (_("%X`%s' referenced in section `%A' of %B: "
                     "defined in discarded section `%A' of %B\n"),
                   h->root.root.string, o, input_bfd, ps, ps->owner);
                  (_("%X`%s' referenced in section `%A' of %B: "
                     "defined in discarded section `%A' of %B\n"),
                   h->root.root.string, o, input_bfd, ps, ps->owner);
@@ -2490,7 +2444,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
                                           flaginfo->sec_ptrs))
            return FALSE;
 
                                           flaginfo->sec_ptrs))
            return FALSE;
 
-         if (flaginfo->info->relocatable)
+         if (bfd_link_relocatable (flaginfo->info))
            {
              bfd_vma offset;
              struct internal_reloc *irelend;
            {
              bfd_vma offset;
              struct internal_reloc *irelend;
@@ -2566,10 +2520,8 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
                          if (name == NULL)
                            return FALSE;
 
                          if (name == NULL)
                            return FALSE;
 
-                         if (! ((*flaginfo->info->callbacks->unattached_reloc)
-                                (flaginfo->info, name, input_bfd, o,
-                                 irel->r_vaddr)))
-                           return FALSE;
+                         (*flaginfo->info->callbacks->unattached_reloc)
+                           (flaginfo->info, name, input_bfd, o, irel->r_vaddr);
                        }
                    }
                }
                        }
                    }
                }
@@ -2684,7 +2636,7 @@ _bfd_coff_write_global_sym (struct bfd_hash_entry *bh, void *data)
       bfd_size_type indx;
 
       hash = TRUE;
       bfd_size_type indx;
 
       hash = TRUE;
-      if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
+      if (flaginfo->info->traditional_format)
        hash = FALSE;
       indx = _bfd_stringtab_add (flaginfo->strtab, h->root.root.string, hash,
                                 FALSE);
        hash = FALSE;
       indx = _bfd_stringtab_add (flaginfo->strtab, h->root.root.string, hash,
                                 FALSE);
@@ -2718,8 +2670,8 @@ _bfd_coff_write_global_sym (struct bfd_hash_entry *bh, void *data)
   /* When a weak symbol is not overridden by a strong one,
      turn it into an external symbol when not building a
      shared or relocatable object.  */
   /* When a weak symbol is not overridden by a strong one,
      turn it into an external symbol when not building a
      shared or relocatable object.  */
-  if (! flaginfo->info->shared
-      && ! flaginfo->info->relocatable
+  if (! bfd_link_pic (flaginfo->info)
+      && ! bfd_link_relocatable (flaginfo->info)
       && IS_WEAK_EXTERNAL (flaginfo->output_bfd, isym))
     isym.n_sclass = C_EXT;
 
       && IS_WEAK_EXTERNAL (flaginfo->output_bfd, isym))
     isym.n_sclass = C_EXT;
 
@@ -2772,21 +2724,19 @@ _bfd_coff_write_global_sym (struct bfd_hash_entry *bh, void *data)
                  not matter.  FIXME: Why not?  */
              if (sec->reloc_count > 0xffff
                  && (! obj_pe (output_bfd)
                  not matter.  FIXME: Why not?  */
              if (sec->reloc_count > 0xffff
                  && (! obj_pe (output_bfd)
-                     || flaginfo->info->relocatable))
-               (*_bfd_error_handler)
-                 (_("%s: %s: reloc overflow: 0x%lx > 0xffff"),
-                  bfd_get_filename (output_bfd),
-                  bfd_get_section_name (output_bfd, sec),
-                  sec->reloc_count);
+                     || bfd_link_relocatable (flaginfo->info)))
+               _bfd_error_handler
+                 /* xgettext: c-format */
+                 (_("%B: %A: reloc overflow: 0x%lx > 0xffff"),
+                  output_bfd, sec, sec->reloc_count);
 
              if (sec->lineno_count > 0xffff
                  && (! obj_pe (output_bfd)
 
              if (sec->lineno_count > 0xffff
                  && (! obj_pe (output_bfd)
-                     || flaginfo->info->relocatable))
-               (*_bfd_error_handler)
-                 (_("%s: warning: %s: line number overflow: 0x%lx > 0xffff"),
-                  bfd_get_filename (output_bfd),
-                  bfd_get_section_name (output_bfd, sec),
-                  sec->lineno_count);
+                     || bfd_link_relocatable (flaginfo->info)))
+               _bfd_error_handler
+                 /* xgettext: c-format */
+                 (_("%B: warning: %A: line number overflow: 0x%lx > 0xffff"),
+                  output_bfd, sec, sec->lineno_count);
 
              auxp->x_scn.x_nreloc = sec->reloc_count;
              auxp->x_scn.x_nlinno = sec->lineno_count;
 
              auxp->x_scn.x_nreloc = sec->reloc_count;
              auxp->x_scn.x_nlinno = sec->lineno_count;
@@ -2871,7 +2821,7 @@ _bfd_coff_reloc_link_order (bfd *output_bfd,
 
       size = bfd_get_reloc_size (howto);
       buf = (bfd_byte *) bfd_zmalloc (size);
 
       size = bfd_get_reloc_size (howto);
       buf = (bfd_byte *) bfd_zmalloc (size);
-      if (buf == NULL)
+      if (buf == NULL && size != 0)
        return FALSE;
 
       rstat = _bfd_relocate_contents (howto, output_bfd,
        return FALSE;
 
       rstat = _bfd_relocate_contents (howto, output_bfd,
@@ -2885,18 +2835,14 @@ _bfd_coff_reloc_link_order (bfd *output_bfd,
        case bfd_reloc_outofrange:
          abort ();
        case bfd_reloc_overflow:
        case bfd_reloc_outofrange:
          abort ();
        case bfd_reloc_overflow:
-         if (! ((*flaginfo->info->callbacks->reloc_overflow)
-                (flaginfo->info, NULL,
-                 (link_order->type == bfd_section_reloc_link_order
-                  ? bfd_section_name (output_bfd,
-                                      link_order->u.reloc.p->u.section)
-                  : link_order->u.reloc.p->u.name),
-                 howto->name, link_order->u.reloc.p->addend,
-                 (bfd *) NULL, (asection *) NULL, (bfd_vma) 0)))
-           {
-             free (buf);
-             return FALSE;
-           }
+         (*flaginfo->info->callbacks->reloc_overflow)
+           (flaginfo->info, NULL,
+            (link_order->type == bfd_section_reloc_link_order
+             ? bfd_section_name (output_bfd,
+                                 link_order->u.reloc.p->u.section)
+             : link_order->u.reloc.p->u.name),
+            howto->name, link_order->u.reloc.p->addend,
+            (bfd *) NULL, (asection *) NULL, (bfd_vma) 0);
          break;
        }
       loc = link_order->offset * bfd_octets_per_byte (output_bfd);
          break;
        }
       loc = link_order->offset * bfd_octets_per_byte (output_bfd);
@@ -2952,10 +2898,9 @@ _bfd_coff_reloc_link_order (bfd *output_bfd,
        }
       else
        {
        }
       else
        {
-         if (! ((*flaginfo->info->callbacks->unattached_reloc)
-                (flaginfo->info, link_order->u.reloc.p->u.name, (bfd *) NULL,
-                 (asection *) NULL, (bfd_vma) 0)))
-           return FALSE;
+         (*flaginfo->info->callbacks->unattached_reloc)
+           (flaginfo->info, link_order->u.reloc.p->u.name,
+            (bfd *) NULL, (asection *) NULL, (bfd_vma) 0);
          irel->r_symndx = 0;
        }
     }
          irel->r_symndx = 0;
        }
     }
@@ -2997,6 +2942,7 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
       struct internal_syment *sym;
       bfd_vma addend;
       bfd_vma val;
       struct internal_syment *sym;
       bfd_vma addend;
       bfd_vma val;
+      asection *sec;
       reloc_howto_type *howto;
       bfd_reloc_status_type rstat;
 
       reloc_howto_type *howto;
       bfd_reloc_status_type rstat;
 
@@ -3010,8 +2956,9 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
       else if (symndx < 0
               || (unsigned long) symndx >= obj_raw_syment_count (input_bfd))
        {
       else if (symndx < 0
               || (unsigned long) symndx >= obj_raw_syment_count (input_bfd))
        {
-         (*_bfd_error_handler)
-           ("%B: illegal symbol index %ld in relocs", input_bfd, symndx);
+         _bfd_error_handler
+           /* xgettext: c-format */
+           (_("%B: illegal symbol index %ld in relocs"), input_bfd, symndx);
          return FALSE;
        }
       else
          return FALSE;
        }
       else
@@ -3040,18 +2987,16 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
          then we should ignore the symbol value.  */
       if (howto->pc_relative && howto->pcrel_offset)
        {
          then we should ignore the symbol value.  */
       if (howto->pc_relative && howto->pcrel_offset)
        {
-         if (info->relocatable)
+         if (bfd_link_relocatable (info))
            continue;
          if (sym != NULL && sym->n_scnum != 0)
            addend += sym->n_value;
        }
 
       val = 0;
            continue;
          if (sym != NULL && sym->n_scnum != 0)
            addend += sym->n_value;
        }
 
       val = 0;
-
+      sec = NULL;
       if (h == NULL)
        {
       if (h == NULL)
        {
-         asection *sec;
-
          if (symndx == -1)
            {
              sec = bfd_abs_section_ptr;
          if (symndx == -1)
            {
              sec = bfd_abs_section_ptr;
@@ -3060,6 +3005,12 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
          else
            {
              sec = sections[symndx];
          else
            {
              sec = sections[symndx];
+
+             /* PR 19623: Relocations against symbols in
+                the absolute sections should ignored.  */
+              if (bfd_is_abs_section (sec))
+               continue;
+
               val = (sec->output_section->vma
                     + sec->output_offset
                     + sym->n_value);
               val = (sec->output_section->vma
                     + sec->output_offset
                     + sym->n_value);
@@ -3073,8 +3024,6 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
              || h->root.type == bfd_link_hash_defweak)
            {
              /* Defined weak symbols are a GNU extension. */
              || h->root.type == bfd_link_hash_defweak)
            {
              /* Defined weak symbols are a GNU extension. */
-             asection *sec;
-
              sec = h->root.u.def.section;
              val = (h->root.u.def.value
                     + sec->output_section->vma
              sec = h->root.u.def.section;
              val = (h->root.u.def.value
                     + sec->output_section->vma
@@ -3095,7 +3044,6 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
                     will resolve a weak external only if a normal
                     external causes the library member to be linked.
                     See also linker.c: generic_link_check_archive_element. */
                     will resolve a weak external only if a normal
                     external causes the library member to be linked.
                     See also linker.c: generic_link_check_archive_element. */
-                 asection *sec;
                  struct coff_link_hash_entry *h2 =
                    h->auxbfd->tdata.coff_obj_data->sym_hashes[
                    h->aux->x_sym.x_tagndx.l];
                  struct coff_link_hash_entry *h2 =
                    h->auxbfd->tdata.coff_obj_data->sym_hashes[
                    h->aux->x_sym.x_tagndx.l];
@@ -3117,13 +3065,19 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
                val = 0;
            }
 
                val = 0;
            }
 
-         else if (! info->relocatable)
-           {
-             if (! ((*info->callbacks->undefined_symbol)
-                    (info, h->root.root.string, input_bfd, input_section,
-                     rel->r_vaddr - input_section->vma, TRUE)))
-               return FALSE;
-           }
+         else if (! bfd_link_relocatable (info))
+           (*info->callbacks->undefined_symbol)
+             (info, h->root.root.string, input_bfd, input_section,
+              rel->r_vaddr - input_section->vma, TRUE);
+       }
+
+      /* If the input section defining the symbol has been discarded
+        then zero this reloc field.  */
+      if (sec != NULL && discarded_section (sec))
+       {
+         _bfd_clear_contents (howto, input_bfd, input_section,
+                              contents + (rel->r_vaddr - input_section->vma));
+         continue;
        }
 
       if (info->base_file)
        }
 
       if (info->base_file)
@@ -3164,9 +3118,10 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
        case bfd_reloc_ok:
          break;
        case bfd_reloc_outofrange:
        case bfd_reloc_ok:
          break;
        case bfd_reloc_outofrange:
-         (*_bfd_error_handler)
+         _bfd_error_handler
+           /* xgettext: c-format */
            (_("%B: bad reloc address 0x%lx in section `%A'"),
            (_("%B: bad reloc address 0x%lx in section `%A'"),
-            input_bfd, input_section, (unsigned long) rel->r_vaddr);
+            input_bfd, (unsigned long) rel->r_vaddr, input_section);
          return FALSE;
        case bfd_reloc_overflow:
          {
          return FALSE;
        case bfd_reloc_overflow:
          {
@@ -3184,11 +3139,10 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
                  return FALSE;
              }
 
                  return FALSE;
              }
 
-           if (! ((*info->callbacks->reloc_overflow)
-                  (info, (h ? &h->root : NULL), name, howto->name,
-                   (bfd_vma) 0, input_bfd, input_section,
-                   rel->r_vaddr - input_section->vma)))
-             return FALSE;
+           (*info->callbacks->reloc_overflow)
+             (info, (h ? &h->root : NULL), name, howto->name,
+              (bfd_vma) 0, input_bfd, input_section,
+              rel->r_vaddr - input_section->vma);
          }
        }
     }
          }
        }
     }
This page took 0.035286 seconds and 4 git commands to generate.