// plugin.cc -- 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.

#include "gold.h"

#include <cstdio>
#include <cstdarg>
#include <cstring>
#include <string>
#include <vector>

#ifdef ENABLE_PLUGINS
#include <dlfcn.h>
#endif

#include "parameters.h"
#include "errors.h"
#include "fileread.h"
#include "layout.h"
#include "options.h"
#include "plugin.h"
#include "target.h"
#include "readsyms.h"
#include "symtab.h"
#include "elfcpp.h"

namespace gold
{

#ifdef ENABLE_PLUGINS

// The linker's exported interfaces.

extern "C"
{

static enum ld_plugin_status
register_claim_file(ld_plugin_claim_file_handler handler);

static enum ld_plugin_status
register_all_symbols_read(ld_plugin_all_symbols_read_handler handler);

static enum ld_plugin_status
register_cleanup(ld_plugin_cleanup_handler handler);

static enum ld_plugin_status
add_symbols(void *handle, int nsyms, const struct ld_plugin_symbol *syms);

static enum ld_plugin_status
get_input_file(const void *handle, struct ld_plugin_input_file *file);

static enum ld_plugin_status
get_view(const void *handle, const void **viewp);

static enum ld_plugin_status
release_input_file(const void *handle);

static enum ld_plugin_status
get_symbols(const void *handle, int nsyms, struct ld_plugin_symbol *syms);

static enum ld_plugin_status
add_input_file(const char *pathname);

static enum ld_plugin_status
add_input_library(const char *pathname);

static enum ld_plugin_status
set_extra_library_path(const char *path);

static enum ld_plugin_status
message(int level, const char *format, ...);

static enum ld_plugin_status
get_input_section_count(const void* handle, unsigned int* count);

static enum ld_plugin_status
get_input_section_type(const struct ld_plugin_section section,
                       unsigned int* type);

static enum ld_plugin_status
get_input_section_name(const struct ld_plugin_section section,
                       char** section_name_ptr);

static enum ld_plugin_status
get_input_section_contents(const struct ld_plugin_section section,
                           const unsigned char** section_contents,
		           size_t* len);

static enum ld_plugin_status
update_section_order(const struct ld_plugin_section *section_list,
		     unsigned int num_sections);

static enum ld_plugin_status
allow_section_ordering();

};

#endif // ENABLE_PLUGINS

static Pluginobj* make_sized_plugin_object(Input_file* input_file,
                                           off_t offset, off_t filesize);

// Plugin methods.

// Load one plugin library.

void
Plugin::load()
{
#ifdef ENABLE_PLUGINS
  // Load the plugin library.
  // FIXME: Look for the library in standard locations.
  this->handle_ = dlopen(this->filename_.c_str(), RTLD_NOW);
  if (this->handle_ == NULL)
    {
      gold_error(_("%s: could not load plugin library: %s"),
                 this->filename_.c_str(), dlerror());
      return;
    }

  // Find the plugin's onload entry point.
  void* ptr = dlsym(this->handle_, "onload");
  if (ptr == NULL)
    {
      gold_error(_("%s: could not find onload entry point"),
                 this->filename_.c_str());
      return;
    }
  ld_plugin_onload onload;
  gold_assert(sizeof(onload) == sizeof(ptr));
  memcpy(&onload, &ptr, sizeof(ptr));

  // Get the linker's version number.
  const char* ver = get_version_string();
  int major = 0;
  int minor = 0;
  sscanf(ver, "%d.%d", &major, &minor);

  // Allocate and populate a transfer vector.
  const int tv_fixed_size = 23;

  int tv_size = this->args_.size() + tv_fixed_size;
  ld_plugin_tv* tv = new ld_plugin_tv[tv_size];

  // Put LDPT_MESSAGE at the front of the list so the plugin can use it
  // while processing subsequent entries.
  int i = 0;
  tv[i].tv_tag = LDPT_MESSAGE;
  tv[i].tv_u.tv_message = message;

  ++i;
  tv[i].tv_tag = LDPT_API_VERSION;
  tv[i].tv_u.tv_val = LD_PLUGIN_API_VERSION;

  ++i;
  tv[i].tv_tag = LDPT_GOLD_VERSION;
  tv[i].tv_u.tv_val = major * 100 + minor;

  ++i;
  tv[i].tv_tag = LDPT_LINKER_OUTPUT;
  if (parameters->options().relocatable())
    tv[i].tv_u.tv_val = LDPO_REL;
  else if (parameters->options().shared())
    tv[i].tv_u.tv_val = LDPO_DYN;
  else
    tv[i].tv_u.tv_val = LDPO_EXEC;

  ++i;
  tv[i].tv_tag = LDPT_OUTPUT_NAME;
  tv[i].tv_u.tv_string = parameters->options().output();

  for (unsigned int j = 0; j < this->args_.size(); ++j)
    {
      ++i;
      tv[i].tv_tag = LDPT_OPTION;
      tv[i].tv_u.tv_string = this->args_[j].c_str();
    }

  ++i;
  tv[i].tv_tag = LDPT_REGISTER_CLAIM_FILE_HOOK;
  tv[i].tv_u.tv_register_claim_file = register_claim_file;

  ++i;
  tv[i].tv_tag = LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK;
  tv[i].tv_u.tv_register_all_symbols_read = register_all_symbols_read;

  ++i;
  tv[i].tv_tag = LDPT_REGISTER_CLEANUP_HOOK;
  tv[i].tv_u.tv_register_cleanup = register_cleanup;

  ++i;
  tv[i].tv_tag = LDPT_ADD_SYMBOLS;
  tv[i].tv_u.tv_add_symbols = add_symbols;

  ++i;
  tv[i].tv_tag = LDPT_GET_INPUT_FILE;
  tv[i].tv_u.tv_get_input_file = get_input_file;

  ++i;
  tv[i].tv_tag = LDPT_GET_VIEW;
  tv[i].tv_u.tv_get_view = get_view;

  ++i;
  tv[i].tv_tag = LDPT_RELEASE_INPUT_FILE;
  tv[i].tv_u.tv_release_input_file = release_input_file;

  ++i;
  tv[i].tv_tag = LDPT_GET_SYMBOLS;
  tv[i].tv_u.tv_get_symbols = get_symbols;

  ++i;
  tv[i].tv_tag = LDPT_ADD_INPUT_FILE;
  tv[i].tv_u.tv_add_input_file = add_input_file;

  ++i;
  tv[i].tv_tag = LDPT_ADD_INPUT_LIBRARY;
  tv[i].tv_u.tv_add_input_library = add_input_library;

  ++i;
  tv[i].tv_tag = LDPT_SET_EXTRA_LIBRARY_PATH;
  tv[i].tv_u.tv_set_extra_library_path = set_extra_library_path;

  ++i;
  tv[i].tv_tag = LDPT_GET_INPUT_SECTION_COUNT;
  tv[i].tv_u.tv_get_input_section_count = get_input_section_count;

  ++i;
  tv[i].tv_tag = LDPT_GET_INPUT_SECTION_TYPE;
  tv[i].tv_u.tv_get_input_section_type = get_input_section_type;

  ++i;
  tv[i].tv_tag = LDPT_GET_INPUT_SECTION_NAME;
  tv[i].tv_u.tv_get_input_section_name = get_input_section_name;

  ++i;
  tv[i].tv_tag = LDPT_GET_INPUT_SECTION_CONTENTS;
  tv[i].tv_u.tv_get_input_section_contents = get_input_section_contents;

  ++i;
  tv[i].tv_tag = LDPT_UPDATE_SECTION_ORDER;
  tv[i].tv_u.tv_update_section_order = update_section_order;

  ++i;
  tv[i].tv_tag = LDPT_ALLOW_SECTION_ORDERING;
  tv[i].tv_u.tv_allow_section_ordering = allow_section_ordering;

  ++i;
  tv[i].tv_tag = LDPT_NULL;
  tv[i].tv_u.tv_val = 0;

  gold_assert(i == tv_size - 1);

  // Call the onload entry point.
  (*onload)(tv);

  delete[] tv;
#endif // ENABLE_PLUGINS
}

// Call the plugin claim-file handler.

inline bool
Plugin::claim_file(struct ld_plugin_input_file* plugin_input_file)
{
  int claimed = 0;

  if (this->claim_file_handler_ != NULL)
    {
      (*this->claim_file_handler_)(plugin_input_file, &claimed);
      if (claimed)
        return true;
    }
  return false;
}

// Call the all-symbols-read handler.

inline void
Plugin::all_symbols_read()
{
  if (this->all_symbols_read_handler_ != NULL)
    (*this->all_symbols_read_handler_)();
}

// Call the cleanup handler.

inline void
Plugin::cleanup()
{
  if (this->cleanup_handler_ != NULL && !this->cleanup_done_)
    {
      // Set this flag before calling to prevent a recursive plunge
      // in the event that a plugin's cleanup handler issues a
      // fatal error.
      this->cleanup_done_ = true;
      (*this->cleanup_handler_)();
    }
}

// This task is used to rescan archives as needed.

class Plugin_rescan : public Task
{
 public:
  Plugin_rescan(Task_token* this_blocker, Task_token* next_blocker)
    : this_blocker_(this_blocker), next_blocker_(next_blocker)
  { }

