Support -d/--define-common.
authorIan Lance Taylor <iant@google.com>
Thu, 28 Feb 2008 20:35:39 +0000 (20:35 +0000)
committerIan Lance Taylor <iant@google.com>
Thu, 28 Feb 2008 20:35:39 +0000 (20:35 +0000)
gold/gold.cc
gold/object.cc
gold/options.cc
gold/options.h
gold/script-c.h
gold/script.cc
gold/symtab.cc
gold/yyscript.y

index f6437a8..2ac1a67 100644 (file)
@@ -254,9 +254,7 @@ queue_middle_tasks(const General_options& options,
 
   // Allocate common symbols.  This requires write access to the
   // symbol table, but is independent of the relocation processing.
-  // FIXME: We should have an option to do this even for a relocatable
-  // link.
-  if (!parameters->options().relocatable())
+  if (parameters->options().define_common())
     {
       blocker->add_blocker();
       workqueue->queue(new Allocate_commons_task(options, symtab, layout,
index e444ec1..98bcb62 100644 (file)
@@ -951,7 +951,7 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index,
       
       if (shndx >= elfcpp::SHN_LORESERVE)
        {
-         if (shndx == elfcpp::SHN_ABS)
+         if (shndx == elfcpp::SHN_ABS || shndx == elfcpp::SHN_COMMON)
            lv.set_output_value(lv.input_value());
          else
            {
index 716b133..41fa678 100644 (file)
@@ -488,6 +488,14 @@ options::Command_line_options::options[] =
               N_("--compress-debug-sections=[none" ZLIB_STR "]"),
               TWO_DASHES,
               &General_options::set_compress_debug_sections),
+  GENERAL_NOARG('d', "define-common", N_("Define common symbols"),
+               NULL, TWO_DASHES, &General_options::set_define_common),
+  GENERAL_NOARG('\0', "dc", NULL, NULL, ONE_DASH,
+               &General_options::set_define_common),
+  GENERAL_NOARG('\0', "dp", NULL, NULL, ONE_DASH,
+               &General_options::set_define_common),
+  GENERAL_NOARG('\0', "no-define-common", N_("Do not define common symbols"),
+               NULL, TWO_DASHES, &General_options::set_no_define_common),
   SPECIAL('\0', "defsym", N_("Define a symbol"),
           N_("--defsym SYMBOL=EXPRESSION"), TWO_DASHES,
           &add_to_defsym),
@@ -664,7 +672,9 @@ const int options::Command_line_options::debug_options_size =
 // The default values for the general options.
 
 General_options::General_options()
-  : entry_(NULL),
+  : define_common_(false),
+    user_set_define_common_(false),
+    entry_(NULL),
     export_dynamic_(false),
     soname_(NULL),
     dynamic_linker_(NULL),
@@ -1138,6 +1148,10 @@ Command_line::normalize_options()
       this->options_.set_strip_debug(true);
     }
 
+  // Set default value for define_common.
+  if (!this->options_.user_set_define_common())
+    this->options_.set_define_common(!this->options_.relocatable());
+
   // FIXME: we can/should be doing a lot more sanity checking here.
 }
 
index c4e9859..db13929 100644 (file)
@@ -121,6 +121,11 @@ class General_options
 
   General_options();
 
+  // -d: define common symbols.
+  bool
+  define_common() const
+  { return this->define_common_; }
+
   // -e: set entry address.
   const char*
   entry() const
@@ -384,6 +389,21 @@ class General_options
   };
 
   void
+  set_define_common(bool value)
+  {
+    this->define_common_ = value;
+    this->user_set_define_common_ = true;
+  }
+
+  void
+  set_no_define_common(bool value)
+  { this->set_define_common(!value); }
+
+  bool
+  user_set_define_common() const
+  { return this->user_set_define_common_; }
+
+  void
   set_entry(const char* arg)
   { this->entry_ = arg; }
 
@@ -625,6 +645,8 @@ class General_options
   void
   add_sysroot();
 
+  bool define_common_;
+  bool user_set_define_common_;
   const char* entry_;
   bool export_dynamic_;
   const char* soname_;
index 0eacd28..4f19b63 100644 (file)
@@ -235,6 +235,11 @@ script_end_as_needed(void* closure);
 extern void
 script_set_entry(void* closure, const char*, size_t);
 
+/* Called by the bison parser to set whether to define common symbols.  */
+
+extern void
+script_set_common_allocation(void* closure, int);
+
 /* Called by the bison parser to parse an OPTION.  */
 
 extern void
index 307d1cf..eef034e 100644 (file)
@@ -2080,6 +2080,15 @@ script_set_entry(void* closurev, const char* entry, size_t length)
   script_parse_option(closurev, arg.c_str(), arg.size());
 }
 
+// Called by the bison parser to set whether to define common symbols.
+
+extern "C" void
+script_set_common_allocation(void* closurev, int set)
+{
+  const char* arg = set != 0 ? "--define-common" : "--no-define-common";
+  script_parse_option(closurev, arg, strlen(arg));
+}
+
 // Called by the bison parser to define a symbol.
 
 extern "C" void
index 25f1cab..cb2a798 100644 (file)
@@ -1715,7 +1715,8 @@ Symbol_table::sized_finalize_symbol(Symbol* unsized_sym)
 
        // FIXME: We need some target specific support here.
        if (shndx >= elfcpp::SHN_LORESERVE
-           && shndx != elfcpp::SHN_ABS)
+           && shndx != elfcpp::SHN_ABS
+           && shndx != elfcpp::SHN_COMMON)
          {
            gold_error(_("%s: unsupported symbol section 0x%x"),
                       sym->demangled_name().c_str(), shndx);
@@ -1730,7 +1731,7 @@ Symbol_table::sized_finalize_symbol(Symbol* unsized_sym)
          }
        else if (shndx == elfcpp::SHN_UNDEF)
          value = 0;
