mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 10:03:47 +08:00
* cref.cc: New file.
* cref.h: New file. * options.h (class General_options): Add --print-symbol-counts. * main.cc (main): Issue defined symbol report if requested. * archive.cc (Archive::interpret_header): Make into a const member function. (Archive::add_symbols): Call Input_objects::archive_start and archive_stop. (Archive::const_iterator): Define new class. (Archive::begin, Archive::end): New functions. (Archive::include_all_members): Rewrite to use iterator. (Archive::count_members): New function. * archive.h (class Archive): Update declarations. (Archive::filename): New function. * object.cc: Include "cref.h". (Sized_relobj::Sized_relobj): Initialize defined_count_. (Sized_relobj::do_get_global_symbol_counts): New function. (Input_objects::add_object): Add object to cross-referencer. (Input_objects::archive_start): New function. (Input_objects::archive_stop): New function. (Input_objects::print_symbol_counts): New function. * object.h: Declare Cref and Archive. (Object::get_global_symbol_counts): New function. (Object::do_get_global_symbol_counts): New pure virtual function. (class Sized_relobj): Add defined_count_ field. Update declarations. (class Input_objects): Add cref_ field. Update constructor. Update declarations. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize symbols_ and defined_count_. (Sized_dynobj::do_add_symbols): Allocate symbols_ if printing symbol counts. (Sized_dynobj::do_get_global_symbol_counts): New function. * dynobj.h (class Sized_dynobj): Add fields symbols_ and defined_count_. Update declarations. Define Symbols typedef. * symtab.cc (Symbol_table::add_from_relobj): Add defined parameter. Change all callers. (Symbol_table::add_from_dynobj): Add sympointers and defined parameters. Change all callers. * symtab.h (class Symbol_table): Update declarations. * Makefile.am (CCFILES): Add cref.cc. (HFILES): Add cref.h. * Makefile.in: Rebuild.
This commit is contained in:
parent
3f7c5e1d99
commit
92de84a60c
@ -1,3 +1,49 @@
|
||||
2008-07-22 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* cref.cc: New file.
|
||||
* cref.h: New file.
|
||||
* options.h (class General_options): Add --print-symbol-counts.
|
||||
* main.cc (main): Issue defined symbol report if requested.
|
||||
* archive.cc (Archive::interpret_header): Make into a const member
|
||||
function.
|
||||
(Archive::add_symbols): Call Input_objects::archive_start and
|
||||
archive_stop.
|
||||
(Archive::const_iterator): Define new class.
|
||||
(Archive::begin, Archive::end): New functions.
|
||||
(Archive::include_all_members): Rewrite to use iterator.
|
||||
(Archive::count_members): New function.
|
||||
* archive.h (class Archive): Update declarations.
|
||||
(Archive::filename): New function.
|
||||
* object.cc: Include "cref.h".
|
||||
(Sized_relobj::Sized_relobj): Initialize defined_count_.
|
||||
(Sized_relobj::do_get_global_symbol_counts): New function.
|
||||
(Input_objects::add_object): Add object to cross-referencer.
|
||||
(Input_objects::archive_start): New function.
|
||||
(Input_objects::archive_stop): New function.
|
||||
(Input_objects::print_symbol_counts): New function.
|
||||
* object.h: Declare Cref and Archive.
|
||||
(Object::get_global_symbol_counts): New function.
|
||||
(Object::do_get_global_symbol_counts): New pure virtual function.
|
||||
(class Sized_relobj): Add defined_count_ field. Update
|
||||
declarations.
|
||||
(class Input_objects): Add cref_ field. Update constructor.
|
||||
Update declarations.
|
||||
* dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize symbols_ and
|
||||
defined_count_.
|
||||
(Sized_dynobj::do_add_symbols): Allocate symbols_ if printing
|
||||
symbol counts.
|
||||
(Sized_dynobj::do_get_global_symbol_counts): New function.
|
||||
* dynobj.h (class Sized_dynobj): Add fields symbols_ and
|
||||
defined_count_. Update declarations. Define Symbols typedef.
|
||||
* symtab.cc (Symbol_table::add_from_relobj): Add defined
|
||||
parameter. Change all callers.
|
||||
(Symbol_table::add_from_dynobj): Add sympointers and defined
|
||||
parameters. Change all callers.
|
||||
* symtab.h (class Symbol_table): Update declarations.
|
||||
* Makefile.am (CCFILES): Add cref.cc.
|
||||
(HFILES): Add cref.h.
|
||||
* Makefile.in: Rebuild.
|
||||
|
||||
2008-07-22 Simon Baldwin <simonb@google.com>
|
||||
|
||||
* symtab.cc (Symbol_table::sized_write_symbol): Set symbol size
|
||||
@ -212,7 +258,7 @@
|
||||
|
||||
* reduced_debug_output.cc: New file.
|
||||
* reduced_debug_output.h: New file.
|
||||
* options.h (class General_optoins): Add --strip-debug-non-line.
|
||||
* options.h (class General_options): Add --strip-debug-non-line.
|
||||
* options.cc (General_options::finalize): Add strip_debug_non_line
|
||||
to the strip heirarchy.
|
||||
* layout.h (class Layout): Add debug_abbrev_ and debug_info_
|
||||
|
@ -34,6 +34,7 @@ CCFILES = \
|
||||
common.cc \
|
||||
compressed_output.cc \
|
||||
copy-relocs.cc \
|
||||
cref.cc \
|
||||
defstd.cc \
|
||||
dirsearch.cc \
|
||||
dynobj.cc \
|
||||
@ -70,6 +71,7 @@ HFILES = \
|
||||
common.h \
|
||||
compressed_output.h \
|
||||
copy-relocs.h \
|
||||
cref.h \
|
||||
defstd.h \
|
||||
dirsearch.h \
|
||||
dynobj.h \
|
||||
|
@ -76,16 +76,16 @@ libgold_a_AR = $(AR) $(ARFLAGS)
|
||||
libgold_a_LIBADD =
|
||||
am__objects_1 = archive.$(OBJEXT) binary.$(OBJEXT) common.$(OBJEXT) \
|
||||
compressed_output.$(OBJEXT) copy-relocs.$(OBJEXT) \
|
||||
defstd.$(OBJEXT) dirsearch.$(OBJEXT) dynobj.$(OBJEXT) \
|
||||
dwarf_reader.$(OBJEXT) ehframe.$(OBJEXT) errors.$(OBJEXT) \
|
||||
expression.$(OBJEXT) fileread.$(OBJEXT) gold.$(OBJEXT) \
|
||||
gold-threads.$(OBJEXT) layout.$(OBJEXT) mapfile.$(OBJEXT) \
|
||||
merge.$(OBJEXT) object.$(OBJEXT) options.$(OBJEXT) \
|
||||
output.$(OBJEXT) parameters.$(OBJEXT) readsyms.$(OBJEXT) \
|
||||
reduced_debug_output.$(OBJEXT) reloc.$(OBJEXT) \
|
||||
resolve.$(OBJEXT) script-sections.$(OBJEXT) script.$(OBJEXT) \
|
||||
stringpool.$(OBJEXT) symtab.$(OBJEXT) target-select.$(OBJEXT) \
|
||||
version.$(OBJEXT) workqueue.$(OBJEXT) \
|
||||
cref.$(OBJEXT) defstd.$(OBJEXT) dirsearch.$(OBJEXT) \
|
||||
dynobj.$(OBJEXT) dwarf_reader.$(OBJEXT) ehframe.$(OBJEXT) \
|
||||
errors.$(OBJEXT) expression.$(OBJEXT) fileread.$(OBJEXT) \
|
||||
gold.$(OBJEXT) gold-threads.$(OBJEXT) layout.$(OBJEXT) \
|
||||
mapfile.$(OBJEXT) merge.$(OBJEXT) object.$(OBJEXT) \
|
||||
options.$(OBJEXT) output.$(OBJEXT) parameters.$(OBJEXT) \
|
||||
readsyms.$(OBJEXT) reduced_debug_output.$(OBJEXT) \
|
||||
reloc.$(OBJEXT) resolve.$(OBJEXT) script-sections.$(OBJEXT) \
|
||||
script.$(OBJEXT) stringpool.$(OBJEXT) symtab.$(OBJEXT) \
|
||||
target-select.$(OBJEXT) version.$(OBJEXT) workqueue.$(OBJEXT) \
|
||||
workqueue-threads.$(OBJEXT)
|
||||
am__objects_2 =
|
||||
am__objects_3 = yyscript.$(OBJEXT)
|
||||
@ -316,6 +316,7 @@ CCFILES = \
|
||||
common.cc \
|
||||
compressed_output.cc \
|
||||
copy-relocs.cc \
|
||||
cref.cc \
|
||||
defstd.cc \
|
||||
dirsearch.cc \
|
||||
dynobj.cc \
|
||||
@ -352,6 +353,7 @@ HFILES = \
|
||||
common.h \
|
||||
compressed_output.h \
|
||||
copy-relocs.h \
|
||||
cref.h \
|
||||
defstd.h \
|
||||
dirsearch.h \
|
||||
dynobj.h \
|
||||
@ -524,6 +526,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compressed_output.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/copy-relocs.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cref.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/defstd.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dirsearch.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_reader.Po@am__quote@
|
||||
|
192
gold/archive.cc
192
gold/archive.cc
@ -191,7 +191,7 @@ Archive::read_header(off_t off, bool cache, std::string* pname,
|
||||
|
||||
off_t
|
||||
Archive::interpret_header(const Archive_header* hdr, off_t off,
|
||||
std::string* pname, off_t* nested_off)
|
||||
std::string* pname, off_t* nested_off) const
|
||||
{
|
||||
if (memcmp(hdr->ar_fmag, arfmag, sizeof arfmag) != 0)
|
||||
{
|
||||
@ -293,6 +293,8 @@ Archive::add_symbols(Symbol_table* symtab, Layout* layout,
|
||||
return this->include_all_members(symtab, layout, input_objects,
|
||||
mapfile);
|
||||
|
||||
input_objects->archive_start(this);
|
||||
|
||||
const size_t armap_size = this->armap_.size();
|
||||
|
||||
// This is a quick optimization, since we usually see many symbols
|
||||
@ -359,6 +361,137 @@ Archive::add_symbols(Symbol_table* symtab, Layout* layout,
|
||||
}
|
||||
}
|
||||
while (added_new_object);
|
||||
|
||||
input_objects->archive_stop(this);
|
||||
}
|
||||
|
||||
// An archive member iterator.
|
||||
|
||||
class Archive::const_iterator
|
||||
{
|
||||
public:
|
||||
// The header of an archive member. This is what this iterator
|
||||
// points to.
|
||||
struct Header
|
||||
{
|
||||
// The name of the member.
|
||||
std::string name;
|
||||
// The file offset of the member.
|
||||
off_t off;
|
||||
// The file offset of a nested archive member.
|
||||
off_t nested_off;
|
||||
// The size of the member.
|
||||
off_t size;
|
||||
};
|
||||
|
||||
const_iterator(const Archive* archive, off_t off)
|
||||
: archive_(archive), off_(off)
|
||||
{ this->read_next_header(); }
|
||||
|
||||
const Header&
|
||||
operator*() const
|
||||
{ return this->header_; }
|
||||
|
||||
const Header*
|
||||
operator->() const
|
||||
{ return &this->header_; }
|
||||
|
||||
const_iterator&
|
||||
operator++()
|
||||
{
|
||||
if (this->off_ == this->archive_->file().filesize())
|
||||
return *this;
|
||||
this->off_ += sizeof(Archive_header);
|
||||
if (!this->archive_->is_thin_archive())
|
||||
this->off_ += this->header_.size;
|
||||
if ((this->off_ & 1) != 0)
|
||||
++this->off_;
|
||||
this->read_next_header();
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
operator++(int)
|
||||
{
|
||||
const_iterator ret = *this;
|
||||
++*this;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const const_iterator p) const
|
||||
{ return this->off_ == p->off; }
|
||||
|
||||
bool
|
||||
operator!=(const const_iterator p) const
|
||||
{ return this->off_ != p->off; }
|
||||
|
||||
private:
|
||||
void
|
||||
read_next_header();
|
||||
|
||||
// The underlying archive.
|
||||
const Archive* archive_;
|
||||
// The current offset in the file.
|
||||
off_t off_;
|
||||
// The current archive header.
|
||||
Header header_;
|
||||
};
|
||||
|
||||
// Read the next archive header.
|
||||
|
||||
void
|
||||
Archive::const_iterator::read_next_header()
|
||||
{
|
||||
off_t filesize = this->archive_->file().filesize();
|
||||
while (true)
|
||||
{
|
||||
if (filesize - this->off_ < static_cast<off_t>(sizeof(Archive_header)))
|
||||
{
|
||||
if (filesize != this->off_)
|
||||
{
|
||||
gold_error(_("%s: short archive header at %zu"),
|
||||
this->archive_->filename().c_str(),
|
||||
static_cast<size_t>(this->off_));
|
||||
this->off_ = filesize;
|
||||
}
|
||||
this->header_.off = filesize;
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char buf[sizeof(Archive_header)];
|
||||
this->archive_->file().read(this->off_, sizeof(Archive_header), buf);
|
||||
|
||||
const Archive_header* hdr = reinterpret_cast<const Archive_header*>(buf);
|
||||
this->header_.size =
|
||||
this->archive_->interpret_header(hdr, this->off_, &this->header_.name,
|
||||
&this->header_.nested_off);
|
||||
this->header_.off = this->off_;
|
||||
|
||||
// Skip special members.
|
||||
if (!this->header_.name.empty() && this->header_.name != "/")
|
||||
return;
|
||||
|
||||
this->off_ += sizeof(Archive_header) + this->header_.size;
|
||||
if ((this->off_ & 1) != 0)
|
||||
++this->off_;
|
||||
}
|
||||
}
|
||||
|
||||
// Initial iterator.
|
||||
|
||||
Archive::const_iterator
|
||||
Archive::begin() const
|
||||
{
|
||||
return Archive::const_iterator(this, sarmag);
|
||||
}
|
||||
|
||||
// Final iterator.
|
||||
|
||||
Archive::const_iterator
|
||||
Archive::end() const
|
||||
{
|
||||
return Archive::const_iterator(this, this->input_file_->file().filesize());
|
||||
}
|
||||
|
||||
// Include all the archive members in the link. This is for --whole-archive.
|
||||
@ -367,46 +500,29 @@ void
|
||||
Archive::include_all_members(Symbol_table* symtab, Layout* layout,
|
||||
Input_objects* input_objects, Mapfile* mapfile)
|
||||
{
|
||||
off_t off = sarmag;
|
||||
off_t filesize = this->input_file_->file().filesize();
|
||||
while (true)
|
||||
{
|
||||
if (filesize - off < static_cast<off_t>(sizeof(Archive_header)))
|
||||
{
|
||||
if (filesize != off)
|
||||
gold_error(_("%s: short archive header at %zu"),
|
||||
this->name().c_str(), static_cast<size_t>(off));
|
||||
break;
|
||||
}
|
||||
input_objects->archive_start(this);
|
||||
|
||||
unsigned char hdr_buf[sizeof(Archive_header)];
|
||||
this->input_file_->file().read(off, sizeof(Archive_header), hdr_buf);
|
||||
for (Archive::const_iterator p = this->begin();
|
||||
p != this->end();
|
||||
++p)
|
||||
this->include_member(symtab, layout, input_objects, p->off,
|
||||
mapfile, NULL, "--whole-archive");
|
||||
|
||||
const Archive_header* hdr =
|
||||
reinterpret_cast<const Archive_header*>(hdr_buf);
|
||||
std::string name;
|
||||
off_t size = this->interpret_header(hdr, off, &name, NULL);
|
||||
bool special_member = false;
|
||||
if (name.empty())
|
||||
{
|
||||
// Symbol table.
|
||||
special_member = true;
|
||||
}
|
||||
else if (name == "/")
|
||||
{
|
||||
// Extended name table.
|
||||
special_member = true;
|
||||
}
|
||||
else
|
||||
this->include_member(symtab, layout, input_objects, off,
|
||||
mapfile, NULL, "--whole-archive");
|
||||
input_objects->archive_stop(this);
|
||||
}
|
||||
|
||||
off += sizeof(Archive_header);
|
||||
if (special_member || !this->is_thin_archive_)
|
||||
off += size;
|
||||
if ((off & 1) != 0)
|
||||
++off;
|
||||
}
|
||||
// Return the number of members in the archive. This is only used for
|
||||
// reports.
|
||||
|
||||
size_t
|
||||
Archive::count_members() const
|
||||
{
|
||||
size_t ret = 0;
|
||||
for (Archive::const_iterator p = this->begin();
|
||||
p != this->end();
|
||||
++p)
|
||||
++ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Include an archive member in the link. OFF is the file offset of
|
||||
|
@ -62,11 +62,18 @@ class Archive
|
||||
// The string expected at the end of an archive member header.
|
||||
static const char arfmag[2];
|
||||
|
||||
// The name of the object.
|
||||
// The name of the object. This is the name used on the command
|
||||
// line; e.g., if "-lgcc" is on the command line, this will be
|
||||
// "gcc".
|
||||
const std::string&
|
||||
name() const
|
||||
{ return this->name_; }
|
||||
|
||||
// The file name.
|
||||
const std::string&
|
||||
filename() const
|
||||
{ return this->input_file_->filename(); }
|
||||
|
||||
// Set up the archive: read the symbol map.
|
||||
void
|
||||
setup();
|
||||
@ -110,6 +117,11 @@ class Archive
|
||||
clear_uncached_views()
|
||||
{ this->input_file_->file().clear_uncached_views(); }
|
||||
|
||||
// Whether this is a thin archive.
|
||||
bool
|
||||
is_thin_archive() const
|
||||
{ return this->is_thin_archive_; }
|
||||
|
||||
// Unlock any nested archives.
|
||||
void
|
||||
unlock_nested_archives();
|
||||
@ -119,6 +131,10 @@ class Archive
|
||||
void
|
||||
add_symbols(Symbol_table*, Layout*, Input_objects*, Mapfile*);
|
||||
|
||||
// Return the number of members in the archive.
|
||||
size_t
|
||||
count_members() const;
|
||||
|
||||
private:
|
||||
Archive(const Archive&);
|
||||
Archive& operator=(const Archive&);
|
||||
@ -144,7 +160,7 @@ class Archive
|
||||
// member, and set *PNAME to the name.
|
||||
off_t
|
||||
interpret_header(const Archive_header* hdr, off_t off, std::string* pname,
|
||||
off_t* nested_off);
|
||||
off_t* nested_off) const;
|
||||
|
||||
// Include all the archive members in the link.
|
||||
void
|
||||
@ -155,6 +171,17 @@ class Archive
|
||||
include_member(Symbol_table*, Layout*, Input_objects*, off_t off,
|
||||
Mapfile*, Symbol*, const char* why);
|
||||
|
||||
// Iterate over archive members.
|
||||
class const_iterator;
|
||||
|
||||
const_iterator
|
||||
begin() const;
|
||||
|
||||
const_iterator
|
||||
end() const;
|
||||
|
||||
friend class const_iterator;
|
||||
|
||||
// An entry in the archive map of symbols to object files.
|
||||
struct Armap_entry
|
||||
{
|
||||
|
253
gold/cref.cc
Normal file
253
gold/cref.cc
Normal file
@ -0,0 +1,253 @@
|
||||
// cref.cc -- cross reference for gold
|
||||
|
||||
// Copyright 2008 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
||||
// MA 02110-1301, USA.
|
||||
|
||||
#include "gold.h"
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "object.h"
|
||||
#include "archive.h"
|
||||
#include "cref.h"
|
||||
|
||||
namespace gold
|
||||
{
|
||||
|
||||
// Class Cref_inputs. This is used to hold the list of input files
|
||||
// for cross referencing.
|
||||
|
||||
class Cref_inputs
|
||||
{
|
||||
public:
|
||||
Cref_inputs()
|
||||
: objects_(), archives_(), current_(&this->objects_)
|
||||
{ }
|
||||
|
||||
// Add an input object file.
|
||||
void
|
||||
add_object(Object* object);
|
||||
|
||||
// Start adding an archive. We support nested archives for future
|
||||
// flexibility.
|
||||
void
|
||||
add_archive_start(Archive*);
|
||||
|
||||
// Finish adding an archive.
|
||||
void
|
||||
add_archive_stop(Archive*);
|
||||
|
||||
// Report symbol counts.
|
||||
void
|
||||
print_symbol_counts(const Symbol_table*, FILE*) const;
|
||||
|
||||
private:
|
||||
// A list of input objects.
|
||||
typedef std::vector<Object*> Objects;
|
||||
|
||||
// Information we record for an archive.
|
||||
struct Archive_info
|
||||
{
|
||||
// Archive name.
|
||||
std::string name;
|
||||
// List of objects included from the archive.
|
||||
Objects* objects;
|
||||
// Number of archive members.
|
||||
size_t member_count;
|
||||
};
|
||||
|
||||
// A mapping from the name of an archive to the list of objects in
|
||||
// that archive.
|
||||
typedef std::map<std::string, Archive_info> Archives;
|
||||
|
||||
// Report symbol counts for a list of Objects.
|
||||
void
|
||||
print_objects_symbol_counts(const Symbol_table*, FILE*, const Objects*) const;
|
||||
|
||||
// Report symbol counts for an object.
|
||||
void
|
||||
print_object_symbol_counts(const Symbol_table*, FILE*, const Object*) const;
|
||||
|
||||
// List of input objects.
|
||||
Objects objects_;
|
||||
// List of input archives. This is a mapping from the archive file
|
||||
// name to the list of objects.
|
||||
Archives archives_;
|
||||
// The list to which we are currently adding objects.
|
||||
Objects* current_;
|
||||
};
|
||||
|
||||
// Add an object.
|
||||
|
||||
void
|
||||
Cref_inputs::add_object(Object* object)
|
||||
{
|
||||
this->current_->push_back(object);
|
||||
}
|
||||
|
||||
// Start adding an archive.
|
||||
|
||||
void
|
||||
Cref_inputs::add_archive_start(Archive* archive)
|
||||
{
|
||||
gold_assert(this->current_ == &this->objects_);
|
||||
if (this->archives_.find(archive->name()) == this->archives_.end())
|
||||
{
|
||||
Archive_info* pai = &this->archives_[archive->name()];
|
||||
pai->name = archive->filename();
|
||||
pai->objects = new Objects();
|
||||
pai->member_count = archive->count_members();
|
||||
}
|
||||
this->current_ = this->archives_[archive->name()].objects;
|
||||
}
|
||||
|
||||
// Stop adding an archive.
|
||||
|
||||
void
|
||||
Cref_inputs::add_archive_stop(Archive*)
|
||||
{
|
||||
gold_assert(this->current_ != &this->objects_);
|
||||
this->current_ = &this->objects_;
|
||||
}
|
||||
|
||||
// Report symbol counts for an object.
|
||||
|
||||
void
|
||||
Cref_inputs::print_object_symbol_counts(const Symbol_table* symtab,
|
||||
FILE* f,
|
||||
const Object* object) const
|
||||
{
|
||||
size_t defined, used;
|
||||
object->get_global_symbol_counts(symtab, &defined, &used);
|
||||
fprintf(f, "symbols %s %zu %zu\n", object->name().c_str(), defined, used);
|
||||
}
|
||||
|
||||
// Report symbol counts for a list of Inputs.
|
||||
|
||||
void
|
||||
Cref_inputs::print_objects_symbol_counts(const Symbol_table* symtab,
|
||||
FILE* f,
|
||||
const Objects* objects) const
|
||||
{
|
||||
for (Objects::const_iterator p = objects->begin();
|
||||
p != objects->end();
|
||||
++p)
|
||||
this->print_object_symbol_counts(symtab, f, *p);
|
||||
}
|
||||
|
||||
// Print symbol counts. This implements --print-symbol-counts. This
|
||||
// is intended to be easily read by a program. This outputs a series
|
||||
// of lines. There are two different types of lines.
|
||||
|
||||
// The first is "symbols FILENAME DEFINED USED". FILENAME is the name
|
||||
// of an object file included in the link; for an archive, this will
|
||||
// be ARCHIVEFILENAME(MEMBERNAME). DEFINED is the number of symbols
|
||||
// which the object file defines. USED is the number of symbols which
|
||||
// are used in the final output; this is the number of symbols which
|
||||
// appear in the final output table as having been defined by this
|
||||
// object. These numbers will be different when weak symbols are
|
||||
// used, and they will be different for dynamic objects.
|
||||
|
||||
// The second is "archives FILENAME MEMBERS USED". FILENAME is the
|
||||
// name of an archive file included in the link. MEMBERS is the
|
||||
// number of members of the archive. USED is the number of archive
|
||||
// members included in the link.
|
||||
|
||||
void
|
||||
Cref_inputs::print_symbol_counts(const Symbol_table* symtab, FILE* f) const
|
||||
{
|
||||
this->print_objects_symbol_counts(symtab, f, &this->objects_);
|
||||
for (Archives::const_iterator p = this->archives_.begin();
|
||||
p != this->archives_.end();
|
||||
++p)
|
||||
{
|
||||
fprintf(f, "archive %s %zu %zu\n", p->second.name.c_str(),
|
||||
p->second.member_count, p->second.objects->size());
|
||||
this->print_objects_symbol_counts(symtab, f, p->second.objects);
|
||||
}
|
||||
}
|
||||
|
||||
// Class Cref.
|
||||
|
||||
// Make sure the Cref_inputs object has been created.
|
||||
|
||||
void
|
||||
Cref::need_inputs()
|
||||
{
|
||||
if (this->inputs_ == NULL)
|
||||
this->inputs_ = new Cref_inputs();
|
||||
}
|
||||
|
||||
// Add an input object file.
|
||||
|
||||
void
|
||||
Cref::add_object(Object* object)
|
||||
{
|
||||
this->need_inputs();
|
||||
this->inputs_->add_object(object);
|
||||
}
|
||||
|
||||
// Start adding an archive.
|
||||
|
||||
void
|
||||
Cref::add_archive_start(Archive* archive)
|
||||
{
|
||||
this->need_inputs();
|
||||
this->inputs_->add_archive_start(archive);
|
||||
}
|
||||
|
||||
// Stop adding an archive.
|
||||
|
||||
void
|
||||
Cref::add_archive_stop(Archive* archive)
|
||||
{
|
||||
this->inputs_->add_archive_stop(archive);
|
||||
}
|
||||
|
||||
// Print symbol counts.
|
||||
|
||||
void
|
||||
Cref::print_symbol_counts(const Symbol_table* symtab) const
|
||||
{
|
||||
if (parameters->options().user_set_print_symbol_counts()
|
||||
&& this->inputs_ != NULL)
|
||||
{
|
||||
FILE* f;
|
||||
if (strcmp(parameters->options().print_symbol_counts(), "-") == 0)
|
||||
f = stdout;
|
||||
else
|
||||
{
|
||||
f = fopen(parameters->options().print_symbol_counts(), "w");
|
||||
if (f == NULL)
|
||||
gold_error(_("cannot open symbol count file %s: %s"),
|
||||
parameters->options().print_symbol_counts(),
|
||||
strerror(errno));
|
||||
}
|
||||
if (f != NULL)
|
||||
this->inputs_->print_symbol_counts(symtab, f);
|
||||
}
|
||||
}
|
||||
|
||||
} // End namespace gold.
|
73
gold/cref.h
Normal file
73
gold/cref.h
Normal file
@ -0,0 +1,73 @@
|
||||
// cref.h -- cross reference reports for gold -*- C++ -*-
|
||||
|
||||
// Copyright 2008 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
||||
// MA 02110-1301, USA.
|
||||
|
||||
#ifndef GOLD_CREF_H
|
||||
#define GOLD_CREF_H
|
||||
|
||||
namespace gold
|
||||
{
|
||||
|
||||
class Object;
|
||||
class Archive;
|
||||
class Cref_inputs;
|
||||
|
||||
// This class collects data for cross reference and other reporting.
|
||||
|
||||
class Cref
|
||||
{
|
||||
public:
|
||||
Cref()
|
||||
: inputs_(NULL)
|
||||
{ }
|
||||
|
||||
// Record an input object file. This is called for each object file
|
||||
// in the order in which it is processed.
|
||||
void
|
||||
add_object(Object*);
|
||||
|
||||
// Start recording an input archive. This is called for each
|
||||
// archive in the order in which it appears on the command line. A
|
||||
// call to add_archive_start precedes calls to add_object for each
|
||||
// object included from the archive.
|
||||
void
|
||||
add_archive_start(Archive*);
|
||||
|
||||
// Finish recording an input archive. This is called after
|
||||
// add_object has been called for each object included from the
|
||||
// archive.
|
||||
void
|
||||
add_archive_stop(Archive*);
|
||||
|
||||
// Print symbol counts.
|
||||
void
|
||||
print_symbol_counts(const Symbol_table*) const;
|
||||
|
||||
private:
|
||||
void
|
||||
need_inputs();
|
||||
|
||||
Cref_inputs* inputs_;
|
||||
};
|
||||
|
||||
} // End namespace gold.
|
||||
|
||||
#endif // !defined(GOLD_CREF_H)
|
@ -73,7 +73,9 @@ Sized_dynobj<size, big_endian>::Sized_dynobj(
|
||||
const elfcpp::Ehdr<size, big_endian>& ehdr)
|
||||
: Dynobj(name, input_file, offset),
|
||||
elf_file_(this, ehdr),
|
||||
dynsym_shndx_(-1U)
|
||||
dynsym_shndx_(-1U),
|
||||
symbols_(NULL),
|
||||
defined_count_(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -675,6 +677,14 @@ 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())
|
||||
{
|
||||
this->symbols_ = new Symbols();
|
||||
this->symbols_->resize(symcount);
|
||||
}
|
||||
|
||||
const char* sym_names =
|
||||
reinterpret_cast<const char*>(sd->symbol_names->data());
|
||||
symtab->add_from_dynobj(this, sd->symbols->data(), symcount,
|
||||
@ -683,7 +693,9 @@ Sized_dynobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
|
||||
? NULL
|
||||
: sd->versym->data()),
|
||||
sd->versym_size,
|
||||
&version_map);
|
||||
&version_map,
|
||||
this->symbols_,
|
||||
&this->defined_count_);
|
||||
|
||||
delete sd->symbols;
|
||||
sd->symbols = NULL;
|
||||
@ -710,6 +722,29 @@ Sized_dynobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
|
||||
this->clear_view_cache_marks();
|
||||
}
|
||||
|
||||
// Get symbol counts.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
void
|
||||
Sized_dynobj<size, big_endian>::do_get_global_symbol_counts(
|
||||
const Symbol_table*,
|
||||
size_t* defined,
|
||||
size_t* used) const
|
||||
{
|
||||
*defined = this->defined_count_;
|
||||
size_t count = 0;
|
||||
for (typename Symbols::const_iterator p = this->symbols_->begin();
|
||||
p != this->symbols_->end();
|
||||
++p)
|
||||
if (*p != NULL
|
||||
&& (*p)->source() == Symbol::FROM_OBJECT
|
||||
&& (*p)->object() == this
|
||||
&& (*p)->is_defined()
|
||||
&& (*p)->dynsym_index() != -1U)
|
||||
++count;
|
||||
*used = count;
|
||||
}
|
||||
|
||||
// Given a vector of hash codes, compute the number of hash buckets to
|
||||
// use.
|
||||
|
||||
|
@ -156,6 +156,8 @@ template<int size, bool big_endian>
|
||||
class Sized_dynobj : public Dynobj
|
||||
{
|
||||
public:
|
||||
typedef typename Sized_relobj<size, big_endian>::Symbols Symbols;
|
||||
|
||||
Sized_dynobj(const std::string& name, Input_file* input_file, off_t offset,
|
||||
const typename elfcpp::Ehdr<size, big_endian>&);
|
||||
|
||||
@ -225,6 +227,10 @@ class Sized_dynobj : public Dynobj
|
||||
Xindex*
|
||||
do_initialize_xindex();
|
||||
|
||||
// Get symbol counts.
|
||||
void
|
||||
do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const;
|
||||
|
||||
private:
|
||||
// For convenience.
|
||||
typedef Sized_dynobj<size, big_endian> This;
|
||||
@ -288,6 +294,11 @@ class Sized_dynobj : public Dynobj
|
||||
elfcpp::Elf_file<size, big_endian, Object> elf_file_;
|
||||
// The section index of the dynamic symbol table.
|
||||
unsigned int dynsym_shndx_;
|
||||
// The entries in the symbol table for the symbols. We only keep
|
||||
// this if we need it to print symbol information.
|
||||
Symbols* symbols_;
|
||||
// Number of defined symbols.
|
||||
size_t defined_count_;
|
||||
};
|
||||
|
||||
// A base class for Verdef and Verneed_version which just handles the
|
||||
|
@ -237,6 +237,10 @@ main(int argc, char** argv)
|
||||
if (mapfile != NULL)
|
||||
mapfile->close();
|
||||
|
||||
// Issue defined symbol report.
|
||||
if (command_line.options().user_set_print_symbol_counts())
|
||||
input_objects.print_symbol_counts(&symtab);
|
||||
|
||||
if (parameters->options().fatal_warnings()
|
||||
&& errors.warning_count() > 0
|
||||
&& errors.error_count() == 0)
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "layout.h"
|
||||
#include "output.h"
|
||||
#include "symtab.h"
|
||||
#include "cref.h"
|
||||
#include "reloc.h"
|
||||
#include "object.h"
|
||||
#include "dynobj.h"
|
||||
@ -245,6 +246,7 @@ Sized_relobj<size, big_endian>::Sized_relobj(
|
||||
output_local_symbol_count_(0),
|
||||
output_local_dynsym_count_(0),
|
||||
symbols_(),
|
||||
defined_count_(0),
|
||||
local_symbol_offset_(0),
|
||||
local_dynsym_offset_(0),
|
||||
local_values_(),
|
||||
@ -1087,7 +1089,8 @@ Sized_relobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
|
||||
sd->symbols->data() + sd->external_symbols_offset,
|
||||
symcount, this->local_symbol_count_,
|
||||
sym_names, sd->symbol_names_size,
|
||||
&this->symbols_);
|
||||
&this->symbols_,
|
||||
&this->defined_count_);
|
||||
|
||||
delete sd->symbols;
|
||||
sd->symbols = NULL;
|
||||
@ -1577,6 +1580,28 @@ Sized_relobj<size, big_endian>::map_to_kept_section(
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get symbol counts.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
void
|
||||
Sized_relobj<size, big_endian>::do_get_global_symbol_counts(
|
||||
const Symbol_table*,
|
||||
size_t* defined,
|
||||
size_t* used) const
|
||||
{
|
||||
*defined = this->defined_count_;
|
||||
size_t count = 0;
|
||||
for (Symbols::const_iterator p = this->symbols_.begin();
|
||||
p != this->symbols_.end();
|
||||
++p)
|
||||
if (*p != NULL
|
||||
&& (*p)->source() == Symbol::FROM_OBJECT
|
||||
&& (*p)->object() == this
|
||||
&& (*p)->is_defined())
|
||||
++count;
|
||||
*used = count;
|
||||
}
|
||||
|
||||
// Input_objects methods.
|
||||
|
||||
// Add a regular relocatable object to the list. Return false if this
|
||||
@ -1631,6 +1656,14 @@ Input_objects::add_object(Object* obj)
|
||||
}
|
||||
}
|
||||
|
||||
// Add this object to the cross-referencer if requested.
|
||||
if (parameters->options().user_set_print_symbol_counts())
|
||||
{
|
||||
if (this->cref_ == NULL)
|
||||
this->cref_ = new Cref();
|
||||
this->cref_->add_object(obj);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1671,6 +1704,38 @@ Input_objects::check_dynamic_dependencies() const
|
||||
}
|
||||
}
|
||||
|
||||
// Start processing an archive.
|
||||
|
||||
void
|
||||
Input_objects::archive_start(Archive* archive)
|
||||
{
|
||||
if (parameters->options().user_set_print_symbol_counts())
|
||||
{
|
||||
if (this->cref_ == NULL)
|
||||
this->cref_ = new Cref();
|
||||
this->cref_->add_archive_start(archive);
|
||||
}
|
||||
}
|
||||
|
||||
// Stop processing an archive.
|
||||
|
||||
void
|
||||
Input_objects::archive_stop(Archive* archive)
|
||||
{
|
||||
if (parameters->options().user_set_print_symbol_counts())
|
||||
this->cref_->add_archive_stop(archive);
|
||||
}
|
||||
|
||||
// Print symbol counts
|
||||
|
||||
void
|
||||
Input_objects::print_symbol_counts(const Symbol_table* symtab) const
|
||||
{
|
||||
if (parameters->options().user_set_print_symbol_counts()
|
||||
&& this->cref_ != NULL)
|
||||
this->cref_->print_symbol_counts(symtab);
|
||||
}
|
||||
|
||||
// Relocate_info methods.
|
||||
|
||||
// Return a string describing the location of a relocation. This is
|
||||
|
@ -36,6 +36,8 @@ namespace gold
|
||||
|
||||
class General_options;
|
||||
class Task;
|
||||
class Cref;
|
||||
class Archive;
|
||||
class Layout;
|
||||
class Output_section;
|
||||
class Output_file;
|
||||
@ -421,6 +423,14 @@ class Object
|
||||
clear_view_cache_marks()
|
||||
{ this->input_file()->file().clear_view_cache_marks(); }
|
||||
|
||||
// Get the number of global symbols defined by this object, and the
|
||||
// number of the symbols whose final definition came from this
|
||||
// object.
|
||||
void
|
||||
get_global_symbol_counts(const Symbol_table* symtab, size_t* defined,
|
||||
size_t* used) const
|
||||
{ this->do_get_global_symbol_counts(symtab, defined, used); }
|
||||
|
||||
protected:
|
||||
// Read the symbols--implemented by child class.
|
||||
virtual void
|
||||
@ -476,6 +486,10 @@ class Object
|
||||
virtual Xindex*
|
||||
do_initialize_xindex() = 0;
|
||||
|
||||
// Implement get_global_symbol_counts--implemented by child class.
|
||||
virtual void
|
||||
do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const = 0;
|
||||
|
||||
// Get the file. We pass on const-ness.
|
||||
Input_file*
|
||||
input_file()
|
||||
@ -1395,6 +1409,10 @@ class Sized_relobj : public Relobj
|
||||
Xindex*
|
||||
do_initialize_xindex();
|
||||
|
||||
// Get symbol counts.
|
||||
void
|
||||
do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const;
|
||||
|
||||
// Get the offset of a section.
|
||||
uint64_t
|
||||
do_output_section_offset(unsigned int shndx) const
|
||||
@ -1628,6 +1646,8 @@ class Sized_relobj : public Relobj
|
||||
unsigned int output_local_dynsym_count_;
|
||||
// The entries in the symbol table for the external symbols.
|
||||
Symbols symbols_;
|
||||
// Number of symbols defined in object file itself.
|
||||
size_t defined_count_;
|
||||
// File offset for local symbols.
|
||||
off_t local_symbol_offset_;
|
||||
// File offset for local dynamic symbols.
|
||||
@ -1655,7 +1675,8 @@ class Input_objects
|
||||
{
|
||||
public:
|
||||
Input_objects()
|
||||
: relobj_list_(), dynobj_list_(), sonames_(), system_library_directory_()
|
||||
: relobj_list_(), dynobj_list_(), sonames_(), system_library_directory_(),
|
||||
cref_(NULL)
|
||||
{ }
|
||||
|
||||
// The type of the list of input relocateable objects.
|
||||
@ -1671,6 +1692,14 @@ class Input_objects
|
||||
bool
|
||||
add_object(Object*);
|
||||
|
||||
// Start processing an archive.
|
||||
void
|
||||
archive_start(Archive*);
|
||||
|
||||
// Stop processing an archive.
|
||||
void
|
||||
archive_stop(Archive*);
|
||||
|
||||
// For each dynamic object, check whether we've seen all of its
|
||||
// explicit dependencies.
|
||||
void
|
||||
@ -1681,6 +1710,10 @@ class Input_objects
|
||||
bool
|
||||
found_in_system_library_directory(const Object*) const;
|
||||
|
||||
// Print symbol counts.
|
||||
void
|
||||
print_symbol_counts(const Symbol_table*) const;
|
||||
|
||||
// Iterate over all regular objects.
|
||||
|
||||
Relobj_iterator
|
||||
@ -1723,6 +1756,8 @@ class Input_objects
|
||||
Unordered_set<std::string> sonames_;
|
||||
// The directory in which we find the libc.so.
|
||||
std::string system_library_directory_;
|
||||
// Manage cross-references if requested.
|
||||
Cref* cref_;
|
||||
};
|
||||
|
||||
// Some of the information we pass to the relocation routines. We
|
||||
|
@ -679,6 +679,10 @@ class General_options
|
||||
DEFINE_string(oformat, options::EXACTLY_TWO_DASHES, '\0', "elf",
|
||||
N_("Set output format"), N_("[binary]"));
|
||||
|
||||
DEFINE_string(print_symbol_counts, options::TWO_DASHES, '\0', NULL,
|
||||
N_("Print symbols defined and used for each input"),
|
||||
N_("FILENAME"));
|
||||
|
||||
DEFINE_bool(Qy, options::EXACTLY_ONE_DASH, '\0', false,
|
||||
N_("Ignored for SVR4 compatibility"), NULL);
|
||||
|
||||
|
@ -835,8 +835,11 @@ Symbol_table::add_from_relobj(
|
||||
size_t symndx_offset,
|
||||
const char* sym_names,
|
||||
size_t sym_name_size,
|
||||
typename Sized_relobj<size, big_endian>::Symbols* sympointers)
|
||||
typename Sized_relobj<size, big_endian>::Symbols* sympointers,
|
||||
size_t *defined)
|
||||
{
|
||||
*defined = 0;
|
||||
|
||||
gold_assert(size == relobj->target()->get_size());
|
||||
gold_assert(size == parameters->target().get_size());
|
||||
|
||||
@ -847,6 +850,8 @@ Symbol_table::add_from_relobj(
|
||||
const unsigned char* p = syms;
|
||||
for (size_t i = 0; i < count; ++i, p += sym_size)
|
||||
{
|
||||
(*sympointers)[i] = NULL;
|
||||
|
||||
elfcpp::Sym<size, big_endian> sym(p);
|
||||
|
||||
unsigned int st_name = sym.get_st_name();
|
||||
@ -867,6 +872,9 @@ Symbol_table::add_from_relobj(
|
||||
if (!is_ordinary)
|
||||
orig_st_shndx = elfcpp::SHN_UNDEF;
|
||||
|
||||
if (st_shndx != elfcpp::SHN_UNDEF)
|
||||
++*defined;
|
||||
|
||||
// A symbol defined in a section which we are not including must
|
||||
// be treated as an undefined symbol.
|
||||
if (st_shndx != elfcpp::SHN_UNDEF
|
||||
@ -977,8 +985,12 @@ Symbol_table::add_from_dynobj(
|
||||
size_t sym_name_size,
|
||||
const unsigned char* versym,
|
||||
size_t versym_size,
|
||||
const std::vector<const char*>* version_map)
|
||||
const std::vector<const char*>* version_map,
|
||||
typename Sized_relobj<size, big_endian>::Symbols* sympointers,
|
||||
size_t* defined)
|
||||
{
|
||||
*defined = 0;
|
||||
|
||||
gold_assert(size == dynobj->target()->get_size());
|
||||
gold_assert(size == parameters->target().get_size());
|
||||
|
||||
@ -1012,6 +1024,9 @@ Symbol_table::add_from_dynobj(
|
||||
{
|
||||
elfcpp::Sym<size, big_endian> sym(p);
|
||||
|
||||
if (sympointers != NULL)
|
||||
(*sympointers)[i] = NULL;
|
||||
|
||||
// Ignore symbols with local binding or that have
|
||||
// internal or hidden visibility.
|
||||
if (sym.get_st_bind() == elfcpp::STB_LOCAL
|
||||
@ -1047,6 +1062,9 @@ Symbol_table::add_from_dynobj(
|
||||
unsigned int st_shndx = dynobj->adjust_sym_shndx(i, psym->get_st_shndx(),
|
||||
&is_ordinary);
|
||||
|
||||
if (st_shndx != elfcpp::SHN_UNDEF)
|
||||
++*defined;
|
||||
|
||||
Sized_symbol<size>* res;
|
||||
|
||||
if (versym == NULL)
|
||||
@ -1142,6 +1160,9 @@ Symbol_table::add_from_dynobj(
|
||||
&& res->source() == Symbol::FROM_OBJECT
|
||||
&& res->object() == dynobj)
|
||||
object_symbols.push_back(res);
|
||||
|
||||
if (sympointers != NULL)
|
||||
(*sympointers)[i] = res;
|
||||
}
|
||||
|
||||
this->record_weak_aliases(&object_symbols);
|
||||
@ -2628,7 +2649,8 @@ Symbol_table::add_from_relobj<32, false>(
|
||||
size_t symndx_offset,
|
||||
const char* sym_names,
|
||||
size_t sym_name_size,
|
||||
Sized_relobj<32, true>::Symbols* sympointers);
|
||||
Sized_relobj<32, true>::Symbols* sympointers,
|
||||
size_t* defined);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_32_BIG
|
||||
@ -2641,7 +2663,8 @@ Symbol_table::add_from_relobj<32, true>(
|
||||
size_t symndx_offset,
|
||||
const char* sym_names,
|
||||
size_t sym_name_size,
|
||||
Sized_relobj<32, false>::Symbols* sympointers);
|
||||
Sized_relobj<32, false>::Symbols* sympointers,
|
||||
size_t* defined);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_64_LITTLE
|
||||
@ -2654,7 +2677,8 @@ Symbol_table::add_from_relobj<64, false>(
|
||||
size_t symndx_offset,
|
||||
const char* sym_names,
|
||||
size_t sym_name_size,
|
||||
Sized_relobj<64, true>::Symbols* sympointers);
|
||||
Sized_relobj<64, true>::Symbols* sympointers,
|
||||
size_t* defined);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_64_BIG
|
||||
@ -2667,7 +2691,8 @@ Symbol_table::add_from_relobj<64, true>(
|
||||
size_t symndx_offset,
|
||||
const char* sym_names,
|
||||
size_t sym_name_size,
|
||||
Sized_relobj<64, false>::Symbols* sympointers);
|
||||
Sized_relobj<64, false>::Symbols* sympointers,
|
||||
size_t* defined);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_32_LITTLE
|
||||
@ -2681,7 +2706,9 @@ Symbol_table::add_from_dynobj<32, false>(
|
||||
size_t sym_name_size,
|
||||
const unsigned char* versym,
|
||||
size_t versym_size,
|
||||
const std::vector<const char*>* version_map);
|
||||
const std::vector<const char*>* version_map,
|
||||
Sized_relobj<32, false>::Symbols* sympointers,
|
||||
size_t* defined);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_32_BIG
|
||||
@ -2695,7 +2722,9 @@ Symbol_table::add_from_dynobj<32, true>(
|
||||
size_t sym_name_size,
|
||||
const unsigned char* versym,
|
||||
size_t versym_size,
|
||||
const std::vector<const char*>* version_map);
|
||||
const std::vector<const char*>* version_map,
|
||||
Sized_relobj<32, true>::Symbols* sympointers,
|
||||
size_t* defined);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_64_LITTLE
|
||||
@ -2709,7 +2738,9 @@ Symbol_table::add_from_dynobj<64, false>(
|
||||
size_t sym_name_size,
|
||||
const unsigned char* versym,
|
||||
size_t versym_size,
|
||||
const std::vector<const char*>* version_map);
|
||||
const std::vector<const char*>* version_map,
|
||||
Sized_relobj<64, false>::Symbols* sympointers,
|
||||
size_t* defined);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_64_BIG
|
||||
@ -2723,7 +2754,9 @@ Symbol_table::add_from_dynobj<64, true>(
|
||||
size_t sym_name_size,
|
||||
const unsigned char* versym,
|
||||
size_t versym_size,
|
||||
const std::vector<const char*>* version_map);
|
||||
const std::vector<const char*>* version_map,
|
||||
Sized_relobj<64, true>::Symbols* sympointers,
|
||||
size_t* defined);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
|
||||
|
@ -1086,14 +1086,16 @@ class Symbol_table
|
||||
// the symbol table. SYMS is the symbols, SYMNDX_OFFSET is the
|
||||
// offset in the symbol table of the first symbol, SYM_NAMES is
|
||||
// their names, SYM_NAME_SIZE is the size of SYM_NAMES. This sets
|
||||
// SYMPOINTERS to point to the symbols in the symbol table.
|
||||
// SYMPOINTERS to point to the symbols in the symbol table. It sets
|
||||
// *DEFINED to the number of defined symbols.
|
||||
template<int size, bool big_endian>
|
||||
void
|
||||
add_from_relobj(Sized_relobj<size, big_endian>* relobj,
|
||||
const unsigned char* syms, size_t count,
|
||||
size_t symndx_offset, const char* sym_names,
|
||||
size_t sym_name_size,
|
||||
typename Sized_relobj<size, big_endian>::Symbols*);
|
||||
typename Sized_relobj<size, big_endian>::Symbols*,
|
||||
size_t* defined);
|
||||
|
||||
// Add COUNT dynamic symbols from the dynamic object DYNOBJ to the
|
||||
// symbol table. SYMS is the symbols. SYM_NAMES is their names.
|
||||
@ -1105,7 +1107,9 @@ class Symbol_table
|
||||
const unsigned char* syms, size_t count,
|
||||
const char* sym_names, size_t sym_name_size,
|
||||
const unsigned char* versym, size_t versym_size,
|
||||
const std::vector<const char*>*);
|
||||
const std::vector<const char*>*,
|
||||
typename Sized_relobj<size, big_endian>::Symbols*,
|
||||
size_t* defined);
|
||||
|
||||
// Define a special symbol based on an Output_data. It is a
|
||||
// multiple definition error if this symbol is already defined.
|
||||
|
Loading…
Reference in New Issue
Block a user