mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-27 06:17:47 +08:00
From Craig Silverstein: Add support for --demangle.
This commit is contained in:
@ -1301,7 +1301,7 @@ Versions::add_def(const Symbol* sym, const char* version,
|
|||||||
if (parameters->output_is_shared())
|
if (parameters->output_is_shared())
|
||||||
{
|
{
|
||||||
gold_error(_("symbol %s has undefined version %s"),
|
gold_error(_("symbol %s has undefined version %s"),
|
||||||
sym->name(), version);
|
sym->demangled_name().c_str(), version);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ Errors::undefined_symbol(const Symbol* sym,
|
|||||||
}
|
}
|
||||||
fprintf(stderr, _("%s: %s: undefined reference to '%s'\n"),
|
fprintf(stderr, _("%s: %s: undefined reference to '%s'\n"),
|
||||||
this->program_name_, relinfo->location(relnum, reloffset).c_str(),
|
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)
|
Symbol* gsym)
|
||||||
{
|
{
|
||||||
gold_error(_("%s: unsupported reloc %u against global symbol %s"),
|
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.
|
// Scan a relocation for a global symbol.
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
|
#include "demangle.h"
|
||||||
#include "libiberty.h"
|
#include "libiberty.h"
|
||||||
|
|
||||||
#include "target-select.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)
|
if (sym.get_st_name() > names_size)
|
||||||
info->enclosing_symbol_name = "(invalid)";
|
info->enclosing_symbol_name = "(invalid)";
|
||||||
else
|
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;
|
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))
|
if (this->object->get_symbol_location_info(this->data_shndx, offset, &info))
|
||||||
{
|
{
|
||||||
ret += " in function ";
|
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 += info.enclosing_symbol_name;
|
||||||
ret += ":";
|
ret += ":";
|
||||||
filename = info.source_file;
|
filename = info.source_file;
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "gold.h"
|
#include "gold.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include "filenames.h"
|
#include "filenames.h"
|
||||||
@ -361,6 +362,11 @@ options::Command_line_options::options[] =
|
|||||||
&Position_dependent_options::set_static_search),
|
&Position_dependent_options::set_static_search),
|
||||||
GENERAL_NOARG('\0', "Bsymbolic", N_("Bind defined symbols locally"),
|
GENERAL_NOARG('\0', "Bsymbolic", N_("Bind defined symbols locally"),
|
||||||
NULL, ONE_DASH, &General_options::set_symbolic),
|
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",
|
GENERAL_NOARG('\0', "detect-odr-violations",
|
||||||
N_("Try to detect violations of the One Definition Rule"),
|
N_("Try to detect violations of the One Definition Rule"),
|
||||||
NULL, TWO_DASHES, &General_options::set_detect_odr_violations),
|
NULL, TWO_DASHES, &General_options::set_detect_odr_violations),
|
||||||
@ -500,6 +506,12 @@ General_options::General_options()
|
|||||||
thread_count_final_(0),
|
thread_count_final_(0),
|
||||||
execstack_(EXECSTACK_FROM_INPUT)
|
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.
|
// The default values for the position dependent options.
|
||||||
|
@ -159,6 +159,11 @@ class General_options
|
|||||||
symbolic() const
|
symbolic() const
|
||||||
{ return this->symbolic_; }
|
{ 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.
|
// --detect-odr-violations: Whether to search for One Defn Rule violations.
|
||||||
bool
|
bool
|
||||||
detect_odr_violations() const
|
detect_odr_violations() const
|
||||||
@ -318,6 +323,14 @@ class General_options
|
|||||||
set_symbolic()
|
set_symbolic()
|
||||||
{ this->symbolic_ = true; }
|
{ this->symbolic_ = true; }
|
||||||
|
|
||||||
|
void
|
||||||
|
set_demangle()
|
||||||
|
{ this->demangle_ = true; }
|
||||||
|
|
||||||
|
void
|
||||||
|
clear_demangle()
|
||||||
|
{ this->demangle_ = false; }
|
||||||
|
|
||||||
void
|
void
|
||||||
set_detect_odr_violations()
|
set_detect_odr_violations()
|
||||||
{ this->detect_odr_violations_ = true; }
|
{ this->detect_odr_violations_ = true; }
|
||||||
@ -436,6 +449,7 @@ class General_options
|
|||||||
Strip strip_;
|
Strip strip_;
|
||||||
bool allow_shlib_undefined_;
|
bool allow_shlib_undefined_;
|
||||||
bool symbolic_;
|
bool symbolic_;
|
||||||
|
bool demangle_;
|
||||||
bool detect_odr_violations_;
|
bool detect_odr_violations_;
|
||||||
bool create_eh_frame_hdr_;
|
bool create_eh_frame_hdr_;
|
||||||
Dir_list rpath_;
|
Dir_list rpath_;
|
||||||
|
@ -34,7 +34,7 @@ Parameters::Parameters(Errors* errors)
|
|||||||
: errors_(errors), output_file_name_(NULL),
|
: errors_(errors), output_file_name_(NULL),
|
||||||
output_file_type_(OUTPUT_INVALID), sysroot_(),
|
output_file_type_(OUTPUT_INVALID), sysroot_(),
|
||||||
strip_(STRIP_INVALID), allow_shlib_undefined_(false),
|
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),
|
optimization_level_(0), export_dynamic_(false),
|
||||||
is_doing_static_link_valid_(false), doing_static_link_(false),
|
is_doing_static_link_valid_(false), doing_static_link_(false),
|
||||||
is_size_and_endian_valid_(false), size_(0), is_big_endian_(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->sysroot_ = options->sysroot();
|
||||||
this->allow_shlib_undefined_ = options->allow_shlib_undefined();
|
this->allow_shlib_undefined_ = options->allow_shlib_undefined();
|
||||||
this->symbolic_ = options->symbolic();
|
this->symbolic_ = options->symbolic();
|
||||||
|
this->demangle_ = options->demangle();
|
||||||
this->detect_odr_violations_ = options->detect_odr_violations();
|
this->detect_odr_violations_ = options->detect_odr_violations();
|
||||||
this->optimization_level_ = options->optimization_level();
|
this->optimization_level_ = options->optimization_level();
|
||||||
this->export_dynamic_ = options->export_dynamic();
|
this->export_dynamic_ = options->export_dynamic();
|
||||||
|
@ -129,6 +129,11 @@ class Parameters
|
|||||||
return this->symbolic_;
|
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.
|
// Whether we should try to detect violations of the One Definition Rule.
|
||||||
bool
|
bool
|
||||||
detect_odr_violations() const
|
detect_odr_violations() const
|
||||||
@ -236,6 +241,8 @@ class Parameters
|
|||||||
bool allow_shlib_undefined_;
|
bool allow_shlib_undefined_;
|
||||||
// Whether we are doing a symbolic link.
|
// Whether we are doing a symbolic link.
|
||||||
bool symbolic_;
|
bool symbolic_;
|
||||||
|
// Whether we should demangle C++ symbols in our log messages.
|
||||||
|
bool demangle_;
|
||||||
// Whether we try to detect One Definition Rule violations.
|
// Whether we try to detect One Definition Rule violations.
|
||||||
bool detect_odr_violations_;
|
bool detect_odr_violations_;
|
||||||
// The optimization level.
|
// The optimization level.
|
||||||
|
@ -256,11 +256,11 @@ Symbol_table::resolve(Sized_symbol<size>* to,
|
|||||||
// on C++ symbols. These have (mangled) names starting with _Z.
|
// on C++ symbols. These have (mangled) names starting with _Z.
|
||||||
&& to->name()[0] == '_' && to->name()[1] == '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() };
|
= { object, orig_sym.get_st_shndx(), orig_sym.get_st_value() };
|
||||||
Symbol_location to_location = { to->object(), to->shndx(), to->value() };
|
Symbol_location toloc = { to->object(), to->shndx(), to->value() };
|
||||||
this->candidate_odr_violations_[to->name()].insert(from_location);
|
this->candidate_odr_violations_[to->name()].insert(fromloc);
|
||||||
this->candidate_odr_violations_[to->name()].insert(to_location);
|
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.
|
// FIXME: Do a better job of reporting locations.
|
||||||
gold_error(_("%s: multiple definition of %s"),
|
gold_error(_("%s: multiple definition of %s"),
|
||||||
object != NULL ? object->name().c_str() : _("command line"),
|
object != NULL ? object->name().c_str() : _("command line"),
|
||||||
to->name());
|
to->demangled_name().c_str());
|
||||||
gold_error(_("%s: previous definition here"),
|
gold_error(_("%s: previous definition here"),
|
||||||
(to->source() == Symbol::FROM_OBJECT
|
(to->source() == Symbol::FROM_OBJECT
|
||||||
? to->object()->name().c_str()
|
? to->object()->name().c_str()
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include "demangle.h"
|
||||||
|
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
#include "dwarf_reader.h"
|
#include "dwarf_reader.h"
|
||||||
@ -72,6 +73,32 @@ Symbol::init_fields(const char* name, const char* version,
|
|||||||
this->needs_value_in_got_ = false;
|
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.
|
// Initialize the fields in the base class Symbol for SYM in OBJECT.
|
||||||
|
|
||||||
template<int size, bool big_endian>
|
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)
|
&& shndx != elfcpp::SHN_ABS)
|
||||||
{
|
{
|
||||||
gold_error(_("%s: unsupported symbol section 0x%x"),
|
gold_error(_("%s: unsupported symbol section 0x%x"),
|
||||||
sym->name(), shndx);
|
sym->demangled_name().c_str(), shndx);
|
||||||
shndx = elfcpp::SHN_UNDEF;
|
shndx = elfcpp::SHN_UNDEF;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1647,7 +1674,7 @@ Symbol_table::sized_write_globals(const Input_objects* input_objects,
|
|||||||
&& in_shndx != elfcpp::SHN_ABS)
|
&& in_shndx != elfcpp::SHN_ABS)
|
||||||
{
|
{
|
||||||
gold_error(_("%s: unsupported symbol section 0x%x"),
|
gold_error(_("%s: unsupported symbol section 0x%x"),
|
||||||
sym->name(), in_shndx);
|
sym->demangled_name().c_str(), in_shndx);
|
||||||
shndx = in_shndx;
|
shndx = in_shndx;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1771,7 +1798,8 @@ Symbol_table::warn_about_undefined_dynobj_symbol(
|
|||||||
Dynobj* dynobj = static_cast<Dynobj*>(sym->object());
|
Dynobj* dynobj = static_cast<Dynobj*>(sym->object());
|
||||||
if (!dynobj->has_unknown_needed_entries())
|
if (!dynobj->has_unknown_needed_entries())
|
||||||
gold_error(_("%s: undefined reference to '%s'"),
|
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 "
|
gold_warning(_("while linking %s: symbol %s defined in multiple "
|
||||||
"places (possible ODR violation):"),
|
"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();
|
for (std::set<std::string>::const_iterator it2 = line_nums.begin();
|
||||||
it2 != line_nums.end();
|
it2 != line_nums.end();
|
||||||
++it2)
|
++it2)
|
||||||
|
@ -98,6 +98,13 @@ class Symbol
|
|||||||
name() const
|
name() const
|
||||||
{ return this->name_; }
|
{ 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
|
// Return the symbol version. This will return NULL for an
|
||||||
// unversioned symbol.
|
// unversioned symbol.
|
||||||
const char*
|
const char*
|
||||||
|
@ -918,7 +918,7 @@ Target_x86_64::Scan::unsupported_reloc_global(Sized_relobj<64, false>* object,
|
|||||||
Symbol* gsym)
|
Symbol* gsym)
|
||||||
{
|
{
|
||||||
gold_error(_("%s: unsupported reloc %u against global symbol %s"),
|
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.
|
// 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:
|
case elfcpp::R_X86_64_SIZE64:
|
||||||
default:
|
default:
|
||||||
gold_error(_("%s: unsupported reloc %u against global symbol %s"),
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user