Automatic date update in version.in
[deliverable/binutils-gdb.git] / bfd / cofflink.c
index 0ca8649dff894a33857bb0159c7499d10522fc01..63bdcde115deae70f52d4eb543ab1170d2c49d81 100644 (file)
@@ -1,5 +1,5 @@
 /* COFF specific linker code.
 /* COFF specific linker code.
-   Copyright (C) 1994-2019 Free Software Foundation, Inc.
+   Copyright (C) 1994-2020 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.
@@ -109,7 +109,7 @@ struct bfd_link_hash_table *
 _bfd_coff_link_hash_table_create (bfd *abfd)
 {
   struct coff_link_hash_table *ret;
 _bfd_coff_link_hash_table_create (bfd *abfd)
 {
   struct coff_link_hash_table *ret;
-  bfd_size_type amt = sizeof (struct coff_link_hash_table);
+  size_t amt = sizeof (struct coff_link_hash_table);
 
   ret = (struct coff_link_hash_table *) bfd_malloc (amt);
   if (ret == NULL)
 
   ret = (struct coff_link_hash_table *) bfd_malloc (amt);
   if (ret == NULL)
@@ -212,6 +212,12 @@ coff_link_check_archive_element (bfd *abfd,
   if (h->type != bfd_link_hash_undefined)
     return TRUE;
 
   if (h->type != bfd_link_hash_undefined)
     return TRUE;
 
+  /* If the archive element has already been loaded then one
+     of the symbols defined by that element might have been
+     made undefined due to being in a discarded section.  */
+  if (((struct coff_link_hash_entry *) h)->indx == -3)
+    return TRUE;
+
   /* PR 22369 - Skip non COFF objects in the archive.  */
   if (! bfd_family_coff (abfd))
     return TRUE;
   /* PR 22369 - Skip non COFF objects in the archive.  */
   if (! bfd_family_coff (abfd))
     return TRUE;
@@ -286,6 +292,7 @@ coff_link_add_symbols (bfd *abfd,
          asection *section;
          bfd_vma value;
          bfd_boolean addit;
          asection *section;
          bfd_vma value;
          bfd_boolean addit;
+         bfd_boolean discarded = FALSE;
 
          /* This symbol is externally visible.  */
 
 
          /* This symbol is externally visible.  */
 
@@ -311,7 +318,10 @@ coff_link_add_symbols (bfd *abfd,
              flags = BSF_EXPORT | BSF_GLOBAL;
              section = coff_section_from_bfd_index (abfd, sym.n_scnum);
              if (discarded_section (section))
              flags = BSF_EXPORT | BSF_GLOBAL;
              section = coff_section_from_bfd_index (abfd, sym.n_scnum);
              if (discarded_section (section))
-               section = bfd_und_section_ptr;
+               {
+                 discarded = TRUE;
+                 section = bfd_und_section_ptr;
+               }
              else if (! obj_pe (abfd))
                value -= section->vma;
              break;
              else if (! obj_pe (abfd))
                value -= section->vma;
              break;
@@ -408,6 +418,9 @@ coff_link_add_symbols (bfd *abfd,
                      (const char *) NULL, copy, FALSE,
                      (struct bfd_link_hash_entry **) sym_hash)))
                goto error_return;
                      (const char *) NULL, copy, FALSE,
                      (struct bfd_link_hash_entry **) sym_hash)))
                goto error_return;
+
+             if (discarded)
+               (*sym_hash)->indx = -3;
            }
 
          if (obj_pe (abfd) && (flags & BSF_SECTION_SYM) != 0)
            }
 
          if (obj_pe (abfd) && (flags & BSF_SECTION_SYM) != 0)
@@ -689,7 +702,7 @@ _bfd_coff_final_link (bfd *abfd,
          rel_filepos += o->reloc_count * relsz;
          /* In PE COFF, if there are at least 0xffff relocations an
             extra relocation will be written out to encode the count.  */
          rel_filepos += o->reloc_count * relsz;
          /* In PE COFF, if there are at least 0xffff relocations an
             extra relocation will be written out to encode the count.  */
-         if (obj_pe (abfd) && o->reloc_count >= 0xffff)
+         if ((obj_pe (abfd) || obj_go32 (abfd)) && o->reloc_count >= 0xffff)
            rel_filepos += relsz;
        }
 
            rel_filepos += relsz;
        }
 
