From Craig Silverstein: rework handling of Script_options.
authorIan Lance Taylor <iant@google.com>
Tue, 26 Feb 2008 22:48:08 +0000 (22:48 +0000)
committerIan Lance Taylor <iant@google.com>
Tue, 26 Feb 2008 22:48:08 +0000 (22:48 +0000)
gold/dynobj.cc
gold/dynobj.h
gold/layout.cc
gold/main.cc
gold/options.cc
gold/options.h
gold/script.cc
gold/script.h
gold/testsuite/binary_unittest.cc

index 780e0c902bdc02daa11a118a8de03f63b4b9300d..a33707b8c812d189a6d4ed0876f858a5f236ccda 100644 (file)
@@ -27,7 +27,6 @@
 
 #include "elfcpp.h"
 #include "parameters.h"
-#include "options.h"
 #include "script.h"
 #include "symtab.h"
 #include "dynobj.h"
@@ -1229,9 +1228,10 @@ Verneed::write(const Stringpool* dynpool, bool is_last,
 
 // Versions methods.
 
-Versions::Versions(const General_options& options, Stringpool* dynpool)
+Versions::Versions(const Version_script_info& version_script,
+                   Stringpool* dynpool)
   : defs_(), needs_(), version_table_(),
-    is_finalized_(false), version_script_(options.version_script())
+    is_finalized_(false), version_script_(version_script)
 {
   // We always need a base version, so define that first. Nothing
   // explicitly declares itself as part of base, so it doesn't need to
@@ -1260,7 +1260,7 @@ Versions::Versions(const General_options& options, Stringpool* dynpool)
                                              true, &version_key);
           Verdef* const vd = new Verdef(
               version,
-              options.version_script().get_dependencies(version),
+              this->version_script_.get_dependencies(version),
               false, false, false);
           this->defs_.push_back(vd);
           Key key(version_key, 0);
index d61df16b92fbcc7856e52f6d34e5ebcfeedc4055..cdfa9ce6dd93eb55c56f3673654e34a6eaf16f56 100644 (file)
@@ -31,7 +31,6 @@
 namespace gold
 {
 
-class General_options;
 class Version_script_info;
 
 // A dynamic object (ET_DYN).  This is an abstract base class itself.
@@ -476,7 +475,7 @@ class Verneed
 class Versions
 {
  public:
-  Versions(const General_options&, Stringpool*);
+  Versions(const Version_script_info&, Stringpool*);
 
   ~Versions();
 
@@ -531,7 +530,7 @@ class Versions
   const Version_script_info&
   version_script() const
   { return this->version_script_; }
-      
+
  private:
   Versions(const Versions&);
   Versions& operator=(const Versions&);
index 98cafc5a73eb59bf631c60f8bbedf544920c6803..6685156eac0e5e5c6ceb4a7fd31a0ce58653ebb4 100644 (file)
@@ -925,7 +925,8 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
       Output_section* dynstr;
       std::vector<Symbol*> dynamic_symbols;
       unsigned int local_dynamic_count;
-      Versions versions(this->options_, &this->dynpool_);
+      Versions versions(*this->script_options()->version_script_info(),
+                        &this->dynpool_);
       this->create_dynamic_symtab(input_objects, symtab, &dynstr,
                                  &local_dynamic_count, &dynamic_symbols,
                                  &versions);
@@ -980,7 +981,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
   // Lay out the file header.
   Output_file_header* file_header;
   file_header = new Output_file_header(target, symtab, segment_headers,
-                                      this->script_options_->entry());
+                                      this->options_.entry());
   if (load_seg != NULL)
     load_seg->add_initial_output_data(file_header);
 
index 6e356581701d89230750487d6dc086622517c20b..678bd032efdb719c57eb8f841bd314d6ffd287a6 100644 (file)
@@ -147,12 +147,8 @@ main(int argc, char** argv)
   // errors object.
   initialize_parameters(&errors);
 
-  // Options which may be set by the command line or by linker
-  // scripts.
-  Script_options script_options;
-
   // Handle the command line options.
-  Command_line command_line(&script_options);
+  Command_line command_line;
   command_line.process(argc - 1, argv + 1);
 
   long start_time = 0;
@@ -174,7 +170,7 @@ main(int argc, char** argv)
   // permit some linker optimizations.  Perhaps we need yet another
   // option to control this.  FIXME.
   if (parameters->output_is_object())
-    command_line.script_options()->version_script_info()->clear();
+    command_line.script_options().version_script_info()->clear();
 
   // The work queue.
   Workqueue workqueue(command_line.options());
@@ -187,10 +183,10 @@ main(int argc, char** argv)
   // this is off, it means at worst we don't quite optimize hashtable
   // resizing as well as we could have (perhap using more memory).
   Symbol_table symtab(command_line.number_of_input_files() * 1024,
-                      command_line.options().version_script());
+                      command_line.version_script());
 
   // The layout object.
-  Layout layout(command_line.options(), &script_options);
+  Layout layout(command_line.options(), &command_line.script_options());
 
   // Get the search path from the -L options.
   Dirsearch search_path;
index 8b607afe827e7d73f06a3a6db7079854a794ec0c..2dbfad86e515706aa2ddfc281e5884d5495e9c7e 100644 (file)
@@ -169,6 +169,19 @@ string_to_object_format(const char* arg)
     }
 }
 
