[gold patch] Add --export-dynamic-symbol option

Cary Coutant ccoutant@google.com
Fri Apr 13 01:26:00 GMT 2012


This patch adds a new command-line option --export-dynamic-symbol=sym.
It's similar to --dynamic-list=list, but takes a single, mangled,
symbol name from the command line rather than using a version script
file. Like -u, it can be used repeatedly, and the symbols named by
this option will be treated as referenced, will cause an archive
member to be loaded, and will not be garbage collected.

Symbols named via --dynamic-list, on the other hand, do not prevent
garbage collection and do not cause archive members to be loaded. I
considered changing that, but decided not to at this time. If we do
decide to change that option, I'd want to do that as a separate patch.
Symbols in that file work more like a version script -- they're
treated as demangled names, may have approximate matching, there's no
error if such a symbol is never defined, and we check that list only
after garbage collection has taken place -- so it didn't quite seem
appropriate to make that option work the same way. The --dynamic-list
option is more like the --dynamic-list-xxx options: more passive,
applying only to symbols that have already survived archive selection
and garbage collection.

I've added a warning if there's an attempt to export a forced-local
symbol (e.g., a symbol with "hidden" visibility).

OK to commit?

-cary

	* archive.cc (Library_base::should_include_member): Check for
	--export-dynamic-symbol.
	* options.h (class General_options): Add --export-dynamic-symbol.
	* symtab.cc (Symbol::should_add_dynsym_entry): Check for
	--export-dynamic-symbol.
	(Symbol_table::gc_mark_undef_symbols): Likewise.
	(Symbol_table::do_add_undefined_symbols_from_command_line): Likewise.
-------------- next part --------------
2012-04-12  Cary Coutant  <ccoutant@google.com>

	* archive.cc (Library_base::should_include_member): Check for
	--export-dynamic-symbol.
	* options.h (class General_options): Add --export-dynamic-symbol.
	* symtab.cc (Symbol::should_add_dynsym_entry): Check for
	--export-dynamic-symbol.
	(Symbol_table::gc_mark_undef_symbols): Likewise.
	(Symbol_table::do_add_undefined_symbols_from_command_line): Likewise.


commit 0d5b3ac553d8f1cbd8bdeaa58f0e063881c8fbc4
Author: Cary Coutant <ccoutant@google.com>
Date:   Thu Apr 12 17:52:13 2012 -0700

    Add --export-dynamic-symbol option.

diff --git a/gold/archive.cc b/gold/archive.cc
index c2e6ff6..4db813d 100644
--- a/gold/archive.cc
+++ b/gold/archive.cc
@@ -104,6 +104,11 @@ Library_base::should_include_member(Symbol_table* symtab, Layout* layout,
           *why = "-u ";
           *why += sym_name;
         }
+      else if (parameters->options().is_export_dynamic_symbol(sym_name))
+        {
+          *why = "--export-dynamic-symbol ";
+          *why += sym_name;
+        }
       else if (layout->script_options()->is_referenced(sym_name))
 	{
 	  size_t alc = 100 + strlen(sym_name);
diff --git a/gold/options.h b/gold/options.h
index b5df3eb..b244bd5 100644
--- a/gold/options.h
+++ b/gold/options.h
@@ -739,6 +739,9 @@ class General_options
               N_("Export all dynamic symbols"),
 	      N_("Do not export all dynamic symbols (default)"));
 
+  DEFINE_set(export_dynamic_symbol, options::TWO_DASHES, '\0',
+	     N_("Export SYMBOL to dynamic symbol table"), N_("SYMBOL"));
+
   DEFINE_special(EB, options::ONE_DASH, '\0',
 		 N_("Link big-endian objects."), NULL);
 
diff --git a/gold/symtab.cc b/gold/symtab.cc
index f0ba1d5..1edb88d 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -363,14 +363,22 @@ Symbol::should_add_dynsym_entry(Symbol_table* symtab) const
         return false;
     }
 
+  // If the symbol was forced dynamic in a --dynamic-list file
+  // or an --export-dynamic-symbol option, add it.
+  if (parameters->options().in_dynamic_list(this->name())
+      || parameters->options().is_export_dynamic_symbol(this->name()))
+    {
+      if (!this->is_forced_local())
+        return true;
+      gold_warning(_("Cannot export local symbol '%s'"),
+		   this->demangled_name().c_str());
+      return false;
+    }
+
   // If the symbol was forced local in a version script, do not add it.
   if (this->is_forced_local())
     return false;
 
-  // If the symbol was forced dynamic in a --dynamic-list file, add it.
-  if (parameters->options().in_dynamic_list(this->name()))
-    return true;
-
   // If dynamic-list-data was specified, add any STT_OBJECT.
   if (parameters->options().dynamic_list_data()
       && !this->is_from_dynobj()
@@ -551,8 +559,8 @@ Symbol_table::is_section_folded(Object* obj, unsigned int shndx) const
           && this->icf_->is_section_folded(obj, shndx));
 }
 
-// For symbols that have been listed with -u option, add them to the
-// work list to avoid gc'ing them.
+// For symbols that have been listed with a -u or --export-dynamic-symbol
+// option, add them to the work list to avoid gc'ing them.
 
 void 
 Symbol_table::gc_mark_undef_symbols(Layout* layout)
@@ -579,6 +587,28 @@ Symbol_table::gc_mark_undef_symbols(Layout* layout)
         }
     }
 
+  for (options::String_set::const_iterator p =
+	 parameters->options().export_dynamic_symbol_begin();
+       p != parameters->options().export_dynamic_symbol_end();
+       ++p)
+    {
+      const char* name = p->c_str();
+      Symbol* sym = this->lookup(name);
+      gold_assert(sym != NULL);
+      if (sym->source() == Symbol::FROM_OBJECT 
+          && !sym->object()->is_dynamic())
+        {
+          Relobj* obj = static_cast<Relobj*>(sym->object());
+          bool is_ordinary;
+          unsigned int shndx = sym->shndx(&is_ordinary);
+          if (is_ordinary)
+            {
+              gold_assert(this->gc_ != NULL);
+              this->gc_->worklist().push(Section_id(obj, shndx));
+            }
+        }
+    }
+
   for (Script_options::referenced_const_iterator p =
 	 layout->script_options()->referenced_begin();
        p != layout->script_options()->referenced_end();
@@ -2291,6 +2321,12 @@ Symbol_table::do_add_undefined_symbols_from_command_line(Layout* layout)
        ++p)
     this->add_undefined_symbol_from_command_line<size>(p->c_str());
 
+  for (options::String_set::const_iterator p =
+	 parameters->options().export_dynamic_symbol_begin();
+       p != parameters->options().export_dynamic_symbol_end();
+       ++p)
+    this->add_undefined_symbol_from_command_line<size>(p->c_str());
+
   for (Script_options::referenced_const_iterator p =
 	 layout->script_options()->referenced_begin();
        p != layout->script_options()->referenced_end();


More information about the Binutils mailing list