From Craig Silverstein: Add support for --demangle.

This commit is contained in:
Ian Lance Taylor 2007-11-15 01:12:55 +00:00
parent 2a1932dcc7
commit a2b1aa12f7
12 changed files with 100 additions and 21 deletions

View 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;
}

View 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());
}

View 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.

View 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;

View 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.

View 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_;

View 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();

View 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.

View 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()

View 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)

View 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*

View 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;
}
}