summaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
Diffstat (limited to 'gold')
-rw-r--r--gold/dynobj.cc2
-rw-r--r--gold/errors.cc2
-rw-r--r--gold/i386.cc2
-rw-r--r--gold/object.cc21
-rw-r--r--gold/options.cc12
-rw-r--r--gold/options.h14
-rw-r--r--gold/parameters.cc3
-rw-r--r--gold/parameters.h7
-rw-r--r--gold/resolve.cc10
-rw-r--r--gold/symtab.cc36
-rw-r--r--gold/symtab.h7
-rw-r--r--gold/x86_64.cc5
12 files changed, 100 insertions, 21 deletions
diff --git a/gold/dynobj.cc b/gold/dynobj.cc
index a6f3588f48..f479352794 100644
--- a/gold/dynobj.cc
+++ b/gold/dynobj.cc
@@ -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;
}
diff --git a/gold/errors.cc b/gold/errors.cc
index 3aa3ece897..2da1a2569e 100644
--- a/gold/errors.cc
+++ b/gold/errors.cc
@@ -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());
}
diff --git a/gold/i386.cc b/gold/i386.cc
index b4c7e42160..4a6aa7353f 100644
--- a/gold/i386.cc
+++ b/gold/i386.cc
@@ -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.
diff --git a/gold/object.cc b/gold/object.cc
index 7a4b1fb41e..ecefa8bf39 100644
--- a/gold/object.cc
+++ b/gold/object.cc
@@ -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;
diff --git a/gold/options.cc b/gold/options.cc
index 69f452dd38..20714359e8 100644
--- a/gold/options.cc
+++ b/gold/options.cc
@@ -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.
diff --git a/gold/options.h b/gold/options.h
index b5d2328a1a..1a67a7e27a 100644
--- a/gold/options.h
+++ b/gold/options.h
@@ -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
@@ -319,6 +324,14 @@ class General_options
{ 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_;
diff --git a/gold/parameters.cc b/gold/parameters.cc
index b96221a8b2..aceb61ee73 100644
--- a/gold/parameters.cc
+++ b/gold/parameters.cc
@@ -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();
diff --git a/gold/parameters.h b/gold/parameters.h
index ee60b10b4a..b760eceb4c 100644
--- a/gold/parameters.h
+++ b/gold/parameters.h
@@ -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.
diff --git a/gold/resolve.cc b/gold/resolve.cc
index b3328d564f..6e3d3acce3 100644
--- a/gold/resolve.cc
+++ b/gold/resolve.cc
@@ -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()
diff --git a/gold/symtab.cc b/gold/symtab.cc
index caac2a77fb..c918db3293 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -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)
diff --git a/gold/symtab.h b/gold/symtab.h
index 8206cbaa33..b6e550463e 100644
--- a/gold/symtab.h
+++ b/gold/symtab.h
@@ -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*
diff --git a/gold/x86_64.cc b/gold/x86_64.cc
index 5078237385..992b8bf24c 100644
--- a/gold/x86_64.cc
+++ b/gold/x86_64.cc
@@ -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;
}
}