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

// Copyright 2008, 2009, 2010, 2011 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),
      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 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; }

  // 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_;
  // 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),
      options_(options), workqueue_(NULL), task_(NULL), input_objects_(NULL),
      symtab_(NULL), layout_(NULL), dirpath_(NULL), mapfile_(NULL),
      this_blocker_(NULL), extra_search_path_()
  { this->current_ = plugins_.end(); }

  ~Plugin_manager();

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

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

  // 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,
                   Layout* layout, 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 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 Pluginobj associated with the given HANDLE.
  Pluginobj*
  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->objects_.empty() && !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);

  // 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_; }

 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<Pluginobj*> 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_;

  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 seach for the libraries passed by
  // add_input_library.
  std::string extra_search_path_;
};


// 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(int nsyms, ld_plugin_symbol* syms) 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_; }

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

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

  // Return a view of the contents of a section.
  Object::Location
  do_section_contents(unsigned int shndx);

  // 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),
      layout_(layout), 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_;
  Layout* layout_;
  Dirsearch* dirpath_;
  Mapfile* mapfile_;
  Task_token* this_blocker_;
  Task_token* next_blocker_;
};

} // End namespace gold.

#endif // !defined(GOLD_PLUGIN_H)
