// plugin.h -- plugin manager for gold      -*- C++ -*-

// Copyright (C) 2008-2018 Free Software Foundation, Inc.
// Written by Cary Coutant <ccoutant@google.com>.

// This file is part of gold.

// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// MA 02110-1301, USA.

#ifndef GOLD_PLUGIN_H
#define GOLD_PLUGIN_H

#include <list>
#include <string>

#include "object.h"
#include "plugin-api.h"
#include "workqueue.h"

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;

// This class represents a single plugin library.

class Plugin
{
 public:
  Plugin(const char* filename)
    : handle_(NULL),
      filename_(filename),
      args_(),
      claim_file_handler_(NULL),
      all_symbols_read_handler_(NULL),
      cleanup_handler_(NULL),
      new_input_handler_(NULL),
      cleanup_done_(false)
  { }

  ~Plugin()
  { }

  // Load the library and call its entry point.
  void
  load();

  // Call the claim-file handler.
  bool
  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();

  // Register a claim-file handler.
  void
  set_claim_file_handler(ld_plugin_claim_file_handler handler)
  { this->claim_file_handler_ = handler; }

  // Register an all-symbols-read handler.
  void
  set_all_symbols_read_handler(ld_plugin_all_symbols_read_handler handler)
  { this->all_symbols_read_handler_ = handler; }

  // Register a claim-file handler.
  void
  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)
  {
    this->args_.push_back(arg);
  }

 private:
  Plugin(const Plugin&);
  Plugin& operator=(const Plugin&);

  // The shared library handle returned by dlopen.
  void* handle_;
  // The argument string given to --plugin.
  std::string filename_;
  // The list of argument string given to --plugin-opt.
  std::vector<std::string> args_;
  // The plugin's event handlers.
  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_;
};

// A manager class for plugins.

class Plugin_manager
{
 public:
  Plugin_manager(const General_options& options)
    : plugins_(), objects_(), deferred_layout_objects_(), input_file_(NULL),
      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_(), lock_(NULL),
      initialize_lock_(&lock_), defsym_defines_set_()
  { 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)
  { this->plugins_.push_back(new Plugin(filename)); }

  // Add an argument to the current plugin.
  void
  add_plugin_option(const char* opt)
  {
    Plugin* last = this->plugins_.back();
    last->add_option(opt);
  }

  // Load all plugin libraries.
  void
  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,
             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,
                   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();

  // Call the cleanup handlers.
  void
  cleanup();

  // Register a claim-file handler.
  void
  set_claim_file_handler(ld_plugin_claim_file_handler handler)
  {
    gold_assert(this->current_ != plugins_.end());
    (*this->current_)->set_claim_file_handler(handler);
  }

  // Register an all-symbols-read handler.
  void
  set_all_symbols_read_handler(ld_plugin_all_symbols_read_handler handler)
  {
    gold_assert(this->current_ != plugins_.end());
    (*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)
  {
    gold_assert(this->current_ != plugins_.end());
    (*this->current_)->set_cleanup_handler(handler);
  }

  // Make a new Pluginobj object.  This is called when the plugin calls
  // the add_symbols API.
  Pluginobj*
  make_plugin_object(unsigned int handle);

  // Return the object associated with the given HANDLE.
  Object*
  object(unsigned int handle) const
  {
    if (handle >= this->objects_.size())
      return NULL;
    return this->objects_[handle];
  }

  // Return TRUE if any input files have been claimed by a plugin
  // and we are still in the initial input phase.
  bool
  should_defer_layout() const
  { 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
  // replacement files have arrived.
  void
  add_deferred_layout_object(Relobj* obj)
  { this->deferred_layout_objects_.push_back(obj); }

  // 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);

  ld_plugin_status
  get_view(unsigned int handle, const void **viewp);

  // Release an input file.
  ld_plugin_status
  release_input_file(unsigned int handle);

  // Add a new input file.
  ld_plugin_status
  add_input_file(const char* pathname, bool is_lib);

  // Set the extra library path.
  ld_plugin_status
  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_; }

 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*> Plugin_list;
  typedef std::vector<Object*> Object_list;
  typedef std::vector<Relobj*> Deferred_layout_list;
  typedef std::vector<Rescannable> Rescannable_list;
  typedef std::vector<Symbol*> 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_;
  // A pointer to the current plugin.  Used while loading plugins.
  Plugin_list::iterator current_;

  // The list of plugin objects.  The index of an item in this list
  // serves as the "handle" that we pass to the plugins.
  Object_list objects_;

  // The list of regular objects whose layout has been deferred.
  Deferred_layout_list deferred_layout_objects_;

  // The file currently up for claim by the plugins.
  Input_file* input_file_;
  struct ld_plugin_input_file plugin_input_file_;

  // 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_;
  Input_objects* input_objects_;
  Symbol_table* symtab_;
  Layout* layout_;
  Dirsearch* dirpath_;
  Mapfile* mapfile_;
  Task_token* this_blocker_;

  // 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<std::string> Defsym_defines_set;
  Defsym_defines_set defsym_defines_set_;
};


// An object file claimed by a plugin.  This is an abstract base class.
// The implementation is the template class Sized_pluginobj.

class Pluginobj : public Object
{
 public:

