From Craig Silverstein: Add support for --demangle.
authorIan Lance Taylor <iant@google.com>
Thu, 15 Nov 2007 01:12:55 +0000 (01:12 +0000)
committerIan Lance Taylor <iant@google.com>
Thu, 15 Nov 2007 01:12:55 +0000 (01:12 +0000)
12 files changed:
gold/dynobj.cc
gold/errors.cc
gold/i386.cc
gold/object.cc
gold/options.cc
gold/options.h
gold/parameters.cc
gold/parameters.h
gold/resolve.cc
gold/symtab.cc
gold/symtab.h
gold/x86_64.cc

index a6f3588f48c9ad306e110e2456d74d060d2722d7..f4793527949e5bfd9198c4377df40d6f68f4e848 100644 (file)
@@ -1301,7 +1301,7 @@ Versions::add_def(const Symbol* sym, const char* version,
       if (parameters->output_is_shared())
        {
          gold_error(_("symbol %s has undefined version %s"),
-                    sym->name(), version);
+                    sym->demangled_name().c_str(), version);
          return;
        }
 
index 3aa3ece89729bd2db535ac1a4fbbd41225dbb70b..2da1a2569edd9e6943b42a522becdf82c893ad1a 100644 (file)
@@ -135,7 +135,7 @@ Errors::undefined_symbol(const Symbol* sym,
   }
   fprintf(stderr, _("%s: %s: undefined reference to '%s'\n"),
          this->program_name_, relinfo->location(relnum, reloffset).c_str(),
-         sym->name());
+         sym->demangled_name().c_str());
 }
 
 
index b4c7e42160208710e1efdaaa946153629701fa08..4a6aa7353f206c515b7da7b5a397a8cd3a7d84f2 100644 (file)
@@ -1019,7 +1019,7 @@ Target_i386::Scan::unsupported_reloc_global(Sized_relobj<32, false>* object,
                                            Symbol* gsym)
 {
   gold_error(_("%s: unsupported reloc %u against global symbol %s"),
-            object->name().c_str(), r_type, gsym->name());
+            object->name().c_str(), r_type, gsym->demangled_name().c_str());
 }
 
 // Scan a relocation for a global symbol.
index 7a4b1fb41e090c813da70ae22f8d31650af6393a..ecefa8bf393c11aa673aea36a666aa00a5677bd0 100644 (file)
@@ -25,6 +25,7 @@
 #include <cerrno>
 #include <cstring>
 #include <cstdarg>
+#include "demangle.h"
 #include "libiberty.h"
 
 #include "target-select.h"
@@ -1032,7 +1033,20 @@ Sized_relobj<size, big_endian>::get_symbol_location_info(
           if (sym.get_st_name() > names_size)
            info->enclosing_symbol_name = "(invalid)";
          else
-           info->enclosing_symbol_name = symbol_names + sym.get_st_name();
+            {
+              info->enclosing_symbol_name = symbol_names + sym.get_st_name();
+              if (parameters->demangle())
+                {
+                  char* demangled_name = cplus_demangle(
+                      info->enclosing_symbol_name.c_str(),
+                      DMGL_ANSI | DMGL_PARAMS);
+                  if (demangled_name != NULL)
+                    {
+                      info->enclosing_symbol_name.assign(demangled_name);
+                      free(demangled_name);
+                    }
+                }
+            }
          return true;
         }
     }
@@ -1155,11 +1169,6 @@ Relocate_info<size, big_endian>::location(size_t, off_t offset) const
   if (this->object->get_symbol_location_info(this->data_shndx, offset, &info))
     {
       ret += " in function ";
-      // We could demangle this name before printing, but we don't
-      // bother because gcc runs linker output through a demangle
-      // filter itself.  The only advantage to demangling here is if
-      // someone might call ld directly, rather than via gcc.  If we
-      // did want to demangle, cplus_demangle() is in libiberty.
       ret += info.enclosing_symbol_name;
       ret += ":";
       filename = info.source_file;
index 69f452dd380bd9ca1e6021d6b875ef3a54254a80..20714359e8a7cb3f0e1c984d8c1313d00e5fdd14 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "gold.h"
 
+#include <cstdlib>
 #include <iostream>
 #include <sys/stat.h>
 #include "filenames.h"
@@ -361,6 +362,11 @@ options::Command_line_options::options[] =
               &Position_dependent_options::set_static_search),
   GENERAL_NOARG('\0', "Bsymbolic", N_("Bind defined symbols locally"),
                NULL, ONE_DASH, &General_options::set_symbolic),
+  GENERAL_NOARG('\0', "demangle", N_("Demangle C++ symbols in log messages"),
+                NULL, TWO_DASHES, &General_options::set_demangle),
+  GENERAL_NOARG('\0', "no-demangle",
+               N_("Do not demangle C++ symbols in log messages"),
+                NULL, TWO_DASHES, &General_options::clear_demangle),
   GENERAL_NOARG('\0', "detect-odr-violations",
                 N_("Try to detect violations of the One Definition Rule"),
                 NULL, TWO_DASHES, &General_options::set_detect_odr_violations),
