Change default to discard temporary local symbols in merge sections.
authorCary Coutant <ccoutant@gmail.com>
Fri, 5 Jun 2015 03:58:08 +0000 (20:58 -0700)
committerCary Coutant <ccoutant@gmail.com>
Fri, 5 Jun 2015 03:58:08 +0000 (20:58 -0700)
Add --discard-none to keep all local symbols.

gold/
PR gold/17498
* object.cc (Sized_relobj_file::do_count_local_symbols): Discard
temporary locals in merge sections.
* options.cc (General_options::parse_discard_all): New method.
(General_options::parse_discard_locals): New method.
(General_options::parse_discard_none): New method.
(General_options::General_options): Initialize discard_locals_.
* options.h (--discard-all): Convert to special option.
(--discard-locals): Likewise.
(--discard-none): New option.
(General_options::discard_all): New method.
(General_options::discard_locals): New method.
(General_options::discard_sec_merge): New method.
(General_options::Discard_locals): New enum.
(General_options::discard_locals_): New data member.

gold/ChangeLog
gold/object.cc
gold/options.cc
gold/options.h

index 8996a97..bb3ea82 100644 (file)
@@ -1,3 +1,21 @@
+2015-06-04  Cary Coutant  <ccoutant@gmail.com>
+
+       PR gold/17498
+       * object.cc (Sized_relobj_file::do_count_local_symbols): Discard
+       temporary locals in merge sections.
+       * options.cc (General_options::parse_discard_all): New method.
+       (General_options::parse_discard_locals): New method.
+       (General_options::parse_discard_none): New method.
+       (General_options::General_options): Initialize discard_locals_.
+       * options.h (--discard-all): Convert to special option.
+       (--discard-locals): Likewise.
+       (--discard-none): New option.
+       (General_options::discard_all): New method.
+       (General_options::discard_locals): New method.
+       (General_options::discard_sec_merge): New method.
+       (General_options::Discard_locals): New enum.
+       (General_options::discard_locals_): New data member.
+
 2015-06-03  Cary Coutant  <cary@google.com>
 
        * script-sections.cc (Script_sections::Script_sections): Initialize
index 18c6670..4e94f7e 100644 (file)
@@ -2174,6 +2174,7 @@ Sized_relobj_file<size, big_endian>::do_count_local_symbols(Stringpool* pool,
   // Loop over the local symbols.
 
   const Output_sections& out_sections(this->output_sections());
+  std::vector<Address>& out_section_offsets(this->section_offsets());
   unsigned int shnum = this->shnum();
   unsigned int count = 0;
   unsigned int dyncount = 0;
@@ -2182,6 +2183,7 @@ Sized_relobj_file<size, big_endian>::do_count_local_symbols(Stringpool* pool,
   bool strip_all = parameters->options().strip_all();
   bool discard_all = parameters->options().discard_all();
   bool discard_locals = parameters->options().discard_locals();
+  bool discard_sec_merge = parameters->options().discard_sec_merge();
   for (unsigned int i = 1; i < loccount; ++i, psyms += sym_size)
     {
       elfcpp::Sym<size, big_endian> sym(psyms);
@@ -2246,6 +2248,7 @@ Sized_relobj_file<size, big_endian>::do_count_local_symbols(Stringpool* pool,
          continue;
        }
 
+      // By default, discard temporary local symbols in merge sections.
       // If --discard-locals option is used, discard all temporary local
       // symbols.  These symbols start with system-specific local label
       // prefixes, typically .L for ELF system.  We want to be compatible
@@ -2258,7 +2261,10 @@ Sized_relobj_file<size, big_endian>::do_count_local_symbols(Stringpool* pool,
       //   - the symbol has a name.
       //
       // We do not discard a symbol if it needs a dynamic symbol entry.
-      if (discard_locals
+      if ((discard_locals
+          || (discard_sec_merge
+              && is_ordinary
+              && out_section_offsets[shndx] == invalid_address))
          && sym.get_st_type() != elfcpp::STT_FILE
          && !lv.needs_output_dynsym_entry()
          && lv.may_be_discarded_from_output_symtab()
index 39dc311..c42623f 100644 (file)
@@ -346,6 +346,27 @@ General_options::parse_defsym(const char*, const char* arg,
 }
 
 void
+General_options::parse_discard_all(const char*, const char*,
+                                  Command_line*)
+{
+  this->discard_locals_ = DISCARD_ALL;
+}
+
+void
+General_options::parse_discard_locals(const char*, const char*,
+                                     Command_line*)
+{
+  this->discard_locals_ = DISCARD_LOCALS;
+}
+
+void
+General_options::parse_discard_none(const char*, const char*,
+                                   Command_line*)
+{
+  this->discard_locals_ = DISCARD_NONE;
+}
+
+void
 General_options::parse_incremental(const char*, const char*,
                                   Command_line*)
 {
@@ -927,7 +948,8 @@ General_options::General_options()
     symbols_to_retain_(),
     section_starts_(),
     fix_v4bx_(FIX_V4BX_NONE),
-    endianness_(ENDIANNESS_NOT_SET)
+    endianness_(ENDIANNESS_NOT_SET),
+    discard_locals_(DISCARD_SEC_MERGE)
 {
   // Turn off option registration once construction is complete.
   gold::options::ready_to_register = false;
index 67eb1b2..658ad42 100644 (file)
@@ -739,10 +739,12 @@ class General_options
              N_("Look for violations of the C++ One Definition Rule"),
              N_("Do not look for violations of the C++ One Definition Rule"));
 
-  DEFINE_bool(discard_all, options::TWO_DASHES, 'x', false,
-             N_("Delete all local symbols"), NULL);
-  DEFINE_bool(discard_locals, options::TWO_DASHES, 'X', false,
-             N_("Delete all temporary local symbols"), NULL);
+  DEFINE_special(discard_all, options::TWO_DASHES, 'x',
+                N_("Delete all local symbols"), NULL);
+  DEFINE_special(discard_locals, options::TWO_DASHES, 'X',
+                N_("Delete all temporary local symbols"), NULL);
+  DEFINE_special(discard_none, options::TWO_DASHES, '\0',
+                N_("Keep all local symbols"), NULL);
 
   DEFINE_bool(dynamic_list_data, options::TWO_DASHES, '\0', false,
              N_("Add data symbols to dynamic symbols"), NULL);
@@ -1526,11 +1528,36 @@ class General_options
   endianness() const
   { return this->endianness_; }
 
+  bool
+  discard_all() const
+  { return this->discard_locals_ == DISCARD_ALL; }
+
+  bool
+  discard_locals() const
+  { return this->discard_locals_ == DISCARD_LOCALS; }
+
+  bool
+  discard_sec_merge() const
+  { return this->discard_locals_ == DISCARD_SEC_MERGE; }
+
  private:
   // Don't copy this structure.
   General_options(const General_options&);
   General_options& operator=(const General_options&);
 
+  // What local symbols to discard.
+  enum Discard_locals
+  {
+    // Locals in merge sections (default).
+    DISCARD_SEC_MERGE,
+    // None (--discard-none).
+    DISCARD_NONE,
+    // Temporary locals (--discard-locals/-X).
+    DISCARD_LOCALS,
+    // All locals (--discard-all/-x).
+    DISCARD_ALL
+  };
+
   // Whether to mark the stack as executable.
   enum Execstack
   {
@@ -1626,6 +1653,8 @@ class General_options
   Fix_v4bx fix_v4bx_;
   // Endianness.
   Endianness endianness_;
+  // What local symbols to discard.
+  Discard_locals discard_locals_;
 };
 
 // The position-dependent options.  We use this to store the state of