[gold patch] Add --no-gnu-unique option to disable STB_GNU_UNIQUE

Cary Coutant ccoutant@google.com
Thu Oct 27 21:54:00 GMT 2011


The use of STB_GNU_UNIQUE breaks a bunch of applications that expect
dlopen("lib", RTLD_LOCAL) to load "lib" in a local namespace. The
loader makes the subset of symbols that have STB_GNU_UNIQUE binding
global, regardless of the option to dlopen(), and the apps break
because of the unexpected sharing across namespaces. The attached
patch adds --[no-]gnu-unique options to control conversion of
STB_GNU_UNIQUE symbols into regular STB_GLOBAL symbols in the output
file.

OK?

-cary


	* options.h (class General_options): Add --[no-]gnu-unique options.
	* symtab.cc (Symbol_table::sized_write_globals): Convert
	STB_GNU_UNIQUE to STB_GLOBAL if --no-gnu-unique.
-------------- next part --------------
2011-10-27  Cary Coutant  <ccoutant@google.com>

	* options.h (class General_options): Add --[no-]gnu-unique options.
	* symtab.cc (Symbol_table::sized_write_globals): Convert
	STB_GNU_UNIQUE to STB_GLOBAL if --no-gnu-unique.


commit 80d88be500f6328258f58e8217bd38c4e18a069f
Author: Cary Coutant <ccoutant@google.com>
Date:   Thu Oct 27 14:37:16 2011 -0700

    Add --no-gnu-unique option.

diff --git a/gold/options.h b/gold/options.h
index 2837790..9909483 100644
--- a/gold/options.h
+++ b/gold/options.h
@@ -787,6 +787,10 @@ class General_options
   DEFINE_bool(g, options::EXACTLY_ONE_DASH, '\0', false,
 	      N_("Ignored"), NULL);
 
+  DEFINE_bool(gnu_unique, options::TWO_DASHES, '\0', true,
+	      N_("Enable STB_GNU_UNIQUE symbol binding (default)"),
+	      N_("Disable STB_GNU_UNIQUE symbol binding"));
+
   DEFINE_string(soname, options::ONE_DASH, 'h', NULL,
                 N_("Set shared library name"), N_("FILENAME"));
 
diff --git a/gold/symtab.cc b/gold/symtab.cc
index a90fee4..a5ea374 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -2822,6 +2822,12 @@ Symbol_table::sized_write_globals(const Stringpool* sympool,
       typename elfcpp::Elf_types<size>::Elf_Addr sym_value = sym->value();
       typename elfcpp::Elf_types<size>::Elf_Addr dynsym_value = sym_value;
       elfcpp::STB binding = sym->binding();
+
+      // If --no-gnu-unique is set, change STB_GNU_UNIQUE to STB_GLOBAL.
+      if (binding == elfcpp::STB_GNU_UNIQUE
+	  && !parameters->options().gnu_unique())
+	binding = elfcpp::STB_GLOBAL;
+
       switch (sym->source())
 	{
 	case Symbol::FROM_OBJECT:


More information about the Binutils mailing list