This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: PR ld/5789: Linker doesn't check weak and hidden symbols


Gcc 4.3 will optimize hidden symbol access. If a hidden symbol is
weak, it may lead to run-time failure for shared library and
PIE:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32219

Hidden symbol must be defined locally. A weak symbol may not
be defined locally. A weak hidden symbol isn't a problem for 
normal executable since linker can resolve it to 0. But for shared
library and PIE, it isn't easy to make sure that a weak hidden
symbol wil be 0 at run-time. It doesn't make senses to have a
weak hidden symbol in shared library and PIE. This patch checks
for it. If it is OK, I will update linker testsuite.


H.J.
----
2008-02-23  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/5789
	* elflink.c (_bfd_elf_symbol_refs_local_p): Always return true
	for hidden and local symbols.
	(elf_link_output_extsym): When creating a shared library, issue
	a fatal error if a weak symbol with hidden or internal visibility
	is not defined locally. 

--- bfd/elflink.c.hidden	2008-02-23 09:29:30.000000000 -0800
+++ bfd/elflink.c	2008-02-23 16:01:08.000000000 -0800
@@ -2829,6 +2829,11 @@ _bfd_elf_symbol_refs_local_p (struct elf
   if (h == NULL)
     return TRUE;
 
+  /* STV_HIDDEN or STV_INTERNAL ones must be local.  */
+  if (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
+      || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL)
+    return TRUE;
+
   /* Common symbols that become definitions don't get the DEF_REGULAR
      flag set, so test it first, and don't bail out.  */
   if (ELF_COMMON_DEF_P (h))
@@ -2857,10 +2862,6 @@ _bfd_elf_symbol_refs_local_p (struct elf
   if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
     return FALSE;
 
-  /* However, STV_HIDDEN or STV_INTERNAL ones must be local.  */
-  if (ELF_ST_VISIBILITY (h->other) != STV_PROTECTED)
-    return TRUE;
-
   hash_table = elf_hash_table (info);
   if (!is_elf_hash_table (hash_table))
     return TRUE;
@@ -8711,6 +8712,24 @@ elf_link_output_extsym (struct elf_link_
       return FALSE;
     }
 
+  /* When creating a shared library, it is a fatal error if a weak
+     symbol with hidden or internal visibility is not defined locally.  */
+  if (finfo->info->shared
+      && (ELF_ST_VISIBILITY (sym.st_other) == STV_HIDDEN
+	  || ELF_ST_VISIBILITY (sym.st_other) == STV_INTERNAL)
+      && h->root.type == bfd_link_hash_undefweak 
+      && !h->def_regular)
+    {
+      (*_bfd_error_handler)
+	(_("%B: weak %s symbol `%s' isn't defined"),
+	 finfo->output_bfd,
+	 ELF_ST_VISIBILITY (sym.st_other) == STV_INTERNAL
+	 ? "internal" : "hidden",
+	 h->root.root.string);
+      eoinfo->failed = TRUE;
+      return FALSE;
+    }
+
   /* If this symbol should be put in the .dynsym section, then put it
      there now.  We already know the symbol index.  We also fill in
      the entry in the .hash section.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]