  ~Plugin_rescan()
  {
    delete this->this_blocker_;
  }

  Task_token*
  is_runnable()
  {
    if (this->this_blocker_->is_blocked())
      return this->this_blocker_;
    return NULL;
  }

  void
  locks(Task_locker* tl)
  { tl->add(this, this->next_blocker_); }

  void
  run(Workqueue*)
  { parameters->options().plugins()->rescan(this); }

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

 private:
  Task_token* this_blocker_;
  Task_token* next_blocker_;
};

// Plugin_manager methods.

Plugin_manager::~Plugin_manager()
{
  for (Plugin_list::iterator p = this->plugins_.begin();
       p != this->plugins_.end();
       ++p)
    delete *p;
  this->plugins_.clear();
  for (Object_list::iterator obj = this->objects_.begin();
       obj != this->objects_.end();
       ++obj)
    delete *obj;
  this->objects_.clear();
}

// Load all plugin libraries.

void
Plugin_manager::load_plugins(Layout* layout)
{
  this->layout_ = layout;
  for (this->current_ = this->plugins_.begin();
       this->current_ != this->plugins_.end();
       ++this->current_)
    (*this->current_)->load();
}

// Call the plugin claim-file handlers in turn to see if any claim the file.

Pluginobj*
Plugin_manager::claim_file(Input_file* input_file, off_t offset,
                           off_t filesize, Object* elf_object)
{
  if (this->in_replacement_phase_)
    return NULL;

  unsigned int handle = this->objects_.size();
  this->input_file_ = input_file;
  this->plugin_input_file_.name = input_file->filename().c_str();
  this->plugin_input_file_.fd = input_file->file().descriptor();
  this->plugin_input_file_.offset = offset;
  this->plugin_input_file_.filesize = filesize;
  this->plugin_input_file_.handle = reinterpret_cast<void*>(handle);
  if (elf_object != NULL)
    this->objects_.push_back(elf_object);
  this->in_claim_file_handler_ = true;

  for (this->current_ = this->plugins_.begin();
       this->current_ != this->plugins_.end();
       ++this->current_)
    {
      if ((*this->current_)->claim_file(&this->plugin_input_file_))
        {
	  this->any_claimed_ = true;
	  this->in_claim_file_handler_ = false;

          if (this->objects_.size() > handle
              && this->objects_[handle]->pluginobj() != NULL)
            return this->objects_[handle]->pluginobj();

          // If the plugin claimed the file but did not call the
          // add_symbols callback, we need to create the Pluginobj now.
          Pluginobj* obj = this->make_plugin_object(handle);
          return obj;
        }
    }

  this->in_claim_file_handler_ = false;
  return NULL;
}

// Save an archive.  This is used so that a plugin can add a file
// which refers to a symbol which was not previously referenced.  In
// that case we want to pretend that the symbol was referenced before,
// and pull in the archive object.

void
Plugin_manager::save_archive(Archive* archive)
{
  if (this->in_replacement_phase_ || !this->any_claimed_)
    delete archive;
  else
    this->rescannable_.push_back(Rescannable(archive));
}

// Save an Input_group.  This is like save_archive.

void
Plugin_manager::save_input_group(Input_group* input_group)
{
  if (this->in_replacement_phase_ || !this->any_claimed_)
    delete input_group;
  else
    this->rescannable_.push_back(Rescannable(input_group));
}

// Call the all-symbols-read handlers.

void
Plugin_manager::all_symbols_read(Workqueue* workqueue, Task* task,
                                 Input_objects* input_objects,
	                         Symbol_table* symtab,
	                         Dirsearch* dirpath, Mapfile* mapfile,
	                         Task_token** last_blocker)
{
  this->in_replacement_phase_ = true;
  this->workqueue_ = workqueue;
  this->task_ = task;
  this->input_objects_ = input_objects;
  this->symtab_ = symtab;
  this->dirpath_ = dirpath;
  this->mapfile_ = mapfile;
  this->this_blocker_ = NULL;

  for (this->current_ = this->plugins_.begin();
       this->current_ != this->plugins_.end();
       ++this->current_)
    (*this->current_)->all_symbols_read();

  if (this->any_added_)
    {
      Task_token* next_blocker = new Task_token(true);
      next_blocker->add_blocker();
      workqueue->queue(new Plugin_rescan(this->this_blocker_, next_blocker));
      this->this_blocker_ = next_blocker;
    }

  *last_blocker = this->this_blocker_;
}

// This is called when we see a new undefined symbol.  If we are in
// the replacement phase, this means that we may need to rescan some
// archives we have previously seen.

void
Plugin_manager::new_undefined_symbol(Symbol* sym)
{
  if (this->in_replacement_phase_)
    this->undefined_symbols_.push_back(sym);
}

// Rescan archives as needed.  This handles the case where a new
// object file added by a plugin has an undefined reference to some
// symbol defined in an archive.

void
Plugin_manager::rescan(Task* task)
{
  size_t rescan_pos = 0;
  size_t rescan_size = this->rescannable_.size();
  while (!this->undefined_symbols_.empty())
    {
      if (rescan_pos >= rescan_size)
	{
	  this->undefined_symbols_.clear();
	  return;
	}

      Undefined_symbol_list undefs;
      undefs.reserve(this->undefined_symbols_.size());
      this->undefined_symbols_.swap(undefs);

      size_t min_rescan_pos = rescan_size;

      for (Undefined_symbol_list::const_iterator p = undefs.begin();
	   p != undefs.end();
	   ++p)
	{
	  if (!(*p)->is_undefined())
	    continue;

	  this->undefined_symbols_.push_back(*p);

	  // Find the first rescan archive which defines this symbol,
	  // starting at the current rescan position.  The rescan position
	  // exists so that given -la -lb -lc we don't look for undefined
	  // symbols in -lb back in -la, but instead get the definition
	  // from -lc.  Don't bother to look past the current minimum
	  // rescan position.
	  for (size_t i = rescan_pos; i < min_rescan_pos; ++i)
	    {
	      if (this->rescannable_defines(i, *p))
		{
		  min_rescan_pos = i;
		  break;
		}
	    }
	}

      if (min_rescan_pos >= rescan_size)
	{
	  // We didn't find any rescannable archives which define any
	  // undefined symbols.
	  return;
	}

      const Rescannable& r(this->rescannable_[min_rescan_pos]);
      if (r.is_archive)
	{
	  Task_lock_obj<Archive> tl(task, r.u.archive);
	  r.u.archive->add_symbols(this->symtab_, this->layout_,
				   this->input_objects_, this->mapfile_);
	}
      else
	{
	  size_t next_saw_undefined = this->symtab_->saw_undefined();
	  size_t saw_undefined;
	  do
	    {
	      saw_undefined = next_saw_undefined;

	      for (Input_group::const_iterator p = r.u.input_group->begin();
		   p != r.u.input_group->end();
		   ++p)
		{
		  Task_lock_obj<Archive> tl(task, *p);

		  (*p)->add_symbols(this->symtab_, this->layout_,
				    this->input_objects_, this->mapfile_);
		}

	      next_saw_undefined = this->symtab_->saw_undefined();
	    }
	  while (saw_undefined != next_saw_undefined);
	}

      for (size_t i = rescan_pos; i < min_rescan_pos + 1; ++i)
	{
	  if (this->rescannable_[i].is_archive)
	    delete this->rescannable_[i].u.archive;
	  else
	    delete this->rescannable_[i].u.input_group;
	}

      rescan_pos = min_rescan_pos + 1;
    }
}

// Return whether the rescannable at index I defines SYM.

bool
Plugin_manager::rescannable_defines(size_t i, Symbol* sym)
{
  const Rescannable& r(this->rescannable_[i]);
  if (r.is_archive)
    return r.u.archive->defines_symbol(sym);
  else
    {
      for (Input_group::const_iterator p = r.u.input_group->begin();
	   p != r.u.input_group->end();
	   ++p)
	{
	  if ((*p)->defines_symbol(sym))
	    return true;
	}
      return false;
    }
}

// Layout deferred objects.

void
Plugin_manager::layout_deferred_objects()
{
  Deferred_layout_list::iterator obj;

  for (obj = this->deferred_layout_objects_.begin();
       obj != this->deferred_layout_objects_.end();
       ++obj)
    {
      // Lock the object so we can read from it.  This is only called
      // single-threaded from queue_middle_tasks, so it is OK to lock.
      // Unfortunately we have no way to pass in a Task token.
      const Task* dummy_task = reinterpret_cast<const Task*>(-1);
      Task_lock_obj<Object> tl(dummy_task, *obj);
      (*obj)->layout_deferred_sections(this->layout_);
    }
}

// Call the cleanup handlers.

void
Plugin_manager::cleanup()
{
  for (this->current_ = this->plugins_.begin();
       this->current_ != this->plugins_.end();
       ++this->current_)
    (*this->current_)->cleanup();
}

// Make a new Pluginobj object.  This is called when the plugin calls
// the add_symbols API.

Pluginobj*
Plugin_manager::make_plugin_object(unsigned int handle)
{
  // Make sure we aren't asked to make an object for the same handle twice.
  if (this->objects_.size() != handle
      && this->objects_[handle]->pluginobj() != NULL)
    return NULL;

  Pluginobj* obj = make_sized_plugin_object(this->input_file_,
                                            this->plugin_input_file_.offset,
                                            this->plugin_input_file_.filesize);


  // If the elf object for this file was pushed into the objects_ vector, delete
  // it to make room for the Pluginobj as this file is claimed.
  if (this->objects_.size() != handle)
    this->objects_.pop_back();

  this->objects_.push_back(obj);
  return obj;
}

// Get the input file information with an open (possibly re-opened)
// file descriptor.

ld_plugin_status
Plugin_manager::get_input_file(unsigned int handle,
                               struct ld_plugin_input_file* file)
{
  Pluginobj* obj = this->object(handle)->pluginobj();
  if (obj == NULL)
    return LDPS_BAD_HANDLE;