-       else if (shndx == elfcpp::SHN_ABS)
+       else if (shndx == elfcpp::SHN_ABS || shndx == elfcpp::SHN_COMMON)
          value = sym->value();
        else
          {
@@ -1904,7 +1905,8 @@ Symbol_table::sized_write_globals(const Input_objects* input_objects,
 
            // FIXME: We need some target specific support here.
            if (in_shndx >= elfcpp::SHN_LORESERVE
-               && in_shndx != elfcpp::SHN_ABS)
+               && in_shndx != elfcpp::SHN_ABS
+               && in_shndx != elfcpp::SHN_COMMON)
              {
                gold_error(_("%s: unsupported symbol section 0x%x"),
                           sym->demangled_name().c_str(), in_shndx);
@@ -1920,7 +1922,8 @@ Symbol_table::sized_write_globals(const Input_objects* input_objects,
                    shndx = elfcpp::SHN_UNDEF;
                  }
                else if (in_shndx == elfcpp::SHN_UNDEF
-                        || in_shndx == elfcpp::SHN_ABS)
+                        || in_shndx == elfcpp::SHN_ABS
+                        || in_shndx == elfcpp::SHN_COMMON)
                  shndx = in_shndx;
                else
                  {
index 3605158..ca2835f 100644 (file)
@@ -232,10 +232,14 @@ linker_script:
 
 /* A command which may appear at top level of a linker script.  */
 file_cmd:
-         GROUP
+         FORCE_COMMON_ALLOCATION
+           { script_set_common_allocation(closure, 1); }
+       | GROUP
            { script_start_group(closure); }
          '(' input_list ')'
            { script_end_group(closure); }
+       | INHIBIT_COMMON_ALLOCATION
+           { script_set_common_allocation(closure, 0); }
         | OPTION '(' string ')'
            { script_parse_option(closure, $3.value, $3.length); }
        | PHDRS '{' phdrs_defs '}'