Plugin interfaces to do Pettis Hansen style code layout in the gold linker.
Sriraman Tallam
tmsriram@google.com
Mon Mar 14 18:45:00 GMT 2011
More information about the Binutils mailing list
Mon Mar 14 18:45:00 GMT 2011
- Previous message (by thread): Plugin interfaces to do Pettis Hansen style code layout in the gold linker.
- Next message (by thread): Plugin interfaces to do Pettis Hansen style code layout in the gold linker.
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi, I made all the changes. It is true that I always pass non-negative values as handles. The comment was a left-over from a previous implementation that I forgot to cleanup, sorry. I have attached the new patch with all the changes made. Thanks, -Sri. On Mon, Mar 14, 2011 at 11:22 AM, Cary Coutant <ccoutant@google.com> wrote: >> Like we discussed, I made all the changes. I now have a separate >> list of unclaimed objects in the Plugin manager and the handle will be >> an index into it. I have also added a new hook called >> "inspect_unclaimed_object". This handler allows the plugin to examine >> the contents of an unclaimed object. Now, I have disallowed examining >> claimed objects here as the methods to get their contents etc. are not >> defined in Pluginobj. Also, I have kept the original interfaces to get >> section count or type or contents. I think I would need this interface >> for my work rather than only get contents based on filters. I guess >> more interfaces can be added easily. > > Index: main.cc > =================================================================== > + const char* section_ordering_file > + = parameters->options().section_ordering_file(); > > We usually indent continuations like this by 4 spaces. > > > Index: plugin.cc > =================================================================== > +register_inspect_unclaimed_object(ld_plugin_inspect_unclaimed_object_handler > handler); > > Line too long. > > +Plugin_manager::get_unclaimed_object(const void* handle) > +{ > + unsigned int index = static_cast<unsigned > int>(reinterpret_cast<intptr_t>(handle)); > > Line too long. > > > +static enum ld_plugin_status > +register_inspect_unclaimed_object > + (ld_plugin_inspect_unclaimed_object_handler handler) > +{ > + gold_assert(parameters->options().has_plugins()); > + parameters->options().plugins()->set_inspect_unclaimed_object_handler( > + handler); > > Also indent here by 4 spaces. > > + const unsigned char* section_contents = obj->section_contents(shndx, &plen, > + false); > > I think the indentation here is not quite correct. > > > Index: plugin.h > =================================================================== > + // Register a inspect_unclaimed_object handler. > + void > + set_inspect_unclaimed_object_handler > + (ld_plugin_inspect_unclaimed_object_handler handler) > > The left paren should be at the end of the line above, and the > continuation line indented 4 spaces. > > + // Register a inspect_unclaimed_object handler. > + void > + set_inspect_unclaimed_object_handler > + (ld_plugin_inspect_unclaimed_object_handler handler) > > Same here. > > + // The list of unclaimed objects. The negative of the index of an > + // in this list serves as the "handle" that we pass to the plugins. > + // Postive integer values for "handle" are for the claimed objects > + // and negative values are for the unclaimed objects. > > It doesn't look like this is how you implemented it -- I think you're > returning straight non-negative indices in both cases. Also, remember > that 0 is used as a handle for the first claimed object, so it should > really be negative vs. "non-negative". > > This looks good to me with these changes. (You need Ian's approval to > commit, though.) > > Thanks! > > -cary > -------------- next part -------------- Index: layout.cc =================================================================== RCS file: /cvs/src/src/gold/layout.cc,v retrieving revision 1.190 diff -u -u -p -r1.190 layout.cc --- layout.cc 10 Jan 2011 21:57:31 -0000 1.190 +++ layout.cc 14 Mar 2011 18:40:50 -0000 @@ -207,7 +207,10 @@ Layout::Layout(int number_of_input_files record_output_section_data_from_script_(false), script_output_section_data_list_(), segment_states_(NULL), - relaxation_debug_check_(NULL) + relaxation_debug_check_(NULL), + section_ordering_specified_(false), + input_section_position_(), + input_section_glob_() { // Make space for more than enough segments for a typical file. // This is just for efficiency--it's OK if we wind up needing more. @@ -1817,13 +1820,28 @@ Layout::find_section_order_index(const s return 0; } +// Updates the input section order of all output sections. This +// is called when the section order is specified via plugins. + +void +Layout::update_layout_of_sections() +{ + for (Section_list::iterator p = this->section_list_.begin(); + p != this->section_list_.end(); + ++p) + { + if ((*p) == NULL) + continue; + (*p)->update_section_layout(this); + } +} + // Read the sequence of input sections from the file specified with -// --section-ordering-file. +// linker option --section-ordering-file. void -Layout::read_layout_from_file() +Layout::read_layout_from_file(const char* filename) { - const char* filename = parameters->options().section_ordering_file(); std::ifstream in; std::string line; @@ -1834,6 +1852,7 @@ Layout::read_layout_from_file() std::getline(in, line); // this chops off the trailing \n, if any unsigned int position = 1; + this->section_ordering_specified(); while (in) { Index: layout.h =================================================================== RCS file: /cvs/src/src/gold/layout.h,v retrieving revision 1.88 diff -u -u -p -r1.88 layout.h --- layout.h 14 Dec 2010 19:03:30 -0000 1.88 +++ layout.h 14 Mar 2011 18:40:50 -0000 @@ -414,11 +414,25 @@ class Layout const char* name, const elfcpp::Shdr<size, big_endian>& shdr, unsigned int reloc_shndx, unsigned int reloc_type, off_t* offset); + bool + is_section_ordering_specified() + { return section_ordering_specified_; } + + void + section_ordering_specified() + { section_ordering_specified_ = true; } + 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(const char* filename); + + // Updates the order of input sections in the output sections. void - read_layout_from_file(); + update_layout_of_sections(); // Layout an input reloc section when doing a relocatable link. The // section is RELOC_SHNDX in OBJECT, with data in SHDR. @@ -1147,6 +1161,9 @@ class Layout Segment_states* segment_states_; // A relaxation debug checker. We only create one when in debugging mode. Relaxation_debug_check* relaxation_debug_check_; + // True if the input sections in the output sections should be sorted + // as specified in a section ordering file. + bool section_ordering_specified_; // Hash a pattern to its position in the section ordering file. Unordered_map<std::string, unsigned int> input_section_position_; // Vector of glob only patterns in the section_ordering file. Index: main.cc =================================================================== RCS file: /cvs/src/src/gold/main.cc,v retrieving revision 1.42 diff -u -u -p -r1.42 main.cc --- main.cc 14 Dec 2010 19:03:30 -0000 1.42 +++ main.cc 14 Mar 2011 18:40:50 -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()); @@ -231,8 +227,15 @@ main(int argc, char** argv) if (layout.incremental_inputs() != NULL) layout.incremental_inputs()->report_command_line(argc, 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); + + const char* section_ordering_file + = parameters->options().section_ordering_file(); + + if (section_ordering_file) + layout.read_layout_from_file(section_ordering_file); // Get the search path from the -L options. Dirsearch search_path; Index: output.cc =================================================================== RCS file: /cvs/src/src/gold/output.cc,v retrieving revision 1.140 diff -u -u -p -r1.140 output.cc --- output.cc 12 Feb 2011 03:19:24 -0000 1.140 +++ output.cc 14 Mar 2011 18:40:50 -0000 @@ -2165,10 +2165,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)); @@ -3041,6 +3041,34 @@ Output_section::Input_section_sort_secti return s1_secn_index < s2_secn_index; } +// Updates the ordering of input sections in this output section. + +void +Output_section::update_section_layout(Layout* layout) +{ + 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()); + + std::string section_name = obj->section_name((*p).shndx()); + unsigned int section_order_index = + layout->find_section_order_index(section_name); + 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 @@ -3083,7 +3111,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: output.h =================================================================== RCS file: /cvs/src/src/gold/output.h,v retrieving revision 1.118 diff -u -u -p -r1.118 output.h --- output.h 23 Dec 2010 19:56:14 -0000 1.118 +++ output.h 14 Mar 2011 18:40:50 -0000 @@ -2564,6 +2564,9 @@ class Output_section : public Output_dat flags() const { return this->flags_; } + void + update_section_layout(Layout* layout); + // Update the output section flags based on input section flags. void update_flags_for_input_section(elfcpp::Elf_Xword flags); Index: plugin.cc =================================================================== RCS file: /cvs/src/src/gold/plugin.cc,v retrieving revision 1.43 diff -u -u -p -r1.43 plugin.cc --- plugin.cc 8 Feb 2011 05:03:19 -0000 1.43 +++ plugin.cc 14 Mar 2011 18:40:50 -0000 @@ -57,6 +57,10 @@ static enum ld_plugin_status register_claim_file(ld_plugin_claim_file_handler handler); static enum ld_plugin_status +register_inspect_unclaimed_object( + ld_plugin_inspect_unclaimed_object_handler handler); + +static enum ld_plugin_status register_all_symbols_read(ld_plugin_all_symbols_read_handler handler); static enum ld_plugin_status @@ -86,6 +90,28 @@ set_extra_library_path(const char *path) static enum ld_plugin_status message(int level, const char *format, ...); +static enum ld_plugin_status +get_section_count(const void* handle, unsigned int* count); + +static enum ld_plugin_status +get_section_type(void* handle, unsigned int shndx, + unsigned int* type); + +static enum ld_plugin_status +get_section_name(void* handle, unsigned int shndx, + char** section_name_ptr); + +static enum ld_plugin_status +get_section_contents(void* handle, unsigned int shndx, + unsigned char** section_contents, + unsigned int* len); + +static enum ld_plugin_status +read_layout_from_file(const char* filename); + +static enum ld_plugin_status +allow_section_ordering(); + }; #endif // ENABLE_PLUGINS @@ -130,7 +156,7 @@ Plugin::load() sscanf(ver, "%d.%d", &major, &minor); // Allocate and populate a transfer vector. - const int tv_fixed_size = 16; + 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]; @@ -173,6 +199,11 @@ Plugin::load() tv[i].tv_u.tv_register_claim_file = register_claim_file; ++i; + tv[i].tv_tag = LDPT_REGISTER_INSPECT_UNCLAIMED_OBJECT_HOOK; + tv[i].tv_u.tv_register_inspect_unclaimed_object + = register_inspect_unclaimed_object; + + ++i; tv[i].tv_tag = LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK; tv[i].tv_u.tv_register_all_symbols_read = register_all_symbols_read; @@ -209,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_SECTION_COUNT; + tv[i].tv_u.tv_get_section_count = get_section_count; + + ++i; + tv[i].tv_tag = LDPT_GET_SECTION_TYPE; + tv[i].tv_u.tv_get_section_type = get_section_type; + + ++i; + tv[i].tv_tag = LDPT_GET_SECTION_NAME; + tv[i].tv_u.tv_get_section_name = get_section_name; + + ++i; + tv[i].tv_tag = LDPT_GET_SECTION_CONTENTS; + tv[i].tv_u.tv_get_section_contents = get_section_contents; + + ++i; + tv[i].tv_tag = LDPT_READ_LAYOUT_FROM_FILE; + tv[i].tv_u.tv_read_layout_from_file = read_layout_from_file; + + ++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; @@ -237,6 +292,16 @@ Plugin::claim_file(struct ld_plugin_inpu return false; } +// Call the plugin inspect_unclaimed_object handler. + +inline void +Plugin::inspect_unclaimed_object(unsigned int index) +{ + void* handle = reinterpret_cast<void*>(index); + if (this->inspect_unclaimed_object_handler_ != NULL) + (*this->inspect_unclaimed_object_handler_)(handle); +} + // Call the all-symbols-read handler. inline void @@ -319,8 +384,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_) @@ -365,6 +431,27 @@ Plugin_manager::claim_file(Input_file* i return NULL; } +// Call the plugin inspect_unclaimed_object handlers to allow them to inspect +// the unclaimed object. Pass the handle of the object which is the index +// into the vector containing the unclaimed objects. + +void +Plugin_manager::inspect_unclaimed_object(Object* obj) +{ + unsigned int index; + index = this->unclaimed_objects_.size(); + this->unclaimed_objects_.push_back(obj); + + this->in_inspect_unclaimed_object_handler_ = true; + + for (this->current_ = this->plugins_.begin(); + this->current_ != this->plugins_.end(); + ++this->current_) + (*this->current_)->inspect_unclaimed_object(index); + + this->in_inspect_unclaimed_object_handler_ = false; +} + // Save an archive. This is used so that a plugin can add a file // which refers to a symbol which was not previously referenced. In // that case we want to pretend that the symbol was referenced before, @@ -395,7 +482,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) { @@ -404,7 +491,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; @@ -635,6 +721,21 @@ Plugin_manager::release_input_file(unsig return LDPS_OK; } +// Get the object from the list of unclaimed objects with +// index specified in handle. + +Object* +Plugin_manager::get_unclaimed_object(const void* handle) +{ + unsigned int index + = static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle)); + Object* obj = NULL; + + obj = parameters->options().plugins()->unclaimed_object(index); + + return obj; +} + // Add a new library path. ld_plugin_status @@ -1168,7 +1269,6 @@ Plugin_hook::run(Workqueue* workqueue) this, this->input_objects_, this->symtab_, - this->layout_, this->dirpath_, this->mapfile_, &this->this_blocker_); @@ -1190,6 +1290,18 @@ register_claim_file(ld_plugin_claim_file return LDPS_OK; } +//Register a inspect_unclaimed_object handler. + +static enum ld_plugin_status +register_inspect_unclaimed_object + (ld_plugin_inspect_unclaimed_object_handler handler) +{ + gold_assert(parameters->options().has_plugins()); + parameters->options().plugins()->set_inspect_unclaimed_object_handler( + handler); + return LDPS_OK; +} + // Register an all-symbols-read handler. static enum ld_plugin_status @@ -1317,6 +1429,123 @@ 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 inspect_unclaimed_object +// handler of the plugin. + +static enum ld_plugin_status +get_section_count(const void* handle, unsigned int* count) +{ + gold_assert(parameters->options().has_plugins()); + + if (!parameters->options().plugins()->in_inspect_unclaimed_object_handler()) + return LDPS_ERR; + + Object* obj = parameters->options().plugins()->get_unclaimed_object(handle); + + if (obj == NULL) + return LDPS_BAD_HANDLE; + + *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 +// inspect_unclaimed_object handler of the plugin. + +static enum ld_plugin_status +get_section_type(void* handle, unsigned int shndx, unsigned int* type) +{ + gold_assert(parameters->options().has_plugins()); + + if (!parameters->options().plugins()->in_inspect_unclaimed_object_handler()) + return LDPS_ERR; + + Object* obj = parameters->options().plugins()->get_unclaimed_object(handle); + + if (obj == NULL) + return LDPS_BAD_HANDLE; + + *type = obj->section_type(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 +// inspect_unclaimed_object handler of the plugin. + +static enum ld_plugin_status +get_section_name(void* handle, unsigned int shndx, char** section_name_ptr) +{ + gold_assert(parameters->options().has_plugins()); + + if (!parameters->options().plugins()->in_inspect_unclaimed_object_handler()) + return LDPS_ERR; + + Object* obj = parameters->options().plugins()->get_unclaimed_object(handle); + + if (obj == NULL) + return LDPS_BAD_HANDLE; + + const char* section_name = obj->section_name(shndx).c_str(); + *section_name_ptr = (char*)malloc(strlen(section_name) + 1); + strcpy(*section_name_ptr, section_name); + 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 +// inspect_unclaimed_object handler of the plugin. + +static enum ld_plugin_status +get_section_contents(void* handle, unsigned int shndx, + unsigned char** section_contents_ptr, + unsigned int* len) +{ + gold_assert(parameters->options().has_plugins()); + + if (!parameters->options().plugins()->in_inspect_unclaimed_object_handler()) + return LDPS_ERR; + + Object* obj = parameters->options().plugins()->get_unclaimed_object(handle); + + if (obj == NULL) + return LDPS_BAD_HANDLE; + + section_size_type plen; + const unsigned char* section_contents = obj->section_contents(shndx, &plen, + false); + *section_contents_ptr = (unsigned char*)malloc(plen); + memcpy(*section_contents_ptr, section_contents, plen); + *len = plen; + return LDPS_OK; +} + +// Specify the ordering of sections in the final layout in a file. This +// does what the linker option --section-ordering-file does. + +static enum ld_plugin_status +read_layout_from_file(const char* filename) +{ + gold_assert(parameters->options().has_plugins()); + Layout* layout = parameters->options().plugins()->layout(); + layout->read_layout_from_file(filename); + layout->update_layout_of_sections(); + 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->section_ordering_specified(); + return LDPS_OK; +} + #endif // ENABLE_PLUGINS // Allocate a Pluginobj object of the appropriate size and endianness. Index: plugin.h =================================================================== RCS file: /cvs/src/src/gold/plugin.h,v retrieving revision 1.16 diff -u -u -p -r1.16 plugin.h --- plugin.h 24 Jan 2011 21:48:40 -0000 1.16 +++ plugin.h 14 Mar 2011 18:40:51 -0000 @@ -58,6 +58,7 @@ class Plugin filename_(filename), args_(), claim_file_handler_(NULL), + inspect_unclaimed_object_handler_(NULL), all_symbols_read_handler_(NULL), cleanup_handler_(NULL), cleanup_done_(false) @@ -74,6 +75,10 @@ class Plugin bool claim_file(struct ld_plugin_input_file* plugin_input_file); + // Call the inspect_unclaimed_object handler. + void + inspect_unclaimed_object(unsigned int index); + // Call the all-symbols-read handler. void all_symbols_read(); @@ -87,6 +92,12 @@ class Plugin set_claim_file_handler(ld_plugin_claim_file_handler handler) { this->claim_file_handler_ = handler; } + // Register a inspect_unclaimed_object handler. + void + set_inspect_unclaimed_object_handler( + ld_plugin_inspect_unclaimed_object_handler handler) + { this->inspect_unclaimed_object_handler_ = handler; } + // Register an all-symbols-read handler. void set_all_symbols_read_handler(ld_plugin_all_symbols_read_handler handler) @@ -116,6 +127,7 @@ class Plugin std::vector<std::string> args_; // The plugin's event handlers. ld_plugin_claim_file_handler claim_file_handler_; + ld_plugin_inspect_unclaimed_object_handler inspect_unclaimed_object_handler_; ld_plugin_all_symbols_read_handler all_symbols_read_handler_; ld_plugin_cleanup_handler cleanup_handler_; // TRUE if the cleanup handlers have been called. @@ -128,9 +140,11 @@ class Plugin_manager { public: Plugin_manager(const General_options& options) - : plugins_(), objects_(), deferred_layout_objects_(), input_file_(NULL), + : plugins_(), objects_(), unclaimed_objects_(), + deferred_layout_objects_(), input_file_(NULL), plugin_input_file_(), rescannable_(), undefined_symbols_(), any_claimed_(false), in_replacement_phase_(false), any_added_(false), + in_inspect_unclaimed_object_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,12 +167,26 @@ 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); + // Call the plugin inspect_unclaimed_object handlers to allow them + // to inspect the file. + void + inspect_unclaimed_object(Object* obj); + + Object* + get_unclaimed_object(const void* handle); + + // True if the inspect_unclaimed_object handler of the plugins are being + // called. + bool + in_inspect_unclaimed_object_handler() + { return in_inspect_unclaimed_object_handler_; } + // Let the plugin manager save an archive for later rescanning. // This takes ownership of the Archive pointer. void @@ -173,7 +201,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 @@ -197,6 +225,15 @@ class Plugin_manager (*this->current_)->set_claim_file_handler(handler); } + // Register a inspect_unclaimed_object handler. + void + set_inspect_unclaimed_object_handler( + ld_plugin_inspect_unclaimed_object_handler handler) + { + gold_assert(this->current_ != plugins_.end()); + (*this->current_)->set_inspect_unclaimed_object_handler(handler); + } + // Register an all-symbols-read handler. void set_all_symbols_read_handler(ld_plugin_all_symbols_read_handler handler) @@ -227,6 +264,15 @@ class Plugin_manager return this->objects_[handle]; } + // Return the unclaimed object associated with the given HANDLE. + Object* + unclaimed_object(unsigned int handle) const + { + if (handle >= this->unclaimed_objects_.size()) + return NULL; + return this->unclaimed_objects_[handle]; + } + // Return TRUE if any input files have been claimed by a plugin // and we are still in the initial input phase. bool @@ -262,6 +308,14 @@ class Plugin_manager in_replacement_phase() const { return this->in_replacement_phase_; } + Input_objects* + input_objects() const + { return input_objects_; } + + Layout* + layout() + { return layout_; } + private: Plugin_manager(const Plugin_manager&); Plugin_manager& operator=(const Plugin_manager&); @@ -291,6 +345,7 @@ class Plugin_manager typedef std::list<Plugin*> Plugin_list; typedef std::vector<Pluginobj*> Object_list; + typedef std::vector<Object*> Unclaimed_object_list; typedef std::vector<Relobj*> Deferred_layout_list; typedef std::vector<Rescannable> Rescannable_list; typedef std::vector<Symbol*> Undefined_symbol_list; @@ -312,6 +367,11 @@ class Plugin_manager // serves as the "handle" that we pass to the plugins. Object_list objects_; + // The list of unclaimed objects. The the index of an item in this + // in this list serves as the "handle" that we pass to the plugins + // in inspect_unclaimed_object_handler. + Unclaimed_object_list unclaimed_objects_; + // The list of regular objects whose layout has been deferred. Deferred_layout_list deferred_layout_objects_; @@ -337,6 +397,10 @@ class Plugin_manager // Whether any input files or libraries were added by a plugin. bool any_added_; + // Set to true when the inspect_unclaimed_object_handler of the plugins are being + // called. + bool in_inspect_unclaimed_object_handler_; + const General_options& options_; Workqueue* workqueue_; Task* task_; Index: readsyms.cc =================================================================== RCS file: /cvs/src/src/gold/readsyms.cc,v retrieving revision 1.47 diff -u -u -p -r1.47 readsyms.cc --- readsyms.cc 24 Jan 2011 21:48:40 -0000 1.47 +++ readsyms.cc 14 Mar 2011 18:40:51 -0000 @@ -380,6 +380,10 @@ Read_symbols::do_read_symbols(Workqueue* return false; } + // Allow the plugins to inspect the unclaimed object now. + if (parameters->options().has_plugins()) + parameters->options().plugins()->inspect_unclaimed_object(obj); + Read_symbols_data* sd = new Read_symbols_data; obj->read_symbols(sd); cvs diff: Diffing po cvs diff: Diffing testsuite Index: 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 --- testsuite/plugin_test.c 9 Nov 2009 16:11:34 -0000 1.4 +++ testsuite/plugin_test.c 14 Mar 2011 18:40:51 -0000 @@ -52,6 +52,8 @@ static struct claimed_file* first_claime static struct claimed_file* last_claimed_file = NULL; static ld_plugin_register_claim_file register_claim_file_hook = NULL; +static ld_plugin_register_inspect_unclaimed_object + register_inspect_unclaimed_object_hook = NULL; static ld_plugin_register_all_symbols_read register_all_symbols_read_hook = NULL; static ld_plugin_register_cleanup register_cleanup_hook = NULL; static ld_plugin_add_symbols add_symbols = NULL; @@ -60,6 +62,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_section_count get_section_count = NULL; +static ld_plugin_get_section_type get_section_type = NULL; +static ld_plugin_get_section_name get_section_name = NULL; +static ld_plugin_get_section_contents get_section_contents = NULL; +static ld_plugin_read_layout_from_file read_layout_from_file = NULL; +static ld_plugin_allow_section_ordering allow_section_ordering = NULL; #define MAXOPTS 10 @@ -69,6 +77,7 @@ static int nopts = 0; enum ld_plugin_status onload(struct ld_plugin_tv *tv); enum ld_plugin_status claim_file_hook(const struct ld_plugin_input_file *file, int *claimed); +enum ld_plugin_status inspect_unclaimed_object_hook(void* handle); enum ld_plugin_status all_symbols_read_hook(void); enum ld_plugin_status cleanup_hook(void); @@ -101,6 +110,10 @@ onload(struct ld_plugin_tv *tv) case LDPT_REGISTER_CLAIM_FILE_HOOK: register_claim_file_hook = entry->tv_u.tv_register_claim_file; break; + case LDPT_REGISTER_INSPECT_UNCLAIMED_OBJECT_HOOK: + register_inspect_unclaimed_object_hook + = entry->tv_u.tv_register_inspect_unclaimed_object; + break; case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK: register_all_symbols_read_hook = entry->tv_u.tv_register_all_symbols_read; @@ -126,6 +139,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_SECTION_COUNT: + get_section_count = *entry->tv_u.tv_get_section_count; + break; + case LDPT_GET_SECTION_TYPE: + get_section_type = *entry->tv_u.tv_get_section_type; + break; + case LDPT_GET_SECTION_NAME: + get_section_name = *entry->tv_u.tv_get_section_name; + break; + case LDPT_GET_SECTION_CONTENTS: + get_section_contents = *entry->tv_u.tv_get_section_contents; + break; + case LDPT_READ_LAYOUT_FROM_FILE: + read_layout_from_file = *entry->tv_u.tv_read_layout_from_file; + break; + case LDPT_ALLOW_SECTION_ORDERING: + allow_section_ordering = *entry->tv_u.tv_allow_section_ordering; + break; default: break; } @@ -143,6 +174,13 @@ onload(struct ld_plugin_tv *tv) return LDPS_ERR; } + if (register_inspect_unclaimed_object_hook == NULL) + { + fprintf(stderr, + "tv_register_inspect_unclaimed_object_hook interface missing\n"); + return LDPS_ERR; + } + if (register_all_symbols_read_hook == NULL) { fprintf(stderr, "tv_register_all_symbols_read_hook interface missing\n"); @@ -167,6 +205,14 @@ onload(struct ld_plugin_tv *tv) return LDPS_ERR; } + if ((*register_inspect_unclaimed_object_hook) + (inspect_unclaimed_object_hook) != LDPS_OK) + { + (*message)(LDPL_ERROR, + "error registering inspect unclaimed object hook"); + return LDPS_ERR; + } + if ((*register_all_symbols_read_hook)(all_symbols_read_hook) != LDPS_OK) { (*message)(LDPL_ERROR, "error registering all symbols read hook"); @@ -179,10 +225,53 @@ onload(struct ld_plugin_tv *tv) return LDPS_ERR; } + if (get_section_count == NULL) + { + fprintf(stderr, "tv_get_section_count interface missing\n"); + return LDPS_ERR; + } + + if (get_section_type == NULL) + { + fprintf(stderr, "tv_get_section_type interface missing\n"); + return LDPS_ERR; + } + + if (get_section_name == NULL) + { + fprintf(stderr, "tv_get_section_name interface missing\n"); + return LDPS_ERR; + } + + if (get_section_contents == NULL) + { + fprintf(stderr, "tv_get_section_contents interface missing\n"); + return LDPS_ERR; + } + + if (read_layout_from_file == NULL) + { + fprintf(stderr, "tv_read_layout_from_file 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; } enum ld_plugin_status +inspect_unclaimed_object_hook (void* handle) +{ + (*message)(LDPL_INFO, "Inspect unclaimed object hook called with handle: %p", + handle); + return LDPS_OK; +} +enum ld_plugin_status claim_file_hook (const struct ld_plugin_input_file* file, int* claimed) { int len; Index: plugin-api.h =================================================================== RCS file: /cvs/src/src/include/plugin-api.h,v retrieving revision 1.13 diff -u -u -p -r1.13 plugin-api.h --- plugin-api.h 3 Jan 2011 21:05:50 -0000 1.13 +++ plugin-api.h 13 Mar 2011 02:24:32 -0000 @@ -157,6 +157,12 @@ enum ld_plugin_status (*ld_plugin_claim_file_handler) ( const struct ld_plugin_input_file *file, int *claimed); +/* The plugin library's "observe file" handler. */ + +typedef +enum ld_plugin_status +(*ld_plugin_inspect_unclaimed_object_handler) (void *); + /* The plugin library's "all symbols read" handler. */ typedef @@ -175,6 +181,13 @@ typedef enum ld_plugin_status (*ld_plugin_register_claim_file) (ld_plugin_claim_file_handler handler); +/* The linker's interface for registering the "observe file" handler. */ + +typedef +enum ld_plugin_status +(*ld_plugin_register_inspect_unclaimed_object) + (ld_plugin_inspect_unclaimed_object_handler handler); + /* The linker's interface for registering the "all symbols read" handler. */ typedef @@ -240,6 +253,59 @@ 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 inspect_unclaimed_object_handler. This + interface should only be invoked in the inspect_unclaimed_object_handler. */ + +typedef +enum ld_plugin_status +(*ld_plugin_get_section_count) (const void* handle, unsigned int* count); + +/* The linker's interface for retrieving the section type of a specific + section in an object. The handle is obtained in the + inspect_unclaimed_object_handler. This interface should only be + invoked in the inspect_unclaimed_object_handler. */ + +typedef +enum ld_plugin_status +(*ld_plugin_get_section_type) (void* handle, unsigned int shndx, + unsigned int* type); + +/* The linker's interface for retrieving the name of specific section in + an object. The handle is obtained in the inspect_unclaimed_object_handler. + This interface should only be invoked in the + inspect_unclaimed_object_handler. */ + +typedef +enum ld_plugin_status +(*ld_plugin_get_section_name) (void* handle, unsigned int shndx, + char** section_name_ptr); + +/* The linker's interface for retrieving the contents of a specific section + in an object. The handle is obtained in the + inspect_unclaimed_object_handler. This interface should only be invoked + in the inspect_unclaimed_object_handler. */ + +typedef +enum ld_plugin_status +(*ld_plugin_get_section_contents) (void* handle, unsigned int shndx, + unsigned char** section_contents, + unsigned int* len); + +/* The linker's interface for specifying the desired order of sections + through a file. */ + +typedef +enum ld_plugin_status +(*ld_plugin_read_layout_from_file) (const char* filename); + +/* The linker's interface for specifying that reordering of sections is + desired. */ + +typedef +enum ld_plugin_status +(*ld_plugin_allow_section_ordering) (void); + enum ld_plugin_level { LDPL_INFO, @@ -258,6 +324,7 @@ enum ld_plugin_tag LDPT_LINKER_OUTPUT, LDPT_OPTION, LDPT_REGISTER_CLAIM_FILE_HOOK, + LDPT_REGISTER_INSPECT_UNCLAIMED_OBJECT_HOOK, LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK, LDPT_REGISTER_CLEANUP_HOOK, LDPT_ADD_SYMBOLS, @@ -269,7 +336,13 @@ enum ld_plugin_tag LDPT_ADD_INPUT_LIBRARY, LDPT_OUTPUT_NAME, LDPT_SET_EXTRA_LIBRARY_PATH, - LDPT_GNU_LD_VERSION + LDPT_GNU_LD_VERSION, + LDPT_GET_SECTION_COUNT, + LDPT_GET_SECTION_TYPE, + LDPT_GET_SECTION_NAME, + LDPT_GET_SECTION_CONTENTS, + LDPT_READ_LAYOUT_FROM_FILE, + LDPT_ALLOW_SECTION_ORDERING }; /* The plugin transfer vector. */ @@ -282,6 +355,8 @@ struct ld_plugin_tv int tv_val; const char *tv_string; ld_plugin_register_claim_file tv_register_claim_file; + ld_plugin_register_inspect_unclaimed_object + tv_register_inspect_unclaimed_object; ld_plugin_register_all_symbols_read tv_register_all_symbols_read; ld_plugin_register_cleanup tv_register_cleanup; ld_plugin_add_symbols tv_add_symbols; @@ -292,6 +367,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_section_count tv_get_section_count; + ld_plugin_get_section_type tv_get_section_type; + ld_plugin_get_section_name tv_get_section_name; + ld_plugin_get_section_contents tv_get_section_contents; + ld_plugin_read_layout_from_file tv_read_layout_from_file; + ld_plugin_allow_section_ordering tv_allow_section_ordering; } tv_u; };
- Previous message (by thread): Plugin interfaces to do Pettis Hansen style code layout in the gold linker.
- Next message (by thread): Plugin interfaces to do Pettis Hansen style code layout in the gold linker.
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list