  obj->lock(this->task_);
  file->name = obj->filename().c_str();
  file->fd = obj->descriptor();
  file->offset = obj->offset();
  file->filesize = obj->filesize();
  file->handle = reinterpret_cast<void*>(handle);
  return LDPS_OK;
}

// Release the input file.

ld_plugin_status
Plugin_manager::release_input_file(unsigned int handle)
{
  if (this->object(handle) == NULL)
    return LDPS_BAD_HANDLE;

  Pluginobj* obj = this->object(handle)->pluginobj();

  if (obj == NULL)
    return LDPS_BAD_HANDLE;

  obj->unlock(this->task_);
  return LDPS_OK;
}

// Get the elf object corresponding to the handle. Return NULL if we
// found a Pluginobj instead.

Object*
Plugin_manager::get_elf_object(const void* handle)
{
  Object* obj = this->object(
      static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle)));

  // The object should not be a Pluginobj.
  if (obj == NULL
      || obj->pluginobj() != NULL)
    return NULL;

  return obj;
}

ld_plugin_status
Plugin_manager::get_view(unsigned int handle, const void **viewp)
{
  off_t offset;
  size_t filesize;
  Input_file *input_file;
  if (this->in_claim_file_handler_)
    {
      // We are being called from the claim_file hook.
      const struct ld_plugin_input_file &f = this->plugin_input_file_;
      offset = f.offset;
      filesize = f.filesize;
      input_file = this->input_file_;
    }
  else
    {
      // An already claimed file.
      if (this->object(handle) == NULL)
        return LDPS_BAD_HANDLE;
      Pluginobj* obj = this->object(handle)->pluginobj();
      if (obj == NULL)
        return LDPS_BAD_HANDLE;
      offset = obj->offset();
      filesize = obj->filesize();
      input_file = obj->input_file();
    }
  *viewp = (void*) input_file->file().get_view(offset, 0, filesize, false,
                                               false);
  return LDPS_OK;
}

