From Craig Silverstein: Add support for --demangle.
This commit is contained in:
parent
2a1932dcc7
commit
a2b1aa12f7
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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_;
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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*
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user