PR 11855
authorIan Lance Taylor <ian@airs.com>
Mon, 2 Aug 2010 13:34:33 +0000 (13:34 +0000)
committerIan Lance Taylor <ian@airs.com>
Mon, 2 Aug 2010 13:34:33 +0000 (13:34 +0000)
* script.cc (Script_options::Script_options): Initialize
symbol_definitions_ and symbol_references_.
(Script_options::add_symbol_assignment): Update
symbol_definitions_ and symbol_references_.
(Script_options::add_symbol_reference): New function.
(script_symbol): New function.
* script.h (class Script_options): Add symbol_definitions_ and
symbol_references_ fields.
(Script_options::referenced_const_iterator): New type.
(Script_options::referenced_begin): New function.
(Script_options::referenced_end): New function.
(Script_options::is_referenced): New function.
(Script_options::any_unreferenced): New function.
* script-c.h (script_symbol): Declare.
* yyscript.y (exp): Call script_symbol.
* symtab.cc: Include "script.h".
(Symbol_table::gc_mark_undef_symbols): Add layout parameter.
Change all callers.  Check symbols referenced by scripts.
(Symbol_table::add_undefined_symbols_from_command_line): Add
layout parameter.  Change all callers.
(Symbol_table::do_add_undefined_symbols_from_command_line):
Likewise.  Break out loop body.  Check symbols referenced by
scripts.
(Symbol_table::add_undefined_symbol_from_command_line): New
function broken out of
do_add_undefined_symbols_from_command_line.
* symtab.h (class Symbol_table): Update declarations.
* archive.cc: Include "layout.h".
(Archive::should_include_member): Add layout parameter.  Change
all callers.  Check for symbol mentioned in expression.
* archive.h (class Archive): Update declaration.
* object.cc (Sized_relobj::do_should_include_member): Add layout
parameter.
* object.h (Object::should_include_member): Add layout parameter.
Change all callers.
(Object::do_should_include_member): Add layout parameter.
(class Sized_relobj): Update declaration.
* dynobj.cc (Sized_dynobj::do_should_include_member): Add layout
parameter.
* dynobj.h (class Sized_dynobj): Update declaration.
* plugin.cc (Sized_pluginobj::do_should_include_member): Add
layout parameter.
* plugin.h (class Sized_pluginobj): Update declaration.

16 files changed:
gold/ChangeLog
gold/archive.cc
gold/archive.h
gold/dynobj.cc
gold/dynobj.h
gold/gold.cc
gold/object.cc
gold/object.h
gold/plugin.cc
gold/plugin.h
gold/script-c.h
gold/script.cc
gold/script.h
gold/symtab.cc
gold/symtab.h
gold/yyscript.y

index 97f7977495a88bfab3ec27f36d2f9acabe2ace3b..b08fcdfb59f2c5b377a02b6de149437a76a45a76 100644 (file)
@@ -1,3 +1,50 @@
+2010-08-02  Ian Lance Taylor  <iant@google.com>
+
+       PR 11855
+       * script.cc (Script_options::Script_options): Initialize
+       symbol_definitions_ and symbol_references_.
+       (Script_options::add_symbol_assignment): Update
+       symbol_definitions_ and symbol_references_.
+       (Script_options::add_symbol_reference): New function.
+       (script_symbol): New function.
+       * script.h (class Script_options): Add symbol_definitions_ and
+       symbol_references_ fields.
+       (Script_options::referenced_const_iterator): New type.
+       (Script_options::referenced_begin): New function.
+       (Script_options::referenced_end): New function.
+       (Script_options::is_referenced): New function.
+       (Script_options::any_unreferenced): New function.
+       * script-c.h (script_symbol): Declare.
+       * yyscript.y (exp): Call script_symbol.
+       * symtab.cc: Include "script.h".
+       (Symbol_table::gc_mark_undef_symbols): Add layout parameter.
+       Change all callers.  Check symbols referenced by scripts.
+       (Symbol_table::add_undefined_symbols_from_command_line): Add
+       layout parameter.  Change all callers.
+       (Symbol_table::do_add_undefined_symbols_from_command_line):
+       Likewise.  Break out loop body.  Check symbols referenced by
+       scripts.
+       (Symbol_table::add_undefined_symbol_from_command_line): New
+       function broken out of
+       do_add_undefined_symbols_from_command_line.
+       * symtab.h (class Symbol_table): Update declarations.
+       * archive.cc: Include "layout.h".
+       (Archive::should_include_member): Add layout parameter.  Change
+       all callers.  Check for symbol mentioned in expression.
+       * archive.h (class Archive): Update declaration.
+       * object.cc (Sized_relobj::do_should_include_member): Add layout
+       parameter.
+       * object.h (Object::should_include_member): Add layout parameter.
+       Change all callers.
+       (Object::do_should_include_member): Add layout parameter.
+       (class Sized_relobj): Update declaration.
+       * dynobj.cc (Sized_dynobj::do_should_include_member): Add layout
+       parameter.
+       * dynobj.h (class Sized_dynobj): Update declaration.
+       * plugin.cc (Sized_pluginobj::do_should_include_member): Add
+       layout parameter.
+       * plugin.h (class Sized_pluginobj): Update declaration.
+
 2010-08-02  Ian Lance Taylor  <iant@google.com>
 
        PR 11866