// Add a new library path.

ld_plugin_status
Plugin_manager::set_extra_library_path(const char* path)
{
  this->extra_search_path_ = std::string(path);
  return LDPS_OK;
}

// Add a new input file.

ld_plugin_status
Plugin_manager::add_input_file(const char* pathname, bool is_lib)
{
  Input_file_argument file(pathname,
                           (is_lib
                            ? Input_file_argument::INPUT_FILE_TYPE_LIBRARY
                            : Input_file_argument::INPUT_FILE_TYPE_FILE),
                           (is_lib
                            ? this->extra_search_path_.c_str()
                            : ""),
                           false,
                           this->options_);
  Input_argument* input_argument = new Input_argument(file);
  Task_token* next_blocker = new Task_token(true);
  next_blocker->add_blocker();
  if (parameters->incremental())
    gold_error(_("input files added by plug-ins in --incremental mode not "
		 "supported yet"));
  this->workqueue_->queue_soon(new Read_symbols(this->input_objects_,
                                                this->symtab_,
                                                this->layout_,
                                                this->dirpath_,
						0,
                                                this->mapfile_,
                                                input_argument,
                                                NULL,
                                                NULL,
                                                this->this_blocker_,
                                                next_blocker));
  this->this_blocker_ = next_blocker;
  this->any_added_ = true;
  return LDPS_OK;
}

// Class Pluginobj.

Pluginobj::Pluginobj(const std::string& name, Input_file* input_file,
                     off_t offset, off_t filesize)
  : Object(name, input_file, false, offset),
    nsyms_(0), syms_(NULL), symbols_(), filesize_(filesize), comdat_map_()
{
}

// Return TRUE if a defined symbol might be reachable from outside the
// universe of claimed objects.

static inline bool
is_visible_from_outside(Symbol* lsym)
{
  if (lsym->in_real_elf())
    return true;
  if (parameters->options().relocatable())
    return true;
  if (parameters->options().is_undefined(lsym->name()))
    return true;
  if (parameters->options().export_dynamic() || parameters->options().shared())
    return lsym->is_externally_visible();
  return false;
}

