* 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:
Cary Coutant 2009-01-15 01:29:25 +00:00
parent fa7f3e7229
commit 0f7c0701ba
16 changed files with 479 additions and 165 deletions

View file

@ -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"),