@@ -500,6 +506,12 @@ General_options::General_options()
     thread_count_final_(0),
     execstack_(EXECSTACK_FROM_INPUT)
 {
+  // We initialize demangle_ based on the environment variable
+  // COLLECT_NO_DEMANGLE.  The gcc collect2 program will demangle the
+  // output of the linker, unless COLLECT_NO_DEMANGLE is set in the
+  // environment.  Acting the same way here lets us provide the same
+  // interface by default.
+  this->demangle_ = getenv("COLLECT_NO_DEMANGLE") == NULL;
 }
 
 // The default values for the position dependent options.
index b5d2328a1a63171de604fa7ad6ebf4c505bf0a75..1a67a7e27a5f6591b9ecccd9c72851bb209d1ee0 100644 (file)
@@ -159,6 +159,11 @@ class General_options
   symbolic() const
   { return this->symbolic_; }
 
+  // --demangle: demangle C++ symbols in our log messages.
+  bool
+  demangle() const
+  { return this->demangle_; }
+
   // --detect-odr-violations: Whether to search for One Defn Rule violations.
   bool
   detect_odr_violations() const
@@ -318,6 +323,14 @@ class General_options
   set_symbolic()
   { this->symbolic_ = true; }
 
+  void
+  set_demangle()
+  { this->demangle_ = true; }
+
+  void
+  clear_demangle()
+  { this->demangle_ = false; }
+
   void
   set_detect_odr_violations()
   { this->detect_odr_violations_ = true; }
@@ -436,6 +449,7 @@ class General_options
   Strip strip_;
   bool allow_shlib_undefined_;
   bool symbolic_;
+  bool demangle_;
   bool detect_odr_violations_;
   bool create_eh_frame_hdr_;
   Dir_list rpath_;
index b96221a8b2449764b6b93e089b595e76093d97d7..aceb61ee737496645229007975725d2d265792f1 100644 (file)
@@ -34,7 +34,7 @@ Parameters::Parameters(Errors* errors)
   : errors_(errors), output_file_name_(NULL),
     output_file_type_(OUTPUT_INVALID), sysroot_(),
     strip_(STRIP_INVALID), allow_shlib_undefined_(false),
-    symbolic_(false), detect_odr_violations_(false),
+    symbolic_(false), demangle_(false), detect_odr_violations_(false),
     optimization_level_(0), export_dynamic_(false),
     is_doing_static_link_valid_(false), doing_static_link_(false),
     is_size_and_endian_valid_(false), size_(0), is_big_endian_(false)
@@ -50,6 +50,7 @@ Parameters::set_from_options(const General_options* options)
   this->sysroot_ = options->sysroot();
   this->allow_shlib_undefined_ = options->allow_shlib_undefined();
   this->symbolic_ = options->symbolic();
+  this->demangle_ = options->demangle();
   this->detect_odr_violations_ = options->detect_odr_violations();
   this->optimization_level_ = options->optimization_level();
   this->export_dynamic_ = options->export_dynamic();
index ee60b10b4a0de868100903b88ec86f337c7b4c1d..b760eceb4cffc038e5c968a7f5a9f206b81e82c5 100644 (file)
@@ -129,6 +129,11 @@ class Parameters
     return this->symbolic_;
   }
 
+  // Whether we should demangle C++ symbols in our log messages.
+  bool
+  demangle() const
+  { return this->demangle_; }
+
   // Whether we should try to detect violations of the One Definition Rule.
   bool
   detect_odr_violations() const
@@ -236,6 +241,8 @@ class Parameters
   bool allow_shlib_undefined_;
   // Whether we are doing a symbolic link.
   bool symbolic_;
+  // Whether we should demangle C++ symbols in our log messages.
+  bool demangle_;
   // Whether we try to detect One Definition Rule violations.
   bool detect_odr_violations_;
   // The optimization level.
index b3328d564fe9377b7d27c552f378b695e91bf1b9..6e3d3acce37ff0d2625b77640f4846f57ca93a6b 100644 (file)
@@ -256,11 +256,11 @@ Symbol_table::resolve(Sized_symbol<size>* to,
       // on C++ symbols.  These have (mangled) names starting with _Z.
       && to->name()[0] == '_' && to->name()[1] == 'Z')
     {
-      Symbol_location from_location
+      Symbol_location fromloc
           = { object, orig_sym.get_st_shndx(), orig_sym.get_st_value() };
-      Symbol_location to_location = { to->object(), to->shndx(), to->value() };
-      this->candidate_odr_violations_[to->name()].insert(from_location);
-      this->candidate_odr_violations_[to->name()].insert(to_location);
+      Symbol_location toloc = { to->object(), to->shndx(), to->value() };
+      this->candidate_odr_violations_[to->name()].insert(fromloc);
+      this->candidate_odr_violations_[to->name()].insert(toloc);
     }
 }
 
