* archive.cc (Library_base::should_include_member): Move
method here from class Archive. (Archive::Archive): Initialize base class. (Archive::should_include_member): Move to base class. (Archive::do_for_all_unused_symbols): New function. (Add_archive_symbols::run): Remove redundant access to incremental_inputs. (Lib_group::Lib_group): Initialize base class. (Lib_group::do_filename): New function. (Lib_group::include_member): Pass pointer to Lib_group to report_object. (Lib_group::do_for_all_unused_symbols): New function. (Add_lib_group_symbols::run): Report archive information for incremental links. * archive.h (class Library_base): New base class. (class Archive): Derive from Library_base. (Archive::filename): Move to base class. (Archive::set_incremental_info): Likewise. (Archive::incremental_info): Likewise. (Archive::Should_include): Likewise. (Archive::should_include_member): Likewise. (Archive::Armap_entry): Remove. (Archive::Unused_symbol_iterator): Remove. (Archive::unused_symbols_begin): Remove. (Archive::unused_symbols_end): Remove. (Archive::do_filename): New function. (Archive::do_get_mtime): New function. (Archive::do_for_all_unused_symbols): New function. (Archive::task_): Move to base class. (Archive::incremental_info_): Likewise. (class Lib_group): Derive from Library_base. (Lib_group::do_filename): New function. (Lib_group::do_get_mtime): New function. (Lib_group::do_for_all_unused_symbols): New function. (Lib_group::task_): Move to base class. * dynobj.cc (Sized_dynobj::do_for_all_global_symbols): New function. * dynobj.h (Sized_dynobj::do_for_all_global_symbols): New function. * incremental.cc (Incremental_inputs::report_archive_begin): Use Library_base; call library's get_mtime; add incremental inputs entry before members. (class Unused_symbol_visitor): New class. (Incremental_inputs::report_archive_end): Use Library_base; use visitor class to record unused symbols; don't add incremental inputs entry after members. (Incremental_inputs::report_object): Use Library_base. * incremental.h (Incremental_archive_entry::Incremental_archive_entry): Remove unused Archive parameter. (Incremental_inputs::report_archive_begin): Use Library_base. (Incremental_inputs::report_archive_end): Likewise. (Incremental_inputs::report_object): Likewise. * object.cc (Sized_relobj::do_for_all_global_symbols): New function. * object.h (Object::for_all_global_symbols): New function. (Object::do_for_all_global_symbols): New function. (Sized_relobj::do_for_all_global_symbols): New function. * plugin.cc (Sized_pluginobj::do_for_all_global_symbols): New function. * plugin.h (Sized_pluginobj::do_for_all_global_symbols): New function.
This commit is contained in:
parent
53a9226b8f
commit
e0c5278066
|
@ -1,3 +1,68 @@
|
||||||
|
2011-03-29 Cary Coutant <ccoutant@google.com>
|
||||||
|
|
||||||
|
* archive.cc (Library_base::should_include_member): Move
|
||||||
|
method here from class Archive.
|
||||||
|
(Archive::Archive): Initialize base class.
|
||||||
|
(Archive::should_include_member): Move to base class.
|
||||||
|
(Archive::do_for_all_unused_symbols): New function.
|
||||||
|
(Add_archive_symbols::run): Remove redundant access to
|
||||||
|
incremental_inputs.
|
||||||
|
(Lib_group::Lib_group): Initialize base class.
|
||||||
|
(Lib_group::do_filename): New function.
|
||||||
|
(Lib_group::include_member): Pass pointer to Lib_group to
|
||||||
|
report_object.
|
||||||
|
(Lib_group::do_for_all_unused_symbols): New function.
|
||||||
|
(Add_lib_group_symbols::run): Report archive information for
|
||||||
|
incremental links.
|
||||||
|
* archive.h (class Library_base): New base class.
|
||||||
|
(class Archive): Derive from Library_base.
|
||||||
|
(Archive::filename): Move to base class.
|
||||||
|
(Archive::set_incremental_info): Likewise.
|
||||||
|
(Archive::incremental_info): Likewise.
|
||||||
|
(Archive::Should_include): Likewise.
|
||||||
|
(Archive::should_include_member): Likewise.
|
||||||
|
(Archive::Armap_entry): Remove.
|
||||||
|
(Archive::Unused_symbol_iterator): Remove.
|
||||||
|
(Archive::unused_symbols_begin): Remove.
|
||||||
|
(Archive::unused_symbols_end): Remove.
|
||||||
|
(Archive::do_filename): New function.
|
||||||
|
(Archive::do_get_mtime): New function.
|
||||||
|
(Archive::do_for_all_unused_symbols): New function.
|
||||||
|
(Archive::task_): Move to base class.
|
||||||
|
(Archive::incremental_info_): Likewise.
|
||||||
|
(class Lib_group): Derive from Library_base.
|
||||||
|
(Lib_group::do_filename): New function.
|
||||||
|
(Lib_group::do_get_mtime): New function.
|
||||||
|
(Lib_group::do_for_all_unused_symbols): New function.
|
||||||
|
(Lib_group::task_): Move to base class.
|
||||||
|
* dynobj.cc (Sized_dynobj::do_for_all_global_symbols): New
|
||||||
|
function.
|
||||||
|
* dynobj.h (Sized_dynobj::do_for_all_global_symbols): New
|
||||||
|
function.
|
||||||
|
* incremental.cc (Incremental_inputs::report_archive_begin):
|
||||||
|
Use Library_base; call library's get_mtime; add incremental inputs
|
||||||
|
entry before members.
|
||||||
|
(class Unused_symbol_visitor): New class.
|
||||||
|
(Incremental_inputs::report_archive_end): Use Library_base; use
|
||||||
|
visitor class to record unused symbols; don't add incremental inputs
|
||||||
|
entry after members.
|
||||||
|
(Incremental_inputs::report_object): Use Library_base.
|
||||||
|
* incremental.h
|
||||||
|
(Incremental_archive_entry::Incremental_archive_entry): Remove
|
||||||
|
unused Archive parameter.
|
||||||
|
(Incremental_inputs::report_archive_begin): Use Library_base.
|
||||||
|
(Incremental_inputs::report_archive_end): Likewise.
|
||||||
|
(Incremental_inputs::report_object): Likewise.
|
||||||
|
* object.cc (Sized_relobj::do_for_all_global_symbols): New
|
||||||
|
function.
|
||||||
|
* object.h (Object::for_all_global_symbols): New function.
|
||||||
|
(Object::do_for_all_global_symbols): New function.
|
||||||
|
(Sized_relobj::do_for_all_global_symbols): New function.
|
||||||
|
* plugin.cc (Sized_pluginobj::do_for_all_global_symbols): New
|
||||||
|
function.
|
||||||
|
* plugin.h (Sized_pluginobj::do_for_all_global_symbols): New
|
||||||
|
function.
|
||||||
|
|
||||||
2011-03-27 Ian Lance Taylor <iant@google.com>
|
2011-03-27 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
* archive.cc (Archive::interpret_header): Return -1 if something
|
* archive.cc (Archive::interpret_header): Return -1 if something
|
||||||
|
|
221
gold/archive.cc
221
gold/archive.cc
|
@ -44,6 +44,90 @@
|
||||||
namespace gold
|
namespace gold
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Library_base methods.
|
||||||
|
|
||||||
|
// Determine whether a definition of SYM_NAME should cause an archive
|
||||||
|
// library member to be included in the link. Returns SHOULD_INCLUDE_YES
|
||||||
|
// if the symbol is referenced but not defined, SHOULD_INCLUDE_NO if the
|
||||||
|
// symbol is already defined, and SHOULD_INCLUDE_UNKNOWN if the symbol is
|
||||||
|
// neither referenced nor defined.
|
||||||
|
|
||||||
|
Library_base::Should_include
|
||||||
|
Library_base::should_include_member(Symbol_table* symtab, Layout* layout,
|
||||||
|
const char* sym_name, Symbol** symp,
|
||||||
|
std::string* why, char** tmpbufp,
|
||||||
|
size_t* tmpbuflen)
|
||||||
|
{
|
||||||
|
// In an object file, and therefore in an archive map, an
|
||||||
|
// '@' in the name separates the symbol name from the
|
||||||
|
// version name. If there are two '@' characters, this is
|
||||||
|
// the default version.
|
||||||
|
char* tmpbuf = *tmpbufp;
|
||||||
|
const char* ver = strchr(sym_name, '@');
|
||||||
|
bool def = false;
|
||||||
|
if (ver != NULL)
|
||||||
|
{
|
||||||
|
size_t symlen = ver - sym_name;
|
||||||
|
if (symlen + 1 > *tmpbuflen)
|
||||||
|
{
|
||||||
|
tmpbuf = static_cast<char*>(xrealloc(tmpbuf, symlen + 1));
|
||||||
|
*tmpbufp = tmpbuf;
|
||||||
|
*tmpbuflen = symlen + 1;
|
||||||
|
}
|
||||||
|
memcpy(tmpbuf, sym_name, symlen);
|
||||||
|
tmpbuf[symlen] = '\0';
|
||||||
|
sym_name = tmpbuf;
|
||||||
|
|
||||||
|
++ver;
|
||||||
|
if (*ver == '@')
|
||||||
|
{
|
||||||
|
++ver;
|
||||||
|
def = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Symbol* sym = symtab->lookup(sym_name, ver);
|
||||||
|
if (def
|
||||||
|
&& ver != NULL
|
||||||
|
&& (sym == NULL
|
||||||
|
|| !sym->is_undefined()
|
||||||
|
|| sym->binding() == elfcpp::STB_WEAK))
|
||||||
|
sym = symtab->lookup(sym_name, NULL);
|
||||||
|
|
||||||
|
*symp = sym;
|
||||||
|
|
||||||
|
if (sym == NULL)
|
||||||
|
{
|
||||||
|
// Check whether the symbol was named in a -u option.
|
||||||
|
if (parameters->options().is_undefined(sym_name))
|
||||||
|
{
|
||||||
|
*why = "-u ";
|
||||||
|
*why += sym_name;
|
||||||
|
}
|
||||||
|
else if (layout->script_options()->is_referenced(sym_name))
|
||||||
|
{
|
||||||
|
size_t alc = 100 + strlen(sym_name);
|
||||||
|
char* buf = new char[alc];
|
||||||
|
snprintf(buf, alc, _("script or expression reference to %s"),
|
||||||
|
sym_name);
|
||||||
|
*why = buf;
|
||||||
|
delete[] buf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return Library_base::SHOULD_INCLUDE_UNKNOWN;
|
||||||
|
}
|
||||||
|
else if (!sym->is_undefined())
|
||||||
|
return Library_base::SHOULD_INCLUDE_NO;
|
||||||
|
// PR 12001: Do not include an archive when the undefined
|
||||||
|
// symbol has actually been defined on the command line.
|
||||||
|
else if (layout->script_options()->is_pending_assignment(sym_name))
|
||||||
|
return Library_base::SHOULD_INCLUDE_NO;
|
||||||
|
else if (sym->binding() == elfcpp::STB_WEAK)
|
||||||
|
return Library_base::SHOULD_INCLUDE_UNKNOWN;
|
||||||
|
|
||||||
|
return Library_base::SHOULD_INCLUDE_YES;
|
||||||
|
}
|
||||||
|
|
||||||
// The header of an entry in the archive. This is all readable text,
|
// The header of an entry in the archive. This is all readable text,
|
||||||
// padded with spaces where necessary. If the contents of an archive
|
// padded with spaces where necessary. If the contents of an archive
|
||||||
// are all text file, the entire archive is readable.
|
// are all text file, the entire archive is readable.
|
||||||
|
@ -87,11 +171,10 @@ const char Archive::arfmag[2] = { '`', '\n' };
|
||||||
|
|
||||||
Archive::Archive(const std::string& name, Input_file* input_file,
|
Archive::Archive(const std::string& name, Input_file* input_file,
|
||||||
bool is_thin_archive, Dirsearch* dirpath, Task* task)
|
bool is_thin_archive, Dirsearch* dirpath, Task* task)
|
||||||
: name_(name), input_file_(input_file), armap_(), armap_names_(),
|
: Library_base(task), name_(name), input_file_(input_file), armap_(),
|
||||||
extended_names_(), armap_checked_(), seen_offsets_(), members_(),
|
armap_names_(), extended_names_(), armap_checked_(), seen_offsets_(),
|
||||||
is_thin_archive_(is_thin_archive), included_member_(false),
|
members_(), is_thin_archive_(is_thin_archive), included_member_(false),
|
||||||
nested_archives_(), dirpath_(dirpath), task_(task), num_members_(0),
|
nested_archives_(), dirpath_(dirpath), num_members_(0)
|
||||||
incremental_info_(NULL)
|
|
||||||
{
|
{
|
||||||
this->no_export_ =
|
this->no_export_ =
|
||||||
parameters->options().check_excluded_libs(input_file->found_name());
|
parameters->options().check_excluded_libs(input_file->found_name());
|
||||||
|
@ -619,82 +702,6 @@ Archive::read_symbols(off_t off)
|
||||||
this->members_[off] = member;
|
this->members_[off] = member;
|
||||||
}
|
}
|
||||||
|
|
||||||
Archive::Should_include
|
|
||||||
Archive::should_include_member(Symbol_table* symtab, Layout* layout,
|
|
||||||
const char* sym_name, Symbol** symp,
|
|
||||||
std::string* why, char** tmpbufp,
|
|
||||||
size_t* tmpbuflen)
|
|
||||||
{
|
|
||||||
// In an object file, and therefore in an archive map, an
|
|
||||||
// '@' in the name separates the symbol name from the
|
|
||||||
// version name. If there are two '@' characters, this is
|
|
||||||
// the default version.
|
|
||||||
char* tmpbuf = *tmpbufp;
|
|
||||||
const char* ver = strchr(sym_name, '@');
|
|
||||||
bool def = false;
|
|
||||||
if (ver != NULL)
|
|
||||||
{
|
|
||||||
size_t symlen = ver - sym_name;
|
|
||||||
if (symlen + 1 > *tmpbuflen)
|
|
||||||
{
|
|
||||||
tmpbuf = static_cast<char*>(xrealloc(tmpbuf, symlen + 1));
|
|
||||||
*tmpbufp = tmpbuf;
|
|
||||||
*tmpbuflen = symlen + 1;
|
|
||||||
}
|
|
||||||
memcpy(tmpbuf, sym_name, symlen);
|
|
||||||
tmpbuf[symlen] = '\0';
|
|
||||||
sym_name = tmpbuf;
|
|
||||||
|
|
||||||
++ver;
|
|
||||||
if (*ver == '@')
|
|
||||||
{
|
|
||||||
++ver;
|
|
||||||
def = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Symbol* sym = symtab->lookup(sym_name, ver);
|
|
||||||
if (def
|
|
||||||
&& ver != NULL
|
|
||||||
&& (sym == NULL
|
|
||||||
|| !sym->is_undefined()
|
|
||||||
|| sym->binding() == elfcpp::STB_WEAK))
|
|
||||||
sym = symtab->lookup(sym_name, NULL);
|
|
||||||
|
|
||||||
*symp = sym;
|
|
||||||
|
|
||||||
if (sym == NULL)
|
|
||||||
{
|
|
||||||
// Check whether the symbol was named in a -u option.
|
|
||||||
if (parameters->options().is_undefined(sym_name))
|
|
||||||
{
|
|
||||||
*why = "-u ";
|
|
||||||
*why += sym_name;
|
|
||||||
}
|
|
||||||
else if (layout->script_options()->is_referenced(sym_name))
|
|
||||||
{
|
|
||||||
size_t alc = 100 + strlen(sym_name);
|
|
||||||
char* buf = new char[alc];
|
|
||||||
snprintf(buf, alc, _("script or expression reference to %s"),
|
|
||||||
sym_name);
|
|
||||||
*why = buf;
|
|
||||||
delete[] buf;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return Archive::SHOULD_INCLUDE_UNKNOWN;
|
|
||||||
}
|
|
||||||
else if (!sym->is_undefined())
|
|
||||||
return Archive::SHOULD_INCLUDE_NO;
|
|
||||||
// PR 12001: Do not include an archive when the undefined
|
|
||||||
// symbol has actually been defined on the command line.
|
|
||||||
else if (layout->script_options()->is_pending_assignment(sym_name))
|
|
||||||
return Archive::SHOULD_INCLUDE_NO;
|
|
||||||
else if (sym->binding() == elfcpp::STB_WEAK)
|
|
||||||
return Archive::SHOULD_INCLUDE_UNKNOWN;
|
|
||||||
|
|
||||||
return Archive::SHOULD_INCLUDE_YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select members from the archive and add them to the link. We walk
|
// Select members from the archive and add them to the link. We walk
|
||||||
// through the elements in the archive map, and look each one up in
|
// through the elements in the archive map, and look each one up in
|
||||||
// the symbol table. If it exists as a strong undefined symbol, we
|
// the symbol table. If it exists as a strong undefined symbol, we
|
||||||
|
@ -971,6 +978,21 @@ Archive::include_member(Symbol_table* symtab, Layout* layout,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Iterate over all unused symbols, and call the visitor class V for each.
|
||||||
|
|
||||||
|
void
|
||||||
|
Archive::do_for_all_unused_symbols(Symbol_visitor_base* v) const
|
||||||
|
{
|
||||||
|
for (std::vector<Armap_entry>::const_iterator p = this->armap_.begin();
|
||||||
|
p != this->armap_.end();
|
||||||
|
++p)
|
||||||
|
{
|
||||||
|
if (this->seen_offsets_.find(p->file_offset)
|
||||||
|
== this->seen_offsets_.end())
|
||||||
|
v->visit(this->armap_names_.data() + p->name_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Print statistical information to stderr. This is used for --stats.
|
// Print statistical information to stderr. This is used for --stats.
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1047,7 +1069,6 @@ Add_archive_symbols::run(Workqueue* workqueue)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// For an incremental link, finish recording the layout information.
|
// For an incremental link, finish recording the layout information.
|
||||||
Incremental_inputs* incremental_inputs = this->layout_->incremental_inputs();
|
|
||||||
if (incremental_inputs != NULL)
|
if (incremental_inputs != NULL)
|
||||||
incremental_inputs->report_archive_end(this->archive_);
|
incremental_inputs->report_archive_end(this->archive_);
|
||||||
|
|
||||||
|
@ -1073,11 +1094,18 @@ unsigned int Lib_group::total_members;
|
||||||
unsigned int Lib_group::total_members_loaded;
|
unsigned int Lib_group::total_members_loaded;
|
||||||
|
|
||||||
Lib_group::Lib_group(const Input_file_lib* lib, Task* task)
|
Lib_group::Lib_group(const Input_file_lib* lib, Task* task)
|
||||||
: lib_(lib), task_(task), members_()
|
: Library_base(task), lib_(lib), members_()
|
||||||
{
|
{
|
||||||
this->members_.resize(lib->size());
|
this->members_.resize(lib->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string&
|
||||||
|
Lib_group::do_filename() const
|
||||||
|
{
|
||||||
|
std::string *filename = new std::string("<group>");
|
||||||
|
return *filename;
|
||||||
|
}
|
||||||
|
|
||||||
// Select members from the lib group and add them to the link. We walk
|
// Select members from the lib group and add them to the link. We walk
|
||||||
// through the members, and check if each one up should be included.
|
// through the members, and check if each one up should be included.
|
||||||
// If the object says it should be included, we do so. We have to do
|
// If the object says it should be included, we do so. We have to do
|
||||||
|
@ -1167,9 +1195,8 @@ Lib_group::include_member(Symbol_table* symtab, Layout* layout,
|
||||||
obj->lock(this->task_);
|
obj->lock(this->task_);
|
||||||
if (input_objects->add_object(obj))
|
if (input_objects->add_object(obj))
|
||||||
{
|
{
|
||||||
// FIXME: Record incremental link info for --start-lib/--end-lib.
|
|
||||||
if (layout->incremental_inputs() != NULL)
|
if (layout->incremental_inputs() != NULL)
|
||||||
layout->incremental_inputs()->report_object(obj, NULL);
|
layout->incremental_inputs()->report_object(obj, this);
|
||||||
obj->layout(symtab, layout, sd);
|
obj->layout(symtab, layout, sd);
|
||||||
obj->add_symbols(symtab, sd, layout);
|
obj->add_symbols(symtab, sd, layout);
|
||||||
}
|
}
|
||||||
|
@ -1178,6 +1205,22 @@ Lib_group::include_member(Symbol_table* symtab, Layout* layout,
|
||||||
obj->unlock(this->task_);
|
obj->unlock(this->task_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Iterate over all unused symbols, and call the visitor class V for each.
|
||||||
|
|
||||||
|
void
|
||||||
|
Lib_group::do_for_all_unused_symbols(Symbol_visitor_base* v) const
|
||||||
|
{
|
||||||
|
// Files are removed from the members list when used, so all the
|
||||||
|
// files remaining on the list are unused.
|
||||||
|
for (std::vector<Archive_member>::const_iterator p = this->members_.begin();
|
||||||
|
p != this->members_.end();
|
||||||
|
++p)
|
||||||
|
{
|
||||||
|
Object* obj = p->obj_;
|
||||||
|
obj->for_all_global_symbols(p->sd_, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Print statistical information to stderr. This is used for --stats.
|
// Print statistical information to stderr. This is used for --stats.
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1210,9 +1253,15 @@ Add_lib_group_symbols::locks(Task_locker* tl)
|
||||||
void
|
void
|
||||||
Add_lib_group_symbols::run(Workqueue*)
|
Add_lib_group_symbols::run(Workqueue*)
|
||||||
{
|
{
|
||||||
|
// For an incremental link, begin recording layout information.
|
||||||
|
Incremental_inputs* incremental_inputs = this->layout_->incremental_inputs();
|
||||||
|
if (incremental_inputs != NULL)
|
||||||
|
incremental_inputs->report_archive_begin(this->lib_);
|
||||||
|
|
||||||
this->lib_->add_symbols(this->symtab_, this->layout_, this->input_objects_);
|
this->lib_->add_symbols(this->symtab_, this->layout_, this->input_objects_);
|
||||||
|
|
||||||
// FIXME: Record incremental link info for --start_lib/--end_lib.
|
if (incremental_inputs != NULL)
|
||||||
|
incremental_inputs->report_archive_end(this->lib_);
|
||||||
}
|
}
|
||||||
|
|
||||||
Add_lib_group_symbols::~Add_lib_group_symbols()
|
Add_lib_group_symbols::~Add_lib_group_symbols()
|
||||||
|
|
235
gold/archive.h
235
gold/archive.h
|
@ -59,10 +59,105 @@ struct Archive_member
|
||||||
Read_symbols_data* sd_;
|
Read_symbols_data* sd_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This class serves as a base class for Archive and Lib_group objects.
|
||||||
|
|
||||||
|
class Library_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Library_base(Task* task)
|
||||||
|
: task_(task), incremental_info_(NULL)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual
|
||||||
|
~Library_base()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
// The file name.
|
||||||
|
const std::string&
|
||||||
|
filename() const
|
||||||
|
{ return this->do_filename(); }
|
||||||
|
|
||||||
|
// The modification time of the archive file.
|
||||||
|
Timespec
|
||||||
|
get_mtime()
|
||||||
|
{ return this->do_get_mtime(); }
|
||||||
|
|
||||||
|
// When we see a symbol in an archive we might decide to include the member,
|
||||||
|
// not include the member or be undecided. This enum represents these
|
||||||
|
// possibilities.
|
||||||
|
|
||||||
|
enum Should_include
|
||||||
|
{
|
||||||
|
SHOULD_INCLUDE_NO,
|
||||||
|
SHOULD_INCLUDE_YES,
|
||||||
|
SHOULD_INCLUDE_UNKNOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
static Should_include
|
||||||
|
should_include_member(Symbol_table* symtab, Layout*, const char* sym_name,
|
||||||
|
Symbol** symp, std::string* why, char** tmpbufp,
|
||||||
|
size_t* tmpbuflen);
|
||||||
|
|
||||||
|
// Store a pointer to the incremental link info for the library.
|
||||||
|
void
|
||||||
|
set_incremental_info(Incremental_archive_entry* info)
|
||||||
|
{ this->incremental_info_ = info; }
|
||||||
|
|
||||||
|
// Return the pointer to the incremental link info for the library.
|
||||||
|
Incremental_archive_entry*
|
||||||
|
incremental_info() const
|
||||||
|
{ return this->incremental_info_; }
|
||||||
|
|
||||||
|
// Abstract base class for processing unused symbols.
|
||||||
|
class Symbol_visitor_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Symbol_visitor_base()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual
|
||||||
|
~Symbol_visitor_base()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
// This function will be called for each unused global
|
||||||
|
// symbol in a library, with a pointer to the symbol name.
|
||||||
|
virtual void
|
||||||
|
visit(const char* /* name */) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Iterator for unused global symbols in the library.
|
||||||
|
// Calls v->visit() for each global symbol defined
|
||||||
|
// in each unused library member, passing a pointer to
|
||||||
|
// the symbol name.
|
||||||
|
void
|
||||||
|
for_all_unused_symbols(Symbol_visitor_base* v) const
|
||||||
|
{ this->do_for_all_unused_symbols(v); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// The task reading this archive.
|
||||||
|
Task *task_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// The file name.
|
||||||
|
virtual const std::string&
|
||||||
|
do_filename() const = 0;
|
||||||
|
|
||||||
|
// Return the modification time of the archive file.
|
||||||
|
virtual Timespec
|
||||||
|
do_get_mtime() = 0;
|
||||||
|
|
||||||
|
// Iterator for unused global symbols in the library.
|
||||||
|
virtual void
|
||||||
|
do_for_all_unused_symbols(Symbol_visitor_base* v) const = 0;
|
||||||
|
|
||||||
|
// The incremental link information for this archive.
|
||||||
|
Incremental_archive_entry* incremental_info_;
|
||||||
|
};
|
||||||
|
|
||||||
// This class represents an archive--generally a libNAME.a file.
|
// This class represents an archive--generally a libNAME.a file.
|
||||||
// Archives have a symbol table and a list of objects.
|
// Archives have a symbol table and a list of objects.
|
||||||
|
|
||||||
class Archive
|
class Archive : public Library_base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Archive(const std::string& name, Input_file* input_file,
|
Archive(const std::string& name, Input_file* input_file,
|
||||||
|
@ -90,11 +185,6 @@ class Archive
|
||||||
input_file() const
|
input_file() const
|
||||||
{ return this->input_file_; }
|
{ return this->input_file_; }
|
||||||
|
|
||||||
// The file name.
|
|
||||||
const std::string&
|
|
||||||
filename() const
|
|
||||||
{ return this->input_file_->filename(); }
|
|
||||||
|
|
||||||
// Set up the archive: read the symbol map.
|
// Set up the archive: read the symbol map.
|
||||||
void
|
void
|
||||||
setup();
|
setup();
|
||||||
|
@ -169,99 +259,20 @@ class Archive
|
||||||
no_export()
|
no_export()
|
||||||
{ return this->no_export_; }
|
{ return this->no_export_; }
|
||||||
|
|
||||||
// Store a pointer to the incremental link info for the archive.
|
|
||||||
void
|
|
||||||
set_incremental_info(Incremental_archive_entry* info)
|
|
||||||
{ this->incremental_info_ = info; }
|
|
||||||
|
|
||||||
// Return the pointer to the incremental link info for the archive.
|
|
||||||
Incremental_archive_entry*
|
|
||||||
incremental_info() const
|
|
||||||
{ return this->incremental_info_; }
|
|
||||||
|
|
||||||
// When we see a symbol in an archive we might decide to include the member,
|
|
||||||
// not include the member or be undecided. This enum represents these
|
|
||||||
// possibilities.
|
|
||||||
|
|
||||||
enum Should_include
|
|
||||||
{
|
|
||||||
SHOULD_INCLUDE_NO,
|
|
||||||
SHOULD_INCLUDE_YES,
|
|
||||||
SHOULD_INCLUDE_UNKNOWN
|
|
||||||
};
|
|
||||||
|
|
||||||
static Should_include
|
|
||||||
should_include_member(Symbol_table* symtab, Layout*, const char* sym_name,
|
|
||||||
Symbol** symp, std::string* why, char** tmpbufp,
|
|
||||||
size_t* tmpbuflen);
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct Armap_entry;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Iterator class for unused global symbols. This iterator is used
|
|
||||||
// for incremental links.
|
|
||||||
|
|
||||||
class Unused_symbol_iterator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Unused_symbol_iterator(Archive* arch,
|
|
||||||
std::vector<Armap_entry>::const_iterator it)
|
|
||||||
: arch_(arch), it_(it)
|
|
||||||
{ this->skip_used_symbols(); }
|
|
||||||
|
|
||||||
const char*
|
|
||||||
operator*() const
|
|
||||||
{ return this->arch_->armap_names_.data() + this->it_->name_offset; }
|
|
||||||
|
|
||||||
Unused_symbol_iterator&
|
|
||||||
operator++()
|
|
||||||
{
|
|
||||||
++this->it_;
|
|
||||||
this->skip_used_symbols();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
operator==(const Unused_symbol_iterator p) const
|
|
||||||
{ return this->it_ == p.it_; }
|
|
||||||
|
|
||||||
bool
|
|
||||||
operator!=(const Unused_symbol_iterator p) const
|
|
||||||
{ return this->it_ != p.it_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Skip over symbols defined by members that have been included.
|
|
||||||
void
|
|
||||||
skip_used_symbols()
|
|
||||||
{
|
|
||||||
while (this->it_ != this->arch_->armap_.end()
|
|
||||||
&& (this->arch_->seen_offsets_.find(this->it_->file_offset)
|
|
||||||
!= this->arch_->seen_offsets_.end()))
|
|
||||||
++it_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The underlying archive.
|
|
||||||
Archive* arch_;
|
|
||||||
|
|
||||||
// The underlying iterator over all entries in the archive map.
|
|
||||||
std::vector<Armap_entry>::const_iterator it_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return an iterator referring to the first unused symbol.
|
|
||||||
Unused_symbol_iterator
|
|
||||||
unused_symbols_begin()
|
|
||||||
{ return Unused_symbol_iterator(this, this->armap_.begin()); }
|
|
||||||
|
|
||||||
// Return an iterator referring to the end of the unused symbols.
|
|
||||||
Unused_symbol_iterator
|
|
||||||
unused_symbols_end()
|
|
||||||
{ return Unused_symbol_iterator(this, this->armap_.end()); }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Archive(const Archive&);
|
Archive(const Archive&);
|
||||||
Archive& operator=(const Archive&);
|
Archive& operator=(const Archive&);
|
||||||
|
|
||||||
|
// The file name.
|
||||||
|
const std::string&
|
||||||
|
do_filename() const
|
||||||
|
{ return this->input_file_->filename(); }
|
||||||
|
|
||||||
|
// The modification time of the archive file.
|
||||||
|
Timespec
|
||||||
|
do_get_mtime()
|
||||||
|
{ return this->file().get_mtime(); }
|
||||||
|
|
||||||
struct Archive_header;
|
struct Archive_header;
|
||||||
|
|
||||||
// Total number of archives seen.
|
// Total number of archives seen.
|
||||||
|
@ -339,6 +350,10 @@ class Archive
|
||||||
|
|
||||||
friend class const_iterator;
|
friend class const_iterator;
|
||||||
|
|
||||||
|
// Iterator for unused global symbols in the library.
|
||||||
|
void
|
||||||
|
do_for_all_unused_symbols(Symbol_visitor_base* v) const;
|
||||||
|
|
||||||
// An entry in the archive map of symbols to object files.
|
// An entry in the archive map of symbols to object files.
|
||||||
struct Armap_entry
|
struct Armap_entry
|
||||||
{
|
{
|
||||||
|
@ -384,14 +399,10 @@ class Archive
|
||||||
Nested_archive_table nested_archives_;
|
Nested_archive_table nested_archives_;
|
||||||
// The directory search path.
|
// The directory search path.
|
||||||
Dirsearch* dirpath_;
|
Dirsearch* dirpath_;
|
||||||
// The task reading this archive.
|
|
||||||
Task* task_;
|
|
||||||
// Number of members in this archive;
|
// Number of members in this archive;
|
||||||
unsigned int num_members_;
|
unsigned int num_members_;
|
||||||
// True if we exclude this library archive from automatic export.
|
// True if we exclude this library archive from automatic export.
|
||||||
bool no_export_;
|
bool no_export_;
|
||||||
// The incremental link information for this archive.
|
|
||||||
Incremental_archive_entry* incremental_info_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// This class is used to read an archive and pick out the desired
|
// This class is used to read an archive and pick out the desired
|
||||||
|
@ -451,7 +462,7 @@ class Add_archive_symbols : public Task
|
||||||
|
|
||||||
// This class represents the files surrounded by a --start-lib ... --end-lib.
|
// This class represents the files surrounded by a --start-lib ... --end-lib.
|
||||||
|
|
||||||
class Lib_group
|
class Lib_group : public Library_base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Lib_group(const Input_file_lib* lib, Task* task);
|
Lib_group(const Input_file_lib* lib, Task* task);
|
||||||
|
@ -470,10 +481,6 @@ class Lib_group
|
||||||
return &this->members_[i];
|
return &this->members_[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dump statistical information to stderr.
|
|
||||||
static void
|
|
||||||
print_stats();
|
|
||||||
|
|
||||||
// Total number of archives seen.
|
// Total number of archives seen.
|
||||||
static unsigned int total_lib_groups;
|
static unsigned int total_lib_groups;
|
||||||
// Total number of archive members seen.
|
// Total number of archive members seen.
|
||||||
|
@ -481,11 +488,27 @@ class Lib_group
|
||||||
// Number of archive members loaded.
|
// Number of archive members loaded.
|
||||||
static unsigned int total_members_loaded;
|
static unsigned int total_members_loaded;
|
||||||
|
|
||||||
|
// Dump statistical information to stderr.
|
||||||
|
static void
|
||||||
|
print_stats();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// The file name.
|
||||||
|
const std::string&
|
||||||
|
do_filename() const;
|
||||||
|
|
||||||
|
// A Lib_group does not have a modification time, since there is no
|
||||||
|
// real library file.
|
||||||
|
Timespec
|
||||||
|
do_get_mtime()
|
||||||
|
{ return Timespec(0, 0); }
|
||||||
|
|
||||||
|
// Iterator for unused global symbols in the library.
|
||||||
|
void
|
||||||
|
do_for_all_unused_symbols(Symbol_visitor_base*) const;
|
||||||
|
|
||||||
// For reading the files.
|
// For reading the files.
|
||||||
const Input_file_lib* lib_;
|
const Input_file_lib* lib_;
|
||||||
// The task reading this lib group.
|
|
||||||
Task* task_;
|
|
||||||
// Table of the objects in the group.
|
// Table of the objects in the group.
|
||||||
std::vector<Archive_member> members_;
|
std::vector<Archive_member> members_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -761,6 +761,32 @@ Sized_dynobj<size, big_endian>::do_should_include_member(Symbol_table*,
|
||||||
return Archive::SHOULD_INCLUDE_YES;
|
return Archive::SHOULD_INCLUDE_YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Iterate over global symbols, calling a visitor class V for each.
|
||||||
|
|
||||||
|
template<int size, bool big_endian>
|
||||||
|
void
|
||||||
|
Sized_dynobj<size, big_endian>::do_for_all_global_symbols(
|
||||||
|
Read_symbols_data* sd,
|
||||||
|
Library_base::Symbol_visitor_base* v)
|
||||||
|
{
|
||||||
|
const char* sym_names =
|
||||||
|
reinterpret_cast<const char*>(sd->symbol_names->data());
|
||||||
|
const unsigned char* syms =
|
||||||
|
sd->symbols->data() + sd->external_symbols_offset;
|
||||||
|
const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
|
||||||
|
size_t symcount = ((sd->symbols_size - sd->external_symbols_offset)
|
||||||
|
/ sym_size);
|
||||||
|
const unsigned char* p = syms;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < symcount; ++i, p += sym_size)
|
||||||
|
{
|
||||||
|
elfcpp::Sym<size, big_endian> sym(p);
|
||||||
|
if (sym.get_st_shndx() != elfcpp::SHN_UNDEF
|
||||||
|
&& sym.get_st_bind() != elfcpp::STB_LOCAL)
|
||||||
|
v->visit(sym_names + sym.get_st_name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get symbol counts.
|
// Get symbol counts.
|
||||||
|
|
||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
|
|
|
@ -181,6 +181,11 @@ class Sized_dynobj : public Dynobj
|
||||||
do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
|
do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
|
||||||
std::string* why);
|
std::string* why);
|
||||||
|
|
||||||
|
// Iterate over global symbols, calling a visitor class V for each.
|
||||||
|
void
|
||||||
|
do_for_all_global_symbols(Read_symbols_data* sd,
|
||||||
|
Library_base::Symbol_visitor_base* v);
|
||||||
|
|
||||||
// Get the size of a section.
|
// Get the size of a section.
|
||||||
uint64_t
|
uint64_t
|
||||||
do_section_size(unsigned int shndx)
|
do_section_size(unsigned int shndx)
|
||||||
|
|
|
@ -436,38 +436,59 @@ Incremental_inputs::report_command_line(int argc, const char* const* argv)
|
||||||
// input objects until report_archive_end is called.
|
// input objects until report_archive_end is called.
|
||||||
|
|
||||||
void
|
void
|
||||||
Incremental_inputs::report_archive_begin(Archive* arch)
|
Incremental_inputs::report_archive_begin(Library_base* arch)
|
||||||
{
|
{
|
||||||
Stringpool::Key filename_key;
|
Stringpool::Key filename_key;
|
||||||
Timespec mtime = arch->file().get_mtime();
|
Timespec mtime = arch->get_mtime();
|
||||||
|
|
||||||
this->strtab_->add(arch->filename().c_str(), false, &filename_key);
|
this->strtab_->add(arch->filename().c_str(), false, &filename_key);
|
||||||
Incremental_archive_entry* entry =
|
Incremental_archive_entry* entry =
|
||||||
new Incremental_archive_entry(filename_key, arch, mtime);
|
new Incremental_archive_entry(filename_key, mtime);
|
||||||
arch->set_incremental_info(entry);
|
arch->set_incremental_info(entry);
|
||||||
|
this->inputs_.push_back(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Visitor class for processing the unused global symbols in a library.
|
||||||
|
// An instance of this class is passed to the library's
|
||||||
|
// for_all_unused_symbols() iterator, which will call the visit()
|
||||||
|
// function for each global symbol defined in each unused library
|
||||||
|
// member. We add those symbol names to the incremental info for the
|
||||||
|
// library.
|
||||||
|
|
||||||
|
class Unused_symbol_visitor : public Library_base::Symbol_visitor_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Unused_symbol_visitor(Incremental_archive_entry* entry, Stringpool* strtab)
|
||||||
|
: entry_(entry), strtab_(strtab)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void
|
||||||
|
visit(const char* sym)
|
||||||
|
{
|
||||||
|
Stringpool::Key symbol_key;
|
||||||
|
this->strtab_->add(sym, true, &symbol_key);
|
||||||
|
this->entry_->add_unused_global_symbol(symbol_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Incremental_archive_entry* entry_;
|
||||||
|
Stringpool* strtab_;
|
||||||
|
};
|
||||||
|
|
||||||
// Finish recording the input archive file ARCHIVE. This is called by the
|
// Finish recording the input archive file ARCHIVE. This is called by the
|
||||||
// Add_archive_symbols task after determining which archive members
|
// Add_archive_symbols task after determining which archive members
|
||||||
// to include.
|
// to include.
|
||||||
|
|
||||||
void
|
void
|
||||||
Incremental_inputs::report_archive_end(Archive* arch)
|
Incremental_inputs::report_archive_end(Library_base* arch)
|
||||||
{
|
{
|
||||||
Incremental_archive_entry* entry = arch->incremental_info();
|
Incremental_archive_entry* entry = arch->incremental_info();
|
||||||
|
|
||||||
gold_assert(entry != NULL);
|
gold_assert(entry != NULL);
|
||||||
|
|
||||||
// Collect unused global symbols.
|
// Collect unused global symbols.
|
||||||
for (Archive::Unused_symbol_iterator p = arch->unused_symbols_begin();
|
Unused_symbol_visitor v(entry, this->strtab_);
|
||||||
p != arch->unused_symbols_end();
|
arch->for_all_unused_symbols(&v);
|
||||||
++p)
|
|
||||||
{
|
|
||||||
Stringpool::Key symbol_key;
|
|
||||||
this->strtab_->add(*p, true, &symbol_key);
|
|
||||||
entry->add_unused_global_symbol(symbol_key);
|
|
||||||
}
|
|
||||||
this->inputs_.push_back(entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record the input object file OBJ. If ARCH is not NULL, attach
|
// Record the input object file OBJ. If ARCH is not NULL, attach
|
||||||
|
@ -475,7 +496,7 @@ Incremental_inputs::report_archive_end(Archive* arch)
|
||||||
// Add_symbols task after finding out the type of the file.
|
// Add_symbols task after finding out the type of the file.
|
||||||
|
|
||||||
void
|
void
|
||||||
Incremental_inputs::report_object(Object* obj, Archive* arch)
|
Incremental_inputs::report_object(Object* obj, Library_base* arch)
|
||||||
{
|
{
|
||||||
Stringpool::Key filename_key;
|
Stringpool::Key filename_key;
|
||||||
Timespec mtime = obj->input_file()->file().get_mtime();
|
Timespec mtime = obj->input_file()->file().get_mtime();
|
||||||
|
|
|
@ -451,8 +451,7 @@ class Incremental_object_entry : public Incremental_input_entry
|
||||||
class Incremental_archive_entry : public Incremental_input_entry
|
class Incremental_archive_entry : public Incremental_input_entry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Incremental_archive_entry(Stringpool::Key filename_key, Archive*,
|
Incremental_archive_entry(Stringpool::Key filename_key, Timespec mtime)
|
||||||
Timespec mtime)
|
|
||||||
: Incremental_input_entry(filename_key, mtime), members_(), unused_syms_()
|
: Incremental_input_entry(filename_key, mtime), members_(), unused_syms_()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
@ -531,16 +530,16 @@ class Incremental_inputs
|
||||||
|
|
||||||
// Record the initial info for archive file ARCHIVE.
|
// Record the initial info for archive file ARCHIVE.
|
||||||
void
|
void
|
||||||
report_archive_begin(Archive* arch);
|
report_archive_begin(Library_base* arch);
|
||||||
|
|
||||||
// Record the final info for archive file ARCHIVE.
|
// Record the final info for archive file ARCHIVE.
|
||||||
void
|
void
|
||||||
report_archive_end(Archive* arch);
|
report_archive_end(Library_base* arch);
|
||||||
|
|
||||||
// Record the info for object file OBJ. If ARCH is not NULL,
|
// Record the info for object file OBJ. If ARCH is not NULL,
|
||||||
// attach the object file to the archive.
|
// attach the object file to the archive.
|
||||||
void
|
void
|
||||||
report_object(Object* obj, Archive* arch);
|
report_object(Object* obj, Library_base* arch);
|
||||||
|
|
||||||
// Record an input section belonging to object file OBJ.
|
// Record an input section belonging to object file OBJ.
|
||||||
void
|
void
|
||||||
|
|
|
@ -1691,6 +1691,31 @@ Sized_relobj<size, big_endian>::do_should_include_member(Symbol_table* symtab,
|
||||||
return Archive::SHOULD_INCLUDE_UNKNOWN;
|
return Archive::SHOULD_INCLUDE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Iterate over global defined symbols, calling a visitor class V for each.
|
||||||
|
|
||||||
|
template<int size, bool big_endian>
|
||||||
|
void
|
||||||
|
Sized_relobj<size, big_endian>::do_for_all_global_symbols(
|
||||||
|
Read_symbols_data* sd,
|
||||||
|
Library_base::Symbol_visitor_base* v)
|
||||||
|
{
|
||||||
|
const char* sym_names =
|
||||||
|
reinterpret_cast<const char*>(sd->symbol_names->data());
|
||||||
|
const unsigned char* syms =
|
||||||
|
sd->symbols->data() + sd->external_symbols_offset;
|
||||||
|
const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
|
||||||
|
size_t symcount = ((sd->symbols_size - sd->external_symbols_offset)
|
||||||
|
/ sym_size);
|
||||||
|
const unsigned char* p = syms;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < symcount; ++i, p += sym_size)
|
||||||
|
{
|
||||||
|
elfcpp::Sym<size, big_endian> sym(p);
|
||||||
|
if (sym.get_st_shndx() != elfcpp::SHN_UNDEF)
|
||||||
|
v->visit(sym_names + sym.get_st_name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Return whether the local symbol SYMNDX has a PLT offset.
|
// Return whether the local symbol SYMNDX has a PLT offset.
|
||||||
|
|
||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
|
|
|
@ -422,6 +422,12 @@ class Object
|
||||||
Read_symbols_data* sd, std::string* why)
|
Read_symbols_data* sd, std::string* why)
|
||||||
{ return this->do_should_include_member(symtab, layout, sd, why); }
|
{ return this->do_should_include_member(symtab, layout, sd, why); }
|
||||||
|
|
||||||
|
// Iterate over global symbols, calling a visitor class V for each.
|
||||||
|
void
|
||||||
|
for_all_global_symbols(Read_symbols_data* sd,
|
||||||
|
Library_base::Symbol_visitor_base* v)
|
||||||
|
{ return this->do_for_all_global_symbols(sd, v); }
|
||||||
|
|
||||||
// Functions and types for the elfcpp::Elf_file interface. This
|
// Functions and types for the elfcpp::Elf_file interface. This
|
||||||
// permit us to use Object as the File template parameter for
|
// permit us to use Object as the File template parameter for
|
||||||
// elfcpp::Elf_file.
|
// elfcpp::Elf_file.
|
||||||
|
@ -572,6 +578,11 @@ class Object
|
||||||
do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
|
do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
|
||||||
std::string* why) = 0;
|
std::string* why) = 0;
|
||||||
|
|
||||||
|
// Iterate over global symbols, calling a visitor class V for each.
|
||||||
|
virtual void
|
||||||
|
do_for_all_global_symbols(Read_symbols_data* sd,
|
||||||
|
Library_base::Symbol_visitor_base* v) = 0;
|
||||||
|
|
||||||
// Return the location of the contents of a section. Implemented by
|
// Return the location of the contents of a section. Implemented by
|
||||||
// child class.
|
// child class.
|
||||||
virtual Location
|
virtual Location
|
||||||
|
@ -1810,6 +1821,11 @@ class Sized_relobj : public Relobj
|
||||||
do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
|
do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
|
||||||
std::string* why);
|
std::string* why);
|
||||||
|
|
||||||
|
// Iterate over global symbols, calling a visitor class V for each.
|
||||||
|
void
|
||||||
|
do_for_all_global_symbols(Read_symbols_data* sd,
|
||||||
|
Library_base::Symbol_visitor_base* v);
|
||||||
|
|
||||||
// Read the relocs.
|
// Read the relocs.
|
||||||
void
|
void
|
||||||
do_read_relocs(Read_relocs_data*);
|
do_read_relocs(Read_relocs_data*);
|
||||||
|
|
|
@ -985,6 +985,22 @@ Sized_pluginobj<size, big_endian>::do_should_include_member(
|
||||||
return Archive::SHOULD_INCLUDE_UNKNOWN;
|
return Archive::SHOULD_INCLUDE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Iterate over global symbols, calling a visitor class V for each.
|
||||||
|
|
||||||
|
template<int size, bool big_endian>
|
||||||
|
void
|
||||||
|
Sized_pluginobj<size, big_endian>::do_for_all_global_symbols(
|
||||||
|
Read_symbols_data*,
|
||||||
|
Library_base::Symbol_visitor_base* v)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < this->nsyms_; ++i)
|
||||||
|
{
|
||||||
|
const struct ld_plugin_symbol& sym = this->syms_[i];
|
||||||
|
if (sym.def != LDPK_UNDEF)
|
||||||
|
v->visit(sym.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get the size of a section. Not used for plugin objects.
|
// Get the size of a section. Not used for plugin objects.
|
||||||
|
|
||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
|
|
|
@ -449,6 +449,11 @@ class Sized_pluginobj : public Pluginobj
|
||||||
do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
|
do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
|
||||||
std::string* why);
|
std::string* why);
|
||||||
|
|
||||||
|
// Iterate over global symbols, calling a visitor class V for each.
|
||||||
|
void
|
||||||
|
do_for_all_global_symbols(Read_symbols_data* sd,
|
||||||
|
Library_base::Symbol_visitor_base* v);
|
||||||
|
|
||||||
// Get the size of a section.
|
// Get the size of a section.
|
||||||
uint64_t
|
uint64_t
|
||||||
do_section_size(unsigned int shndx);
|
do_section_size(unsigned int shndx);
|
||||||
|
|
Loading…
Reference in New Issue