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

// Copyright 2008, 2009, 2010 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 Symbol_table;
class Layout;
class Dirsearch;
class Mapfile;
class Task_token;
class Pluginobj;

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

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

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

  typedef std::list<Plugin*> Plugin_list;
  typedef std::vector<Pluginobj*> Object_list;
  typedef std::vector<Relobj*> Deferred_layout_list;

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

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

  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)