@@ -993,41 +1006,20 @@ _bfd_coff_final_link (bfd *abfd,
   coff_debug_merge_hash_table_free (&flaginfo.debug_merge);
   debug_merge_allocated = FALSE;
 
   coff_debug_merge_hash_table_free (&flaginfo.debug_merge);
   debug_merge_allocated = FALSE;
 
-  if (flaginfo.internal_syms != NULL)
-    {
-      free (flaginfo.internal_syms);
-      flaginfo.internal_syms = NULL;
-    }
-  if (flaginfo.sec_ptrs != NULL)
-    {
-      free (flaginfo.sec_ptrs);
-      flaginfo.sec_ptrs = NULL;
-    }
-  if (flaginfo.sym_indices != NULL)
-    {
-      free (flaginfo.sym_indices);
-      flaginfo.sym_indices = NULL;
-    }
-  if (flaginfo.linenos != NULL)
-    {
-      free (flaginfo.linenos);
-      flaginfo.linenos = NULL;
-    }
-  if (flaginfo.contents != NULL)
-    {
-      free (flaginfo.contents);
-      flaginfo.contents = NULL;
-    }
-  if (flaginfo.external_relocs != NULL)
-    {
-      free (flaginfo.external_relocs);
-      flaginfo.external_relocs = NULL;
-    }
-  if (flaginfo.internal_relocs != NULL)
-    {
-      free (flaginfo.internal_relocs);
-      flaginfo.internal_relocs = NULL;
-    }
+  free (flaginfo.internal_syms);
+  flaginfo.internal_syms = NULL;
+  free (flaginfo.sec_ptrs);
+  flaginfo.sec_ptrs = NULL;
+  free (flaginfo.sym_indices);
+  flaginfo.sym_indices = NULL;
+  free (flaginfo.linenos);
+  flaginfo.linenos = NULL;
+  free (flaginfo.contents);
+  flaginfo.contents = NULL;
+  free (flaginfo.external_relocs);
+  flaginfo.external_relocs = NULL;
+  free (flaginfo.internal_relocs);
+  flaginfo.internal_relocs = NULL;
 
   /* The value of the last C_FILE symbol is supposed to be the symbol
      index of the first external symbol.  Write it out again if
 
   /* The value of the last C_FILE symbol is supposed to be the symbol
      index of the first external symbol.  Write it out again if
@@ -1066,11 +1058,8 @@ _bfd_coff_final_link (bfd *abfd,
     goto error_return;
 
   /* The outsyms buffer is used by _bfd_coff_write_global_sym.  */
     goto error_return;
 
   /* The outsyms buffer is used by _bfd_coff_write_global_sym.  */
-  if (flaginfo.outsyms != NULL)
-    {
-      free (flaginfo.outsyms);
-      flaginfo.outsyms = NULL;
-    }
+  free (flaginfo.outsyms);
+  flaginfo.outsyms = NULL;
 
   if (bfd_link_relocatable (info) && max_output_reloc_count > 0)
     {
 
   if (bfd_link_relocatable (info) && max_output_reloc_count > 0)
     {
@@ -1108,7 +1097,7 @@ _bfd_coff_final_link (bfd *abfd,
 
          if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0)
            goto error_return;
 
          if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0)
            goto error_return;
-         if (obj_pe (abfd) && o->reloc_count >= 0xffff)
+         if ((obj_pe (abfd) || obj_go32 (abfd)) && o->reloc_count >= 0xffff)
            {
              /* In PE COFF, write the count of relocs as the first
                 reloc.  The header overflow bit will be set
            {
              /* In PE COFF, write the count of relocs as the first
                 reloc.  The header overflow bit will be set
@@ -1141,10 +1130,8 @@ _bfd_coff_final_link (bfd *abfd,
 
       for (i = 0; i < abfd->section_count; i++)
        {
 
       for (i = 0; i < abfd->section_count; i++)
        {
-         if (flaginfo.section_info[i].relocs != NULL)
-           free (flaginfo.section_info[i].relocs);
-         if (flaginfo.section_info[i].rel_hashes != NULL)
-           free (flaginfo.section_info[i].rel_hashes);
+         free (flaginfo.section_info[i].relocs);
+         free (flaginfo.section_info[i].rel_hashes);
        }
       free (flaginfo.section_info);
       flaginfo.section_info = NULL;
        }
       free (flaginfo.section_info);
       flaginfo.section_info = NULL;
@@ -1203,31 +1190,20 @@ _bfd_coff_final_link (bfd *abfd,
 
       for (i = 0; i < abfd->section_count; i++)
        {
 
       for (i = 0; i < abfd->section_count; i++)
        {
-         if (flaginfo.section_info[i].relocs != NULL)
-           free (flaginfo.section_info[i].relocs);
-         if (flaginfo.section_info[i].rel_hashes != NULL)
-           free (flaginfo.section_info[i].rel_hashes);
+         free (flaginfo.section_info[i].relocs);
+         free (flaginfo.section_info[i].rel_hashes);
        }
       free (flaginfo.section_info);
     }
        }
       free (flaginfo.section_info);
     }
-  if (flaginfo.internal_syms != NULL)
-    free (flaginfo.internal_syms);
-  if (flaginfo.sec_ptrs != NULL)
-    free (flaginfo.sec_ptrs);
-  if (flaginfo.sym_indices != NULL)
-    free (flaginfo.sym_indices);
-  if (flaginfo.outsyms != NULL)
-    free (flaginfo.outsyms);
-  if (flaginfo.linenos != NULL)
-    free (flaginfo.linenos);
-  if (flaginfo.contents != NULL)
-    free (flaginfo.contents);
-  if (flaginfo.external_relocs != NULL)
-    free (flaginfo.external_relocs);
-  if (flaginfo.internal_relocs != NULL)
-    free (flaginfo.internal_relocs);
-  if (external_relocs != NULL)
-    free (external_relocs);
+  free (flaginfo.internal_syms);
+  free (flaginfo.sec_ptrs);
+  free (flaginfo.sym_indices);
+  free (flaginfo.outsyms);
+  free (flaginfo.linenos);
+  free (flaginfo.contents);
+  free (flaginfo.external_relocs);
+  free (flaginfo.internal_relocs);
+  free (external_relocs);
   return FALSE;
 }
 
   return FALSE;
 }
 
@@ -1286,8 +1262,7 @@ process_embedded_commands (bfd *output_bfd,
 
   if (!bfd_malloc_and_get_section (abfd, sec, &copy))
     {
 
   if (!bfd_malloc_and_get_section (abfd, sec, &copy))
     {
-      if (copy != NULL)
-       free (copy);
+      free (copy);
       return 0;
     }
   e = (char *) copy + sec->size;
       return 0;
     }
   e = (char *) copy + sec->size;
@@ -1647,7 +1622,7 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
          struct coff_debug_merge_element **epp;
          bfd_byte *esl, *eslend;
          struct internal_syment *islp;
          struct coff_debug_merge_element **epp;
          bfd_byte *esl, *eslend;
          struct internal_syment *islp;
-         bfd_size_type amt;
+         size_t amt;
 
          name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf);
          if (name == NULL)
 
          name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf);
          if (name == NULL)
@@ -2605,6 +2580,9 @@ _bfd_coff_write_global_sym (struct bfd_hash_entry *bh, void *data)
       return FALSE;
 
     case bfd_link_hash_undefined:
       return FALSE;
 
     case bfd_link_hash_undefined:
+      if (h->indx == -3)
+       return TRUE;
+      /* Fall through.  */
     case bfd_link_hash_undefweak:
       isym.n_scnum = N_UNDEF;
       isym.n_value = 0;
     case bfd_link_hash_undefweak:
       isym.n_scnum = N_UNDEF;
       isym.n_value = 0;
This page took 0.029465 seconds and 4 git commands to generate.