X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=gold%2Fplugin.h;h=d2b9f228f76ffa57790cd11ceb7a27bcc6d7d961;hb=15a7492a25589fe5721322b73f05a4eeb8899a6f;hp=47e634e7a12cdd740be8675ade7ef37ae5dad2e7;hpb=88a4108bde4d02cccd632048b45458e84bc8b40b;p=external%2Fbinutils.git diff --git a/gold/plugin.h b/gold/plugin.h index 47e634e..d2b9f22 100644 --- a/gold/plugin.h +++ b/gold/plugin.h @@ -1,6 +1,6 @@ // plugin.h -- plugin manager for gold -*- C++ -*- -// Copyright 2008, 2009, 2010 Free Software Foundation, Inc. +// Copyright (C) 2008-2019 Free Software Foundation, Inc. // Written by Cary Coutant . // This file is part of gold. @@ -36,12 +36,18 @@ namespace gold class General_options; class Input_file; class Input_objects; +class Archive; +class Input_group; +class Symbol; class Symbol_table; class Layout; class Dirsearch; class Mapfile; +class Task; class Task_token; class Pluginobj; +class Plugin_rescan; +class Plugin_recorder; // This class represents a single plugin library. @@ -55,6 +61,7 @@ class Plugin claim_file_handler_(NULL), all_symbols_read_handler_(NULL), cleanup_handler_(NULL), + new_input_handler_(NULL), cleanup_done_(false) { } @@ -67,12 +74,16 @@ class Plugin // Call the claim-file handler. bool - claim_file(struct ld_plugin_input_file *plugin_input_file); + claim_file(struct ld_plugin_input_file* plugin_input_file); // Call the all-symbols-read handler. void all_symbols_read(); + // Call the new_input handler. + void + new_input(struct ld_plugin_input_file* plugin_input_file); + // Call the cleanup handler. void cleanup(); @@ -92,13 +103,22 @@ class Plugin set_cleanup_handler(ld_plugin_cleanup_handler handler) { this->cleanup_handler_ = handler; } + // Register a new_input handler. + void + set_new_input_handler(ld_plugin_new_input_handler handler) + { this->new_input_handler_ = handler; } + // Add an argument void - add_option(const char *arg) + add_option(const char* arg) { this->args_.push_back(arg); } + const std::string& + filename() const + { return this->filename_; } + private: Plugin(const Plugin&); Plugin& operator=(const Plugin&); @@ -113,6 +133,7 @@ class Plugin ld_plugin_claim_file_handler claim_file_handler_; ld_plugin_all_symbols_read_handler all_symbols_read_handler_; ld_plugin_cleanup_handler cleanup_handler_; + ld_plugin_new_input_handler new_input_handler_; // TRUE if the cleanup handlers have been called. bool cleanup_done_; }; @@ -124,14 +145,25 @@ class Plugin_manager public: Plugin_manager(const General_options& options) : plugins_(), objects_(), deferred_layout_objects_(), input_file_(NULL), - plugin_input_file_(), in_replacement_phase_(false), + 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_() + this_blocker_(NULL), extra_search_path_(), lock_(NULL), + initialize_lock_(&lock_), defsym_defines_set_(), + recorder_(NULL) { this->current_ = plugins_.end(); } ~Plugin_manager(); + // Returns true if the symbol name is used in the LHS of a defsym. + bool + is_defsym_def(const char* sym_name) const + { + return defsym_defines_set_.find(sym_name) != defsym_defines_set_.end(); + } + // Add a plugin library. void add_plugin(const char* filename) @@ -147,19 +179,45 @@ 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. + void + save_archive(Archive*); + + // Let the plugin manager save an input group for later rescanning. + // This takes ownership of the Input_group pointer. + void + save_input_group(Input_group*); // Call the all-symbols-read handlers. 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 + // may require rescanning. + void + new_undefined_symbol(Symbol*); + // Run deferred layout. void layout_deferred_objects(); @@ -184,6 +242,14 @@ class Plugin_manager (*this->current_)->set_all_symbols_read_handler(handler); } + // Register a new_input handler. + void + set_new_input_handler(ld_plugin_new_input_handler handler) + { + gold_assert(this->current_ != plugins_.end()); + (*this->current_)->set_new_input_handler(handler); + } + // Register a claim-file handler. void set_cleanup_handler(ld_plugin_cleanup_handler handler) @@ -197,8 +263,8 @@ class Plugin_manager Pluginobj* make_plugin_object(unsigned int handle); - // Return the Pluginobj associated with the given HANDLE. - Pluginobj* + // Return the object associated with the given HANDLE. + Object* object(unsigned int handle) const { if (handle >= this->objects_.size()) @@ -210,7 +276,7 @@ class Plugin_manager // and we are still in the initial input phase. bool should_defer_layout() const - { return !this->objects_.empty() && !this->in_replacement_phase_; } + { return this->any_claimed_ && !this->in_replacement_phase_; } // Add a regular object to the deferred layout list. These are // objects whose layout has been deferred until after the @@ -222,7 +288,10 @@ class Plugin_manager // Get input file information with an open (possibly re-opened) // file descriptor. ld_plugin_status - get_input_file(unsigned int handle, struct ld_plugin_input_file *file); + get_input_file(unsigned int handle, struct ld_plugin_input_file* file); + + ld_plugin_status + get_view(unsigned int handle, const void **viewp); // Release an input file. ld_plugin_status @@ -230,24 +299,73 @@ class Plugin_manager // Add a new input file. ld_plugin_status - add_input_file(const char *pathname, bool is_lib); + add_input_file(const char* pathname, bool is_lib); // Set the extra library path. ld_plugin_status - set_extra_library_path(const char *path); + set_extra_library_path(const char* path); // Return TRUE if we are in the replacement phase. bool in_replacement_phase() const { return this->in_replacement_phase_; } + Input_objects* + input_objects() const + { return this->input_objects_; } + + Symbol_table* + symtab() + { return this->symtab_; } + + Layout* + layout() + { return this->layout_; } + + Plugin_recorder* + recorder() const + { return this->recorder_; } + private: Plugin_manager(const Plugin_manager&); Plugin_manager& operator=(const Plugin_manager&); + // Plugin_rescan is a Task which calls the private rescan method. + friend class Plugin_rescan; + + // An archive or input group which may have to be rescanned if a + // plugin adds a new file. + struct Rescannable + { + bool is_archive; + union + { + Archive* archive; + Input_group* input_group; + } u; + + Rescannable(Archive* archive) + : is_archive(true) + { this->u.archive = archive; } + + Rescannable(Input_group* input_group) + : is_archive(false) + { this->u.input_group = input_group; } + }; + 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; + + // Rescan archives for undefined symbols. + void + rescan(Task*); + + // See whether the rescannable at index I defines SYM. + bool + rescannable_defines(size_t i, Symbol* sym); // The list of plugin libraries. Plugin_list plugins_; @@ -265,11 +383,27 @@ class Plugin_manager Input_file* input_file_; struct ld_plugin_input_file plugin_input_file_; - // TRUE after the all symbols read event; indicates that we are - // processing replacement files whose symbols should replace the + // A list of archives and input groups being saved for possible + // later rescanning. + Rescannable_list rescannable_; + + // A list of undefined symbols found in added files. + Undefined_symbol_list undefined_symbols_; + + // Whether any input files have been claimed by a plugin. + bool any_claimed_; + + // Set to true after the all symbols read event; indicates that we + // are processing replacement files whose symbols should replace the // placeholder symbols from the Pluginobj objects. bool in_replacement_phase_; + // 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_; @@ -280,9 +414,18 @@ class Plugin_manager Mapfile* mapfile_; Task_token* this_blocker_; - // An extra directory to seach for the libraries passed by + // An extra directory to search for the libraries passed by // add_input_library. std::string extra_search_path_; + Lock* lock_; + Initialize_lock initialize_lock_; + + // Keep track of all symbols defined by defsym. + typedef Unordered_set Defsym_defines_set; + Defsym_defines_set defsym_defines_set_; + + // Class to record plugin actions. + Plugin_recorder* recorder_; }; @@ -300,7 +443,10 @@ class Pluginobj : public Object // Fill in the symbol resolution status for the given plugin symbols. ld_plugin_status - get_symbol_resolution_info(int nsyms, ld_plugin_symbol* syms) const; + get_symbol_resolution_info(Symbol_table* symtab, + int nsyms, + ld_plugin_symbol* syms, + int version) const; // Store the incoming symbols from the plugin for later processing. void @@ -330,6 +476,16 @@ class Pluginobj : public Object filesize() { return this->filesize_; } + // Return the word size of the object file. + int + elfsize() const + { gold_unreachable(); } + + // Return TRUE if this is a big-endian object file. + bool + is_big_endian() const + { gold_unreachable(); } + protected: // Return TRUE if this is an object claimed by a plugin. virtual Pluginobj* @@ -338,7 +494,7 @@ class Pluginobj : public Object // The number of symbols provided by the plugin. int nsyms_; - + // The symbols provided by the plugin. const struct ld_plugin_symbol* syms_; @@ -379,17 +535,28 @@ class Sized_pluginobj : public Pluginobj do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*, 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); + + // Iterate over local symbols, calling a visitor class V for each GOT offset + // associated with a local symbol. + void + do_for_all_local_got_entries(Got_offset_list::Visitor* v) const; + // Get the size of a section. uint64_t do_section_size(unsigned int shndx); // Get the name of a section. std::string - do_section_name(unsigned int shndx); + do_section_name(unsigned int shndx) const; // Return a view of the contents of a section. - Object::Location - do_section_contents(unsigned int shndx); + const unsigned char* + do_section_contents(unsigned int shndx, section_size_type* plen, + bool cache); // Return section flags. uint64_t @@ -448,11 +615,11 @@ class Plugin_hook : public Task { public: Plugin_hook(const General_options& options, Input_objects* input_objects, - Symbol_table* symtab, Layout* layout, Dirsearch* dirpath, + Symbol_table* symtab, Layout* /*layout*/, Dirsearch* dirpath, Mapfile* mapfile, Task_token* this_blocker, Task_token* next_blocker) : options_(options), input_objects_(input_objects), symtab_(symtab), - layout_(layout), dirpath_(dirpath), mapfile_(mapfile), + dirpath_(dirpath), mapfile_(mapfile), this_blocker_(this_blocker), next_blocker_(next_blocker) { } @@ -477,7 +644,6 @@ class Plugin_hook : public Task const General_options& options_; Input_objects* input_objects_; Symbol_table* symtab_; - Layout* layout_; Dirsearch* dirpath_; Mapfile* mapfile_; Task_token* this_blocker_;