Index: cref.cc =================================================================== RCS file: /cvs/src/src/gold/cref.cc,v retrieving revision 1.1 diff -p -u -r1.1 cref.cc --- cref.cc 22 Jul 2008 22:08:43 -0000 1.1 +++ cref.cc 5 Jan 2010 21:48:57 -0000 @@ -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 . // 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 Objects; @@ -82,6 +87,19 @@ class Cref_inputs // that archive. typedef std::map 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 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( 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 S } } +// 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 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_t } } +// 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. Index: cref.h =================================================================== RCS file: /cvs/src/src/gold/cref.h,v retrieving revision 1.1 diff -p -u -r1.1 cref.h --- cref.h 22 Jul 2008 22:08:43 -0000 1.1 +++ cref.h 5 Jan 2010 21:48:57 -0000 @@ -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 . // This file is part of gold. @@ -23,6 +23,8 @@ #ifndef GOLD_CREF_H #define GOLD_CREF_H +#include + 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(); Index: dynobj.cc =================================================================== RCS file: /cvs/src/src/gold/dynobj.cc,v retrieving revision 1.52 diff -p -u -r1.52 dynobj.cc --- dynobj.cc 30 Dec 2009 08:29:37 -0000 1.52 +++ dynobj.cc 5 Jan 2010 21:48:57 -0000 @@ -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 . // This file is part of gold. @@ -682,9 +682,10 @@ Sized_dynobj::do_add_s 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); Index: dynobj.h =================================================================== RCS file: /cvs/src/src/gold/dynobj.h,v retrieving revision 1.36 diff -p -u -r1.36 dynobj.h --- dynobj.h 14 Dec 2009 19:53:04 -0000 1.36 +++ dynobj.h 5 Jan 2010 21:48:57 -0000 @@ -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 . // 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 This; Index: main.cc =================================================================== RCS file: /cvs/src/src/gold/main.cc,v retrieving revision 1.36 diff -p -u -r1.36 main.cc --- main.cc 29 Dec 2009 23:45:10 -0000 1.36 +++ main.cc 5 Jan 2010 21:48:57 -0000 @@ -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 . // 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) Index: mapfile.h =================================================================== RCS file: /cvs/src/src/gold/mapfile.h,v retrieving revision 1.2 diff -p -u -r1.2 mapfile.h --- mapfile.h 7 Aug 2008 17:02:11 -0000 1.2 +++ mapfile.h 5 Jan 2010 21:48:57 -0000 @@ -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 . // 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 Index: object.cc =================================================================== RCS file: /cvs/src/src/gold/object.cc,v retrieving revision 1.113 diff -p -u -r1.113 object.cc --- object.cc 5 Jan 2010 00:32:22 -0000 1.113 +++ object.cc 5 Jan 2010 21:48:57 -0000 @@ -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 . // 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_dependencie 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* ar 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 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 Index: object.h =================================================================== RCS file: /cvs/src/src/gold/object.h,v retrieving revision 1.87 diff -p -u -r1.87 object.h --- object.h 14 Dec 2009 19:53:05 -0000 1.87 +++ object.h 5 Jan 2010 21:48:57 -0000 @@ -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 . // This file is part of gold. @@ -188,6 +188,8 @@ class Xindex class Object { public: + typedef std::vector 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 Index: options.h =================================================================== RCS file: /cvs/src/src/gold/options.h,v retrieving revision 1.128 diff -p -u -r1.128 options.h --- options.h 5 Jan 2010 05:56:28 -0000 1.128 +++ options.h 5 Jan 2010 21:48:57 -0000 @@ -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 . // 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")); Index: plugin.cc =================================================================== RCS file: /cvs/src/src/gold/plugin.cc,v retrieving revision 1.26 diff -p -u -r1.26 plugin.cc --- plugin.cc 14 Dec 2009 19:53:05 -0000 1.26 +++ plugin.cc 5 Jan 2010 21:48:57 -0000 @@ -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 . // This file is part of gold. @@ -784,6 +784,15 @@ Sized_pluginobj::do_ge gold_unreachable(); } +// Get symbols. Not used for plugin objects. + +template +const Object::Symbols* +Sized_pluginobj::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. Index: plugin.h =================================================================== RCS file: /cvs/src/src/gold/plugin.h,v retrieving revision 1.9 diff -p -u -r1.9 plugin.h --- plugin.h 28 Oct 2009 18:07:25 -0000 1.9 +++ plugin.h 5 Jan 2010 21:48:57 -0000 @@ -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 . // 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);