+// Handle the special -defsym option, which defines a symbol.
+
+int
+add_to_defsym(int argc, char** argv, char* arg, bool long_option,
+              gold::Command_line* cmdline)
+{
+  int ret;
+  const char* val = cmdline->get_special_argument("defsym", argc, argv, arg,
+                                                 long_option, &ret);
+  cmdline->script_options().define_symbol(val);
+  return ret;
+}
+
 // Handle the special -l option, which adds an input file.
 
 int
@@ -476,9 +489,9 @@ options::Command_line_options::options[] =
               N_("--compress-debug-sections=[none" ZLIB_STR "]"),
               TWO_DASHES,
               &General_options::set_compress_debug_sections),
-  GENERAL_ARG('\0', "defsym", N_("Define a symbol"),
-             N_("--defsym SYMBOL=EXPRESSION"), TWO_DASHES,
-             &General_options::add_to_defsym),
+  SPECIAL('\0', "defsym", N_("Define a symbol"),
+          N_("--defsym SYMBOL=EXPRESSION"), TWO_DASHES,
+          &add_to_defsym),
   GENERAL_NOARG('\0', "demangle", N_("Demangle C++ symbols in log messages"),
                 NULL, TWO_DASHES, &General_options::set_demangle),
   GENERAL_NOARG('\0', "no-demangle",
@@ -649,8 +662,9 @@ const int options::Command_line_options::debug_options_size =
 
 // The default values for the general options.
 
-General_options::General_options(Script_options* script_options)
-  : export_dynamic_(false),
+General_options::General_options()
+  : entry_(NULL),
+    export_dynamic_(false),
     soname_(NULL),
     dynamic_linker_(NULL),
     search_path_(),
@@ -681,8 +695,7 @@ General_options::General_options(Script_options* script_options)
     execstack_(EXECSTACK_FROM_INPUT),
     max_page_size_(0),
     common_page_size_(0),
-    debug_(0),
-    script_options_(script_options)
+    debug_(0)
 {
   // We initialize demangle_ based on the environment variable
   // COLLECT_NO_DEMANGLE.  The gcc collect2 program will demangle the
@@ -692,14 +705,6 @@ General_options::General_options(Script_options* script_options)
   this->demangle_ = getenv("COLLECT_NO_DEMANGLE") == NULL;
 }
 
-// Handle the --defsym option.
-
-void
-General_options::add_to_defsym(const char* arg)
-{
-  this->script_options_->define_symbol(arg);
-}
-
 // Handle the --oformat option.
 
 void
@@ -920,8 +925,8 @@ Input_arguments::end_group()
 
 // Command_line options.
 
-Command_line::Command_line(Script_options* script_options)
-  : options_(script_options), position_options_(), inputs_()
+Command_line::Command_line()
+  : options_(), position_options_(), script_options_(), inputs_()
 {
 }
 
index d7dc06cd2e1e4fb8af534676151b23d6293c1c9c..14e1629e52e2cf87f91655046bbb06161aa22dfa 100644 (file)
@@ -119,12 +119,12 @@ class General_options
     OBJECT_FORMAT_BINARY
   };
 
-  General_options(Script_options*);
+  General_options();
 
   // -e: set entry address.
   const char*
   entry() const
-  { return this->script_options_->entry(); }
+  { return this->entry_; }
 
   // -E: export dynamic symbols.
   bool
@@ -255,11 +255,6 @@ class General_options
   sysroot() const
   { return this->sysroot_; }
 
-  // --version-script: The version script to apply if --shared is true.
-  const Version_script_info&
-  version_script() const
-  { return *this->script_options_->version_script_info(); }
-
   // -Tbss: The address of the BSS segment
   uint64_t
   Tbss() const
@@ -334,15 +329,6 @@ class General_options
   debug() const
   { return this->debug_; }
 
-  // Return the options which may be set from a linker script.
-  Script_options*
-  script_options()
-  { return this->script_options_; }
-
-  const Script_options*
-  script_options() const
-  { return this->script_options_; }
-
  private:
   // Don't copy this structure.
   General_options(const General_options&);
@@ -384,7 +370,7 @@ class General_options
 
   void
   set_entry(const char* arg)