// Get symbol resolution info.

ld_plugin_status
Pluginobj::get_symbol_resolution_info(int nsyms, ld_plugin_symbol* syms) const
{
  if (nsyms > this->nsyms_)
    return LDPS_NO_SYMS;

  if (static_cast<size_t>(nsyms) > this->symbols_.size())
    {
      // We never decided to include this object. We mark all symbols as
      // preempted.
      gold_assert(this->symbols_.size() == 0);
      for (int i = 0; i < nsyms; i++)
        syms[i].resolution = LDPR_PREEMPTED_REG;
      return LDPS_OK;
    }

  for (int i = 0; i < nsyms; i++)
    {
      ld_plugin_symbol* isym = &syms[i];
      Symbol* lsym = this->symbols_[i];
      ld_plugin_symbol_resolution res = LDPR_UNKNOWN;

      if (lsym->is_undefined())
        // The symbol remains undefined.
        res = LDPR_UNDEF;
      else if (isym->def == LDPK_UNDEF
               || isym->def == LDPK_WEAKUNDEF
               || isym->def == LDPK_COMMON)
        {
          // The original symbol was undefined or common.
          if (lsym->source() != Symbol::FROM_OBJECT)
            res = LDPR_RESOLVED_EXEC;
          else if (lsym->object()->pluginobj() == this)
            res = (is_visible_from_outside(lsym)
                   ? LDPR_PREVAILING_DEF
                   : LDPR_PREVAILING_DEF_IRONLY);
          else if (lsym->object()->pluginobj() != NULL)
            res = LDPR_RESOLVED_IR;
          else if (lsym->object()->is_dynamic())
            res = LDPR_RESOLVED_DYN;
          else
            res = LDPR_RESOLVED_EXEC;
        }
      else
        {
          // The original symbol was a definition.
          if (lsym->source() != Symbol::FROM_OBJECT)
            res = LDPR_PREEMPTED_REG;
          else if (lsym->object() == static_cast<const Object*>(this))
            res = (is_visible_from_outside(lsym)
                   ? LDPR_PREVAILING_DEF
                   : LDPR_PREVAILING_DEF_IRONLY);
          else
            res = (lsym->object()->pluginobj() != NULL
                   ? LDPR_PREEMPTED_IR
                   : LDPR_PREEMPTED_REG);
        }
      isym->resolution = res;
    }
  return LDPS_OK;
}

// Return TRUE if the comdat group with key COMDAT_KEY from this object
// should be kept.

bool
Pluginobj::include_comdat_group(std::string comdat_key, Layout* layout)
{
  std::pair<Comdat_map::iterator, bool> ins =
    this->comdat_map_.insert(std::make_pair(comdat_key, false));

  // If this is the first time we've seen this comdat key, ask the
  // layout object whether it should be included.
  if (ins.second)
    ins.first->second = layout->find_or_add_kept_section(comdat_key,
							 NULL, 0, true,
							 true, NULL);

  return ins.first->second;
}

// Class Sized_pluginobj.

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

// Read the symbols.  Not used for plugin objects.

template<int size, bool big_endian>
void
Sized_pluginobj<size, big_endian>::do_read_symbols(Read_symbols_data*)
{
  gold_unreachable();
}

// Lay out the input sections.  Not used for plugin objects.

template<int size, bool big_endian>
void
Sized_pluginobj<size, big_endian>::do_layout(Symbol_table*, Layout*,
                                             Read_symbols_data*)
{
  gold_unreachable();
}

// Add the symbols to the symbol table.

template<int size, bool big_endian>
void
Sized_pluginobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
                                                  Read_symbols_data*,
                                                  Layout* layout)
{
  const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
  unsigned char symbuf[sym_size];
  elfcpp::Sym<size, big_endian> sym(symbuf);
  elfcpp::Sym_write<size, big_endian> osym(symbuf);

  typedef typename elfcpp::Elf_types<size>::Elf_WXword Elf_size_type;

  this->symbols_.resize(this->nsyms_);

  for (int i = 0; i < this->nsyms_; ++i)
    {
      const struct ld_plugin_symbol* isym = &this->syms_[i];
      const char* name = isym->name;
      const char* ver = isym->version;
      elfcpp::Elf_Half shndx;
      elfcpp::STB bind;
      elfcpp::STV vis;

      if (name != NULL && name[0] == '\0')
        name = NULL;
      if (ver != NULL && ver[0] == '\0')
        ver = NULL;

      switch (isym->def)
        {
        case LDPK_WEAKDEF:
        case LDPK_WEAKUNDEF:
          bind = elfcpp::STB_WEAK;
          break;
        case LDPK_DEF:
        case LDPK_UNDEF:
        case LDPK_COMMON:
        default:
          bind = elfcpp::STB_GLOBAL;
          break;
        }

      switch (isym->def)
        {
        case LDPK_DEF:
        case LDPK_WEAKDEF:
          shndx = elfcpp::SHN_ABS;
          break;
        case LDPK_COMMON:
          shndx = elfcpp::SHN_COMMON;
          break;
        case LDPK_UNDEF:
        case LDPK_WEAKUNDEF:
        default:
          shndx = elfcpp::SHN_UNDEF;
          break;
        }

      switch (isym->visibility)
        {
        case LDPV_PROTECTED:
          vis = elfcpp::STV_PROTECTED;
          break;
        case LDPV_INTERNAL:
          vis = elfcpp::STV_INTERNAL;
          break;
        case LDPV_HIDDEN:
          vis = elfcpp::STV_HIDDEN;
          break;
        case LDPV_DEFAULT:
        default:
          vis = elfcpp::STV_DEFAULT;
          break;
        }

      if (isym->comdat_key != NULL
          && isym->comdat_key[0] != '\0'
          && !this->include_comdat_group(isym->comdat_key, layout))
        shndx = elfcpp::SHN_UNDEF;

      osym.put_st_name(0);
      osym.put_st_value(0);
      osym.put_st_size(static_cast<Elf_size_type>(isym->size));
      osym.put_st_info(bind, elfcpp::STT_NOTYPE);
      osym.put_st_other(vis, 0);
      osym.put_st_shndx(shndx);

      this->symbols_[i] =
        symtab->add_from_pluginobj<size, big_endian>(this, name, ver, &sym);
    }
}

