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