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