if (parameters->output_is_shared())
{
gold_error(_("symbol %s has undefined version %s"),
- sym->name(), version);
+ sym->demangled_name().c_str(), version);
return;
}
}
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());
}
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.
#include <cerrno>
#include <cstring>
#include <cstdarg>
+#include "demangle.h"
#include "libiberty.h"
#include "target-select.h"
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;
}
}
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;
#include "gold.h"
+#include <cstdlib>
#include <iostream>
#include <sys/stat.h>
#include "filenames.h"
&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),
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.
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
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; }
Strip strip_;
bool allow_shlib_undefined_;
bool symbolic_;
+ bool demangle_;
bool detect_odr_violations_;
bool create_eh_frame_hdr_;
Dir_list rpath_;
: 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)
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();
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
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.
// 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);
}
}
// 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()
#include <set>
#include <string>
#include <utility>
+#include "demangle.h"
#include "object.h"
#include "dwarf_reader.h"
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>
&& 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;
}
&& 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
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());
}
}
{
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)
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*
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.
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;
}
}