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

// Copyright 2008 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* args)
    : handle_(NULL),
      args_(args),
      claim_file_handler_(NULL),
      all_symbols_read_handler_(NULL),
      cleanup_handler_(NULL)      
  { }

  ~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; }

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

  // The shared library handle returned by dlopen.
  void* handle_;
  // The argument string given to --plugin.
  const char* 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_;
};

// A manager class for plugins.

class Plugin_manager
{
 public:
  Plugin_manager(const General_options& options)
    : plugins_(), in_replacement_phase_(false), options_(options),
      workqueue_(NULL), input_objects_(NULL), symtab_(NULL), layout_(NULL),
      dirpath_(NULL), mapfile_(NULL), this_blocker_(NULL)
  { this->current_ = plugins_.end(); }

  ~Plugin_manager();

  // Add a plugin library.
  void
  add_plugin(const char* args)
  { this->plugins_.push_back(new Plugin(args)); }

  // 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, Input_objects* input_objects,
                   Symbol_table* symtab, Layout* layout, Dirsearch* dirpath,
                   Mapfile* mapfile, Task_token** last_blocker);

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

  // Add a new input file.
  ld_plugin_status
  add_input_file(char *pathname);

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

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


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

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

  // Add symbol information to the global symbol table.
  void
  add_symbols(Symbol_table* symtab, Layout* layout)
  { this->do_add_symbols(symtab, layout); }

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

 protected:
  // Return TRUE if this is an object claimed by a plugin.
  virtual Pluginobj*
  do_pluginobj()
  { return this; }

  // Add symbol information to the global symbol table--implemented by
  // child class.
  virtual void
  do_add_symbols(Symbol_table*, Layout*) = 0;

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

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

  void
  do_add_symbols(Symbol_table*, Layout*);

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

  // 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 adding the symbols to the symbol table.  These
// tasks must be run in the same order as the arguments appear on the
// command line.

class Add_plugin_symbols : public Task
{
 public:
  // THIS_BLOCKER is used to prevent this task from running before the
  // one for the previous input file.  NEXT_BLOCKER is used to prevent
  // the next task from running.
  Add_plugin_symbols(Symbol_table* symtab,
	             Layout* layout,
	             Pluginobj* obj,
	             Task_token* this_blocker,
	             Task_token* next_blocker)
    : symtab_(symtab), layout_(layout), obj_(obj),
      this_blocker_(this_blocker), next_blocker_(next_blocker)
  { }

  ~Add_plugin_symbols();

  // The standard Task methods.

  Task_token*
  is_runnable();

  void
  locks(Task_locker*);

  void
  run(Workqueue*);

  std::string
  get_name() const
  { return "Add_plugin_symbols " + this->obj_->name(); }

private:
  Symbol_table* symtab_;
  Layout* layout_;
  Pluginobj* obj_;
  Task_token* this_blocker_;
  Task_token* next_blocker_;
};

// 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:
  // Call the plugin hook.
  void
  do_plugin_hook(Workqueue*);

  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)
