Index: include/plugin-api.h =================================================================== RCS file: /cvs/src/src/include/plugin-api.h,v retrieving revision 1.14 diff -u -u -p -r1.14 plugin-api.h --- include/plugin-api.h 23 Mar 2011 14:09:48 -0000 1.14 +++ include/plugin-api.h 13 Jul 2011 01:32:36 -0000 @@ -93,6 +93,14 @@ struct ld_plugin_symbol int resolution; }; +/* An object's section. */ + +struct ld_plugin_section +{ + const void* handle; + unsigned int shndx; +}; + /* Whether the symbol is a definition, reference, or common, weak or not. */ enum ld_plugin_symbol_kind @@ -244,6 +252,66 @@ typedef enum ld_plugin_status (*ld_plugin_message) (int level, const char *format, ...); +/* The linker's interface for retrieving the number of sections in an object. + The handle is obtained in the claim_file handler. This interface should + only be invoked in the claim_file handler. This function sets *COUNT to + the number of sections in the object. */ + +typedef +enum ld_plugin_status +(*ld_plugin_get_input_section_count) (const void* handle, unsigned int *count); + +/* The linker's interface for retrieving the section type of a specific + section in an object. This interface should only be invoked in the + claim_file handler. This function sets *TYPE to an ELF SHT_xxx value. */ + +typedef +enum ld_plugin_status +(*ld_plugin_get_input_section_type) (const struct ld_plugin_section section, + unsigned int *type); + +/* The linker's interface for retrieving the name of a specific section in + an object. This interface should only be invoked in the claim_file handler. + This function sets *SECTION_NAME_PTR to a null-terminated buffer allocated + by malloc. The plugin must free *SECTION_NAME_PTR. */ + +typedef +enum ld_plugin_status +(*ld_plugin_get_input_section_name) (const struct ld_plugin_section section, + char **section_name_ptr); + +/* The linker's interface for retrieving the contents of a specific section + in an object. This interface should only be invoked in the claim_file + handler. This function sets *SECTION_CONTENTS to point to a buffer that is + valid until inspect_unclaimed_object handler returns. It sets *LEN to the + size of the buffer. */ + +typedef +enum ld_plugin_status +(*ld_plugin_get_input_section_contents) (const struct ld_plugin_section section, + const unsigned char **section_contents, + size_t* len); + +/* The linker's interface for specifying the desired order of sections. + The sections should be specifed using the array SECTION_LIST in the + order in which they should appear in the final layout. NUM_SECTIONS + specifies the number of entries in each array. This should be invoked + in the all_symbols_read handler. */ + +typedef +enum ld_plugin_status +(*ld_plugin_update_section_order) (const struct ld_plugin_section *section_list, + unsigned int num_sections); + +/* The linker's interface for specifying that reordering of sections is + desired so that the linker can prepare for it. This should be invoked + before update_section_order, preferably in the inspect_unclaimed_object + handler. */ + +typedef +enum ld_plugin_status +(*ld_plugin_allow_section_ordering) (void); + enum ld_plugin_level { LDPL_INFO, @@ -274,7 +342,13 @@ enum ld_plugin_tag LDPT_OUTPUT_NAME, LDPT_SET_EXTRA_LIBRARY_PATH, LDPT_GNU_LD_VERSION, - LDPT_GET_VIEW + LDPT_GET_VIEW, + LDPT_GET_INPUT_SECTION_COUNT, + LDPT_GET_INPUT_SECTION_TYPE, + LDPT_GET_INPUT_SECTION_NAME, + LDPT_GET_INPUT_SECTION_CONTENTS, + LDPT_UPDATE_SECTION_ORDER, + LDPT_ALLOW_SECTION_ORDERING }; /* The plugin transfer vector. */ @@ -298,6 +372,12 @@ struct ld_plugin_tv ld_plugin_release_input_file tv_release_input_file; ld_plugin_add_input_library tv_add_input_library; ld_plugin_set_extra_library_path tv_set_extra_library_path; + ld_plugin_get_input_section_count tv_get_input_section_count; + ld_plugin_get_input_section_type tv_get_input_section_type; + ld_plugin_get_input_section_name tv_get_input_section_name; + ld_plugin_get_input_section_contents tv_get_input_section_contents; + ld_plugin_update_section_order tv_update_section_order; + ld_plugin_allow_section_ordering tv_allow_section_ordering; } tv_u; }; Index: gold/archive.cc =================================================================== RCS file: /cvs/src/src/gold/archive.cc,v retrieving revision 1.69 diff -u -u -p -r1.69 archive.cc --- gold/archive.cc 2 Jun 2011 20:13:23 -0000 1.69 +++ gold/archive.cc 13 Jul 2011 01:32:37 -0000 @@ -653,7 +653,8 @@ Archive::get_elf_object_for_member(off_t { Object* obj = parameters->options().plugins()->claim_file(input_file, memoff, - memsize); + memsize, + NULL); if (obj != NULL) { // The input file was claimed by a plugin, and its symbols Index: gold/layout.cc =================================================================== RCS file: /cvs/src/src/gold/layout.cc,v retrieving revision 1.215 diff -u -u -p -r1.215 layout.cc --- gold/layout.cc 11 Jul 2011 16:19:50 -0000 1.215 +++ gold/layout.cc 13 Jul 2011 01:32:37 -0000 @@ -399,11 +399,14 @@ Layout::Layout(int number_of_input_files any_postprocessing_sections_(false), resized_signatures_(false), have_stabstr_section_(false), + section_ordering_specified_(false), incremental_inputs_(NULL), record_output_section_data_from_script_(false), script_output_section_data_list_(), segment_states_(NULL), relaxation_debug_check_(NULL), + input_section_position_(), + input_section_glob_(), incremental_base_(NULL), free_list_() { @@ -2209,7 +2212,7 @@ Layout::find_section_order_index(const s } // Read the sequence of input sections from the file specified with -// --section-ordering-file. +// option --section-ordering-file. void Layout::read_layout_from_file() @@ -2225,6 +2228,7 @@ Layout::read_layout_from_file() std::getline(in, line); // this chops off the trailing \n, if any unsigned int position = 1; + this->set_section_ordering_specified(); while (in) { Index: gold/layout.h =================================================================== RCS file: /cvs/src/src/gold/layout.h,v retrieving revision 1.97 diff -u -u -p -r1.97 layout.h --- gold/layout.h 1 Jul 2011 22:05:01 -0000 1.97 +++ gold/layout.h 13 Jul 2011 01:32:37 -0000 @@ -492,6 +492,14 @@ class Layout const char* name, const elfcpp::Shdr& shdr, unsigned int reloc_shndx, unsigned int reloc_type, off_t* offset); + bool + is_section_ordering_specified() + { return this->section_ordering_specified_; } + + void + set_section_ordering_specified() + { this->section_ordering_specified_ = true; } + // For incremental updates, allocate a block of memory from the // free list. Find a block starting at or after MINOFF. off_t @@ -501,6 +509,8 @@ class Layout unsigned int find_section_order_index(const std::string&); + // Read the sequence of input sections from the file specified with + // linker option --section-ordering-file. void read_layout_from_file(); @@ -1262,6 +1272,9 @@ class Layout bool resized_signatures_; // Whether we have created a .stab*str output section. bool have_stabstr_section_; + // True if the input sections in the output sections should be sorted + // as specified in a section ordering file. + bool section_ordering_specified_; // In incremental build, holds information check the inputs and build the // .gnu_incremental_inputs section. Incremental_inputs* incremental_inputs_; Index: gold/main.cc =================================================================== RCS file: /cvs/src/src/gold/main.cc,v retrieving revision 1.44 diff -u -u -p -r1.44 main.cc --- gold/main.cc 8 Jun 2011 04:43:28 -0000 1.44 +++ gold/main.cc 13 Jul 2011 01:32:37 -0000 @@ -195,10 +195,6 @@ main(int argc, char** argv) if (parameters->options().relocatable()) command_line.script_options().version_script_info()->clear(); - // Load plugin libraries. - if (command_line.options().has_plugins()) - command_line.options().plugins()->load_plugins(); - // The work queue. Workqueue workqueue(command_line.options()); @@ -234,6 +230,10 @@ main(int argc, char** argv) if (parameters->options().section_ordering_file()) layout.read_layout_from_file(); + // Load plugin libraries. + if (command_line.options().has_plugins()) + command_line.options().plugins()->load_plugins(&layout); + // Get the search path from the -L options. Dirsearch search_path; search_path.initialize(&workqueue, &command_line.options().library_path()); Index: gold/output.cc =================================================================== RCS file: /cvs/src/src/gold/output.cc,v retrieving revision 1.155 diff -u -u -p -r1.155 output.cc --- gold/output.cc 8 Jul 2011 22:48:08 -0000 1.155 +++ gold/output.cc 13 Jul 2011 01:32:38 -0000 @@ -2296,7 +2296,7 @@ Output_section::add_input_section(Layout && (sh_flags & elfcpp::SHF_EXECINSTR) != 0 && parameters->target().has_code_fill() && (parameters->target().may_relax() - || parameters->options().section_ordering_file())) + || layout->is_section_ordering_specified())) { gold_assert(this->fills_.empty()); this->generate_code_fills_at_write_ = true; @@ -2335,10 +2335,10 @@ Output_section::add_input_section(Layout || this->must_sort_attached_input_sections() || parameters->options().user_set_Map() || parameters->target().may_relax() - || parameters->options().section_ordering_file()) + || layout->is_section_ordering_specified()) { Input_section isecn(object, shndx, input_section_size, addralign); - if (parameters->options().section_ordering_file()) + if (layout->is_section_ordering_specified()) { unsigned int section_order_index = layout->find_section_order_index(std::string(secname)); @@ -2421,7 +2421,7 @@ Output_section::add_relaxed_input_sectio // If the --section-ordering-file option is used to specify the order of // sections, we need to keep track of sections. - if (parameters->options().section_ordering_file()) + if (layout->is_section_ordering_specified()) { unsigned int section_order_index = layout->find_section_order_index(name); @@ -3339,6 +3339,38 @@ Output_section::Input_section_sort_secti return s1_secn_index < s2_secn_index; } +// This updates the section order index of input sections according to the +// the order specified in the mapping from Section id to order index. + +void +Output_section::update_section_layout( + const Section_layout_order& order_map) +{ + for (Input_section_list::iterator p = this->input_sections_.begin(); + p != this->input_sections_.end(); + ++p) + { + if (p->is_input_section() + || p->is_relaxed_input_section()) + { + Object* obj = (p->is_input_section() + ? p->relobj() + : p->relaxed_input_section()->relobj()); + unsigned int shndx = p->shndx(); + Section_layout_order::const_iterator it + = order_map.find(Section_id(obj, shndx)); + if (it == order_map.end()) + continue; + unsigned int section_order_index = it->second; + if (section_order_index != 0) + { + p->set_section_order_index(section_order_index); + this->set_input_section_order_specified(); + } + } + } +} + // Sort the input sections attached to an output section. void @@ -3381,7 +3413,7 @@ Output_section::sort_attached_input_sect } else { - gold_assert(parameters->options().section_ordering_file()); + gold_assert(this->input_section_order_specified()); std::sort(sort_list.begin(), sort_list.end(), Input_section_sort_section_order_index_compare()); } Index: gold/output.h =================================================================== RCS file: /cvs/src/src/gold/output.h,v retrieving revision 1.126 diff -u -u -p -r1.126 output.h --- gold/output.h 6 Jul 2011 21:19:32 -0000 1.126 +++ gold/output.h 13 Jul 2011 01:32:38 -0000 @@ -2665,6 +2665,11 @@ class Output_section : public Output_dat flags() const { return this->flags_; } + typedef std::map Section_layout_order; + + void + update_section_layout(const Section_layout_order& order_map); + // Update the output section flags based on input section flags. void update_flags_for_input_section(elfcpp::Elf_Xword flags); Index: gold/plugin.cc =================================================================== RCS file: /cvs/src/src/gold/plugin.cc,v retrieving revision 1.47 diff -u -u -p -r1.47 plugin.cc --- gold/plugin.cc 25 May 2011 00:17:47 -0000 1.47 +++ gold/plugin.cc 13 Jul 2011 01:32:38 -0000 @@ -89,6 +89,29 @@ set_extra_library_path(const char *path) static enum ld_plugin_status message(int level, const char *format, ...); +static enum ld_plugin_status +get_input_section_count(const void* handle, unsigned int* count); + +static enum ld_plugin_status +get_input_section_type(const struct ld_plugin_section section, + unsigned int* type); + +static enum ld_plugin_status +get_input_section_name(const struct ld_plugin_section section, + char** section_name_ptr); + +static enum ld_plugin_status +get_input_section_contents(const struct ld_plugin_section section, + const unsigned char** section_contents, + size_t* len); + +static enum ld_plugin_status +update_section_order(const struct ld_plugin_section *section_list, + unsigned int num_sections); + +static enum ld_plugin_status +allow_section_ordering(); + }; #endif // ENABLE_PLUGINS @@ -133,7 +156,8 @@ Plugin::load() sscanf(ver, "%d.%d", &major, &minor); // Allocate and populate a transfer vector. - const int tv_fixed_size = 17; + const int tv_fixed_size = 23; + int tv_size = this->args_.size() + tv_fixed_size; ld_plugin_tv* tv = new ld_plugin_tv[tv_size]; @@ -216,6 +240,30 @@ Plugin::load() tv[i].tv_u.tv_set_extra_library_path = set_extra_library_path; ++i; + tv[i].tv_tag = LDPT_GET_INPUT_SECTION_COUNT; + tv[i].tv_u.tv_get_input_section_count = get_input_section_count; + + ++i; + tv[i].tv_tag = LDPT_GET_INPUT_SECTION_TYPE; + tv[i].tv_u.tv_get_input_section_type = get_input_section_type; + + ++i; + tv[i].tv_tag = LDPT_GET_INPUT_SECTION_NAME; + tv[i].tv_u.tv_get_input_section_name = get_input_section_name; + + ++i; + tv[i].tv_tag = LDPT_GET_INPUT_SECTION_CONTENTS; + tv[i].tv_u.tv_get_input_section_contents = get_input_section_contents; + + ++i; + tv[i].tv_tag = LDPT_UPDATE_SECTION_ORDER; + tv[i].tv_u.tv_update_section_order = update_section_order; + + ++i; + tv[i].tv_tag = LDPT_ALLOW_SECTION_ORDERING; + tv[i].tv_u.tv_allow_section_ordering = allow_section_ordering; + + ++i; tv[i].tv_tag = LDPT_NULL; tv[i].tv_u.tv_val = 0; @@ -326,8 +374,9 @@ Plugin_manager::~Plugin_manager() // Load all plugin libraries. void -Plugin_manager::load_plugins() +Plugin_manager::load_plugins(Layout* layout) { + this->layout_ = layout; for (this->current_ = this->plugins_.begin(); this->current_ != this->plugins_.end(); ++this->current_) @@ -338,7 +387,7 @@ Plugin_manager::load_plugins() Pluginobj* Plugin_manager::claim_file(Input_file* input_file, off_t offset, - off_t filesize) + off_t filesize, Object* elf_object) { if (this->in_replacement_phase_) return NULL; @@ -350,6 +399,9 @@ Plugin_manager::claim_file(Input_file* i this->plugin_input_file_.offset = offset; this->plugin_input_file_.filesize = filesize; this->plugin_input_file_.handle = reinterpret_cast(handle); + if (elf_object != NULL) + this->objects_.push_back(elf_object); + this->in_claim_file_handler_ = true; for (this->current_ = this->plugins_.begin(); this->current_ != this->plugins_.end(); @@ -358,9 +410,11 @@ Plugin_manager::claim_file(Input_file* i if ((*this->current_)->claim_file(&this->plugin_input_file_)) { this->any_claimed_ = true; + this->in_claim_file_handler_ = false; - if (this->objects_.size() > handle) - return this->objects_[handle]; + if (this->objects_.size() > handle + && this->objects_[handle]->pluginobj() != NULL) + return this->objects_[handle]->pluginobj(); // If the plugin claimed the file but did not call the // add_symbols callback, we need to create the Pluginobj now. @@ -369,6 +423,7 @@ Plugin_manager::claim_file(Input_file* i } } + this->in_claim_file_handler_ = false; return NULL; } @@ -402,7 +457,7 @@ Plugin_manager::save_input_group(Input_g void Plugin_manager::all_symbols_read(Workqueue* workqueue, Task* task, Input_objects* input_objects, - Symbol_table* symtab, Layout* layout, + Symbol_table* symtab, Dirsearch* dirpath, Mapfile* mapfile, Task_token** last_blocker) { @@ -411,7 +466,6 @@ Plugin_manager::all_symbols_read(Workque this->task_ = task; this->input_objects_ = input_objects; this->symtab_ = symtab; - this->layout_ = layout; this->dirpath_ = dirpath; this->mapfile_ = mapfile; this->this_blocker_ = NULL; @@ -599,12 +653,20 @@ Pluginobj* Plugin_manager::make_plugin_object(unsigned int handle) { // Make sure we aren't asked to make an object for the same handle twice. - if (this->objects_.size() != handle) + if (this->objects_.size() != handle + && this->objects_[handle]->pluginobj() != NULL) return NULL; Pluginobj* obj = make_sized_plugin_object(this->input_file_, this->plugin_input_file_.offset, this->plugin_input_file_.filesize); + + + // If the elf object for this file was pushed into the objects_ vector, delete + // it to make room for the Pluginobj as this file is claimed. + if (this->objects_.size() != handle) + this->objects_.pop_back(); + this->objects_.push_back(obj); return obj; } @@ -616,7 +678,7 @@ ld_plugin_status Plugin_manager::get_input_file(unsigned int handle, struct ld_plugin_input_file* file) { - Pluginobj* obj = this->object(handle); + Pluginobj* obj = this->object(handle)->pluginobj(); if (obj == NULL) return LDPS_BAD_HANDLE; @@ -634,7 +696,7 @@ Plugin_manager::get_input_file(unsigned ld_plugin_status Plugin_manager::release_input_file(unsigned int handle) { - Pluginobj* obj = this->object(handle); + Pluginobj* obj = this->object(handle)->pluginobj(); if (obj == NULL) return LDPS_BAD_HANDLE; @@ -642,6 +704,23 @@ Plugin_manager::release_input_file(unsig return LDPS_OK; } +// Get the elf object corresponding to the handle. Return NULL if we +// found a Pluginobj instead. + +Object* +Plugin_manager::get_elf_object(const void* handle) +{ + Object* obj = parameters->options().plugins()->object( + static_cast(reinterpret_cast(handle))); + + // The object should not be a Pluginobj. + if (obj == NULL + || obj->pluginobj() != NULL) + return NULL; + + return obj; +} + ld_plugin_status Plugin_manager::get_view(unsigned int handle, const void **viewp) { @@ -659,7 +738,7 @@ Plugin_manager::get_view(unsigned int ha else { // An already claimed file. - Pluginobj* obj = this->object(handle); + Pluginobj* obj = this->object(handle)->pluginobj(); if (obj == NULL) return LDPS_BAD_HANDLE; offset = obj->offset(); @@ -1226,7 +1305,6 @@ Plugin_hook::run(Workqueue* workqueue) this, this->input_objects_, this->symtab_, - this->layout_, this->dirpath_, this->mapfile_, &this->this_blocker_); @@ -1321,7 +1399,7 @@ get_symbols(const void* handle, int nsym { gold_assert(parameters->options().has_plugins()); Pluginobj* obj = parameters->options().plugins()->object( - static_cast(reinterpret_cast(handle))); + static_cast(reinterpret_cast(handle)))->pluginobj(); if (obj == NULL) return LDPS_ERR; return obj->get_symbol_resolution_info(nsyms, syms); @@ -1384,6 +1462,160 @@ message(int level, const char* format, . return LDPS_OK; } +// Get the section count of the object corresponding to the handle. This +// plugin interface can only be called in the claim_file handler of the plugin. + +static enum ld_plugin_status +get_input_section_count(const void* handle, unsigned int* count) +{ + gold_assert(parameters->options().has_plugins()); + + if (!parameters->options().plugins()->in_claim_file_handler()) + return LDPS_ERR; + + Object* obj = parameters->options().plugins()->get_elf_object(handle); + + if (obj == NULL) + return LDPS_ERR; + + *count = obj->shnum(); + return LDPS_OK; +} + +// Get the type of the specified section in the object corresponding +// to the handle. This plugin interface can only be called in the +// claim_file handler of the plugin. + +static enum ld_plugin_status +get_input_section_type(const struct ld_plugin_section section, + unsigned int* type) +{ + gold_assert(parameters->options().has_plugins()); + + if (!parameters->options().plugins()->in_claim_file_handler()) + return LDPS_ERR; + + Object* obj + = parameters->options().plugins()->get_elf_object(section.handle); + + if (obj == NULL) + return LDPS_BAD_HANDLE; + + *type = obj->section_type(section.shndx); + return LDPS_OK; +} + +// Get the name of the specified section in the object corresponding +// to the handle. This plugin interface can only be called in the +// claim_file handler of the plugin. + +static enum ld_plugin_status +get_input_section_name(const struct ld_plugin_section section, + char** section_name_ptr) +{ + gold_assert(parameters->options().has_plugins()); + + if (!parameters->options().plugins()->in_claim_file_handler()) + return LDPS_ERR; + + Object* obj + = parameters->options().plugins()->get_elf_object(section.handle); + + if (obj == NULL) + return LDPS_BAD_HANDLE; + + // Check if the object is locked before getting the section name. + gold_assert(obj->is_locked()); + + const std::string section_name = obj->section_name(section.shndx); + const char* section_name_c_ptr = section_name.c_str(); + *section_name_ptr + = static_cast(malloc(strlen(section_name_c_ptr) + 1)); + strcpy(*section_name_ptr, section_name_c_ptr); + return LDPS_OK; +} + +// Get the contents of the specified section in the object corresponding +// to the handle. This plugin interface can only be called in the +// claim_file handler of the plugin. + +static enum ld_plugin_status +get_input_section_contents(const struct ld_plugin_section section, + const unsigned char** section_contents_ptr, + size_t* len) +{ + gold_assert(parameters->options().has_plugins()); + + if (!parameters->options().plugins()->in_claim_file_handler()) + return LDPS_ERR; + + Object* obj + = parameters->options().plugins()->get_elf_object(section.handle); + + if (obj == NULL) + return LDPS_BAD_HANDLE; + + // Check if the object is locked before getting the section contents. + gold_assert(obj->is_locked()); + + section_size_type plen; + *section_contents_ptr + = obj->section_contents(section.shndx, &plen, false); + *len = plen; + return LDPS_OK; +} + +// Specify the ordering of sections in the final layout. The sections are +// specified as (handle,shndx) pairs in the two arrays in the order in +// which they should appear in the final layout. + +static enum ld_plugin_status +update_section_order(const struct ld_plugin_section *section_list, + unsigned int num_sections) +{ + gold_assert(parameters->options().has_plugins()); + + if (num_sections == 0) + return LDPS_OK; + + if (section_list == NULL) + return LDPS_ERR; + + std::map order_map; + + for (unsigned int i = 0; i < num_sections; ++i) + { + Object* obj = parameters->options().plugins()->get_elf_object( + section_list[i].handle); + if (obj == NULL) + return LDPS_BAD_HANDLE; + unsigned int shndx = section_list[i].shndx; + Section_id secn_id(obj, shndx); + order_map[secn_id] = i + 1; + } + + Layout* layout = parameters->options().plugins()->layout(); + gold_assert (layout != NULL); + + for (Layout::Section_list::const_iterator p = layout->section_list().begin(); + p != layout->section_list().end(); + ++p) + (*p)->update_section_layout(order_map); + + return LDPS_OK; +} + +// Let the linker know that the sections could be reordered. + +static enum ld_plugin_status +allow_section_ordering() +{ + gold_assert(parameters->options().has_plugins()); + Layout* layout = parameters->options().plugins()->layout(); + layout->set_section_ordering_specified(); + return LDPS_OK; +} + #endif // ENABLE_PLUGINS // Allocate a Pluginobj object of the appropriate size and endianness. Index: gold/plugin.h =================================================================== RCS file: /cvs/src/src/gold/plugin.h,v retrieving revision 1.19 diff -u -u -p -r1.19 plugin.h --- gold/plugin.h 12 Apr 2011 00:44:48 -0000 1.19 +++ gold/plugin.h 13 Jul 2011 01:32:38 -0000 @@ -131,6 +131,7 @@ class Plugin_manager : plugins_(), objects_(), deferred_layout_objects_(), input_file_(NULL), plugin_input_file_(), rescannable_(), undefined_symbols_(), any_claimed_(false), in_replacement_phase_(false), any_added_(false), + in_claim_file_handler_(false), options_(options), workqueue_(NULL), task_(NULL), input_objects_(NULL), symtab_(NULL), layout_(NULL), dirpath_(NULL), mapfile_(NULL), this_blocker_(NULL), extra_search_path_() @@ -153,11 +154,22 @@ class Plugin_manager // Load all plugin libraries. void - load_plugins(); + load_plugins(Layout* layout); // Call the plugin claim-file handlers in turn to see if any claim the file. Pluginobj* - claim_file(Input_file* input_file, off_t offset, off_t filesize); + claim_file(Input_file* input_file, off_t offset, off_t filesize, + Object* elf_object); + + // Get the object associated with the handle and check if it is an elf object. + // If it is not a Pluginobj, it is an elf object. + Object* + get_elf_object(const void* handle); + + // True if the claim_file handler of the plugins is being called. + bool + in_claim_file_handler() + { return in_claim_file_handler_; } // Let the plugin manager save an archive for later rescanning. // This takes ownership of the Archive pointer. @@ -173,7 +185,7 @@ class Plugin_manager void all_symbols_read(Workqueue* workqueue, Task* task, Input_objects* input_objects, Symbol_table* symtab, - Layout* layout, Dirsearch* dirpath, Mapfile* mapfile, + Dirsearch* dirpath, Mapfile* mapfile, Task_token** last_blocker); // Tell the plugin manager that we've a new undefined symbol which @@ -219,7 +231,7 @@ class Plugin_manager make_plugin_object(unsigned int handle); // Return the Pluginobj associated with the given HANDLE. - Pluginobj* + Object* object(unsigned int handle) const { if (handle >= this->objects_.size()) @@ -265,6 +277,14 @@ class Plugin_manager in_replacement_phase() const { return this->in_replacement_phase_; } + Input_objects* + input_objects() const + { return this->input_objects_; } + + Layout* + layout() + { return this->layout_; } + private: Plugin_manager(const Plugin_manager&); Plugin_manager& operator=(const Plugin_manager&); @@ -293,7 +313,7 @@ class Plugin_manager }; typedef std::list Plugin_list; - typedef std::vector Object_list; + typedef std::vector Object_list; typedef std::vector Deferred_layout_list; typedef std::vector Rescannable_list; typedef std::vector Undefined_symbol_list; @@ -340,6 +360,9 @@ class Plugin_manager // Whether any input files or libraries were added by a plugin. bool any_added_; + // Set to true when the claim_file handler of a plugin is called. + bool in_claim_file_handler_; + const General_options& options_; Workqueue* workqueue_; Task* task_; Index: gold/readsyms.cc =================================================================== RCS file: /cvs/src/src/gold/readsyms.cc,v retrieving revision 1.50 diff -u -u -p -r1.50 readsyms.cc --- gold/readsyms.cc 6 Jul 2011 22:07:59 -0000 1.50 +++ gold/readsyms.cc 13 Jul 2011 01:32:38 -0000 @@ -320,12 +320,33 @@ Read_symbols::do_read_symbols(Workqueue* } } + Object* elf_obj = NULL; + bool unconfigured; + bool* punconfigured = NULL; + if (is_elf) + { + // This is an ELF object. + + unconfigured = false; + punconfigured = (input_file->will_search_for() + ? &unconfigured + : NULL); + elf_obj = make_elf_object(input_file->filename(), + input_file, 0, ehdr, read_size, + punconfigured); + } + if (parameters->options().has_plugins()) { Pluginobj* obj = parameters->options().plugins()->claim_file(input_file, - 0, filesize); + 0, filesize, + elf_obj); if (obj != NULL) { + // Delete the elf_obj, this file has been claimed. + if (elf_obj != NULL) + delete elf_obj; + // The input file was claimed by a plugin, and its symbols // have been provided by the plugin. @@ -359,14 +380,7 @@ Read_symbols::do_read_symbols(Workqueue* { // This is an ELF object. - bool unconfigured = false; - bool* punconfigured = (input_file->will_search_for() - ? &unconfigured - : NULL); - Object* obj = make_elf_object(input_file->filename(), - input_file, 0, ehdr, read_size, - punconfigured); - if (obj == NULL) + if (elf_obj == NULL) { if (unconfigured) { @@ -382,7 +396,7 @@ Read_symbols::do_read_symbols(Workqueue* } Read_symbols_data* sd = new Read_symbols_data; - obj->read_symbols(sd); + elf_obj->read_symbols(sd); // Opening the file locked it, so now we need to unlock it. We // need to unlock it before queuing the Add_symbols task, @@ -397,7 +411,7 @@ Read_symbols::do_read_symbols(Workqueue* if (this->member_ != NULL) { this->member_->sd_ = sd; - this->member_->obj_ = obj; + this->member_->obj_ = elf_obj; this->member_->arg_serial_ = this->input_argument_->file().arg_serial(); return true; @@ -412,7 +426,7 @@ Read_symbols::do_read_symbols(Workqueue* this->dirindex_, this->mapfile_, this->input_argument_, - obj, + elf_obj, NULL, sd, this->this_blocker_, Index: gold/testsuite/plugin_test.c =================================================================== RCS file: /cvs/src/src/gold/testsuite/plugin_test.c,v retrieving revision 1.4 diff -u -u -p -r1.4 plugin_test.c --- gold/testsuite/plugin_test.c 9 Nov 2009 16:11:34 -0000 1.4 +++ gold/testsuite/plugin_test.c 13 Jul 2011 01:32:38 -0000 @@ -60,6 +60,12 @@ static ld_plugin_add_input_file add_inpu static ld_plugin_message message = NULL; static ld_plugin_get_input_file get_input_file = NULL; static ld_plugin_release_input_file release_input_file = NULL; +static ld_plugin_get_input_section_count get_input_section_count = NULL; +static ld_plugin_get_input_section_type get_input_section_type = NULL; +static ld_plugin_get_input_section_name get_input_section_name = NULL; +static ld_plugin_get_input_section_contents get_input_section_contents = NULL; +static ld_plugin_update_section_order update_section_order = NULL; +static ld_plugin_allow_section_ordering allow_section_ordering = NULL; #define MAXOPTS 10 @@ -126,6 +132,24 @@ onload(struct ld_plugin_tv *tv) case LDPT_RELEASE_INPUT_FILE: release_input_file = entry->tv_u.tv_release_input_file; break; + case LDPT_GET_INPUT_SECTION_COUNT: + get_input_section_count = *entry->tv_u.tv_get_input_section_count; + break; + case LDPT_GET_INPUT_SECTION_TYPE: + get_input_section_type = *entry->tv_u.tv_get_input_section_type; + break; + case LDPT_GET_INPUT_SECTION_NAME: + get_input_section_name = *entry->tv_u.tv_get_input_section_name; + break; + case LDPT_GET_INPUT_SECTION_CONTENTS: + get_input_section_contents = *entry->tv_u.tv_get_input_section_contents; + break; + case LDPT_UPDATE_SECTION_ORDER: + update_section_order = *entry->tv_u.tv_update_section_order; + break; + case LDPT_ALLOW_SECTION_ORDERING: + allow_section_ordering = *entry->tv_u.tv_allow_section_ordering; + break; default: break; } @@ -179,6 +203,42 @@ onload(struct ld_plugin_tv *tv) return LDPS_ERR; } + if (get_input_section_count == NULL) + { + fprintf(stderr, "tv_get_input_section_count interface missing\n"); + return LDPS_ERR; + } + + if (get_input_section_type == NULL) + { + fprintf(stderr, "tv_get_input_section_type interface missing\n"); + return LDPS_ERR; + } + + if (get_input_section_name == NULL) + { + fprintf(stderr, "tv_get_input_section_name interface missing\n"); + return LDPS_ERR; + } + + if (get_input_section_contents == NULL) + { + fprintf(stderr, "tv_get_input_section_contents interface missing\n"); + return LDPS_ERR; + } + + if (update_section_order == NULL) + { + fprintf(stderr, "tv_update_section_order interface missing\n"); + return LDPS_ERR; + } + + if (allow_section_ordering == NULL) + { + fprintf(stderr, "tv_allow_section_ordering interface missing\n"); + return LDPS_ERR; + } + return LDPS_OK; }