]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - bfd/elflink.h
* config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
[thirdparty/binutils-gdb.git] / bfd / elflink.h
index bbd8339826456f2f107dd8757662e9ea9ff346f9..6b263ec71972c3558acaaf8ea3d07b4c14df7f29 100644 (file)
@@ -2240,13 +2240,10 @@ compute_bucket_count (info)
   elf_link_hash_traverse (elf_hash_table (info),
                          elf_collect_hash_codes, &hashcodesp);
 
-/* We have a problem here.  The following code to optimize the table size
-   requires an integer type with more the 32 bits.  If BFD_HOST_U_64_BIT
-   is set or GCC 2 is used we know about such a type.  */
-#if defined BFD_HOST_U_64_BIT || __GNUC__ >= 2
-# ifndef BFD_HOST_U_64_BIT
-#  define BFD_HOST_U_64_BIT    unsigned long long int
-# endif
+/* We have a problem here.  The following code to optimize the table
+   size requires an integer type with more the 32 bits.  If
+   BFD_HOST_U_64_BIT is set we know about such a type.  */
+#ifdef BFD_HOST_U_64_BIT
   if (info->optimize == true)
     {
       unsigned long int nsyms = hashcodesp - hashcodes;
@@ -2259,6 +2256,8 @@ compute_bucket_count (info)
         that the hashing table must at least have NSYMS/4 and at most
         2*NSYMS buckets.  */
       minsize = nsyms / 4;
+      if (minsize == 0)
+       minsize = 1;
       best_size = maxsize = nsyms * 2;
 
       /* Create array where we count the collisions in.  We must use bfd_malloc
@@ -2334,7 +2333,7 @@ compute_bucket_count (info)
       free (counts);
     }
   else
-#endif
+#endif /* defined (BFD_HOST_U_64_BIT) */
     {
       /* This is the fallback solution if no 64bit type is available or if we
         are not supposed to spend much time on optimizations.  We select the
@@ -2984,6 +2983,25 @@ elf_fix_symbol_flags (h, eif)
            }
        }
     }
+  else
+    {
+      /* Unfortunately, ELF_LINK_NON_ELF is only correct if the symbol
+         was first seen in a non-ELF file.  Fortunately, if the symbol
+         was first seen in an ELF file, we're probably OK unless the
+         symbol was defined in a non-ELF file.  Catch that case here.
+         FIXME: We're still in trouble if the symbol was first seen in
+         a dynamic object, and then later in a non-ELF regular object.  */
+      if ((h->root.type == bfd_link_hash_defined
+          || h->root.type == bfd_link_hash_defweak)
+         && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
+         && (h->root.u.def.section->owner != NULL
+             ? (bfd_get_flavour (h->root.u.def.section->owner)
+                != bfd_target_elf_flavour)
+             : (bfd_is_abs_section (h->root.u.def.section)
+                && (h->elf_link_hash_flags
+                    & ELF_LINK_HASH_DEF_DYNAMIC) == 0)))
+       h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+    }
 
   /* If this is a final link, and the symbol was defined as a common
      symbol in a regular object file, and there was no definition in
@@ -3117,6 +3135,18 @@ elf_adjust_dynamic_symbol (h, data)
        }
     }
 
+  /* If a symbol has no type and no size and does not require a PLT
+     entry, then we are probably about to do the wrong thing here: we
+     are probably going to create a COPY reloc for an empty object.
+     This case can arise when a shared object is built with assembly
+     code, and the assembly code fails to set the symbol type.  */
+  if (h->size == 0
+      && h->type == STT_NOTYPE
+      && (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) == 0)
+    (*_bfd_error_handler)
+      (_("warning: type and size of dynamic symbol `%s' are not defined"),
+        h->root.root.string);
+
   dynobj = elf_hash_table (eif->info)->dynobj;
   bed = get_elf_backend_data (dynobj);
   if (! (*bed->elf_backend_adjust_dynamic_symbol) (eif->info, h))
@@ -4295,6 +4325,8 @@ elf_link_output_sym (finfo, name, elfsym, input_sec)
 
   if (name == (const char *) NULL || *name == '\0')
     elfsym->st_name = 0;
+  else if (input_sec->flags & SEC_EXCLUDE)
+    elfsym->st_name = 0;
   else
     {
       elfsym->st_name = (unsigned long) _bfd_stringtab_add (finfo->symstrtab,