  typedef std::vector<Symbol*> Symbols;

  Pluginobj(const std::string& name, Input_file* input_file, off_t offset,
            off_t filesize);

  // Fill in the symbol resolution status for the given plugin symbols.
  ld_plugin_status
  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
  store_incoming_symbols(int nsyms, const struct ld_plugin_symbol* syms)
  {
    this->nsyms_ = nsyms;
    this->syms_ = syms;
  }

  // Return TRUE if the comdat group with key COMDAT_KEY from this object
  // should be kept.
  bool
  include_comdat_group(std::string comdat_key, Layout* layout);

  // Return the filename.
  const std::string&
  filename() const
  { return this->input_file()->filename(); }

  // Return the file descriptor.
  int
  descriptor()
  { return this->input_file()->file().descriptor(); }

  // Return the size of the file or archive member.
  off_t
  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*
  do_pluginobj()
  { return this; }

  // The number of symbols provided by the plugin.
  int nsyms_;

  // The symbols provided by the plugin.
  const struct ld_plugin_symbol* syms_;

  // The entries in the symbol table for the external symbols.
  Symbols symbols_;

 private:
  // Size of the file (or archive member).
  off_t filesize_;
  // Map a comdat key symbol to a boolean indicating whether the comdat
  // group in this object with that key should be kept.
  typedef Unordered_map<std::string, bool> Comdat_map;
  Comdat_map comdat_map_;
};

// A plugin object, size-specific version.

template<int size, bool big_endian>
class Sized_pluginobj : public Pluginobj
{
 public:
  Sized_pluginobj(const std::string& name, Input_file* input_file,
                  off_t offset, off_t filesize);

  // Read the symbols.
  void
  do_read_symbols(Read_symbols_data*);

  // Lay out the input sections.
  void
  do_layout(Symbol_table*, Layout*, Read_symbols_data*);

  // Add the symbols to the symbol table.
  void
  do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*);

  Archive::Should_include
  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) const;

  // Return a view of the contents of a section.
  const unsigned char*
  do_section_contents(unsigned int shndx, section_size_type* plen,
		      bool cache);

  // Return section flags.
  uint64_t
  do_section_flags(unsigned int shndx);

  // Return section entsize.
  uint64_t
  do_section_entsize(unsigned int shndx);

  // Return section address.
  uint64_t
  do_section_address(unsigned int shndx);

  // Return section type.
  unsigned int
  do_section_type(unsigned int shndx);

  // Return the section link field.
  unsigned int
  do_section_link(unsigned int shndx);

  // Return the section link field.
  unsigned int
  do_section_info(unsigned int shndx);

  // Return the section alignment.
  uint64_t
  do_section_addralign(unsigned int shndx);

  // Return the Xindex structure to use.
  Xindex*
  do_initialize_xindex();

  // Get symbol counts.
  void
  do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const;

  // Get global symbols.
  const Symbols*
  do_get_global_symbols() const;

  // Add placeholder symbols from a claimed file.
  ld_plugin_status
  add_symbols_from_plugin(int nsyms, const ld_plugin_symbol* syms);

 protected:

 private:
};

// This Task handles handles the "all symbols read" event hook.
// The plugin may add additional input files at this time, which must
// be queued for reading.

class Plugin_hook : public Task
{
 public:
  Plugin_hook(const General_options& options, Input_objects* input_objects,
	      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),
      dirpath_(dirpath), mapfile_(mapfile),
      this_blocker_(this_blocker), next_blocker_(next_blocker)
  { }

  ~Plugin_hook();

  // The standard Task methods.

  Task_token*
  is_runnable();

  void
  locks(Task_locker*);

  void
  run(Workqueue*);

  std::string
  get_name() const
  { return "Plugin_hook"; }

 private:
  const General_options& options_;
  Input_objects* input_objects_;
  Symbol_table* symtab_;
  Dirsearch* dirpath_;
  Mapfile* mapfile_;
  Task_token* this_blocker_;
  Task_token* next_blocker_;
};

} // End namespace gold.

#endif // !defined(GOLD_PLUGIN_H)
