aboutsummaryrefslogtreecommitdiff
path: root/gold/archive.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2011-01-24 21:48:40 +0000
committerIan Lance Taylor <ian@airs.com>2011-01-24 21:48:40 +0000
commit0f3b89d87a62ea42186fb5ba525dadde36182a97 (patch)
treea1ba50cb45c68cfeaf4d02005a29a693f3d9a687 /gold/archive.cc
parent314d366acd62a3de1ff8fff788d5b369c2f2d36c (diff)
downloadfsf-binutils-gdb-0f3b89d87a62ea42186fb5ba525dadde36182a97.zip
fsf-binutils-gdb-0f3b89d87a62ea42186fb5ba525dadde36182a97.tar.gz
fsf-binutils-gdb-0f3b89d87a62ea42186fb5ba525dadde36182a97.tar.bz2
* plugin.cc (class Plugin_rescan): Define new class.
(Plugin_manager::claim_file): Set any_claimed_. (Plugin_manager::save_archive): New function. (Plugin_manager::save_input_group): New function. (Plugin_manager::all_symbols_read): Create Plugin_rescan task if necessary. (Plugin_manager::new_undefined_symbol): New function. (Plugin_manager::rescan): New function. (Plugin_manager::rescannable_defines): New function. (Plugin_manager::add_input_file): Set any_added_. * plugin.h (class Plugin_manager): define new fields rescannable_, undefined_symbols_, any_claimed_, and any_added_. Declare Plugin_rescan as friend. Declare new functions. (Plugin_manager::Rescannable): Define type. (Plugin_manager::Rescannable_list): Define type. (Plugin_manager::Undefined_symbol_list): Define type. (Plugin_manager::Plugin_manager): Initialize new fields. * archive.cc (Archive::defines_symbol): New function. (Add_archive_symbols::run): Pass archive to plugins if any. * archive.h (class Archive): Declare defines_symbol. * readsyms.cc (Input_group::~Input_group): New function. (Finish_group::run): Pass input_group to plugins if any. * readsyms.h (class Input_group): Declare destructor. * symtab.cc (add_from_object): Pass undefined symbol to plugins if any.
Diffstat (limited to 'gold/archive.cc')
-rw-r--r--gold/archive.cc52
1 files changed, 49 insertions, 3 deletions
diff --git a/gold/archive.cc b/gold/archive.cc
index 2837ec2..89fc422 100644
--- a/gold/archive.cc
+++ b/gold/archive.cc
@@ -1,6 +1,6 @@
// archive.cc -- archive support for gold
-// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
@@ -779,6 +779,42 @@ Archive::add_symbols(Symbol_table* symtab, Layout* layout,
return true;
}
+// Return whether the archive includes a member which defines the
+// symbol SYM.
+
+bool
+Archive::defines_symbol(Symbol* sym) const
+{
+ const char* symname = sym->name();
+ size_t symname_len = strlen(symname);
+ size_t armap_size = this->armap_.size();
+ for (size_t i = 0; i < armap_size; ++i)
+ {
+ if (this->armap_checked_[i])
+ continue;
+ const char* archive_symname = (this->armap_names_.data()
+ + this->armap_[i].name_offset);
+ if (strncmp(archive_symname, symname, symname_len) != 0)
+ continue;
+ char c = archive_symname[symname_len];
+ if (c == '\0' && sym->version() == NULL)
+ return true;
+ if (c == '@')
+ {
+ const char* ver = archive_symname + symname_len + 1;
+ if (*ver == '@')
+ {
+ if (sym->version() == NULL)
+ return true;
+ ++ver;
+ }
+ if (sym->version() != NULL && strcmp(sym->version(), ver) == 0)
+ return true;
+ }
+ }
+ return false;
+}
+
// Include all the archive members in the link. This is for --whole-archive.
bool
@@ -1001,8 +1037,18 @@ Add_archive_symbols::run(Workqueue* workqueue)
if (incremental_inputs != NULL)
incremental_inputs->report_archive_end(this->archive_);
- // We no longer need to know about this archive.
- delete this->archive_;
+ if (!parameters->options().has_plugins()
+ || this->archive_->input_file()->options().whole_archive())
+ {
+ // We no longer need to know about this archive.
+ delete this->archive_;
+ }
+ else
+ {
+ // The plugin interface may want to rescan this archive.
+ parameters->options().plugins()->save_archive(this->archive_);
+ }
+
this->archive_ = NULL;
}
}