template<int size, bool big_endian>
Archive::Should_include
Sized_pluginobj<size, big_endian>::do_should_include_member(
    Symbol_table* symtab,
    Layout* layout,
    Read_symbols_data*,
    std::string* why)
{
  char* tmpbuf = NULL;
  size_t tmpbuflen = 0;

  for (int i = 0; i < this->nsyms_; ++i)
    {
      const struct ld_plugin_symbol& sym = this->syms_[i];
      const char* name = sym.name;
      Symbol* symbol;
      Archive::Should_include t = Archive::should_include_member(symtab,
								 layout,
								 name,
								 &symbol, why,
								 &tmpbuf,
								 &tmpbuflen);
      if (t == Archive::SHOULD_INCLUDE_YES)
	{
	  if (tmpbuf != NULL)
	    free(tmpbuf);
	  return t;
	}
    }
  if (tmpbuf != NULL)
    free(tmpbuf);
  return Archive::SHOULD_INCLUDE_UNKNOWN;
}

// Iterate over global symbols, calling a visitor class V for each.

template<int size, bool big_endian>
void
Sized_pluginobj<size, big_endian>::do_for_all_global_symbols(
    Read_symbols_data*,
    Library_base::Symbol_visitor_base* v)
{
  for (int i = 0; i < this->nsyms_; ++i)
    {
      const struct ld_plugin_symbol& sym = this->syms_[i];
      if (sym.def != LDPK_UNDEF)
	v->visit(sym.name);
    }
}

// Iterate over local symbols, calling a visitor class V for each GOT offset
// associated with a local symbol.
template<int size, bool big_endian>
void
Sized_pluginobj<size, big_endian>::do_for_all_local_got_entries(
    Got_offset_list::Visitor*) const
{
  gold_unreachable();
}

// Get the size of a section.  Not used for plugin objects.

template<int size, bool big_endian>
uint64_t
Sized_pluginobj<size, big_endian>::do_section_size(unsigned int)
{
  gold_unreachable();
  return 0;
}

// Get the name of a section.  Not used for plugin objects.

template<int size, bool big_endian>
std::string
Sized_pluginobj<size, big_endian>::do_section_name(unsigned int)
{
  gold_unreachable();
  return std::string();
}

// Return a view of the contents of a section.  Not used for plugin objects.

template<int size, bool big_endian>
Object::Location
Sized_pluginobj<size, big_endian>::do_section_contents(unsigned int)
{
  Location loc(0, 0);

  gold_unreachable();
  return loc;
}

// Return section flags.  Not used for plugin objects.

template<int size, bool big_endian>
uint64_t
Sized_pluginobj<size, big_endian>::do_section_flags(unsigned int)
{
  gold_unreachable();
  return 0;
}

// Return section entsize.  Not used for plugin objects.

template<int size, bool big_endian>
uint64_t
Sized_pluginobj<size, big_endian>::do_section_entsize(unsigned int)
{
  gold_unreachable();
  return 0;
}

// Return section address.  Not used for plugin objects.

template<int size, bool big_endian>
uint64_t
Sized_pluginobj<size, big_endian>::do_section_address(unsigned int)
{
  gold_unreachable();
  return 0;
}

// Return section type.  Not used for plugin objects.

template<int size, bool big_endian>
unsigned int
Sized_pluginobj<size, big_endian>::do_section_type(unsigned int)
{
  gold_unreachable();
  return 0;
}

// Return the section link field.  Not used for plugin objects.

template<int size, bool big_endian>
unsigned int
Sized_pluginobj<size, big_endian>::do_section_link(unsigned int)
{
  gold_unreachable();
  return 0;
}

// Return the section link field.  Not used for plugin objects.

template<int size, bool big_endian>
unsigned int
Sized_pluginobj<size, big_endian>::do_section_info(unsigned int)
{
  gold_unreachable();
  return 0;
}

// Return the section alignment.  Not used for plugin objects.

template<int size, bool big_endian>
uint64_t
Sized_pluginobj<size, big_endian>::do_section_addralign(unsigned int)
{
  gold_unreachable();
  return 0;
}

// Return the Xindex structure to use.  Not used for plugin objects.

template<int size, bool big_endian>
Xindex*
Sized_pluginobj<size, big_endian>::do_initialize_xindex()
{
  gold_unreachable();
  return NULL;
}

// Get symbol counts.  Not used for plugin objects.

template<int size, bool big_endian>
void
Sized_pluginobj<size, big_endian>::do_get_global_symbol_counts(const Symbol_table*,
                                                   size_t*, size_t*) const
{
  gold_unreachable();
}

// Get symbols.  Not used for plugin objects.

template<int size, bool big_endian>
const Object::Symbols*
Sized_pluginobj<size, big_endian>::do_get_global_symbols() const
{
  gold_unreachable();
}

// Class Plugin_finish.  This task runs after all replacement files have
// been added.  For now, it's a placeholder for a possible plugin API
// to allow the plugin to release most of its resources.  The cleanup
// handlers must be called later, because they can remove the temporary
// object files that are needed until the end of the link.

class Plugin_finish : public Task
{
 public:
  Plugin_finish(Task_token* this_blocker, Task_token* next_blocker)
    : this_blocker_(this_blocker), next_blocker_(next_blocker)
  { }

  ~Plugin_finish()
  {
    if (this->this_blocker_ != NULL)
      delete this->this_blocker_;
  }

