* archive.cc (Archive::get_elf_object_for_member): Remove call
to File_read::claim_for_plugin. * descriptors.cc (Descriptors::open): Remove reference to is_claimed. (Descriptors::claim_for_plugin): Remove. * descriptors.h (Descriptors::claim_for_plugin): Remove. (Descriptors::is_claimed): Remove. (claim_descriptor_for_plugin): Remove. * fileread.cc (File_read::claim_for_plugin): Remove. * fileread.h (File_read::claim_for_plugin): Remove. (File_read::descriptor): Reopen descriptor if necessary. * plugin.cc (Plugin::load): Add two new APIs to transfer vector. (Plugin_manager::all_symbols_read): Add task parameter. Change all callers. (Plugin_manager::get_input_file): New function. (Plugin_manager::release_input_file): New function. (Pluginobj::Pluginobj): Add filesize parameter and initialize corresponding data member. (Sized_pluginobj::Sized_pluginobj): Add filesize parameter and pass to base constructor. Change all callers. (get_input_file, release_input_file): New functions. (make_sized_plugin_object): Add filesize parameter. Change all callers. * plugin.h (Plugin_manager::Plugin_manager): Initialize task_ member. (Plugin_manager::all_symbols_read): Add task parameter. (Plugin_manager::get_input_file): New function. (Plugin_manager::release_input_file): New function. (Plugin_manager::task_): New data member. (Pluginobj::Pluginobj): Add filesize parameter. (Pluginobj::filename): New function. (Pluginobj::descriptor): New function. (Pluginobj::filesize): New function. (Pluginobj::filesize_): New data member. (Sized_pluginobj::Sized_pluginobj): Add filesize parameter. * readsyms.cc (Read_symbols::do_read_symbols): Remove call to File_read::claim_for_plugin; use Object::unlock to unlock the file. * testsuite/Makefile.am (plugin_test_4): New test case for plugins with archive libraries. * testsuite/Makefile.in: Regenerate. * testsuite/plugin_test.c (struct sym_info): New type. (get_input_file, release_input_file): New static variables. (onload): Capture new transfer vector entries. (claim_file_hook): Stop reading at end of file according to filesize. Factor out parsing of readelf output into separate function. (all_symbols_read_hook): Exercise get_input_file and release_input_file APIs and get the source file name from the symbol table. Convert source file name to corresponding object file name. Print info message when adding new input files. (parse_readelf_line): New function. * testsuite/plugin_test_1.sh: Add checks for new info messages. * testsuite/plugin_test_2.sh: Likewise. * testsuite/plugin_test_3.sh: Likewise. * testsuite/plugin_test_4.sh: New test case.
This commit is contained in:
parent
fa7f3e7229
commit
0f7c0701ba
16 changed files with 479 additions and 165 deletions
102
gold/plugin.cc
102
gold/plugin.cc
|
@ -1,6 +1,6 @@
|
|||
// plugin.c -- plugin manager for gold -*- C++ -*-
|
||||
|
||||
// Copyright 2008 Free Software Foundation, Inc.
|
||||
// Copyright 2008, 2009 Free Software Foundation, Inc.
|
||||
// Written by Cary Coutant <ccoutant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
|
@ -61,6 +61,12 @@ 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
|
||||
release_input_file(const void *handle);
|
||||
|
||||
static enum ld_plugin_status
|
||||
get_symbols(const void *handle, int nsyms, struct ld_plugin_symbol *syms);
|
||||
|
||||
|
@ -75,7 +81,7 @@ message(int level, const char *format, ...);
|
|||
#endif // ENABLE_PLUGINS
|
||||
|
||||
static Pluginobj* make_sized_plugin_object(Input_file* input_file,
|
||||
off_t offset);
|
||||
off_t offset, off_t filesize);
|
||||
|
||||
// Plugin methods.
|
||||
|
||||
|
@ -112,7 +118,7 @@ Plugin::load()
|
|||
sscanf(ver, "%d.%d", &major, &minor);
|
||||
|
||||
// Allocate and populate a transfer vector.
|
||||
const int tv_fixed_size = 11;
|
||||
const int tv_fixed_size = 13;
|
||||
int tv_size = this->args_.size() + tv_fixed_size;
|
||||
ld_plugin_tv *tv = new ld_plugin_tv[tv_size];
|
||||
|
||||
|
@ -162,6 +168,14 @@ Plugin::load()
|
|||
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_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;
|
||||
|
@ -283,7 +297,7 @@ Plugin_manager::claim_file(Input_file* input_file, off_t offset,
|
|||
// Call the all-symbols-read handlers.
|
||||
|
||||
void
|
||||
Plugin_manager::all_symbols_read(Workqueue* workqueue,
|
||||
Plugin_manager::all_symbols_read(Workqueue* workqueue, Task* task,
|
||||
Input_objects* input_objects,
|
||||
Symbol_table* symtab, Layout* layout,
|
||||
Dirsearch* dirpath, Mapfile* mapfile,
|
||||
|
@ -291,6 +305,7 @@ Plugin_manager::all_symbols_read(Workqueue* workqueue,
|
|||
{
|
||||
this->in_replacement_phase_ = true;
|
||||
this->workqueue_ = workqueue;
|
||||
this->task_ = task;
|
||||
this->input_objects_ = input_objects;
|
||||
this->symtab_ = symtab;
|
||||
this->layout_ = layout;
|
||||
|
@ -344,11 +359,45 @@ Plugin_manager::make_plugin_object(unsigned int handle)
|
|||
return NULL;
|
||||
|
||||
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->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);
|
||||
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)
|
||||
{
|
||||
Pluginobj* obj = this->object(handle);
|
||||
if (obj == NULL)
|
||||
return LDPS_BAD_HANDLE;
|
||||
|
||||
obj->unlock(this->task_);
|
||||
return LDPS_OK;
|
||||
}
|
||||
|
||||
// Add a new input file.
|
||||
|
||||
ld_plugin_status
|
||||
|
@ -375,9 +424,9 @@ Plugin_manager::add_input_file(char *pathname)
|
|||
// Class Pluginobj.
|
||||
|
||||
Pluginobj::Pluginobj(const std::string& name, Input_file* input_file,
|
||||
off_t offset)
|
||||
off_t offset, off_t filesize)
|
||||
: Object(name, input_file, false, offset),
|
||||
nsyms_(0), syms_(NULL), symbols_(), comdat_map_()
|
||||
nsyms_(0), syms_(NULL), symbols_(), filesize_(filesize), comdat_map_()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -468,8 +517,9 @@ template<int size, bool big_endian>
|
|||
Sized_pluginobj<size, big_endian>::Sized_pluginobj(
|
||||
const std::string& name,
|
||||
Input_file* input_file,
|
||||
off_t offset)
|
||||
: Pluginobj(name, input_file, offset)
|
||||
off_t offset,
|
||||
off_t filesize)
|
||||
: Pluginobj(name, input_file, offset, filesize)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -822,6 +872,7 @@ Plugin_hook::run(Workqueue* workqueue)
|
|||
{
|
||||
gold_assert(this->options_.has_plugins());
|
||||
this->options_.plugins()->all_symbols_read(workqueue,
|
||||
this,
|
||||
this->input_objects_,
|
||||
this->symtab_,
|
||||
this->layout_,
|
||||
|
@ -880,6 +931,29 @@ add_symbols(void* handle, int nsyms, const ld_plugin_symbol *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);
|
||||
}
|
||||
|
||||
// Get the symbol resolution info for a plugin-claimed input file.
|
||||
|
||||
static enum ld_plugin_status
|
||||
|
@ -936,7 +1010,7 @@ message(int level, const char * format, ...)
|
|||
// Allocate a Pluginobj object of the appropriate size and endianness.
|
||||
|
||||
static Pluginobj*
|
||||
make_sized_plugin_object(Input_file* input_file, off_t offset)
|
||||
make_sized_plugin_object(Input_file* input_file, off_t offset, off_t filesize)
|
||||
{
|
||||
Target* target;
|
||||
Pluginobj* obj = NULL;
|
||||
|
@ -951,7 +1025,7 @@ make_sized_plugin_object(Input_file* input_file, off_t offset)
|
|||
if (target->is_big_endian())
|
||||
#ifdef HAVE_TARGET_32_BIG
|
||||
obj = new Sized_pluginobj<32, true>(input_file->filename(),
|
||||
input_file, offset);
|
||||
input_file, offset, filesize);
|
||||
#else
|
||||
gold_error(_("%s: not configured to support "
|
||||
"32-bit big-endian object"),
|
||||
|
@ -960,7 +1034,7 @@ make_sized_plugin_object(Input_file* input_file, off_t offset)
|
|||
else
|
||||
#ifdef HAVE_TARGET_32_LITTLE
|
||||
obj = new Sized_pluginobj<32, false>(input_file->filename(),
|
||||
input_file, offset);
|
||||
input_file, offset, filesize);
|
||||
#else
|
||||
gold_error(_("%s: not configured to support "
|
||||
"32-bit little-endian object"),
|
||||
|
@ -972,7 +1046,7 @@ make_sized_plugin_object(Input_file* input_file, off_t offset)
|
|||
if (target->is_big_endian())
|
||||
#ifdef HAVE_TARGET_64_BIG
|
||||
obj = new Sized_pluginobj<64, true>(input_file->filename(),
|
||||
input_file, offset);
|
||||
input_file, offset, filesize);
|
||||
#else
|
||||
gold_error(_("%s: not configured to support "
|
||||
"64-bit big-endian object"),
|
||||
|
@ -981,7 +1055,7 @@ make_sized_plugin_object(Input_file* input_file, off_t offset)
|
|||
else
|
||||
#ifdef HAVE_TARGET_64_LITTLE
|
||||
obj = new Sized_pluginobj<64, false>(input_file->filename(),
|
||||
input_file, offset);
|
||||
input_file, offset, filesize);
|
||||
#else
|
||||
gold_error(_("%s: not configured to support "
|
||||
"64-bit little-endian object"),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue