plugin.h 16 KB

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