  Task_token*
  is_runnable()
  {
    if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked())
      return this->this_blocker_;
    return NULL;
  }

  void
  locks(Task_locker* tl)
  { tl->add(this, this->next_blocker_); }

  void
  run(Workqueue*)
  {
    // We could call early cleanup handlers here.
  }

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

 private:
  Task_token* this_blocker_;
  Task_token* next_blocker_;
};

// Class Plugin_hook.

Plugin_hook::~Plugin_hook()
{
}

// Return whether a Plugin_hook task is runnable.

Task_token*
Plugin_hook::is_runnable()
{
  if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked())
    return this->this_blocker_;
  return NULL;
}

// Return a Task_locker for a Plugin_hook task.  We don't need any
// locks here.

void
Plugin_hook::locks(Task_locker*)
{
}

// Run the "all symbols read" plugin hook.

void
Plugin_hook::run(Workqueue* workqueue)
{
  gold_assert(this->options_.has_plugins());
  Symbol* start_sym = this->symtab_->lookup(parameters->entry());
  if (start_sym != NULL)
    start_sym->set_in_real_elf();

  this->options_.plugins()->all_symbols_read(workqueue,
                                             this,
                                             this->input_objects_,
                                             this->symtab_,
                                             this->dirpath_,
                                             this->mapfile_,
                                             &this->this_blocker_);
  workqueue->queue_soon(new Plugin_finish(this->this_blocker_,
					  this->next_blocker_));
}

// The C interface routines called by the plugins.

#ifdef ENABLE_PLUGINS

// Register a claim-file handler.

static enum ld_plugin_status
register_claim_file(ld_plugin_claim_file_handler handler)
{
  gold_assert(parameters->options().has_plugins());
  parameters->options().plugins()->set_claim_file_handler(handler);
  return LDPS_OK;
}

// Register an all-symbols-read handler.

static enum ld_plugin_status
register_all_symbols_read(ld_plugin_all_symbols_read_handler handler)
{
  gold_assert(parameters->options().has_plugins());
  parameters->options().plugins()->set_all_symbols_read_handler(handler);
  return LDPS_OK;
}

// Register a cleanup handler.

static enum ld_plugin_status
register_cleanup(ld_plugin_cleanup_handler handler)
{
  gold_assert(parameters->options().has_plugins());
  parameters->options().plugins()->set_cleanup_handler(handler);
  return LDPS_OK;
}

// Add symbols from a plugin-claimed input file.

static enum ld_plugin_status
add_symbols(void* handle, int nsyms, const ld_plugin_symbol* syms)
{
  gold_assert(parameters->options().has_plugins());
  Pluginobj* obj = parameters->options().plugins()->make_plugin_object(
      static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle)));
  if (obj == NULL)
    return LDPS_ERR;
  obj->store_incoming_symbols(nsyms, syms);
  return LDPS_OK;
}

// Get the input file information with an open (possibly re-opened)
// file descriptor.

static enum ld_plugin_status
get_input_file(const void* handle, struct ld_plugin_input_file* file)
{
  gold_assert(parameters->options().has_plugins());
  unsigned int obj_index =
      static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle));
  return parameters->options().plugins()->get_input_file(obj_index, file);
}

// Release the input file.

static enum ld_plugin_status
release_input_file(const void* handle)
{
  gold_assert(parameters->options().has_plugins());
  unsigned int obj_index =
      static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle));
  return parameters->options().plugins()->release_input_file(obj_index);
}

static enum ld_plugin_status
get_view(const void *handle, const void **viewp)
{
  gold_assert(parameters->options().has_plugins());
  unsigned int obj_index =
      static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle));
  return parameters->options().plugins()->get_view(obj_index, viewp);
}

// Get the symbol resolution info for a plugin-claimed input file.

static enum ld_plugin_status
get_symbols(const void* handle, int nsyms, ld_plugin_symbol* syms)
{
  gold_assert(parameters->options().has_plugins());
  Object* obj = parameters->options().plugins()->object(
    static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle)));
  if (obj == NULL)
    return LDPS_ERR;
  Pluginobj* plugin_obj = obj->pluginobj();
  if (plugin_obj == NULL)
    return LDPS_ERR;
  return plugin_obj->get_symbol_resolution_info(nsyms, syms);
}

// Add a new (real) input file generated by a plugin.

static enum ld_plugin_status
add_input_file(const char* pathname)
{
  gold_assert(parameters->options().has_plugins());
  return parameters->options().plugins()->add_input_file(pathname, false);
}

// Add a new (real) library required by a plugin.

static enum ld_plugin_status
add_input_library(const char* pathname)
{
  gold_assert(parameters->options().has_plugins());
  return parameters->options().plugins()->add_input_file(pathname, true);
}

// Set the extra library path to be used by libraries added via
// add_input_library

static enum ld_plugin_status
set_extra_library_path(const char* path)
{
  gold_assert(parameters->options().has_plugins());
  return parameters->options().plugins()->set_extra_library_path(path);
}

// Issue a diagnostic message from a plugin.

static enum ld_plugin_status
message(int level, const char* format, ...)
{
  va_list args;
  va_start(args, format);

  switch (level)
    {
    case LDPL_INFO:
      parameters->errors()->info(format, args);
      break;
    case LDPL_WARNING:
      parameters->errors()->warning(format, args);
      break;
    case LDPL_ERROR:
    default:
      parameters->errors()->error(format, args);
      break;
    case LDPL_FATAL:
      parameters->errors()->fatal(format, args);
      break;
    }

  va_end(args);
  return LDPS_OK;
}

// Get the section count of the object corresponding to the handle.  This
// plugin interface can only be called in the claim_file handler of the plugin.

