OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gold/] [plugin.cc] - Diff between revs 27 and 159

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 27 Rev 159
Line 87... Line 87...
set_extra_library_path(const char *path);
set_extra_library_path(const char *path);
 
 
static enum ld_plugin_status
static enum ld_plugin_status
message(int level, const char *format, ...);
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
#endif // ENABLE_PLUGINS
 
 
static Pluginobj* make_sized_plugin_object(Input_file* input_file,
static Pluginobj* make_sized_plugin_object(Input_file* input_file,
Line 131... Line 154...
  int major = 0;
  int major = 0;
  int minor = 0;
  int minor = 0;
  sscanf(ver, "%d.%d", &major, &minor);
  sscanf(ver, "%d.%d", &major, &minor);
 
 
  // Allocate and populate a transfer vector.
  // Allocate and populate a transfer vector.
  const int tv_fixed_size = 17;
  const int tv_fixed_size = 23;
 
 
  int tv_size = this->args_.size() + tv_fixed_size;
  int tv_size = this->args_.size() + tv_fixed_size;
  ld_plugin_tv* tv = new ld_plugin_tv[tv_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
  // Put LDPT_MESSAGE at the front of the list so the plugin can use it
  // while processing subsequent entries.
  // while processing subsequent entries.
Line 214... Line 238...
  ++i;
  ++i;
  tv[i].tv_tag = LDPT_SET_EXTRA_LIBRARY_PATH;
  tv[i].tv_tag = LDPT_SET_EXTRA_LIBRARY_PATH;
  tv[i].tv_u.tv_set_extra_library_path = set_extra_library_path;
  tv[i].tv_u.tv_set_extra_library_path = set_extra_library_path;
 
 
  ++i;
  ++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_tag = LDPT_NULL;
  tv[i].tv_u.tv_val = 0;
  tv[i].tv_u.tv_val = 0;
 
 
  gold_assert(i == tv_size - 1);
  gold_assert(i == tv_size - 1);
 
 
Line 324... Line 372...
}
}
 
 
// Load all plugin libraries.
// Load all plugin libraries.
 
 
void
void
Plugin_manager::load_plugins()
Plugin_manager::load_plugins(Layout* layout)
{
{
 
  this->layout_ = layout;
  for (this->current_ = this->plugins_.begin();
  for (this->current_ = this->plugins_.begin();
       this->current_ != this->plugins_.end();
       this->current_ != this->plugins_.end();
       ++this->current_)
       ++this->current_)
    (*this->current_)->load();
    (*this->current_)->load();
}
}
 
 
// Call the plugin claim-file handlers in turn to see if any claim the file.
// Call the plugin claim-file handlers in turn to see if any claim the file.
 
 
Pluginobj*
Pluginobj*
Plugin_manager::claim_file(Input_file* input_file, off_t offset,
Plugin_manager::claim_file(Input_file* input_file, off_t offset,
                           off_t filesize)
                           off_t filesize, Object* elf_object)
{
{
  if (this->in_replacement_phase_)
  if (this->in_replacement_phase_)
    return NULL;
    return NULL;
 
 
  unsigned int handle = this->objects_.size();
  unsigned int handle = this->objects_.size();
Line 348... Line 397...
  this->plugin_input_file_.name = input_file->filename().c_str();
  this->plugin_input_file_.name = input_file->filename().c_str();
  this->plugin_input_file_.fd = input_file->file().descriptor();
  this->plugin_input_file_.fd = input_file->file().descriptor();
  this->plugin_input_file_.offset = offset;
  this->plugin_input_file_.offset = offset;
  this->plugin_input_file_.filesize = filesize;
  this->plugin_input_file_.filesize = filesize;
  this->plugin_input_file_.handle = reinterpret_cast<void*>(handle);
  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();
  for (this->current_ = this->plugins_.begin();
       this->current_ != this->plugins_.end();
       this->current_ != this->plugins_.end();
       ++this->current_)
       ++this->current_)
    {
    {
      if ((*this->current_)->claim_file(&this->plugin_input_file_))
      if ((*this->current_)->claim_file(&this->plugin_input_file_))
        {
        {
          this->any_claimed_ = true;
          this->any_claimed_ = true;
 
          this->in_claim_file_handler_ = false;
 
 
          if (this->objects_.size() > handle)
          if (this->objects_.size() > handle
            return this->objects_[handle];
              && this->objects_[handle]->pluginobj() != NULL)
 
            return this->objects_[handle]->pluginobj();
 
 
          // If the plugin claimed the file but did not call the
          // If the plugin claimed the file but did not call the
          // add_symbols callback, we need to create the Pluginobj now.
          // add_symbols callback, we need to create the Pluginobj now.
          Pluginobj* obj = this->make_plugin_object(handle);
          Pluginobj* obj = this->make_plugin_object(handle);
          return obj;
          return obj;
        }
        }
    }
    }
 
 
 
  this->in_claim_file_handler_ = false;
  return NULL;
  return NULL;
}
}
 
 
// Save an archive.  This is used so that a plugin can add a file
// 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
// which refers to a symbol which was not previously referenced.  In
Line 400... Line 455...
// Call the all-symbols-read handlers.
// Call the all-symbols-read handlers.
 
 
void
void
Plugin_manager::all_symbols_read(Workqueue* workqueue, Task* task,
Plugin_manager::all_symbols_read(Workqueue* workqueue, Task* task,
                                 Input_objects* input_objects,
                                 Input_objects* input_objects,
                                 Symbol_table* symtab, Layout* layout,
                                 Symbol_table* symtab,
                                 Dirsearch* dirpath, Mapfile* mapfile,
                                 Dirsearch* dirpath, Mapfile* mapfile,
                                 Task_token** last_blocker)
                                 Task_token** last_blocker)
{
{
  this->in_replacement_phase_ = true;
  this->in_replacement_phase_ = true;
  this->workqueue_ = workqueue;
  this->workqueue_ = workqueue;
  this->task_ = task;
  this->task_ = task;
  this->input_objects_ = input_objects;
  this->input_objects_ = input_objects;
  this->symtab_ = symtab;
  this->symtab_ = symtab;
  this->layout_ = layout;
 
  this->dirpath_ = dirpath;
  this->dirpath_ = dirpath;
  this->mapfile_ = mapfile;
  this->mapfile_ = mapfile;
  this->this_blocker_ = NULL;
  this->this_blocker_ = NULL;
 
 
  for (this->current_ = this->plugins_.begin();
  for (this->current_ = this->plugins_.begin();
Line 597... Line 651...
 
 
Pluginobj*
Pluginobj*
Plugin_manager::make_plugin_object(unsigned int handle)
Plugin_manager::make_plugin_object(unsigned int handle)
{
{
  // Make sure we aren't asked to make an object for the same handle twice.
  // Make sure we aren't asked to make an object for the same handle twice.
  if (this->objects_.size() != handle)
  if (this->objects_.size() != handle
 
      && this->objects_[handle]->pluginobj() != NULL)
    return NULL;
    return NULL;
 
 
  Pluginobj* obj = make_sized_plugin_object(this->input_file_,
  Pluginobj* obj = make_sized_plugin_object(this->input_file_,
                                            this->plugin_input_file_.offset,
                                            this->plugin_input_file_.offset,
                                            this->plugin_input_file_.filesize);
                                            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);
  this->objects_.push_back(obj);
  return obj;
  return obj;
}
}
 
 
// Get the input file information with an open (possibly re-opened)
// Get the input file information with an open (possibly re-opened)
Line 614... Line 676...
 
 
ld_plugin_status
ld_plugin_status
Plugin_manager::get_input_file(unsigned int handle,
Plugin_manager::get_input_file(unsigned int handle,
                               struct ld_plugin_input_file* file)
                               struct ld_plugin_input_file* file)
{
{
  Pluginobj* obj = this->object(handle);
  Pluginobj* obj = this->object(handle)->pluginobj();
  if (obj == NULL)
  if (obj == NULL)
    return LDPS_BAD_HANDLE;
    return LDPS_BAD_HANDLE;
 
 
  obj->lock(this->task_);
  obj->lock(this->task_);
  file->name = obj->filename().c_str();
  file->name = obj->filename().c_str();
Line 632... Line 694...
// Release the input file.
// Release the input file.
 
 
ld_plugin_status
ld_plugin_status
Plugin_manager::release_input_file(unsigned int handle)
Plugin_manager::release_input_file(unsigned int handle)
{
{
  Pluginobj* obj = this->object(handle);
  if (this->object(handle) == NULL)
 
    return LDPS_BAD_HANDLE;
 
 
 
  Pluginobj* obj = this->object(handle)->pluginobj();
 
 
  if (obj == NULL)
  if (obj == NULL)
    return LDPS_BAD_HANDLE;
    return LDPS_BAD_HANDLE;
 
 
  obj->unlock(this->task_);
  obj->unlock(this->task_);
  return LDPS_OK;
  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
ld_plugin_status
Plugin_manager::get_view(unsigned int handle, const void **viewp)
Plugin_manager::get_view(unsigned int handle, const void **viewp)
{
{
  off_t offset;
  off_t offset;
  size_t filesize;
  size_t filesize;
  Input_file *input_file;
  Input_file *input_file;
  if (this->objects_.size() == handle)
  if (this->in_claim_file_handler_)
    {
    {
      // We are being called from the claim_file hook.
      // We are being called from the claim_file hook.
      const struct ld_plugin_input_file &f = this->plugin_input_file_;
      const struct ld_plugin_input_file &f = this->plugin_input_file_;
      offset = f.offset;
      offset = f.offset;
      filesize = f.filesize;
      filesize = f.filesize;
      input_file = this->input_file_;
      input_file = this->input_file_;
    }
    }
  else
  else
    {
    {
      // An already claimed file.
      // An already claimed file.
      Pluginobj* obj = this->object(handle);
      if (this->object(handle) == NULL)
 
        return LDPS_BAD_HANDLE;
 
      Pluginobj* obj = this->object(handle)->pluginobj();
      if (obj == NULL)
      if (obj == NULL)
        return LDPS_BAD_HANDLE;
        return LDPS_BAD_HANDLE;
      offset = obj->offset();
      offset = obj->offset();
      filesize = obj->filesize();
      filesize = obj->filesize();
      input_file = obj->input_file();
      input_file = obj->input_file();
Line 1224... Line 1309...
 
 
  this->options_.plugins()->all_symbols_read(workqueue,
  this->options_.plugins()->all_symbols_read(workqueue,
                                             this,
                                             this,
                                             this->input_objects_,
                                             this->input_objects_,
                                             this->symtab_,
                                             this->symtab_,
                                             this->layout_,
 
                                             this->dirpath_,
                                             this->dirpath_,
                                             this->mapfile_,
                                             this->mapfile_,
                                             &this->this_blocker_);
                                             &this->this_blocker_);
  workqueue->queue_soon(new Plugin_finish(this->this_blocker_,
  workqueue->queue_soon(new Plugin_finish(this->this_blocker_,
                                          this->next_blocker_));
                                          this->next_blocker_));
Line 1318... Line 1402...
 
 
static enum ld_plugin_status
static enum ld_plugin_status
get_symbols(const void* handle, int nsyms, ld_plugin_symbol* syms)
get_symbols(const void* handle, int nsyms, ld_plugin_symbol* syms)
{
{
  gold_assert(parameters->options().has_plugins());
  gold_assert(parameters->options().has_plugins());
  Pluginobj* obj = parameters->options().plugins()->object(
  Object* obj = parameters->options().plugins()->object(
      static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle)));
      static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle)));
  if (obj == NULL)
  if (obj == NULL)
    return LDPS_ERR;
    return LDPS_ERR;
  return obj->get_symbol_resolution_info(nsyms, syms);
  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.
// Add a new (real) input file generated by a plugin.
 
 
static enum ld_plugin_status
static enum ld_plugin_status
Line 1382... Line 1469...
 
 
  va_end(args);
  va_end(args);
  return LDPS_OK;
  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
#endif // ENABLE_PLUGINS
 
 
// Allocate a Pluginobj object of the appropriate size and endianness.
// Allocate a Pluginobj object of the appropriate size and endianness.
 
 
static Pluginobj*
static Pluginobj*

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.