-  { this->script_options_->set_entry(arg, strlen(arg)); }
+  { this->entry_ = arg; }
 
   void
   set_export_dynamic(bool value)
@@ -620,6 +606,7 @@ class General_options
   void
   add_sysroot();
 
+  const char* entry_;
   bool export_dynamic_;
   const char* soname_;
   const char* dynamic_linker_;
@@ -653,9 +640,6 @@ class General_options
   uint64_t max_page_size_;
   uint64_t common_page_size_;
   unsigned int debug_;
-  // Some options can also be set from linker scripts.  Those are
-  // stored here.
-  Script_options* script_options_;
 };
 
 // The current state of the position dependent options.
@@ -940,7 +924,7 @@ class Command_line
  public:
   typedef Input_arguments::const_iterator const_iterator;
 
-  Command_line(Script_options*);
+  Command_line();
 
   // Process the command line options.  This will exit with an
   // appropriate error message if an unrecognized option is seen.
@@ -993,14 +977,15 @@ class Command_line
   position_dependent_options() const
   { return this->position_options_; }
 
-  // Get the options which may be set from a linker script.
-  Script_options*
+  // Get the linker-script options.
+  Script_options&
   script_options()
-  { return this->options_.script_options(); }
+  { return this->script_options_; }
 
-  const Script_options*
-  script_options() const
-  { return this->options_.script_options(); }
+  // Get the version-script options: a convenience routine.
+  const Version_script_info&
+  version_script() const
+  { return *this->script_options_.version_script_info(); }
 
   // The number of input files.
   int
@@ -1044,6 +1029,7 @@ class Command_line
 
   General_options options_;
   Position_dependent_options position_options_;
+  Script_options script_options_;
   Input_arguments inputs_;
 };
 
index faa1cda601c4285038a701c2daa1b2de8d7d7eca..c7b26ef58581a6d2194cc3a234b0afba30e9c742 100644 (file)
@@ -1437,7 +1437,7 @@ read_script_file(const char* filename, Command_line* cmdline,
                         false,
                         input_file.is_in_sysroot(),
                          cmdline,
-                        cmdline->script_options(),
+                        &cmdline->script_options(),
                         &lex);
   if (yyparse(&closure) != 0)
     {
@@ -2111,8 +2111,11 @@ script_end_as_needed(void* closurev)
 extern "C" void
 script_set_entry(void* closurev, const char* entry, size_t length)
 {
-  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
-  closure->script_options()->set_entry(entry, length);
+  // We'll parse this exactly the same as --entry=ENTRY on the commandline
+  // TODO(csilvers): FIXME -- call set_entry directly.
+  std::string arg("entry=");
+  arg.append(entry, length);
+  script_parse_option(closurev, arg.c_str(), arg.size());
 }
 
 // Called by the bison parser to define a symbol.
@@ -2161,7 +2164,9 @@ script_parse_option(void* closurev, const char* option, size_t length)
       gold_assert(mutable_option != NULL);
       closure->command_line()->process_one_option(1, &mutable_option, 0,
                                                   &past_a_double_dash_option);
-      free(mutable_option);
+      // The General_options class will quite possibly store a pointer
+      // into mutable_option, so we can't free it.  In cases the class
+      // does not store such a pointer, this is a memory leak.  Alas. :(
     }
 }
 
index 64d7fd6f8b158efea11e63eb41803b68cf9cd6c3..b2122271de1da60d80af86a284980c3784cfd288 100644 (file)
@@ -294,16 +294,6 @@ class Script_options
  public:
   Script_options();
 
-  // The entry address.
-  const char*
-  entry() const
-  { return this->entry_.empty() ? NULL : this->entry_.c_str(); }
-
-  // Set the entry address.
-  void
-  set_entry(const char* entry, size_t length)
-  { this->entry_.assign(entry, length); }
-
   // Add a symbol to be defined.
   void
   add_symbol_assignment(const char* name, size_t length, Expression* value,
@@ -331,6 +321,10 @@ class Script_options
   version_script_info()
   { return &this->version_script_info_; }
 
+  const Version_script_info*
+  version_script_info() const
+  { return &this->version_script_info_; }
+
   // A SECTIONS clause parsed from a linker script.  Everything else
   // has a pointer to this object.
   Script_sections*
index ea2535b556d36dbbc4e228991dc4b05efd742377..6a3956a2ecb9f1880b7792e284f11bc9516dc8f0 100644 (file)
@@ -113,8 +113,7 @@ Binary_test(Test_report*)
   Errors errors(gold::program_name);
   initialize_parameters(&errors);
 
-  Script_options script_options;
-  General_options options(&script_options);
+  General_options options;
   set_parameters_from_options(&options);
 
   int fail = 0;