From Craig Silverstein: Add --strip-debug-gdb.
authorIan Lance Taylor <iant@google.com>
Thu, 15 Nov 2007 23:03:45 +0000 (23:03 +0000)
committerIan Lance Taylor <iant@google.com>
Thu, 15 Nov 2007 23:03:45 +0000 (23:03 +0000)
gold/layout.cc
gold/options.cc
gold/options.h
gold/parameters.cc
gold/parameters.h

index e4eda44a2d8eeff1dcd3234ffff2aa567f533089..d3c5d6902e9f7615e760df57a30d4c9e21014f39 100644 (file)
@@ -98,6 +98,33 @@ is_prefix_of(const char* prefix, const char* str)
   return strncmp(prefix, str, strlen(prefix)) == 0;
 }
 
+// Returns whether the given section is in the list of
+// debug-sections-used-by-some-version-of-gdb.  Currently,
+// we've checked versions of gdb up to and including 6.7.1.
+
+static const char* gdb_sections[] =
+{ ".debug_abbrev",
+  // ".debug_aranges",   // not used by gdb as of 6.7.1
+  ".debug_frame",
+  ".debug_info",
+  ".debug_line",
+  ".debug_loc",
+  ".debug_macinfo",
+  // ".debug_pubnames",  // not used by gdb as of 6.7.1
+  ".debug_ranges",
+  ".debug_str",
+};
+
+static inline bool
+is_gdb_debug_section(const char* str)
+{
+  // We can do this faster: binary search or a hashtable.  But why bother?
+  for (size_t i = 0; i < sizeof(gdb_sections)/sizeof(*gdb_sections); ++i)
+    if (strcmp(str, gdb_sections[i]) == 0)
+      return true;
+  return false;
+}
+
 // Whether to include this section in the link.
 
 template<int size, bool big_endian>
@@ -134,6 +161,14 @@ Layout::include_section(Sized_relobj<size, big_endian>*, const char* name,
              || is_prefix_of(".stab", name))
            return false;
        }
+      if (parameters->strip_debug_gdb()
+         && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0)
+       {
+         // Debugging sections can only be recognized by name.
+         if (is_prefix_of(".debug", name)
+              && !is_gdb_debug_section(name))
+           return false;
+       }
       return true;
 
     default:
index 20714359e8a7cb3f0e1c984d8c1313d00e5fdd14..c962188f1c26c3c78c4826e2ad078490c3d87662 100644 (file)
@@ -402,6 +402,11 @@ options::Command_line_options::options[] =
               &General_options::add_to_rpath_link),
   GENERAL_NOARG('s', "strip-all", N_("Strip all symbols"), NULL,
                TWO_DASHES, &General_options::set_strip_all),
+  GENERAL_NOARG('\0', "strip-debug-gdb",
+                N_("Strip debug symbols that are unused by gdb "
+                   "(at least versions <= 6.7)"),
+               NULL, TWO_DASHES, &General_options::set_strip_debug_gdb),
+  // This must come after -Sdebug since it's a prefix of it.
   GENERAL_NOARG('S', "strip-debug", N_("Strip debugging information"), NULL,
                TWO_DASHES, &General_options::set_strip_debug),
   GENERAL_NOARG('\0', "shared", N_("Generate shared library"),
index 1a67a7e27a5f6591b9ecccd9c72851bb209d1ee0..48047c2aa3b687a3701d77e4b1ce9b007ae26862 100644 (file)
@@ -148,6 +148,12 @@ class General_options
   strip_debug() const
   { return this->strip_ == STRIP_ALL || this->strip_ == STRIP_DEBUG; }
 
+  // -Sgdb: strip only debugging information that's not used by
+  //         gdb (at least, for gdb versions <= 6.7).
+  bool
+  strip_debug_gdb() const
+  { return this->strip_debug() || this->strip_ == STRIP_DEBUG_UNUSED_BY_GDB; }
+
   // --allow-shlib-undefined: do not warn about unresolved symbols in
   // --shared libraries.
   bool
@@ -259,7 +265,9 @@ class General_options
     // Strip all symbols.
     STRIP_ALL,
     // Strip debugging information.
-    STRIP_DEBUG
+    STRIP_DEBUG,
+    // Strip debugging information that's not used by gdb (at least <= 6.7)
+    STRIP_DEBUG_UNUSED_BY_GDB
   };
 
   // Whether to mark the stack as executable.
@@ -311,6 +319,10 @@ class General_options
   set_strip_debug()
   { this->strip_ = STRIP_DEBUG; }
 
+  void
+  set_strip_debug_gdb()
+  { this->strip_ = STRIP_DEBUG_UNUSED_BY_GDB; }
+
   void
   set_allow_shlib_undefined()
   { this->allow_shlib_undefined_ = true; }
index aceb61ee737496645229007975725d2d265792f1..7fbbf836778957f9b7505f114ac8af35bcbc38ff 100644 (file)
@@ -66,6 +66,8 @@ Parameters::set_from_options(const General_options* options)
     this->strip_ = STRIP_ALL;
   else if (options->strip_debug())
     this->strip_ = STRIP_DEBUG;
+  else if (options->strip_debug_gdb())
+    this->strip_ = STRIP_DEBUG_UNUSED_BY_GDB;
   else
     this->strip_ = STRIP_NONE;
 
index b760eceb4cffc038e5c968a7f5a9f206b81e82c5..3186b6d454d3e848beb28a2fa4536456110c1941 100644 (file)
@@ -112,6 +112,14 @@ class Parameters
     return this->strip_ == STRIP_ALL || this->strip_ == STRIP_DEBUG;
   }
 
+  // Whether to strip debugging information that's not used by gdb.
+  bool
+  strip_debug_gdb() const
+  {
+    gold_assert(this->strip_ != STRIP_INVALID);
+    return this->strip_debug() || this->strip_ == STRIP_DEBUG_UNUSED_BY_GDB;
+  }
+
   // Whether to permit unresolved references from shared libraries.
   bool
   allow_shlib_undefined() const
@@ -221,7 +229,9 @@ class Parameters
     // Strip all symbols.
     STRIP_ALL,
     // Strip debugging information.
-    STRIP_DEBUG
+    STRIP_DEBUG,
+    // Strip debugging information that's not used by gdb (at least <= 6.7)
+    STRIP_DEBUG_UNUSED_BY_GDB
   };
 
   // A pointer to the error handling object.