* archive.cc (Library_base::should_include_member): Check for
authorCary Coutant <ccoutant@google.com>
Tue, 17 Apr 2012 00:28:41 +0000 (00:28 +0000)
committerCary Coutant <ccoutant@google.com>
Tue, 17 Apr 2012 00:28:41 +0000 (00:28 +0000)
--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.

gold/ChangeLog
gold/archive.cc
gold/options.h
gold/symtab.cc

index 83d910559380eb34d90c9859c3f15577bd3e6af7..471db35160b90517af3bffaf7e79363b5fd9ff3a 100644 (file)
@@ -1,3 +1,13 @@
+2012-04-16  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.
+
 2012-04-12  David S. Miller  <davem@davemloft.net>
 
        * sparc.cc (Reloc::wdisp10): New relocation method.
index c2e6ff63db2be11b184ddb0437dfb3a78214588f..4db813d6dffa4f29ee8e54d42e5e3b865baa29aa 100644 (file)
@@ -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);
index b5df3ebf2af7b92f17f1af9738c1de4446589aaa..b244bd54b39490dda10acaaadf3f5359bdca3337 100644 (file)
@@ -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);
 
index f0ba1d560fb5563d5bfa4d80f358c90ab7307959..1edb88da4d83c0729b2285263f9d134a3245750a 100644 (file)
@@ -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();