index 202fc2c8eb3afd4f1f468e8aca5f469bce10520a..f1000a195de25c38588ae3960188767cc7fae337 100644 (file)
@@ -36,6 +36,7 @@
 #include "readsyms.h"
 #include "symtab.h"
 #include "object.h"
+#include "layout.h"
 #include "archive.h"
 #include "plugin.h"
 
@@ -603,8 +604,9 @@ Archive::read_symbols(off_t off)
 }
 
 Archive::Should_include
-Archive::should_include_member(Symbol_table* symtab, const char* sym_name,
-                               Symbol** symp, std::string* why, char** tmpbufp,
+Archive::should_include_member(Symbol_table* symtab, Layout* layout,
+                              const char* sym_name, Symbol** symp,
+                              std::string* why, char** tmpbufp,
                                size_t* tmpbuflen)
 {
   // In an object file, and therefore in an archive map, an
@@ -648,13 +650,22 @@ Archive::should_include_member(Symbol_table* symtab, const char* sym_name,
   if (sym == NULL)
     {
       // Check whether the symbol was named in a -u option.
-      if (!parameters->options().is_undefined(sym_name))
-       return Archive::SHOULD_INCLUDE_UNKNOWN;
-      else
+      if (parameters->options().is_undefined(sym_name))
         {
           *why = "-u ";
           *why += sym_name;
         }
+      else if (layout->script_options()->is_referenced(sym_name))
+       {
+         size_t alc = 100 + strlen(sym_name);
+         char* buf = new char[alc];
+         snprintf(buf, alc, _("script or expression reference to %s"),
+                  sym_name);
+         *why = buf;
+         delete[] buf;
+       }
+      else
+       return Archive::SHOULD_INCLUDE_UNKNOWN;
     }
   else if (!sym->is_undefined())
     return Archive::SHOULD_INCLUDE_NO;
@@ -726,8 +737,8 @@ Archive::add_symbols(Symbol_table* symtab, Layout* layout,
           Symbol* sym;
           std::string why;
           Archive::Should_include t =
-              Archive::should_include_member(symtab, sym_name, &sym, &why,
-                                             &tmpbuf, &tmpbuflen);
+           Archive::should_include_member(symtab, layout, sym_name, &sym,
+                                          &why, &tmpbuf, &tmpbuflen);
 
          if (t == Archive::SHOULD_INCLUDE_NO
               || t == Archive::SHOULD_INCLUDE_YES)
@@ -1015,6 +1026,7 @@ Lib_group::add_symbols(Symbol_table* symtab, Layout* layout,
              && (member.sd_ == NULL || member.sd_->symbol_names != NULL))
             {
              Archive::Should_include t = obj->should_include_member(symtab,
+                                                                    layout,
                                                                     member.sd_,
                                                                     &why);
 
index a2d2af485e08134bec24fc578dc382ac3b7267cf..bff34576ecae225bcea734052e33d9687497b787 100644 (file)
@@ -176,7 +176,7 @@ class Archive
   };
 
   static Should_include
-  should_include_member(Symbol_table* symtab, const char* sym_name,
+  should_include_member(Symbol_table* symtab, Layout*, const char* sym_name,
                         Symbol** symp, std::string* why, char** tmpbufp,
                         size_t* tmpbuflen);
 
index 81bc085b46ad2dea96265bd1ba5a2c86fed4a722..e4a976dcba079ea5a893bef1316292f8671fb9ba 100644 (file)
@@ -753,8 +753,10 @@ Sized_dynobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
 
 template<int size, bool big_endian>
 Archive::Should_include
-Sized_dynobj<size, big_endian>::do_should_include_member(
-    Symbol_table*, Read_symbols_data*, std::string*)
+Sized_dynobj<size, big_endian>::do_should_include_member(Symbol_table*,
+                                                        Layout*,
+                                                        Read_symbols_data*,
+                                                        std::string*)
 {
   return Archive::SHOULD_INCLUDE_YES;
 }
index 08cf78db725663e12f2ab6b2903e945a61980b15..8787adaab60750428a139b55f738d69301de1d83 100644 (file)
@@ -178,7 +178,7 @@ class Sized_dynobj : public Dynobj
   do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*);
 
   Archive::Should_include
-  do_should_include_member(Symbol_table* symtab, Read_symbols_data*,
+  do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
                            std::string* why);
 
   // Get the size of a section.
index ba02db2f1bfd1398acede50bea46b5177df2bce4..541d177be55f14ab14aea70c5ce4ce80c488dad3 100644 (file)
@@ -309,7 +309,7 @@ queue_middle_tasks(const General_options& options,
                   Mapfile* mapfile)
 {
   // Add any symbols named with -u options to the symbol table.
-  symtab->add_undefined_symbols_from_command_line();
+  symtab->add_undefined_symbols_from_command_line(layout);
 
   // If garbage collection was chosen, relocs have been read and processed
   // at this point by pre_middle_tasks.  Layout can then be done for all 
@@ -333,7 +333,7 @@ queue_middle_tasks(const General_options& options,
             }
         }
       // Symbols named with -u should not be considered garbage.
-      symtab->gc_mark_undef_symbols();
+      symtab->gc_mark_undef_symbols(layout);
       gold_assert(symtab->gc() != NULL);
       // Do a transitive closure on all references to determine the worklist.
       symtab->gc()->do_transitive_closure();
index ed87b1aef143911e23e63d9af73f5c1b2b750c93..1bf73677f62e93e4f7dad294ed13f311784ebf54 100644 (file)
@@ -1614,6 +1614,7 @@ Sized_relobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
 template<int size, bool big_endian>
 Archive::Should_include
 Sized_relobj<size, big_endian>::do_should_include_member(Symbol_table* symtab,
+                                                        Layout* layout,
                                                          Read_symbols_data* sd,
                                                          std::string* why)
 {
@@ -1639,7 +1640,9 @@ Sized_relobj<size, big_endian>::do_should_include_member(Symbol_table* symtab,
       unsigned int st_name = sym.get_st_name();
       const char* name = sym_names + st_name;
       Symbol* symbol;
-      Archive::Should_include t = Archive::should_include_member(symtab, name,
+      Archive::Should_include t = Archive::should_include_member(symtab,
+                                                                layout,
+                                                                name,
                                                                 &symbol, why,
                                                                 &tmpbuf,
                                                                 &tmpbuflen);
index f60d90972e78d85474e1b02da6dd92fc02506358..59b723fab40d802c918f141fdef28fc7bccf11a1 100644 (file)
@@ -405,9 +405,9 @@ class Object
 
   // Add symbol information to the global symbol table.
   Archive::Should_include
-  should_include_member(Symbol_table* symtab, Read_symbols_data* sd,
-                        std::string* why)
-  { return this->do_should_include_member(symtab, sd, why); }
+  should_include_member(Symbol_table* symtab, Layout* layout,
+                       Read_symbols_data* sd, std::string* why)
+  { return this->do_should_include_member(symtab, layout, sd, why); }
 
   // Functions and types for the elfcpp::Elf_file interface.  This
   // permit us to use Object as the File template parameter for
@@ -546,7 +546,7 @@ class Object
   do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*) = 0;
 
   virtual Archive::Should_include
-  do_should_include_member(Symbol_table* symtab, Read_symbols_data*,
+  do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
                            std::string* why) = 0;
 
   // Return the location of the contents of a section.  Implemented by
@@ -1623,7 +1623,7 @@ class Sized_relobj : public Relobj
   do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*);
 
   Archive::Should_include
-  do_should_include_member(Symbol_table* symtab, Read_symbols_data*,
+  do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
                            std::string* why);
 
   // Read the relocs.
index 76b24314c46325ad415f7c7f2a185d55c0ee3c4f..1c86c03b422415647dec82a80c0b781ae55e24ab 100644 (file)
@@ -705,26 +705,32 @@ Sized_pluginobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
 template<int size, bool big_endian>
 Archive::Should_include
 Sized_pluginobj<size, big_endian>::do_should_include_member(
-    Symbol_table* symtab, Read_symbols_data*, std::string* why)
+    Symbol_table* symtab,
+    Layout* layout,
+    Read_symbols_data*,
+    std::string* why)
 {
   char* tmpbuf = NULL;
   size_t tmpbuflen = 0;
 
-  for (int i = 0; i < this->nsyms_; ++i) {
-    const struct ld_plugin_symbol& sym = this->syms_[i];
-    const char* name = sym.name;
-    Symbol* symbol;
-    Archive::Should_include t = Archive::should_include_member(symtab, name,
-                                                               &symbol, why,
-                                                               &tmpbuf,
-                                                               &tmpbuflen);
+  for (int i = 0; i < this->nsyms_; ++i)
+    {
+      const struct ld_plugin_symbol& sym = this->syms_[i];
+      const char* name = sym.name;
+      Symbol* symbol;
+      Archive::Should_include t = Archive::should_include_member(symtab,
+                                                                layout,
+                                                                name,
+                                                                &symbol, why,
+                                                                &tmpbuf,
+                                                                &tmpbuflen);
       if (t == Archive::SHOULD_INCLUDE_YES)
        {
          if (tmpbuf != NULL)
            free(tmpbuf);
          return t;
        }
-  }
+    }
   if (tmpbuf != NULL)
     free(tmpbuf);
   return Archive::SHOULD_INCLUDE_UNKNOWN;
index 81c3be6508bd83a46ef72a8ee19e596e16073702..47e634e7a12cdd740be8675ade7ef37ae5dad2e7 100644 (file)
@@ -376,7 +376,7 @@ class Sized_pluginobj : public Pluginobj
   do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*);
 
   Archive::Should_include
-  do_should_include_member(Symbol_table* symtab, Read_symbols_data*,
+  do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
                            std::string* why);
 
   // Get the size of a section.
index 29901e3c3a8c77887b4bf44de1096980379a8a70..1f79eacdd99b464315dc7cde0cac03c49265fe7f 100644 (file)
@@ -303,6 +303,14 @@ script_push_lex_into_version_mode(void* closure);
 extern void
 script_pop_lex_mode(void* closure);
 
+/* Called by the bison parser to get the value of a symbol.  This is
+   called for a reference to a symbol, but is not called for something
+   like "sym += 10".  Uses of the special symbol "." can just call
+   script_exp_string.  */
+
+extern Expression_ptr
+script_symbol(void* closure, const char*, size_t);
+
 /* Called by the bison parser to set a symbol to a value.  PROVIDE is
    non-zero if the symbol should be provided--only defined if there is
    an undefined reference.  HIDDEN is non-zero if the symbol should be
index 2cdaae6384e5f5e9dbd6472029292219a6cdca0c..e0b9359abdc03adabc3757f04bf045c6bfed1a87 100644 (file)
@@ -1045,8 +1045,8 @@ Script_assertion::print(FILE* f) const
 // Class Script_options.
 
 Script_options::Script_options()
-  : entry_(), symbol_assignments_(), version_script_info_(),
-    script_sections_()
+  : entry_(), symbol_assignments_(), symbol_definitions_(),
+    symbol_references_(), version_script_info_(), script_sections_()
 {
 }
 
@@ -1071,6 +1071,13 @@ Script_options::add_symbol_assignment(const char* name, size_t length,
                                                       value, provide, hidden);
          this->symbol_assignments_.push_back(p);
        }
+
+      if (!provide)
+       {
+         std::string n(name, length);
+         this->symbol_definitions_.insert(n);
+         this->symbol_references_.erase(n);
+       }
     }
   else
     {
@@ -1084,6 +1091,19 @@ Script_options::add_symbol_assignment(const char* name, size_t length,
     }
 }
 
+// Add a reference to a symbol.
+
+void
+Script_options::add_symbol_reference(const char* name, size_t length)
+{
+  if (length != 1 || name[0] != '.')
+    {
+      std::string n(name, length);
+      if (this->symbol_definitions_.find(n) == this->symbol_definitions_.end())
+       this->symbol_references_.insert(n);
+    }
+}
+
 // Add an assertion.
 
 void
@@ -2679,6 +2699,17 @@ script_set_common_allocation(void* closurev, int set)
   script_parse_option(closurev, arg, strlen(arg));
 }
 
+// Called by the bison parser to refer to a symbol.
+
+extern "C" Expression*
+script_symbol(void *closurev, const char* name, size_t length)
+{
+  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
+  if (length != 1 || name[0] != '.')
+    closure->script_options()->add_symbol_reference(name, length);
+  return script_exp_string(name, length);
+}
+
 // Called by the bison parser to define a symbol.
 
 extern "C" void
index 3b8cb92f1c8462a18b651bb45640f02a36c224b9..70e3a59e7b44814caecd08017dacea5f94518a1e 100644 (file)
@@ -423,6 +423,10 @@ class Script_options
   add_symbol_assignment(const char* name, size_t length, bool is_defsym,
                        Expression* value, bool provide, bool hidden);
 
+  // Add a reference to a symbol.
+  void
+  add_symbol_reference(const char* name, size_t length);
+
   // Add an assertion.
   void
   add_assertion(Expression* check, const char* message, size_t messagelen);
@@ -439,6 +443,32 @@ class Script_options
   void
   add_symbols_to_table(Symbol_table*);
 
+  // Used to iterate over symbols which are referenced in expressions
+  // but not defined.
+  typedef Unordered_set<std::string>::const_iterator referenced_const_iterator;
+
+  referenced_const_iterator
+  referenced_begin() const
+  { return this->symbol_references_.begin(); }
+
+  referenced_const_iterator
+  referenced_end() const
+  { return this->symbol_references_.end(); }
+
+  // Return whether a symbol is referenced but not defined.
+  bool
+  is_referenced(const std::string& name) const
+  {
+    return (this->symbol_references_.find(name)
+           != this->symbol_references_.end());
+  }
+
+  // Return whether there are any symbols which were referenced but
+  // not defined.
+  bool
+  any_unreferenced() const
+  { return !this->symbol_references_.empty(); }
+
   // Finalize the symbol values.  Also check assertions.
   void
   finalize_symbols(Symbol_table*, const Layout*);
@@ -497,6 +527,10 @@ class Script_options
   std::string entry_;
   // Symbols to set.
   Symbol_assignments symbol_assignments_;
+  // Symbols defined in an expression, for faster lookup.
+  Unordered_set<std::string> symbol_definitions_;
+  // Symbols referenced in an expression.
+  Unordered_set<std::string> symbol_references_;
   // Assertions to check.
   Assertions assertions_;
   // Version information parsed from a version script.
index a29e6adeda9a40b6b629cf04f034beb02809bc52..f46d8deb75a464a56487f3710d411053eb97d146 100644 (file)
@@ -38,7 +38,7 @@
 #include "target.h"
 #include "workqueue.h"
 #include "symtab.h"
-#include "demangle.h"   // needed for --dynamic-list-cpp-new
+#include "script.h"
 #include "plugin.h"
 
 namespace gold
@@ -530,7 +530,7 @@ Symbol_table::is_section_folded(Object* obj, unsigned int shndx) const
 // work list to avoid gc'ing them.
 
 void 
-Symbol_table::gc_mark_undef_symbols()
+Symbol_table::gc_mark_undef_symbols(Layout* layout)
 {
   for (options::String_set::const_iterator p =
         parameters->options().undefined_begin();
@@ -553,6 +553,27 @@ Symbol_table::gc_mark_undef_symbols()
             }
         }
     }
+
+  for (Script_options::referenced_const_iterator p =
+        layout->script_options()->referenced_begin();
+       p != layout->script_options()->referenced_end();
+       ++p)
+    {
+      Symbol* sym = this->lookup(p->c_str());
+      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));
+           }
+       }
+    }
 }
 
 void
@@ -2163,14 +2184,15 @@ Symbol_table::get_copy_source(const Symbol* sym) const
 // Add any undefined symbols named on the command line.
 
 void
-Symbol_table::add_undefined_symbols_from_command_line()
+Symbol_table::add_undefined_symbols_from_command_line(Layout* layout)
 {
-  if (parameters->options().any_undefined())
+  if (parameters->options().any_undefined()
+      || layout->script_options()->any_unreferenced())
     {
       if (parameters->target().get_size() == 32)
        {
 #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
-         this->do_add_undefined_symbols_from_command_line<32>();
+         this->do_add_undefined_symbols_from_command_line<32>(layout);
 #else
          gold_unreachable();
 #endif
@@ -2178,7 +2200,7 @@ Symbol_table::add_undefined_symbols_from_command_line()
       else if (parameters->target().get_size() == 64)
        {
 #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
-         this->do_add_undefined_symbols_from_command_line<64>();
+         this->do_add_undefined_symbols_from_command_line<64>(layout);
 #else
          gold_unreachable();
 #endif
@@ -2190,50 +2212,59 @@ Symbol_table::add_undefined_symbols_from_command_line()
 
 template<int size>
 void
-Symbol_table::do_add_undefined_symbols_from_command_line()
+Symbol_table::do_add_undefined_symbols_from_command_line(Layout* layout)
 {
   for (options::String_set::const_iterator p =
         parameters->options().undefined_begin();
        p != parameters->options().undefined_end();
        ++p)
-    {
-      const char* name = p->c_str();
+    this->add_undefined_symbol_from_command_line<size>(p->c_str());
 
-      if (this->lookup(name) != NULL)
-       continue;
+  for (Script_options::referenced_const_iterator p =
+        layout->script_options()->referenced_begin();
+       p != layout->script_options()->referenced_end();
+       ++p)
+    this->add_undefined_symbol_from_command_line<size>(p->c_str());
+}
+
+template<int size>
+void
+Symbol_table::add_undefined_symbol_from_command_line(const char* name)
+{
+  if (this->lookup(name) != NULL)
+    return;
 
-      const char* version = NULL;
+  const char* version = NULL;
 
-      Sized_symbol<size>* sym;
-      Sized_symbol<size>* oldsym;
-      bool resolve_oldsym;
-      if (parameters->target().is_big_endian())
-       {
+  Sized_symbol<size>* sym;
+  Sized_symbol<size>* oldsym;
+  bool resolve_oldsym;
+  if (parameters->target().is_big_endian())
+    {
 #if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
-         sym = this->define_special_symbol<size, true>(&name, &version,
-                                                       false, &oldsym,
-                                                       &resolve_oldsym);
+      sym = this->define_special_symbol<size, true>(&name, &version,
+                                                   false, &oldsym,
+                                                   &resolve_oldsym);
 #else
-         gold_unreachable();
+      gold_unreachable();
 #endif
-       }
-      else
-       {
+    }
+  else
+    {
 #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE)
-         sym = this->define_special_symbol<size, false>(&name, &version,
-                                                        false, &oldsym,
-                                                        &resolve_oldsym);
+      sym = this->define_special_symbol<size, false>(&name, &version,
+                                                    false, &oldsym,
+                                                    &resolve_oldsym);
 #else
-         gold_unreachable();
+      gold_unreachable();
 #endif
-       }
+    }
 
-      gold_assert(oldsym == NULL);
+  gold_assert(oldsym == NULL);
 
-      sym->init_undefined(name, version, elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
-                         elfcpp::STV_DEFAULT, 0);
-      ++this->saw_undefined_;
-    }
+  sym->init_undefined(name, version, elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
+                     elfcpp::STV_DEFAULT, 0);
+  ++this->saw_undefined_;
 }
 
 // Set the dynamic symbol indexes.  INDEX is the index of the first
index 3058546c7eb8d7123c840dea54fb373e4168e72f..8178e2c605373f05a882a964a368304c401ef0d4 100644 (file)
@@ -1269,7 +1269,7 @@ class Symbol_table
 
   // During garbage collection, this keeps undefined symbols.
   void
-  gc_mark_undef_symbols(); 
+  gc_mark_undef_symbols(Layout*);
 
   // During garbage collection, this ensures externally visible symbols
   // are not treated as garbage while building shared objects.
@@ -1419,7 +1419,7 @@ class Symbol_table
   // Add any undefined symbols named on the command line to the symbol
   // table.
   void
-  add_undefined_symbols_from_command_line();
+  add_undefined_symbols_from_command_line(Layout*);
 
   // SYM is defined using a COPY reloc.  Return the dynamic object
   // where the original definition was found.
@@ -1633,7 +1633,12 @@ class Symbol_table
   // table, sized version.
   template<int size>
   void
-  do_add_undefined_symbols_from_command_line();
+  do_add_undefined_symbols_from_command_line(Layout*);
+
+  // Add one undefined symbol.
+  template<int size>
+  void
+  add_undefined_symbol_from_command_line(const char* name);
 
   // Types of common symbols.
 
index 9cd29fb4705fdea1357d63959532249df0b83736..203deb7cbf86fc8f0b3b960856afd11a3b798202 100644 (file)
@@ -867,7 +867,7 @@ exp:
        | INTEGER
            { $$ = script_exp_integer($1); }
        | string
-           { $$ = script_exp_string($1.value, $1.length); }
+           { $$ = script_symbol(closure, $1.value, $1.length); }
        | MAX_K '(' exp ',' exp ')'
            { $$ = script_exp_function_max($3, $5); }
        | MIN_K '(' exp ',' exp ')'