1*a9fa9459Szrj // plugin.h -- plugin manager for gold -*- C++ -*- 2*a9fa9459Szrj 3*a9fa9459Szrj // Copyright (C) 2008-2016 Free Software Foundation, Inc. 4*a9fa9459Szrj // Written by Cary Coutant <ccoutant@google.com>. 5*a9fa9459Szrj 6*a9fa9459Szrj // This file is part of gold. 7*a9fa9459Szrj 8*a9fa9459Szrj // This program is free software; you can redistribute it and/or modify 9*a9fa9459Szrj // it under the terms of the GNU General Public License as published by 10*a9fa9459Szrj // the Free Software Foundation; either version 3 of the License, or 11*a9fa9459Szrj // (at your option) any later version. 12*a9fa9459Szrj 13*a9fa9459Szrj // This program is distributed in the hope that it will be useful, 14*a9fa9459Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 15*a9fa9459Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*a9fa9459Szrj // GNU General Public License for more details. 17*a9fa9459Szrj 18*a9fa9459Szrj // You should have received a copy of the GNU General Public License 19*a9fa9459Szrj // along with this program; if not, write to the Free Software 20*a9fa9459Szrj // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21*a9fa9459Szrj // MA 02110-1301, USA. 22*a9fa9459Szrj 23*a9fa9459Szrj #ifndef GOLD_PLUGIN_H 24*a9fa9459Szrj #define GOLD_PLUGIN_H 25*a9fa9459Szrj 26*a9fa9459Szrj #include <list> 27*a9fa9459Szrj #include <string> 28*a9fa9459Szrj 29*a9fa9459Szrj #include "object.h" 30*a9fa9459Szrj #include "plugin-api.h" 31*a9fa9459Szrj #include "workqueue.h" 32*a9fa9459Szrj 33*a9fa9459Szrj namespace gold 34*a9fa9459Szrj { 35*a9fa9459Szrj 36*a9fa9459Szrj class General_options; 37*a9fa9459Szrj class Input_file; 38*a9fa9459Szrj class Input_objects; 39*a9fa9459Szrj class Archive; 40*a9fa9459Szrj class Input_group; 41*a9fa9459Szrj class Symbol; 42*a9fa9459Szrj class Symbol_table; 43*a9fa9459Szrj class Layout; 44*a9fa9459Szrj class Dirsearch; 45*a9fa9459Szrj class Mapfile; 46*a9fa9459Szrj class Task; 47*a9fa9459Szrj class Task_token; 48*a9fa9459Szrj class Pluginobj; 49*a9fa9459Szrj class Plugin_rescan; 50*a9fa9459Szrj 51*a9fa9459Szrj // This class represents a single plugin library. 52*a9fa9459Szrj 53*a9fa9459Szrj class Plugin 54*a9fa9459Szrj { 55*a9fa9459Szrj public: Plugin(const char * filename)56*a9fa9459Szrj Plugin(const char* filename) 57*a9fa9459Szrj : handle_(NULL), 58*a9fa9459Szrj filename_(filename), 59*a9fa9459Szrj args_(), 60*a9fa9459Szrj claim_file_handler_(NULL), 61*a9fa9459Szrj all_symbols_read_handler_(NULL), 62*a9fa9459Szrj cleanup_handler_(NULL), 63*a9fa9459Szrj cleanup_done_(false) 64*a9fa9459Szrj { } 65*a9fa9459Szrj ~Plugin()66*a9fa9459Szrj ~Plugin() 67*a9fa9459Szrj { } 68*a9fa9459Szrj 69*a9fa9459Szrj // Load the library and call its entry point. 70*a9fa9459Szrj void 71*a9fa9459Szrj load(); 72*a9fa9459Szrj 73*a9fa9459Szrj // Call the claim-file handler. 74*a9fa9459Szrj bool 75*a9fa9459Szrj claim_file(struct ld_plugin_input_file* plugin_input_file); 76*a9fa9459Szrj 77*a9fa9459Szrj // Call the all-symbols-read handler. 78*a9fa9459Szrj void 79*a9fa9459Szrj all_symbols_read(); 80*a9fa9459Szrj 81*a9fa9459Szrj // Call the cleanup handler. 82*a9fa9459Szrj void 83*a9fa9459Szrj cleanup(); 84*a9fa9459Szrj 85*a9fa9459Szrj // Register a claim-file handler. 86*a9fa9459Szrj void set_claim_file_handler(ld_plugin_claim_file_handler handler)87*a9fa9459Szrj set_claim_file_handler(ld_plugin_claim_file_handler handler) 88*a9fa9459Szrj { this->claim_file_handler_ = handler; } 89*a9fa9459Szrj 90*a9fa9459Szrj // Register an all-symbols-read handler. 91*a9fa9459Szrj void set_all_symbols_read_handler(ld_plugin_all_symbols_read_handler handler)92*a9fa9459Szrj set_all_symbols_read_handler(ld_plugin_all_symbols_read_handler handler) 93*a9fa9459Szrj { this->all_symbols_read_handler_ = handler; } 94*a9fa9459Szrj 95*a9fa9459Szrj // Register a claim-file handler. 96*a9fa9459Szrj void set_cleanup_handler(ld_plugin_cleanup_handler handler)97*a9fa9459Szrj set_cleanup_handler(ld_plugin_cleanup_handler handler) 98*a9fa9459Szrj { this->cleanup_handler_ = handler; } 99*a9fa9459Szrj 100*a9fa9459Szrj // Add an argument 101*a9fa9459Szrj void add_option(const char * arg)102*a9fa9459Szrj add_option(const char* arg) 103*a9fa9459Szrj { 104*a9fa9459Szrj this->args_.push_back(arg); 105*a9fa9459Szrj } 106*a9fa9459Szrj 107*a9fa9459Szrj private: 108*a9fa9459Szrj Plugin(const Plugin&); 109*a9fa9459Szrj Plugin& operator=(const Plugin&); 110*a9fa9459Szrj 111*a9fa9459Szrj // The shared library handle returned by dlopen. 112*a9fa9459Szrj void* handle_; 113*a9fa9459Szrj // The argument string given to --plugin. 114*a9fa9459Szrj std::string filename_; 115*a9fa9459Szrj // The list of argument string given to --plugin-opt. 116*a9fa9459Szrj std::vector<std::string> args_; 117*a9fa9459Szrj // The plugin's event handlers. 118*a9fa9459Szrj ld_plugin_claim_file_handler claim_file_handler_; 119*a9fa9459Szrj ld_plugin_all_symbols_read_handler all_symbols_read_handler_; 120*a9fa9459Szrj ld_plugin_cleanup_handler cleanup_handler_; 121*a9fa9459Szrj // TRUE if the cleanup handlers have been called. 122*a9fa9459Szrj bool cleanup_done_; 123*a9fa9459Szrj }; 124*a9fa9459Szrj 125*a9fa9459Szrj // A manager class for plugins. 126*a9fa9459Szrj 127*a9fa9459Szrj class Plugin_manager 128*a9fa9459Szrj { 129*a9fa9459Szrj public: Plugin_manager(const General_options & options)130*a9fa9459Szrj Plugin_manager(const General_options& options) 131*a9fa9459Szrj : plugins_(), objects_(), deferred_layout_objects_(), input_file_(NULL), 132*a9fa9459Szrj plugin_input_file_(), rescannable_(), undefined_symbols_(), 133*a9fa9459Szrj any_claimed_(false), in_replacement_phase_(false), any_added_(false), 134*a9fa9459Szrj in_claim_file_handler_(false), 135*a9fa9459Szrj options_(options), workqueue_(NULL), task_(NULL), input_objects_(NULL), 136*a9fa9459Szrj symtab_(NULL), layout_(NULL), dirpath_(NULL), mapfile_(NULL), 137*a9fa9459Szrj this_blocker_(NULL), extra_search_path_(), lock_(NULL), 138*a9fa9459Szrj initialize_lock_(&lock_) 139*a9fa9459Szrj { this->current_ = plugins_.end(); } 140*a9fa9459Szrj 141*a9fa9459Szrj ~Plugin_manager(); 142*a9fa9459Szrj 143*a9fa9459Szrj // Add a plugin library. 144*a9fa9459Szrj void add_plugin(const char * filename)145*a9fa9459Szrj add_plugin(const char* filename) 146*a9fa9459Szrj { this->plugins_.push_back(new Plugin(filename)); } 147*a9fa9459Szrj 148*a9fa9459Szrj // Add an argument to the current plugin. 149*a9fa9459Szrj void add_plugin_option(const char * opt)150*a9fa9459Szrj add_plugin_option(const char* opt) 151*a9fa9459Szrj { 152*a9fa9459Szrj Plugin* last = this->plugins_.back(); 153*a9fa9459Szrj last->add_option(opt); 154*a9fa9459Szrj } 155*a9fa9459Szrj 156*a9fa9459Szrj // Load all plugin libraries. 157*a9fa9459Szrj void 158*a9fa9459Szrj load_plugins(Layout* layout); 159*a9fa9459Szrj 160*a9fa9459Szrj // Call the plugin claim-file handlers in turn to see if any claim the file. 161*a9fa9459Szrj Pluginobj* 162*a9fa9459Szrj claim_file(Input_file* input_file, off_t offset, off_t filesize, 163*a9fa9459Szrj Object* elf_object); 164*a9fa9459Szrj 165*a9fa9459Szrj // Get the object associated with the handle and check if it is an elf object. 166*a9fa9459Szrj // If it is not a Pluginobj, it is an elf object. 167*a9fa9459Szrj Object* 168*a9fa9459Szrj get_elf_object(const void* handle); 169*a9fa9459Szrj 170*a9fa9459Szrj // True if the claim_file handler of the plugins is being called. 171*a9fa9459Szrj bool in_claim_file_handler()172*a9fa9459Szrj in_claim_file_handler() 173*a9fa9459Szrj { return in_claim_file_handler_; } 174*a9fa9459Szrj 175*a9fa9459Szrj // Let the plugin manager save an archive for later rescanning. 176*a9fa9459Szrj // This takes ownership of the Archive pointer. 177*a9fa9459Szrj void 178*a9fa9459Szrj save_archive(Archive*); 179*a9fa9459Szrj 180*a9fa9459Szrj // Let the plugin manager save an input group for later rescanning. 181*a9fa9459Szrj // This takes ownership of the Input_group pointer. 182*a9fa9459Szrj void 183*a9fa9459Szrj save_input_group(Input_group*); 184*a9fa9459Szrj 185*a9fa9459Szrj // Call the all-symbols-read handlers. 186*a9fa9459Szrj void 187*a9fa9459Szrj all_symbols_read(Workqueue* workqueue, Task* task, 188*a9fa9459Szrj Input_objects* input_objects, Symbol_table* symtab, 189*a9fa9459Szrj Dirsearch* dirpath, Mapfile* mapfile, 190*a9fa9459Szrj Task_token** last_blocker); 191*a9fa9459Szrj 192*a9fa9459Szrj // Tell the plugin manager that we've a new undefined symbol which 193*a9fa9459Szrj // may require rescanning. 194*a9fa9459Szrj void 195*a9fa9459Szrj new_undefined_symbol(Symbol*); 196*a9fa9459Szrj 197*a9fa9459Szrj // Run deferred layout. 198*a9fa9459Szrj void 199*a9fa9459Szrj layout_deferred_objects(); 200*a9fa9459Szrj 201*a9fa9459Szrj // Call the cleanup handlers. 202*a9fa9459Szrj void 203*a9fa9459Szrj cleanup(); 204*a9fa9459Szrj 205*a9fa9459Szrj // Register a claim-file handler. 206*a9fa9459Szrj void set_claim_file_handler(ld_plugin_claim_file_handler handler)207*a9fa9459Szrj set_claim_file_handler(ld_plugin_claim_file_handler handler) 208*a9fa9459Szrj { 209*a9fa9459Szrj gold_assert(this->current_ != plugins_.end()); 210*a9fa9459Szrj (*this->current_)->set_claim_file_handler(handler); 211*a9fa9459Szrj } 212*a9fa9459Szrj 213*a9fa9459Szrj // Register an all-symbols-read handler. 214*a9fa9459Szrj void set_all_symbols_read_handler(ld_plugin_all_symbols_read_handler handler)215*a9fa9459Szrj set_all_symbols_read_handler(ld_plugin_all_symbols_read_handler handler) 216*a9fa9459Szrj { 217*a9fa9459Szrj gold_assert(this->current_ != plugins_.end()); 218*a9fa9459Szrj (*this->current_)->set_all_symbols_read_handler(handler); 219*a9fa9459Szrj } 220*a9fa9459Szrj 221*a9fa9459Szrj // Register a claim-file handler. 222*a9fa9459Szrj void set_cleanup_handler(ld_plugin_cleanup_handler handler)223*a9fa9459Szrj set_cleanup_handler(ld_plugin_cleanup_handler handler) 224*a9fa9459Szrj { 225*a9fa9459Szrj gold_assert(this->current_ != plugins_.end()); 226*a9fa9459Szrj (*this->current_)->set_cleanup_handler(handler); 227*a9fa9459Szrj } 228*a9fa9459Szrj 229*a9fa9459Szrj // Make a new Pluginobj object. This is called when the plugin calls 230*a9fa9459Szrj // the add_symbols API. 231*a9fa9459Szrj Pluginobj* 232*a9fa9459Szrj make_plugin_object(unsigned int handle); 233*a9fa9459Szrj 234*a9fa9459Szrj // Return the object associated with the given HANDLE. 235*a9fa9459Szrj Object* object(unsigned int handle)236*a9fa9459Szrj object(unsigned int handle) const 237*a9fa9459Szrj { 238*a9fa9459Szrj if (handle >= this->objects_.size()) 239*a9fa9459Szrj return NULL; 240*a9fa9459Szrj return this->objects_[handle]; 241*a9fa9459Szrj } 242*a9fa9459Szrj 243*a9fa9459Szrj // Return TRUE if any input files have been claimed by a plugin 244*a9fa9459Szrj // and we are still in the initial input phase. 245*a9fa9459Szrj bool should_defer_layout()246*a9fa9459Szrj should_defer_layout() const 247*a9fa9459Szrj { return this->any_claimed_ && !this->in_replacement_phase_; } 248*a9fa9459Szrj 249*a9fa9459Szrj // Add a regular object to the deferred layout list. These are 250*a9fa9459Szrj // objects whose layout has been deferred until after the 251*a9fa9459Szrj // replacement files have arrived. 252*a9fa9459Szrj void add_deferred_layout_object(Relobj * obj)253*a9fa9459Szrj add_deferred_layout_object(Relobj* obj) 254*a9fa9459Szrj { this->deferred_layout_objects_.push_back(obj); } 255*a9fa9459Szrj 256*a9fa9459Szrj // Get input file information with an open (possibly re-opened) 257*a9fa9459Szrj // file descriptor. 258*a9fa9459Szrj ld_plugin_status 259*a9fa9459Szrj get_input_file(unsigned int handle, struct ld_plugin_input_file* file); 260*a9fa9459Szrj 261*a9fa9459Szrj ld_plugin_status 262*a9fa9459Szrj get_view(unsigned int handle, const void **viewp); 263*a9fa9459Szrj 264*a9fa9459Szrj // Release an input file. 265*a9fa9459Szrj ld_plugin_status 266*a9fa9459Szrj release_input_file(unsigned int handle); 267*a9fa9459Szrj 268*a9fa9459Szrj // Add a new input file. 269*a9fa9459Szrj ld_plugin_status 270*a9fa9459Szrj add_input_file(const char* pathname, bool is_lib); 271*a9fa9459Szrj 272*a9fa9459Szrj // Set the extra library path. 273*a9fa9459Szrj ld_plugin_status 274*a9fa9459Szrj set_extra_library_path(const char* path); 275*a9fa9459Szrj 276*a9fa9459Szrj // Return TRUE if we are in the replacement phase. 277*a9fa9459Szrj bool in_replacement_phase()278*a9fa9459Szrj in_replacement_phase() const 279*a9fa9459Szrj { return this->in_replacement_phase_; } 280*a9fa9459Szrj 281*a9fa9459Szrj Input_objects* input_objects()282*a9fa9459Szrj input_objects() const 283*a9fa9459Szrj { return this->input_objects_; } 284*a9fa9459Szrj 285*a9fa9459Szrj Symbol_table* symtab()286*a9fa9459Szrj symtab() 287*a9fa9459Szrj { return this->symtab_; } 288*a9fa9459Szrj 289*a9fa9459Szrj Layout* layout()290*a9fa9459Szrj layout() 291*a9fa9459Szrj { return this->layout_; } 292*a9fa9459Szrj 293*a9fa9459Szrj private: 294*a9fa9459Szrj Plugin_manager(const Plugin_manager&); 295*a9fa9459Szrj Plugin_manager& operator=(const Plugin_manager&); 296*a9fa9459Szrj 297*a9fa9459Szrj // Plugin_rescan is a Task which calls the private rescan method. 298*a9fa9459Szrj friend class Plugin_rescan; 299*a9fa9459Szrj 300*a9fa9459Szrj // An archive or input group which may have to be rescanned if a 301*a9fa9459Szrj // plugin adds a new file. 302*a9fa9459Szrj struct Rescannable 303*a9fa9459Szrj { 304*a9fa9459Szrj bool is_archive; 305*a9fa9459Szrj union 306*a9fa9459Szrj { 307*a9fa9459Szrj Archive* archive; 308*a9fa9459Szrj Input_group* input_group; 309*a9fa9459Szrj } u; 310*a9fa9459Szrj RescannableRescannable311*a9fa9459Szrj Rescannable(Archive* archive) 312*a9fa9459Szrj : is_archive(true) 313*a9fa9459Szrj { this->u.archive = archive; } 314*a9fa9459Szrj RescannableRescannable315*a9fa9459Szrj Rescannable(Input_group* input_group) 316*a9fa9459Szrj : is_archive(false) 317*a9fa9459Szrj { this->u.input_group = input_group; } 318*a9fa9459Szrj }; 319*a9fa9459Szrj 320*a9fa9459Szrj typedef std::list<Plugin*> Plugin_list; 321*a9fa9459Szrj typedef std::vector<Object*> Object_list; 322*a9fa9459Szrj typedef std::vector<Relobj*> Deferred_layout_list; 323*a9fa9459Szrj typedef std::vector<Rescannable> Rescannable_list; 324*a9fa9459Szrj typedef std::vector<Symbol*> Undefined_symbol_list; 325*a9fa9459Szrj 326*a9fa9459Szrj // Rescan archives for undefined symbols. 327*a9fa9459Szrj void 328*a9fa9459Szrj rescan(Task*); 329*a9fa9459Szrj 330*a9fa9459Szrj // See whether the rescannable at index I defines SYM. 331*a9fa9459Szrj bool 332*a9fa9459Szrj rescannable_defines(size_t i, Symbol* sym); 333*a9fa9459Szrj 334*a9fa9459Szrj // The list of plugin libraries. 335*a9fa9459Szrj Plugin_list plugins_; 336*a9fa9459Szrj // A pointer to the current plugin. Used while loading plugins. 337*a9fa9459Szrj Plugin_list::iterator current_; 338*a9fa9459Szrj 339*a9fa9459Szrj // The list of plugin objects. The index of an item in this list 340*a9fa9459Szrj // serves as the "handle" that we pass to the plugins. 341*a9fa9459Szrj Object_list objects_; 342*a9fa9459Szrj 343*a9fa9459Szrj // The list of regular objects whose layout has been deferred. 344*a9fa9459Szrj Deferred_layout_list deferred_layout_objects_; 345*a9fa9459Szrj 346*a9fa9459Szrj // The file currently up for claim by the plugins. 347*a9fa9459Szrj Input_file* input_file_; 348*a9fa9459Szrj struct ld_plugin_input_file plugin_input_file_; 349*a9fa9459Szrj 350*a9fa9459Szrj // A list of archives and input groups being saved for possible 351*a9fa9459Szrj // later rescanning. 352*a9fa9459Szrj Rescannable_list rescannable_; 353*a9fa9459Szrj 354*a9fa9459Szrj // A list of undefined symbols found in added files. 355*a9fa9459Szrj Undefined_symbol_list undefined_symbols_; 356*a9fa9459Szrj 357*a9fa9459Szrj // Whether any input files have been claimed by a plugin. 358*a9fa9459Szrj bool any_claimed_; 359*a9fa9459Szrj 360*a9fa9459Szrj // Set to true after the all symbols read event; indicates that we 361*a9fa9459Szrj // are processing replacement files whose symbols should replace the 362*a9fa9459Szrj // placeholder symbols from the Pluginobj objects. 363*a9fa9459Szrj bool in_replacement_phase_; 364*a9fa9459Szrj 365*a9fa9459Szrj // Whether any input files or libraries were added by a plugin. 366*a9fa9459Szrj bool any_added_; 367*a9fa9459Szrj 368*a9fa9459Szrj // Set to true when the claim_file handler of a plugin is called. 369*a9fa9459Szrj bool in_claim_file_handler_; 370*a9fa9459Szrj 371*a9fa9459Szrj const General_options& options_; 372*a9fa9459Szrj Workqueue* workqueue_; 373*a9fa9459Szrj Task* task_; 374*a9fa9459Szrj Input_objects* input_objects_; 375*a9fa9459Szrj Symbol_table* symtab_; 376*a9fa9459Szrj Layout* layout_; 377*a9fa9459Szrj Dirsearch* dirpath_; 378*a9fa9459Szrj Mapfile* mapfile_; 379*a9fa9459Szrj Task_token* this_blocker_; 380*a9fa9459Szrj 381*a9fa9459Szrj // An extra directory to seach for the libraries passed by 382*a9fa9459Szrj // add_input_library. 383*a9fa9459Szrj std::string extra_search_path_; 384*a9fa9459Szrj Lock* lock_; 385*a9fa9459Szrj Initialize_lock initialize_lock_; 386*a9fa9459Szrj }; 387*a9fa9459Szrj 388*a9fa9459Szrj 389*a9fa9459Szrj // An object file claimed by a plugin. This is an abstract base class. 390*a9fa9459Szrj // The implementation is the template class Sized_pluginobj. 391*a9fa9459Szrj 392*a9fa9459Szrj class Pluginobj : public Object 393*a9fa9459Szrj { 394*a9fa9459Szrj public: 395*a9fa9459Szrj 396*a9fa9459Szrj typedef std::vector<Symbol*> Symbols; 397*a9fa9459Szrj 398*a9fa9459Szrj Pluginobj(const std::string& name, Input_file* input_file, off_t offset, 399*a9fa9459Szrj off_t filesize); 400*a9fa9459Szrj 401*a9fa9459Szrj // Fill in the symbol resolution status for the given plugin symbols. 402*a9fa9459Szrj ld_plugin_status 403*a9fa9459Szrj get_symbol_resolution_info(Symbol_table* symtab, 404*a9fa9459Szrj int nsyms, 405*a9fa9459Szrj ld_plugin_symbol* syms, 406*a9fa9459Szrj int version) const; 407*a9fa9459Szrj 408*a9fa9459Szrj // Store the incoming symbols from the plugin for later processing. 409*a9fa9459Szrj void store_incoming_symbols(int nsyms,const struct ld_plugin_symbol * syms)410*a9fa9459Szrj store_incoming_symbols(int nsyms, const struct ld_plugin_symbol* syms) 411*a9fa9459Szrj { 412*a9fa9459Szrj this->nsyms_ = nsyms; 413*a9fa9459Szrj this->syms_ = syms; 414*a9fa9459Szrj } 415*a9fa9459Szrj 416*a9fa9459Szrj // Return TRUE if the comdat group with key COMDAT_KEY from this object 417*a9fa9459Szrj // should be kept. 418*a9fa9459Szrj bool 419*a9fa9459Szrj include_comdat_group(std::string comdat_key, Layout* layout); 420*a9fa9459Szrj 421*a9fa9459Szrj // Return the filename. 422*a9fa9459Szrj const std::string& filename()423*a9fa9459Szrj filename() const 424*a9fa9459Szrj { return this->input_file()->filename(); } 425*a9fa9459Szrj 426*a9fa9459Szrj // Return the file descriptor. 427*a9fa9459Szrj int descriptor()428*a9fa9459Szrj descriptor() 429*a9fa9459Szrj { return this->input_file()->file().descriptor(); } 430*a9fa9459Szrj 431*a9fa9459Szrj // Return the size of the file or archive member. 432*a9fa9459Szrj off_t filesize()433*a9fa9459Szrj filesize() 434*a9fa9459Szrj { return this->filesize_; } 435*a9fa9459Szrj 436*a9fa9459Szrj // Return the word size of the object file. 437*a9fa9459Szrj int elfsize()438*a9fa9459Szrj elfsize() const 439*a9fa9459Szrj { gold_unreachable(); } 440*a9fa9459Szrj 441*a9fa9459Szrj // Return TRUE if this is a big-endian object file. 442*a9fa9459Szrj bool is_big_endian()443*a9fa9459Szrj is_big_endian() const 444*a9fa9459Szrj { gold_unreachable(); } 445*a9fa9459Szrj 446*a9fa9459Szrj protected: 447*a9fa9459Szrj // Return TRUE if this is an object claimed by a plugin. 448*a9fa9459Szrj virtual Pluginobj* do_pluginobj()449*a9fa9459Szrj do_pluginobj() 450*a9fa9459Szrj { return this; } 451*a9fa9459Szrj 452*a9fa9459Szrj // The number of symbols provided by the plugin. 453*a9fa9459Szrj int nsyms_; 454*a9fa9459Szrj 455*a9fa9459Szrj // The symbols provided by the plugin. 456*a9fa9459Szrj const struct ld_plugin_symbol* syms_; 457*a9fa9459Szrj 458*a9fa9459Szrj // The entries in the symbol table for the external symbols. 459*a9fa9459Szrj Symbols symbols_; 460*a9fa9459Szrj 461*a9fa9459Szrj private: 462*a9fa9459Szrj // Size of the file (or archive member). 463*a9fa9459Szrj off_t filesize_; 464*a9fa9459Szrj // Map a comdat key symbol to a boolean indicating whether the comdat 465*a9fa9459Szrj // group in this object with that key should be kept. 466*a9fa9459Szrj typedef Unordered_map<std::string, bool> Comdat_map; 467*a9fa9459Szrj Comdat_map comdat_map_; 468*a9fa9459Szrj }; 469*a9fa9459Szrj 470*a9fa9459Szrj // A plugin object, size-specific version. 471*a9fa9459Szrj 472*a9fa9459Szrj template<int size, bool big_endian> 473*a9fa9459Szrj class Sized_pluginobj : public Pluginobj 474*a9fa9459Szrj { 475*a9fa9459Szrj public: 476*a9fa9459Szrj Sized_pluginobj(const std::string& name, Input_file* input_file, 477*a9fa9459Szrj off_t offset, off_t filesize); 478*a9fa9459Szrj 479*a9fa9459Szrj // Read the symbols. 480*a9fa9459Szrj void 481*a9fa9459Szrj do_read_symbols(Read_symbols_data*); 482*a9fa9459Szrj 483*a9fa9459Szrj // Lay out the input sections. 484*a9fa9459Szrj void 485*a9fa9459Szrj do_layout(Symbol_table*, Layout*, Read_symbols_data*); 486*a9fa9459Szrj 487*a9fa9459Szrj // Add the symbols to the symbol table. 488*a9fa9459Szrj void 489*a9fa9459Szrj do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*); 490*a9fa9459Szrj 491*a9fa9459Szrj Archive::Should_include 492*a9fa9459Szrj do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*, 493*a9fa9459Szrj std::string* why); 494*a9fa9459Szrj 495*a9fa9459Szrj // Iterate over global symbols, calling a visitor class V for each. 496*a9fa9459Szrj void 497*a9fa9459Szrj do_for_all_global_symbols(Read_symbols_data* sd, 498*a9fa9459Szrj Library_base::Symbol_visitor_base* v); 499*a9fa9459Szrj 500*a9fa9459Szrj // Iterate over local symbols, calling a visitor class V for each GOT offset 501*a9fa9459Szrj // associated with a local symbol. 502*a9fa9459Szrj void 503*a9fa9459Szrj do_for_all_local_got_entries(Got_offset_list::Visitor* v) const; 504*a9fa9459Szrj 505*a9fa9459Szrj // Get the size of a section. 506*a9fa9459Szrj uint64_t 507*a9fa9459Szrj do_section_size(unsigned int shndx); 508*a9fa9459Szrj 509*a9fa9459Szrj // Get the name of a section. 510*a9fa9459Szrj std::string 511*a9fa9459Szrj do_section_name(unsigned int shndx) const; 512*a9fa9459Szrj 513*a9fa9459Szrj // Return a view of the contents of a section. 514*a9fa9459Szrj const unsigned char* 515*a9fa9459Szrj do_section_contents(unsigned int shndx, section_size_type* plen, 516*a9fa9459Szrj bool cache); 517*a9fa9459Szrj 518*a9fa9459Szrj // Return section flags. 519*a9fa9459Szrj uint64_t 520*a9fa9459Szrj do_section_flags(unsigned int shndx); 521*a9fa9459Szrj 522*a9fa9459Szrj // Return section entsize. 523*a9fa9459Szrj uint64_t 524*a9fa9459Szrj do_section_entsize(unsigned int shndx); 525*a9fa9459Szrj 526*a9fa9459Szrj // Return section address. 527*a9fa9459Szrj uint64_t 528*a9fa9459Szrj do_section_address(unsigned int shndx); 529*a9fa9459Szrj 530*a9fa9459Szrj // Return section type. 531*a9fa9459Szrj unsigned int 532*a9fa9459Szrj do_section_type(unsigned int shndx); 533*a9fa9459Szrj 534*a9fa9459Szrj // Return the section link field. 535*a9fa9459Szrj unsigned int 536*a9fa9459Szrj do_section_link(unsigned int shndx); 537*a9fa9459Szrj 538*a9fa9459Szrj // Return the section link field. 539*a9fa9459Szrj unsigned int 540*a9fa9459Szrj do_section_info(unsigned int shndx); 541*a9fa9459Szrj 542*a9fa9459Szrj // Return the section alignment. 543*a9fa9459Szrj uint64_t 544*a9fa9459Szrj do_section_addralign(unsigned int shndx); 545*a9fa9459Szrj 546*a9fa9459Szrj // Return the Xindex structure to use. 547*a9fa9459Szrj Xindex* 548*a9fa9459Szrj do_initialize_xindex(); 549*a9fa9459Szrj 550*a9fa9459Szrj // Get symbol counts. 551*a9fa9459Szrj void 552*a9fa9459Szrj do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const; 553*a9fa9459Szrj 554*a9fa9459Szrj // Get global symbols. 555*a9fa9459Szrj const Symbols* 556*a9fa9459Szrj do_get_global_symbols() const; 557*a9fa9459Szrj 558*a9fa9459Szrj // Add placeholder symbols from a claimed file. 559*a9fa9459Szrj ld_plugin_status 560*a9fa9459Szrj add_symbols_from_plugin(int nsyms, const ld_plugin_symbol* syms); 561*a9fa9459Szrj 562*a9fa9459Szrj protected: 563*a9fa9459Szrj 564*a9fa9459Szrj private: 565*a9fa9459Szrj }; 566*a9fa9459Szrj 567*a9fa9459Szrj // This Task handles handles the "all symbols read" event hook. 568*a9fa9459Szrj // The plugin may add additional input files at this time, which must 569*a9fa9459Szrj // be queued for reading. 570*a9fa9459Szrj 571*a9fa9459Szrj class Plugin_hook : public Task 572*a9fa9459Szrj { 573*a9fa9459Szrj public: Plugin_hook(const General_options & options,Input_objects * input_objects,Symbol_table * symtab,Layout *,Dirsearch * dirpath,Mapfile * mapfile,Task_token * this_blocker,Task_token * next_blocker)574*a9fa9459Szrj Plugin_hook(const General_options& options, Input_objects* input_objects, 575*a9fa9459Szrj Symbol_table* symtab, Layout* /*layout*/, Dirsearch* dirpath, 576*a9fa9459Szrj Mapfile* mapfile, Task_token* this_blocker, 577*a9fa9459Szrj Task_token* next_blocker) 578*a9fa9459Szrj : options_(options), input_objects_(input_objects), symtab_(symtab), 579*a9fa9459Szrj dirpath_(dirpath), mapfile_(mapfile), 580*a9fa9459Szrj this_blocker_(this_blocker), next_blocker_(next_blocker) 581*a9fa9459Szrj { } 582*a9fa9459Szrj 583*a9fa9459Szrj ~Plugin_hook(); 584*a9fa9459Szrj 585*a9fa9459Szrj // The standard Task methods. 586*a9fa9459Szrj 587*a9fa9459Szrj Task_token* 588*a9fa9459Szrj is_runnable(); 589*a9fa9459Szrj 590*a9fa9459Szrj void 591*a9fa9459Szrj locks(Task_locker*); 592*a9fa9459Szrj 593*a9fa9459Szrj void 594*a9fa9459Szrj run(Workqueue*); 595*a9fa9459Szrj 596*a9fa9459Szrj std::string get_name()597*a9fa9459Szrj get_name() const 598*a9fa9459Szrj { return "Plugin_hook"; } 599*a9fa9459Szrj 600*a9fa9459Szrj private: 601*a9fa9459Szrj const General_options& options_; 602*a9fa9459Szrj Input_objects* input_objects_; 603*a9fa9459Szrj Symbol_table* symtab_; 604*a9fa9459Szrj Dirsearch* dirpath_; 605*a9fa9459Szrj Mapfile* mapfile_; 606*a9fa9459Szrj Task_token* this_blocker_; 607*a9fa9459Szrj Task_token* next_blocker_; 608*a9fa9459Szrj }; 609*a9fa9459Szrj 610*a9fa9459Szrj } // End namespace gold. 611*a9fa9459Szrj 612*a9fa9459Szrj #endif // !defined(GOLD_PLUGIN_H) 613