mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:54:41 +08:00
PR 10980
* options.h (class General_options): Add --cref. * main.cc (main): Print cref table if --cref. Don't close mapfile until after printing cref table. * cref.cc: Include "symtab.h". (class Cref_inputs): Define Cref_table_compare and Cref_table. (Cref_table_compare::operator()): New function. (Cref_inputs::gather_cref): New function. (filecol): New static const. (Cref_inputs::print_cref): New function. (Cref::print_cref): New function. * cref.h: Include <cstdio>. (class Cref): Update declarations. * mapfile.h (Mapfile::file): New function. * object.h (class Object): Define Symbols. Declare virtual do_get_global_symbols. (Object::get_global_symbols): New function. * object.cc (Input_objects::add_object): Pass object to cref_ if --cref. (Input_objects::archive_start): Likewise. (Input_objects::archive_stop): Likewise. (Input_objects::print_cref): New function. * dynobj.h (Sized_dynobj::do_get_global_symbols): New function. * dynobj.cc (big_endian>::do_add_symbols): Create symbols_ if --cref. * plugin.cc (Sized_pluginobj::do_get_global_symbols): New function. * plugin.h (class Sized_pluginobj): Update declarations.
This commit is contained in:
parent
43e85a8f54
commit
dde3f402cf
@ -1,3 +1,34 @@
|
||||
2010-01-05 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
PR 10980
|
||||
* options.h (class General_options): Add --cref.
|
||||
* main.cc (main): Print cref table if --cref. Don't close mapfile
|
||||
until after printing cref table.
|
||||
* cref.cc: Include "symtab.h".
|
||||
(class Cref_inputs): Define Cref_table_compare and Cref_table.
|
||||
(Cref_table_compare::operator()): New function.
|
||||
(Cref_inputs::gather_cref): New function.
|
||||
(filecol): New static const.
|
||||
(Cref_inputs::print_cref): New function.
|
||||
(Cref::print_cref): New function.
|
||||
* cref.h: Include <cstdio>.
|
||||
(class Cref): Update declarations.
|
||||
* mapfile.h (Mapfile::file): New function.
|
||||
* object.h (class Object): Define Symbols. Declare virtual
|
||||
do_get_global_symbols.
|
||||
(Object::get_global_symbols): New function.
|
||||
* object.cc (Input_objects::add_object): Pass object to cref_ if
|
||||
--cref.
|
||||
(Input_objects::archive_start): Likewise.
|
||||
(Input_objects::archive_stop): Likewise.
|
||||
(Input_objects::print_cref): New function.
|
||||
* dynobj.h (Sized_dynobj::do_get_global_symbols): New function.
|
||||
* dynobj.cc (big_endian>::do_add_symbols): Create symbols_ if
|
||||
--cref.
|
||||
* plugin.cc (Sized_pluginobj::do_get_global_symbols): New
|
||||
function.
|
||||
* plugin.h (class Sized_pluginobj): Update declarations.
|
||||
|
||||
2010-01-05 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* symtab.cc (Symbol_table::add_from_object): Rename def parameter
|
||||
|
158
gold/cref.cc
158
gold/cref.cc
@ -1,6 +1,6 @@
|
||||
// cref.cc -- cross reference for gold
|
||||
|
||||
// Copyright 2008 Free Software Foundation, Inc.
|
||||
// Copyright 2008, 2010 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -31,6 +31,7 @@
|
||||
|
||||
#include "object.h"
|
||||
#include "archive.h"
|
||||
#include "symtab.h"
|
||||
#include "cref.h"
|
||||
|
||||
namespace gold
|
||||
@ -63,6 +64,10 @@ class Cref_inputs
|
||||
void
|
||||
print_symbol_counts(const Symbol_table*, FILE*) const;
|
||||
|
||||
// Print a cross reference tabl.e
|
||||
void
|
||||
print_cref(const Symbol_table*, FILE*) const;
|
||||
|
||||
private:
|
||||
// A list of input objects.
|
||||
typedef std::vector<Object*> Objects;
|
||||
@ -82,6 +87,19 @@ class Cref_inputs
|
||||
// that archive.
|
||||
typedef std::map<std::string, Archive_info> Archives;
|
||||
|
||||
// For --cref, we build a cross reference table which maps from
|
||||
// symbols to lists of objects. The symbols are sorted
|
||||
// alphabetically.
|
||||
|
||||
class Cref_table_compare
|
||||
{
|
||||
public:
|
||||
bool
|
||||
operator()(const Symbol*, const Symbol*) const;
|
||||
};
|
||||
|
||||
typedef std::map<const Symbol*, Objects*, Cref_table_compare> Cref_table;
|
||||
|
||||
// Report symbol counts for a list of Objects.
|
||||
void
|
||||
print_objects_symbol_counts(const Symbol_table*, FILE*, const Objects*) const;
|
||||
@ -90,6 +108,10 @@ class Cref_inputs
|
||||
void
|
||||
print_object_symbol_counts(const Symbol_table*, FILE*, const Object*) const;
|
||||
|
||||
// Gather cross reference information.
|
||||
void
|
||||
gather_cref(const Objects*, Cref_table*) const;
|
||||
|
||||
// List of input objects.
|
||||
Objects objects_;
|
||||
// List of input archives. This is a mapping from the archive file
|
||||
@ -144,7 +166,7 @@ Cref_inputs::print_object_symbol_counts(const Symbol_table* symtab,
|
||||
fprintf(f, "symbols %s %zu %zu\n", object->name().c_str(), defined, used);
|
||||
}
|
||||
|
||||
// Report symbol counts for a list of Inputs.
|
||||
// Report symbol counts for a list of inputs.
|
||||
|
||||
void
|
||||
Cref_inputs::print_objects_symbol_counts(const Symbol_table* symtab,
|
||||
@ -189,6 +211,124 @@ Cref_inputs::print_symbol_counts(const Symbol_table* symtab, FILE* f) const
|
||||
}
|
||||
}
|
||||
|
||||
// Sort symbols for the cross reference table.
|
||||
|
||||
bool
|
||||
Cref_inputs::Cref_table_compare::operator()(const Symbol* s1,
|
||||
const Symbol* s2) const
|
||||
{
|
||||
int i = strcmp(s1->name(), s2->name());
|
||||
if (i != 0)
|
||||
return i < 0;
|
||||
|
||||
if (s1->version() == NULL)
|
||||
{
|
||||
if (s2->version() != NULL)
|
||||
return true;
|
||||
}
|
||||
else if (s2->version() == NULL)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
i = strcmp(s1->version(), s2->version());
|
||||
if (i != 0)
|
||||
return i < 0;
|
||||
}
|
||||
|
||||
// We should never have two different symbols with the same name and
|
||||
// version.
|
||||
if (s1 == s2)
|
||||
return false;
|
||||
gold_unreachable();
|
||||
}
|
||||
|
||||
// Gather cross reference information from a list of inputs.
|
||||
|
||||
void
|
||||
Cref_inputs::gather_cref(const Objects* objects, Cref_table* table) const
|
||||
{
|
||||
for (Objects::const_iterator po = objects->begin();
|
||||
po != objects->end();
|
||||
++po)
|
||||
{
|
||||
const Object::Symbols* symbols = (*po)->get_global_symbols();
|
||||
if (symbols == NULL)
|
||||
continue;
|
||||
for (Object::Symbols::const_iterator ps = symbols->begin();
|
||||
ps != symbols->end();
|
||||
++ps)
|
||||
{
|
||||
const Symbol* sym = *ps;
|
||||
if (sym == NULL)
|
||||
continue;
|
||||
Objects* const onull = NULL;
|
||||
std::pair<Cref_table::iterator, bool> ins =
|
||||
table->insert(std::make_pair(sym, onull));
|
||||
Cref_table::iterator pc = ins.first;
|
||||
if (ins.second)
|
||||
pc->second = new Objects();
|
||||
if (sym->source() == Symbol::FROM_OBJECT
|
||||
&& sym->object() == *po
|
||||
&& sym->is_defined())
|
||||
pc->second->insert(pc->second->begin(), *po);
|
||||
else
|
||||
pc->second->push_back(*po);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The column where the file name starts in a cross reference table.
|
||||
|
||||
static const size_t filecol = 50;
|
||||
|
||||
// Print a cross reference table.
|
||||
|
||||
void
|
||||
Cref_inputs::print_cref(const Symbol_table*, FILE* f) const
|
||||
{
|
||||
Cref_table table;
|
||||
this->gather_cref(&this->objects_, &table);
|
||||
for (Archives::const_iterator p = this->archives_.begin();
|
||||
p != this->archives_.end();
|
||||
++p)
|
||||
this->gather_cref(p->second.objects, &table);
|
||||
|
||||
for (Cref_table::const_iterator pc = table.begin();
|
||||
pc != table.end();
|
||||
++pc)
|
||||
{
|
||||
// If all the objects are dynamic, skip this symbol.
|
||||
const Symbol* sym = pc->first;
|
||||
const Objects* objects = pc->second;
|
||||
Objects::const_iterator po;
|
||||
for (po = objects->begin(); po != objects->end(); ++po)
|
||||
if (!(*po)->is_dynamic())
|
||||
break;
|
||||
if (po == objects->end())
|
||||
continue;
|
||||
|
||||
std::string s = sym->demangled_name();
|
||||
if (sym->version() != NULL)
|
||||
{
|
||||
s += '@';
|
||||
if (sym->is_default())
|
||||
s += '@';
|
||||
s += sym->version();
|
||||
}
|
||||
|
||||
fputs(s.c_str(), f);
|
||||
|
||||
size_t len = s.length();
|
||||
|
||||
for (po = objects->begin(); po != objects->end(); ++po)
|
||||
{
|
||||
int n = len < filecol ? filecol - len : 1;
|
||||
fprintf(f, "%*c%s\n", n, ' ', (*po)->name().c_str());
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Class Cref.
|
||||
|
||||
// Make sure the Cref_inputs object has been created.
|
||||
@ -250,4 +390,18 @@ Cref::print_symbol_counts(const Symbol_table* symtab) const
|
||||
}
|
||||
}
|
||||
|
||||
// Print a cross reference table.
|
||||
|
||||
void
|
||||
Cref::print_cref(const Symbol_table* symtab, FILE* f) const
|
||||
{
|
||||
fprintf(f, _("\nCross Reference Table\n\n"));
|
||||
const char* msg = _("Symbol");
|
||||
int len = filecol - strlen(msg);
|
||||
fprintf(f, "%s%*c%s\n", msg, len, ' ', _("File"));
|
||||
|
||||
if (parameters->options().cref() && this->inputs_ != NULL)
|
||||
this->inputs_->print_cref(symtab, f);
|
||||
}
|
||||
|
||||
} // End namespace gold.
|
||||
|
@ -1,6 +1,6 @@
|
||||
// cref.h -- cross reference reports for gold -*- C++ -*-
|
||||
|
||||
// Copyright 2008 Free Software Foundation, Inc.
|
||||
// Copyright 2008, 2010 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -23,6 +23,8 @@
|
||||
#ifndef GOLD_CREF_H
|
||||
#define GOLD_CREF_H
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
namespace gold
|
||||
{
|
||||
|
||||
@ -61,6 +63,10 @@ class Cref
|
||||
void
|
||||
print_symbol_counts(const Symbol_table*) const;
|
||||
|
||||
// Print a cross reference table.
|
||||
void
|
||||
print_cref(const Symbol_table*, FILE*) const;
|
||||
|
||||
private:
|
||||
void
|
||||
need_inputs();
|
||||
|
@ -1,6 +1,6 @@
|
||||
// dynobj.cc -- dynamic object support for gold
|
||||
|
||||
// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -682,9 +682,10 @@ Sized_dynobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
|
||||
Version_map version_map;
|
||||
this->make_version_map(sd, &version_map);
|
||||
|
||||
// If printing symbol counts, we want to track symbols.
|
||||
|
||||
if (parameters->options().user_set_print_symbol_counts())
|
||||
// If printing symbol counts or a cross reference table, we want to
|
||||
// track symbols.
|
||||
if (parameters->options().user_set_print_symbol_counts()
|
||||
|| parameters->options().cref())
|
||||
{
|
||||
this->symbols_ = new Symbols();
|
||||
this->symbols_->resize(symcount);
|
||||
|
@ -1,6 +1,6 @@
|
||||
// dynobj.h -- dynamic object support for gold -*- C++ -*-
|
||||
|
||||
// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -236,6 +236,11 @@ class Sized_dynobj : public Dynobj
|
||||
void
|
||||
do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const;
|
||||
|
||||
// Get the global symbols.
|
||||
const Symbols*
|
||||
do_get_global_symbols() const
|
||||
{ return this->symbols_; }
|
||||
|
||||
private:
|
||||
// For convenience.
|
||||
typedef Sized_dynobj<size, big_endian> This;
|
||||
|
13
gold/main.cc
13
gold/main.cc
@ -1,6 +1,6 @@
|
||||
// main.cc -- gold main function.
|
||||
|
||||
// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -270,13 +270,18 @@ main(int argc, char** argv)
|
||||
layout.print_stats();
|
||||
}
|
||||
|
||||
if (mapfile != NULL)
|
||||
mapfile->close();
|
||||
|
||||
// Issue defined symbol report.
|
||||
if (command_line.options().user_set_print_symbol_counts())
|
||||
input_objects.print_symbol_counts(&symtab);
|
||||
|
||||
// Output cross reference table.
|
||||
if (command_line.options().cref())
|
||||
input_objects.print_cref(&symtab,
|
||||
mapfile == NULL ? stdout : mapfile->file());
|
||||
|
||||
if (mapfile != NULL)
|
||||
mapfile->close();
|
||||
|
||||
if (parameters->options().fatal_warnings()
|
||||
&& errors.warning_count() > 0
|
||||
&& errors.error_count() == 0)
|
||||
|
@ -1,6 +1,6 @@
|
||||
// mapfile.h -- map file generation for gold -*- C++ -*-
|
||||
|
||||
// Copyright 2008 Free Software Foundation, Inc.
|
||||
// Copyright 2008, 2010 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -54,6 +54,11 @@ class Mapfile
|
||||
void
|
||||
close();
|
||||
|
||||
// Return the underlying file.
|
||||
FILE*
|
||||
file()
|
||||
{ return this->map_file_; }
|
||||
|
||||
// Report that we are including a member from an archive. This is
|
||||
// called by the archive reading code.
|
||||
void
|
||||
|
@ -1,6 +1,6 @@
|
||||
// object.cc -- support for an object file for linking in gold
|
||||
|
||||
// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -2146,7 +2146,8 @@ Input_objects::add_object(Object* obj)
|
||||
}
|
||||
|
||||
// Add this object to the cross-referencer if requested.
|
||||
if (parameters->options().user_set_print_symbol_counts())
|
||||
if (parameters->options().user_set_print_symbol_counts()
|
||||
|| parameters->options().cref())
|
||||
{
|
||||
if (this->cref_ == NULL)
|
||||
this->cref_ = new Cref();
|
||||
@ -2206,7 +2207,8 @@ Input_objects::check_dynamic_dependencies() const
|
||||
void
|
||||
Input_objects::archive_start(Archive* archive)
|
||||
{
|
||||
if (parameters->options().user_set_print_symbol_counts())
|
||||
if (parameters->options().user_set_print_symbol_counts()
|
||||
|| parameters->options().cref())
|
||||
{
|
||||
if (this->cref_ == NULL)
|
||||
this->cref_ = new Cref();
|
||||
@ -2219,7 +2221,8 @@ Input_objects::archive_start(Archive* archive)
|
||||
void
|
||||
Input_objects::archive_stop(Archive* archive)
|
||||
{
|
||||
if (parameters->options().user_set_print_symbol_counts())
|
||||
if (parameters->options().user_set_print_symbol_counts()
|
||||
|| parameters->options().cref())
|
||||
this->cref_->add_archive_stop(archive);
|
||||
}
|
||||
|
||||
@ -2233,6 +2236,15 @@ Input_objects::print_symbol_counts(const Symbol_table* symtab) const
|
||||
this->cref_->print_symbol_counts(symtab);
|
||||
}
|
||||
|
||||
// Print a cross reference table.
|
||||
|
||||
void
|
||||
Input_objects::print_cref(const Symbol_table* symtab, FILE* f) const
|
||||
{
|
||||
if (parameters->options().cref() && this->cref_ != NULL)
|
||||
this->cref_->print_cref(symtab, f);
|
||||
}
|
||||
|
||||
// Relocate_info methods.
|
||||
|
||||
// Return a string describing the location of a relocation. This is
|
||||
|
@ -1,6 +1,6 @@
|
||||
// object.h -- support for an object file for linking in gold -*- C++ -*-
|
||||
|
||||
// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -188,6 +188,8 @@ class Xindex
|
||||
class Object
|
||||
{
|
||||
public:
|
||||
typedef std::vector<Symbol*> Symbols;
|
||||
|
||||
// NAME is the name of the object as we would report it to the user
|
||||
// (e.g., libfoo.a(bar.o) if this is in an archive. INPUT_FILE is
|
||||
// used to read the file. OFFSET is the offset within the input
|
||||
@ -466,6 +468,11 @@ class Object
|
||||
size_t* used) const
|
||||
{ this->do_get_global_symbol_counts(symtab, defined, used); }
|
||||
|
||||
// Get the symbols defined in this object.
|
||||
const Symbols*
|
||||
get_global_symbols() const
|
||||
{ return this->do_get_global_symbols(); }
|
||||
|
||||
// Return whether this object was found in a system directory.
|
||||
bool
|
||||
is_in_system_directory() const
|
||||
@ -553,6 +560,9 @@ class Object
|
||||
virtual void
|
||||
do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const = 0;
|
||||
|
||||
virtual const Symbols*
|
||||
do_get_global_symbols() const = 0;
|
||||
|
||||
// Set the number of sections.
|
||||
void
|
||||
set_shnum(int shnum)
|
||||
@ -1596,6 +1606,11 @@ class Sized_relobj : public Relobj
|
||||
void
|
||||
do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const;
|
||||
|
||||
// Get the global symbols.
|
||||
const Symbols*
|
||||
do_get_global_symbols() const
|
||||
{ return &this->symbols_; }
|
||||
|
||||
// Get the offset of a section.
|
||||
uint64_t
|
||||
do_output_section_offset(unsigned int shndx) const
|
||||
@ -1960,6 +1975,10 @@ class Input_objects
|
||||
void
|
||||
print_symbol_counts(const Symbol_table*) const;
|
||||
|
||||
// Print a cross reference table.
|
||||
void
|
||||
print_cref(const Symbol_table*, FILE*) const;
|
||||
|
||||
// Iterate over all regular objects.
|
||||
|
||||
Relobj_iterator
|
||||
|
@ -1,6 +1,6 @@
|
||||
// options.h -- handle command line options for gold -*- C++ -*-
|
||||
|
||||
// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -643,6 +643,10 @@ class General_options
|
||||
N_("Not supported"),
|
||||
N_("Do not copy DT_NEEDED tags from shared libraries"));
|
||||
|
||||
DEFINE_bool(cref, options::TWO_DASHES, '\0', false,
|
||||
N_("Output cross reference table"),
|
||||
N_("Do not output cross reference table"));
|
||||
|
||||
DEFINE_bool(define_common, options::TWO_DASHES, 'd', false,
|
||||
N_("Define common symbols"),
|
||||
N_("Do not define common symbols"));
|
||||
|
@ -1,6 +1,6 @@
|
||||
// plugin.cc -- plugin manager for gold -*- C++ -*-
|
||||
|
||||
// Copyright 2008, 2009 Free Software Foundation, Inc.
|
||||
// Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Written by Cary Coutant <ccoutant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -784,6 +784,15 @@ Sized_pluginobj<size, big_endian>::do_get_global_symbol_counts(const Symbol_tabl
|
||||
gold_unreachable();
|
||||
}
|
||||
|
||||
// Get symbols. Not used for plugin objects.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
const Object::Symbols*
|
||||
Sized_pluginobj<size, big_endian>::do_get_global_symbols() const
|
||||
{
|
||||
gold_unreachable();
|
||||
}
|
||||
|
||||
// Class Plugin_finish. This task runs after all replacement files have
|
||||
// been added. It calls each plugin's cleanup handler.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// plugin.h -- plugin manager for gold -*- C++ -*-
|
||||
|
||||
// Copyright 2008, 2009 Free Software Foundation, Inc.
|
||||
// Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Written by Cary Coutant <ccoutant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -415,6 +415,10 @@ class Sized_pluginobj : public Pluginobj
|
||||
void
|
||||
do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const;
|
||||
|
||||
// Get global symbols.
|
||||
const Symbols*
|
||||
do_get_global_symbols() const;
|
||||
|
||||
// Add placeholder symbols from a claimed file.
|
||||
ld_plugin_status
|
||||
add_symbols_from_plugin(int nsyms, const ld_plugin_symbol* syms);
|
||||
|
Loading…
Reference in New Issue
Block a user