This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: PR ld/5789: Linker doesn't check weak and hidden symbols
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: binutils at sources dot redhat dot com
- Date: Sat, 23 Feb 2008 16:11:11 -0800
- Subject: 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. */