static enum ld_plugin_status
get_input_section_count(const void* handle, unsigned int* count)
{
  gold_assert(parameters->options().has_plugins());

  if (!parameters->options().plugins()->in_claim_file_handler())
    return LDPS_ERR;

  Object* obj = parameters->options().plugins()->get_elf_object(handle);

  if (obj == NULL)
    return LDPS_ERR;

  *count = obj->shnum();
  return LDPS_OK;
}

// Get the type of the specified section in the object corresponding
// to the handle.  This plugin interface can only be called in the
// claim_file handler of the plugin.

static enum ld_plugin_status
get_input_section_type(const struct ld_plugin_section section,
                       unsigned int* type)
{
  gold_assert(parameters->options().has_plugins());

  if (!parameters->options().plugins()->in_claim_file_handler())
    return LDPS_ERR;

  Object* obj
    = parameters->options().plugins()->get_elf_object(section.handle); 

  if (obj == NULL)
    return LDPS_BAD_HANDLE;

  *type = obj->section_type(section.shndx);
  return LDPS_OK;
}

// Get the name of the specified section in the object corresponding
// to the handle.  This plugin interface can only be called in the
// claim_file handler of the plugin.

static enum ld_plugin_status
get_input_section_name(const struct ld_plugin_section section,
                       char** section_name_ptr)
{
  gold_assert(parameters->options().has_plugins());

  if (!parameters->options().plugins()->in_claim_file_handler())
    return LDPS_ERR;

  Object* obj
    = parameters->options().plugins()->get_elf_object(section.handle); 

  if (obj == NULL)
    return LDPS_BAD_HANDLE;

  // Check if the object is locked before getting the section name.
  gold_assert(obj->is_locked());

  const std::string section_name = obj->section_name(section.shndx);
  *section_name_ptr = static_cast<char*>(malloc(section_name.length() + 1));
  memcpy(*section_name_ptr, section_name.c_str(), section_name.length() + 1);
  return LDPS_OK;
}

// Get the contents of the specified section in the object corresponding
// to the handle.  This plugin interface can only be called in the
// claim_file handler of the plugin.

static enum ld_plugin_status
get_input_section_contents(const struct ld_plugin_section section,
			   const unsigned char** section_contents_ptr,
			   size_t* len)
{
  gold_assert(parameters->options().has_plugins());

  if (!parameters->options().plugins()->in_claim_file_handler())
    return LDPS_ERR;

  Object* obj
    = parameters->options().plugins()->get_elf_object(section.handle); 

  if (obj == NULL)
    return LDPS_BAD_HANDLE;

  // Check if the object is locked before getting the section contents.
  gold_assert(obj->is_locked());

  section_size_type plen;
  *section_contents_ptr
      = obj->section_contents(section.shndx, &plen, false);
  *len = plen;
  return LDPS_OK;
}

// Specify the ordering of sections in the final layout. The sections are
// specified as (handle,shndx) pairs in the two arrays in the order in
// which they should appear in the final layout.

static enum ld_plugin_status
update_section_order(const struct ld_plugin_section *section_list,
		     unsigned int num_sections)
{
  gold_assert(parameters->options().has_plugins());

  if (num_sections == 0)
    return LDPS_OK;

  if (section_list == NULL)
    return LDPS_ERR;

  std::map<Section_id, unsigned int> order_map;

  for (unsigned int i = 0; i < num_sections; ++i)
    {
      Object* obj = parameters->options().plugins()->get_elf_object(
          section_list[i].handle);
      if (obj == NULL)
	return LDPS_BAD_HANDLE;
      unsigned int shndx = section_list[i].shndx;
      Section_id secn_id(obj, shndx);
      order_map[secn_id] = i + 1;
    }

  Layout* layout = parameters->options().plugins()->layout();
  gold_assert (layout != NULL);

  for (Layout::Section_list::const_iterator p = layout->section_list().begin();
       p != layout->section_list().end();
       ++p)
    (*p)->update_section_layout(order_map);

  return LDPS_OK;
}

// Let the linker know that the sections could be reordered.

static enum ld_plugin_status
allow_section_ordering()
{
  gold_assert(parameters->options().has_plugins());
  Layout* layout = parameters->options().plugins()->layout();
  layout->set_section_ordering_specified();
  return LDPS_OK;
}

#endif // ENABLE_PLUGINS

// Allocate a Pluginobj object of the appropriate size and endianness.

static Pluginobj*
make_sized_plugin_object(Input_file* input_file, off_t offset, off_t filesize)
{
  Pluginobj* obj = NULL;

  parameters_force_valid_target();
  const Target& target(parameters->target());

  if (target.get_size() == 32)
    {
      if (target.is_big_endian())
#ifdef HAVE_TARGET_32_BIG
        obj = new Sized_pluginobj<32, true>(input_file->filename(),
                                            input_file, offset, filesize);
#else
        gold_error(_("%s: not configured to support "
		     "32-bit big-endian object"),
		   input_file->filename().c_str());
#endif
      else
#ifdef HAVE_TARGET_32_LITTLE
        obj = new Sized_pluginobj<32, false>(input_file->filename(),
                                             input_file, offset, filesize);
#else
        gold_error(_("%s: not configured to support "
		     "32-bit little-endian object"),
		   input_file->filename().c_str());
#endif
    }
  else if (target.get_size() == 64)
    {
      if (target.is_big_endian())
#ifdef HAVE_TARGET_64_BIG
        obj = new Sized_pluginobj<64, true>(input_file->filename(),
                                            input_file, offset, filesize);
#else
        gold_error(_("%s: not configured to support "
		     "64-bit big-endian object"),
		   input_file->filename().c_str());
#endif
      else
#ifdef HAVE_TARGET_64_LITTLE
        obj = new Sized_pluginobj<64, false>(input_file->filename(),
                                             input_file, offset, filesize);
#else
        gold_error(_("%s: not configured to support "
		     "64-bit little-endian object"),
		   input_file->filename().c_str());
#endif
    }

  gold_assert(obj != NULL);
  return obj;
}

} // End namespace gold.
