diff options
Diffstat (limited to 'gold/plugin.cc')
-rw-r--r-- | gold/plugin.cc | 102 |
1 files changed, 88 insertions, 14 deletions
diff --git a/gold/plugin.cc b/gold/plugin.cc index e2a9e60..7d5b1b7 100644 --- a/gold/plugin.cc +++ b/gold/plugin.cc @@ -1,6 +1,6 @@ // plugin.c -- plugin manager for gold -*- C++ -*- -// Copyright 2008 Free Software Foundation, Inc. +// Copyright 2008, 2009 Free Software Foundation, Inc. // Written by Cary Coutant <ccoutant@google.com>. // This file is part of gold. @@ -62,6 +62,12 @@ static enum ld_plugin_status add_symbols(void *handle, int nsyms, const struct ld_plugin_symbol *syms); static enum ld_plugin_status +get_input_file(const void *handle, struct ld_plugin_input_file *file); + +static enum ld_plugin_status +release_input_file(const void *handle); + +static enum ld_plugin_status get_symbols(const void *handle, int nsyms, struct ld_plugin_symbol *syms); static enum ld_plugin_status @@ -75,7 +81,7 @@ message(int level, const char *format, ...); #endif // ENABLE_PLUGINS static Pluginobj* make_sized_plugin_object(Input_file* input_file, - off_t offset); + off_t offset, off_t filesize); // Plugin methods. @@ -112,7 +118,7 @@ Plugin::load() sscanf(ver, "%d.%d", &major, &minor); // Allocate and populate a transfer vector. - const int tv_fixed_size = 11; + const int tv_fixed_size = 13; int tv_size = this->args_.size() + tv_fixed_size; ld_plugin_tv *tv = new ld_plugin_tv[tv_size]; @@ -163,6 +169,14 @@ Plugin::load() tv[i].tv_u.tv_add_symbols = add_symbols; ++i; + tv[i].tv_tag = LDPT_GET_INPUT_FILE; + tv[i].tv_u.tv_get_input_file = get_input_file; + + ++i; + tv[i].tv_tag = LDPT_RELEASE_INPUT_FILE; + tv[i].tv_u.tv_release_input_file = release_input_file; + + ++i; tv[i].tv_tag = LDPT_GET_SYMBOLS; tv[i].tv_u.tv_get_symbols = get_symbols; @@ -283,7 +297,7 @@ Plugin_manager::claim_file(Input_file* input_file, off_t offset, // Call the all-symbols-read handlers. void -Plugin_manager::all_symbols_read(Workqueue* workqueue, +Plugin_manager::all_symbols_read(Workqueue* workqueue, Task* task, Input_objects* input_objects, Symbol_table* symtab, Layout* layout, Dirsearch* dirpath, Mapfile* mapfile, @@ -291,6 +305,7 @@ Plugin_manager::all_symbols_read(Workqueue* workqueue, { this->in_replacement_phase_ = true; this->workqueue_ = workqueue; + this->task_ = task; this->input_objects_ = input_objects; this->symtab_ = symtab; this->layout_ = layout; @@ -344,11 +359,45 @@ Plugin_manager::make_plugin_object(unsigned int handle) return NULL; Pluginobj* obj = make_sized_plugin_object(this->input_file_, - this->plugin_input_file_.offset); + this->plugin_input_file_.offset, + this->plugin_input_file_.filesize); this->objects_.push_back(obj); return obj; } +// Get the input file information with an open (possibly re-opened) +// file descriptor. + +ld_plugin_status +Plugin_manager::get_input_file(unsigned int handle, + struct ld_plugin_input_file *file) +{ + Pluginobj* obj = this->object(handle); + if (obj == NULL) + return LDPS_BAD_HANDLE; + + obj->lock(this->task_); + file->name = obj->filename().c_str(); + file->fd = obj->descriptor(); + file->offset = obj->offset(); + file->filesize = obj->filesize(); + file->handle = reinterpret_cast<void*>(handle); + return LDPS_OK; +} + +// Release the input file. + +ld_plugin_status +Plugin_manager::release_input_file(unsigned int handle) +{ + Pluginobj* obj = this->object(handle); + if (obj == NULL) + return LDPS_BAD_HANDLE; + + obj->unlock(this->task_); + return LDPS_OK; +} + // Add a new input file. ld_plugin_status @@ -375,9 +424,9 @@ Plugin_manager::add_input_file(char *pathname) // Class Pluginobj. Pluginobj::Pluginobj(const std::string& name, Input_file* input_file, - off_t offset) + off_t offset, off_t filesize) : Object(name, input_file, false, offset), - nsyms_(0), syms_(NULL), symbols_(), comdat_map_() + nsyms_(0), syms_(NULL), symbols_(), filesize_(filesize), comdat_map_() { } @@ -468,8 +517,9 @@ template<int size, bool big_endian> Sized_pluginobj<size, big_endian>::Sized_pluginobj( const std::string& name, Input_file* input_file, - off_t offset) - : Pluginobj(name, input_file, offset) + off_t offset, + off_t filesize) + : Pluginobj(name, input_file, offset, filesize) { } @@ -822,6 +872,7 @@ Plugin_hook::run(Workqueue* workqueue) { gold_assert(this->options_.has_plugins()); this->options_.plugins()->all_symbols_read(workqueue, + this, this->input_objects_, this->symtab_, this->layout_, @@ -880,6 +931,29 @@ add_symbols(void* handle, int nsyms, const ld_plugin_symbol *syms) return LDPS_OK; } +// Get the input file information with an open (possibly re-opened) +// file descriptor. + +static enum ld_plugin_status +get_input_file(const void *handle, struct ld_plugin_input_file *file) +{ + gold_assert(parameters->options().has_plugins()); + unsigned int obj_index = + static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle)); + return parameters->options().plugins()->get_input_file(obj_index, file); +} + +// Release the input file. + +static enum ld_plugin_status +release_input_file(const void *handle) +{ + gold_assert(parameters->options().has_plugins()); + unsigned int obj_index = + static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle)); + return parameters->options().plugins()->release_input_file(obj_index); +} + // Get the symbol resolution info for a plugin-claimed input file. static enum ld_plugin_status @@ -936,7 +1010,7 @@ message(int level, const char * format, ...) // Allocate a Pluginobj object of the appropriate size and endianness. static Pluginobj* -make_sized_plugin_object(Input_file* input_file, off_t offset) +make_sized_plugin_object(Input_file* input_file, off_t offset, off_t filesize) { Target* target; Pluginobj* obj = NULL; @@ -951,7 +1025,7 @@ make_sized_plugin_object(Input_file* input_file, off_t offset) if (target->is_big_endian()) #ifdef HAVE_TARGET_32_BIG obj = new Sized_pluginobj<32, true>(input_file->filename(), - input_file, offset); + input_file, offset, filesize); #else gold_error(_("%s: not configured to support " "32-bit big-endian object"), @@ -960,7 +1034,7 @@ make_sized_plugin_object(Input_file* input_file, off_t offset) else #ifdef HAVE_TARGET_32_LITTLE obj = new Sized_pluginobj<32, false>(input_file->filename(), - input_file, offset); + input_file, offset, filesize); #else gold_error(_("%s: not configured to support " "32-bit little-endian object"), @@ -972,7 +1046,7 @@ make_sized_plugin_object(Input_file* input_file, off_t offset) if (target->is_big_endian()) #ifdef HAVE_TARGET_64_BIG obj = new Sized_pluginobj<64, true>(input_file->filename(), - input_file, offset); + input_file, offset, filesize); #else gold_error(_("%s: not configured to support " "64-bit big-endian object"), @@ -981,7 +1055,7 @@ make_sized_plugin_object(Input_file* input_file, off_t offset) else #ifdef HAVE_TARGET_64_LITTLE obj = new Sized_pluginobj<64, false>(input_file->filename(), - input_file, offset); + input_file, offset, filesize); #else gold_error(_("%s: not configured to support " "64-bit little-endian object"), |