@@ -317,7 +317,7 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits,
       // FIXME: Do a better job of reporting locations.
       gold_error(_("%s: multiple definition of %s"),
                 object != NULL ? object->name().c_str() : _("command line"),
-                to->name());
+                to->demangled_name().c_str());
       gold_error(_("%s: previous definition here"),
                 (to->source() == Symbol::FROM_OBJECT
                  ? to->object()->name().c_str()
index caac2a77fb734f59343e6a90cbb9561c98d21d5e..c918db329334234623952cc6f1550195337e627b 100644 (file)
@@ -26,6 +26,7 @@
 #include <set>
 #include <string>
 #include <utility>
+#include "demangle.h"
 
 #include "object.h"
 #include "dwarf_reader.h"
@@ -72,6 +73,32 @@ Symbol::init_fields(const char* name, const char* version,
   this->needs_value_in_got_ = false;
 }
 
+// Return the demangled version of the symbol's name, but only
+// if the --demangle flag was set.
+
+static std::string
+demangle(const char* name)
+{
+  // cplus_demangle allocates memory for the result it returns,
+  // and returns NULL if the name is already demangled.
+  char* demangled_name = cplus_demangle(name, DMGL_ANSI | DMGL_PARAMS);
+  if (demangled_name == NULL)
+    return name;
+
+  std::string retval(demangled_name);
+  free(demangled_name);
+  return retval;
+}
+
+std::string
+Symbol::demangled_name() const
+{
+  if (parameters->demangle())
+    return demangle(name());
+  else
+    return name();
+}
+
 // Initialize the fields in the base class Symbol for SYM in OBJECT.
 
 template<int size, bool big_endian>
@@ -1434,7 +1461,7 @@ Symbol_table::sized_finalize(unsigned index, off_t off, Stringpool* pool)
                && shndx != elfcpp::SHN_ABS)
              {
                gold_error(_("%s: unsupported symbol section 0x%x"),
-                          sym->name(), shndx);
+                          sym->demangled_name().c_str(), shndx);
                shndx = elfcpp::SHN_UNDEF;
              }
 
@@ -1647,7 +1674,7 @@ Symbol_table::sized_write_globals(const Input_objects* input_objects,
                && in_shndx != elfcpp::SHN_ABS)
              {
                gold_error(_("%s: unsupported symbol section 0x%x"),
-                          sym->name(), in_shndx);
+                          sym->demangled_name().c_str(), in_shndx);
                shndx = in_shndx;
              }
            else
@@ -1771,7 +1798,8 @@ Symbol_table::warn_about_undefined_dynobj_symbol(
       Dynobj* dynobj = static_cast<Dynobj*>(sym->object());
       if (!dynobj->has_unknown_needed_entries())
        gold_error(_("%s: undefined reference to '%s'"),
-                  sym->object()->name().c_str(), sym->name());
+                  sym->object()->name().c_str(),
+                   sym->demangled_name().c_str());
     }
 }
 
@@ -1883,7 +1911,7 @@ Symbol_table::detect_odr_violations(const char* output_file_name) const
         {
           gold_warning(_("while linking %s: symbol %s defined in multiple "
                          "places (possible ODR violation):"),
-                       output_file_name, symbol_name);
+                       output_file_name, demangle(symbol_name).c_str());
           for (std::set<std::string>::const_iterator it2 = line_nums.begin();
                it2 != line_nums.end();
                ++it2)
index 8206cbaa33a39874dd2e131cf686036476b89cb7..b6e550463ee0551e9d011141508997d168ebd70d 100644 (file)
@@ -98,6 +98,13 @@ class Symbol
   name() const
   { return this->name_; }
 
+  // Return the (ANSI) demangled version of the name, if
+  // parameters.demangle() is true.  Otherwise, return the name.  This
+  // is intended to be used only for logging errors, so it's not
+  // super-efficient.
+  std::string
+  demangled_name() const;
+
   // Return the symbol version.  This will return NULL for an
   // unversioned symbol.
   const char*
index 5078237385ea062aa5e2b62b50c1253f0d4a3ec9..992b8bf24c6d57b24afa50a2a57f1f978885d0a0 100644 (file)
@@ -918,7 +918,7 @@ Target_x86_64::Scan::unsupported_reloc_global(Sized_relobj<64, false>* object,
                                               Symbol* gsym)
 {
   gold_error(_("%s: unsupported reloc %u against global symbol %s"),
-            object->name().c_str(), r_type, gsym->name());
+            object->name().c_str(), r_type, gsym->demangled_name().c_str());
 }
 
 // Scan a relocation for a global symbol.
@@ -1146,7 +1146,8 @@ Target_x86_64::Scan::global(const General_options& options,
     case elfcpp::R_X86_64_SIZE64:
     default:
       gold_error(_("%s: unsupported reloc %u against global symbol %s"),
-                object->name().c_str(), r_type, gsym->name());
+                object->name().c_str(), r_type,
+                 gsym->demangled_name().c_str());
       break;
     }
 }