2011-07-13 Sriraman Tallam <tmsriram@google.com>
* plugin-api.h (ld_plugin_section): New struct. (ld_plugin_get_section_count): New typedef. (ld_plugin_get_section_type): New typedef. (ld_plugin_get_section_name): New typedef. (ld_plugin_get_section_contents): New typedef. (ld_plugin_update_section_order): New typedef. (ld_plugin_allow_section_ordering): New typedef. (LDPT_GET_SECTION_COUNT): New enum value. (LDPT_GET_SECTION_TYPE): New enum value. (LDPT_GET_SECTION_NAME): New enum value. (LDPT_GET_SECTION_CONTENTS): New enum value. (LDPT_UPDATE_SECTION_ORDER): New enum value. (LDPT_ALLOW_SECTION_ORDERING): New enum value. (tv_get_section_count): New struct members. (tv_get_section_type): New struct members. (tv_get_section_name): New struct members. (tv_get_section_contents): New struct members. (tv_update_section_order): New struct members. (tv_allow_section_ordering): New struct members. * archive.cc (Archive::get_elf_object_for_member): Add extra parameter to claim_file call. * layout.cc (Layout::Layout): Initialize section_ordering_specified_, input_section_position_, and input_section_glob_. (read_layout_from_file): Call function section_ordering_specified. * layout.h (is_section_ordering_specified): New function. (section_ordering_specified): New function. (section_ordering_specified_): New boolean member. * main.cc(main): Call load_plugins after layout object is defined. * output.cc (Output_section::add_input_section): Use function section_ordering_specified to check if section ordering is needed. * output.cc (Output_section::add_relaxed_input_section): Use function section_ordering_specified to check if section ordering is needed. (Output_section::update_section_layout): New function. (Output_section::sort_attached_input_sections): Check if input section must be reordered. * output.h (Output_section::update_section_layout): New function. * plugin.cc (get_section_count): New function. (get_section_type): New function. (get_section_name): New function. (get_section_contents): New function. (update_section_order): New function. (allow_section_ordering): New function. (Plugin::load): Add the new interfaces to the transfer vector. (Plugin_manager::load_plugins): New parameter. (Plugin_manager::all_symbols_read): New parameter. (Plugin_manager::claim_file): New parameter. Save the elf object for unclaimed objects. (Plugin_manager::get_elf_object): New function. (Plugin_manager::get_view): Change to directly use the bool to check if get_view is called from claim_file_hook. * plugin.h (input_objects): New function (Plugin__manager::load_plugins): New parameter. (Plugin_manager::claim_file): New parameter. (Plugin_manager::get_elf_object): New function. (Plugin_manager::in_claim_file_handler): New function. (Plugin_manager::in_claim_file_handler_): New member. (layout): New function. * readsyms.cc (Read_symbols::do_read_symbols): Call the claim_file handler with an extra parameter. Make the elf object before calling claim_file handler. * testsuite/plugin_test.c (get_section_count): New function pointer. (get_section_type): New function pointer. (get_section_name): New function pointer. (get_section_contents): New function pointer. (update_section_order): New function pointer. (allow_section_ordering): New function pointer. (onload): Check if the new interfaces exist.
This commit is contained in:
parent
41d1d0bd9b
commit
e9552f7ebb
13 changed files with 592 additions and 46 deletions
|
@ -1,3 +1,56 @@
|
||||||
|
2011-07-13 Sriraman Tallam <tmsriram@google.com>
|
||||||
|
|
||||||
|
* archive.cc (Archive::get_elf_object_for_member): Add extra parameter
|
||||||
|
to claim_file call.
|
||||||
|
* layout.cc (Layout::Layout): Initialize section_ordering_specified_,
|
||||||
|
input_section_position_, and input_section_glob_.
|
||||||
|
(read_layout_from_file): Call function section_ordering_specified.
|
||||||
|
* layout.h (is_section_ordering_specified): New function.
|
||||||
|
(section_ordering_specified): New function.
|
||||||
|
(section_ordering_specified_): New boolean member.
|
||||||
|
* main.cc(main): Call load_plugins after layout object is defined.
|
||||||
|
* output.cc (Output_section::add_input_section): Use
|
||||||
|
function section_ordering_specified to check if section ordering is
|
||||||
|
needed.
|
||||||
|
* output.cc (Output_section::add_relaxed_input_section): Use
|
||||||
|
function section_ordering_specified to check if section ordering is
|
||||||
|
needed.
|
||||||
|
(Output_section::update_section_layout): New function.
|
||||||
|
(Output_section::sort_attached_input_sections): Check if input section
|
||||||
|
must be reordered.
|
||||||
|
* output.h (Output_section::update_section_layout): New function.
|
||||||
|
* plugin.cc (get_section_count): New function.
|
||||||
|
(get_section_type): New function.
|
||||||
|
(get_section_name): New function.
|
||||||
|
(get_section_contents): New function.
|
||||||
|
(update_section_order): New function.
|
||||||
|
(allow_section_ordering): New function.
|
||||||
|
(Plugin::load): Add the new interfaces to the transfer vector.
|
||||||
|
(Plugin_manager::load_plugins): New parameter.
|
||||||
|
(Plugin_manager::all_symbols_read): New parameter.
|
||||||
|
(Plugin_manager::claim_file): New parameter. Save the elf object for
|
||||||
|
unclaimed objects.
|
||||||
|
(Plugin_manager::get_elf_object): New function.
|
||||||
|
(Plugin_manager::get_view): Change to directly use the bool to check
|
||||||
|
if get_view is called from claim_file_hook.
|
||||||
|
* plugin.h (input_objects): New function
|
||||||
|
(Plugin__manager::load_plugins): New parameter.
|
||||||
|
(Plugin_manager::claim_file): New parameter.
|
||||||
|
(Plugin_manager::get_elf_object): New function.
|
||||||
|
(Plugin_manager::in_claim_file_handler): New function.
|
||||||
|
(Plugin_manager::in_claim_file_handler_): New member.
|
||||||
|
(layout): New function.
|
||||||
|
* readsyms.cc (Read_symbols::do_read_symbols): Call the claim_file
|
||||||
|
handler with an extra parameter. Make the elf object before calling
|
||||||
|
claim_file handler.
|
||||||
|
* testsuite/plugin_test.c (get_section_count): New function pointer.
|
||||||
|
(get_section_type): New function pointer.
|
||||||
|
(get_section_name): New function pointer.
|
||||||
|
(get_section_contents): New function pointer.
|
||||||
|
(update_section_order): New function pointer.
|
||||||
|
(allow_section_ordering): New function pointer.
|
||||||
|
(onload): Check if the new interfaces exist.
|
||||||
|
|
||||||
2011-07-13 Ian Lance Taylor <iant@google.com>
|
2011-07-13 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
* i386.cc (Target_i386::got_section): If -z now, make .got.plt a
|
* i386.cc (Target_i386::got_section): If -z now, make .got.plt a
|
||||||
|
|
|
@ -653,7 +653,8 @@ Archive::get_elf_object_for_member(off_t off, bool* punconfigured)
|
||||||
{
|
{
|
||||||
Object* obj = parameters->options().plugins()->claim_file(input_file,
|
Object* obj = parameters->options().plugins()->claim_file(input_file,
|
||||||
memoff,
|
memoff,
|
||||||
memsize);
|
memsize,
|
||||||
|
NULL);
|
||||||
if (obj != NULL)
|
if (obj != NULL)
|
||||||
{
|
{
|
||||||
// The input file was claimed by a plugin, and its symbols
|
// The input file was claimed by a plugin, and its symbols
|
||||||
|
|
|
@ -399,11 +399,14 @@ Layout::Layout(int number_of_input_files, Script_options* script_options)
|
||||||
any_postprocessing_sections_(false),
|
any_postprocessing_sections_(false),
|
||||||
resized_signatures_(false),
|
resized_signatures_(false),
|
||||||
have_stabstr_section_(false),
|
have_stabstr_section_(false),
|
||||||
|
section_ordering_specified_(false),
|
||||||
incremental_inputs_(NULL),
|
incremental_inputs_(NULL),
|
||||||
record_output_section_data_from_script_(false),
|
record_output_section_data_from_script_(false),
|
||||||
script_output_section_data_list_(),
|
script_output_section_data_list_(),
|
||||||
segment_states_(NULL),
|
segment_states_(NULL),
|
||||||
relaxation_debug_check_(NULL),
|
relaxation_debug_check_(NULL),
|
||||||
|
input_section_position_(),
|
||||||
|
input_section_glob_(),
|
||||||
incremental_base_(NULL),
|
incremental_base_(NULL),
|
||||||
free_list_()
|
free_list_()
|
||||||
{
|
{
|
||||||
|
@ -2209,7 +2212,7 @@ Layout::find_section_order_index(const std::string& section_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the sequence of input sections from the file specified with
|
// Read the sequence of input sections from the file specified with
|
||||||
// --section-ordering-file.
|
// option --section-ordering-file.
|
||||||
|
|
||||||
void
|
void
|
||||||
Layout::read_layout_from_file()
|
Layout::read_layout_from_file()
|
||||||
|
@ -2225,6 +2228,7 @@ Layout::read_layout_from_file()
|
||||||
|
|
||||||
std::getline(in, line); // this chops off the trailing \n, if any
|
std::getline(in, line); // this chops off the trailing \n, if any
|
||||||
unsigned int position = 1;
|
unsigned int position = 1;
|
||||||
|
this->set_section_ordering_specified();
|
||||||
|
|
||||||
while (in)
|
while (in)
|
||||||
{
|
{
|
||||||
|
|
|
@ -492,6 +492,14 @@ class Layout
|
||||||
const char* name, const elfcpp::Shdr<size, big_endian>& shdr,
|
const char* name, const elfcpp::Shdr<size, big_endian>& shdr,
|
||||||
unsigned int reloc_shndx, unsigned int reloc_type, off_t* offset);
|
unsigned int reloc_shndx, unsigned int reloc_type, off_t* offset);
|
||||||
|
|
||||||
|
bool
|
||||||
|
is_section_ordering_specified()
|
||||||
|
{ return this->section_ordering_specified_; }
|
||||||
|
|
||||||
|
void
|
||||||
|
set_section_ordering_specified()
|
||||||
|
{ this->section_ordering_specified_ = true; }
|
||||||
|
|
||||||
// For incremental updates, allocate a block of memory from the
|
// For incremental updates, allocate a block of memory from the
|
||||||
// free list. Find a block starting at or after MINOFF.
|
// free list. Find a block starting at or after MINOFF.
|
||||||
off_t
|
off_t
|
||||||
|
@ -501,6 +509,8 @@ class Layout
|
||||||
unsigned int
|
unsigned int
|
||||||
find_section_order_index(const std::string&);
|
find_section_order_index(const std::string&);
|
||||||
|
|
||||||
|
// Read the sequence of input sections from the file specified with
|
||||||
|
// linker option --section-ordering-file.
|
||||||
void
|
void
|
||||||
read_layout_from_file();
|
read_layout_from_file();
|
||||||
|
|
||||||
|
@ -1262,6 +1272,9 @@ class Layout
|
||||||
bool resized_signatures_;
|
bool resized_signatures_;
|
||||||
// Whether we have created a .stab*str output section.
|
// Whether we have created a .stab*str output section.
|
||||||
bool have_stabstr_section_;
|
bool have_stabstr_section_;
|
||||||
|
// True if the input sections in the output sections should be sorted
|
||||||
|
// as specified in a section ordering file.
|
||||||
|
bool section_ordering_specified_;
|
||||||
// In incremental build, holds information check the inputs and build the
|
// In incremental build, holds information check the inputs and build the
|
||||||
// .gnu_incremental_inputs section.
|
// .gnu_incremental_inputs section.
|
||||||
Incremental_inputs* incremental_inputs_;
|
Incremental_inputs* incremental_inputs_;
|
||||||
|
|
|
@ -195,10 +195,6 @@ main(int argc, char** argv)
|
||||||
if (parameters->options().relocatable())
|
if (parameters->options().relocatable())
|
||||||
command_line.script_options().version_script_info()->clear();
|
command_line.script_options().version_script_info()->clear();
|
||||||
|
|
||||||
// Load plugin libraries.
|
|
||||||
if (command_line.options().has_plugins())
|
|
||||||
command_line.options().plugins()->load_plugins();
|
|
||||||
|
|
||||||
// The work queue.
|
// The work queue.
|
||||||
Workqueue workqueue(command_line.options());
|
Workqueue workqueue(command_line.options());
|
||||||
|
|
||||||
|
@ -234,6 +230,10 @@ main(int argc, char** argv)
|
||||||
if (parameters->options().section_ordering_file())
|
if (parameters->options().section_ordering_file())
|
||||||
layout.read_layout_from_file();
|
layout.read_layout_from_file();
|
||||||
|
|
||||||
|
// Load plugin libraries.
|
||||||
|
if (command_line.options().has_plugins())
|
||||||
|
command_line.options().plugins()->load_plugins(&layout);
|
||||||
|
|
||||||
// Get the search path from the -L options.
|
// Get the search path from the -L options.
|
||||||
Dirsearch search_path;
|
Dirsearch search_path;
|
||||||
search_path.initialize(&workqueue, &command_line.options().library_path());
|
search_path.initialize(&workqueue, &command_line.options().library_path());
|
||||||
|
|
|
@ -2296,7 +2296,7 @@ Output_section::add_input_section(Layout* layout,
|
||||||
&& (sh_flags & elfcpp::SHF_EXECINSTR) != 0
|
&& (sh_flags & elfcpp::SHF_EXECINSTR) != 0
|
||||||
&& parameters->target().has_code_fill()
|
&& parameters->target().has_code_fill()
|
||||||
&& (parameters->target().may_relax()
|
&& (parameters->target().may_relax()
|
||||||
|| parameters->options().section_ordering_file()))
|
|| layout->is_section_ordering_specified()))
|
||||||
{
|
{
|
||||||
gold_assert(this->fills_.empty());
|
gold_assert(this->fills_.empty());
|
||||||
this->generate_code_fills_at_write_ = true;
|
this->generate_code_fills_at_write_ = true;
|
||||||
|
@ -2335,10 +2335,10 @@ Output_section::add_input_section(Layout* layout,
|
||||||
|| this->must_sort_attached_input_sections()
|
|| this->must_sort_attached_input_sections()
|
||||||
|| parameters->options().user_set_Map()
|
|| parameters->options().user_set_Map()
|
||||||
|| parameters->target().may_relax()
|
|| parameters->target().may_relax()
|
||||||
|| parameters->options().section_ordering_file())
|
|| layout->is_section_ordering_specified())
|
||||||
{
|
{
|
||||||
Input_section isecn(object, shndx, input_section_size, addralign);
|
Input_section isecn(object, shndx, input_section_size, addralign);
|
||||||
if (parameters->options().section_ordering_file())
|
if (layout->is_section_ordering_specified())
|
||||||
{
|
{
|
||||||
unsigned int section_order_index =
|
unsigned int section_order_index =
|
||||||
layout->find_section_order_index(std::string(secname));
|
layout->find_section_order_index(std::string(secname));
|
||||||
|
@ -2421,7 +2421,7 @@ Output_section::add_relaxed_input_section(Layout* layout,
|
||||||
|
|
||||||
// If the --section-ordering-file option is used to specify the order of
|
// If the --section-ordering-file option is used to specify the order of
|
||||||
// sections, we need to keep track of sections.
|
// sections, we need to keep track of sections.
|
||||||
if (parameters->options().section_ordering_file())
|
if (layout->is_section_ordering_specified())
|
||||||
{
|
{
|
||||||
unsigned int section_order_index =
|
unsigned int section_order_index =
|
||||||
layout->find_section_order_index(name);
|
layout->find_section_order_index(name);
|
||||||
|
@ -3339,6 +3339,38 @@ Output_section::Input_section_sort_section_order_index_compare::operator()(
|
||||||
return s1_secn_index < s2_secn_index;
|
return s1_secn_index < s2_secn_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This updates the section order index of input sections according to the
|
||||||
|
// the order specified in the mapping from Section id to order index.
|
||||||
|
|
||||||
|
void
|
||||||
|
Output_section::update_section_layout(
|
||||||
|
const Section_layout_order& order_map)
|
||||||
|
{
|
||||||
|
for (Input_section_list::iterator p = this->input_sections_.begin();
|
||||||
|
p != this->input_sections_.end();
|
||||||
|
++p)
|
||||||
|
{
|
||||||
|
if (p->is_input_section()
|
||||||
|
|| p->is_relaxed_input_section())
|
||||||
|
{
|
||||||
|
Object* obj = (p->is_input_section()
|
||||||
|
? p->relobj()
|
||||||
|
: p->relaxed_input_section()->relobj());
|
||||||
|
unsigned int shndx = p->shndx();
|
||||||
|
Section_layout_order::const_iterator it
|
||||||
|
= order_map.find(Section_id(obj, shndx));
|
||||||
|
if (it == order_map.end())
|
||||||
|
continue;
|
||||||
|
unsigned int section_order_index = it->second;
|
||||||
|
if (section_order_index != 0)
|
||||||
|
{
|
||||||
|
p->set_section_order_index(section_order_index);
|
||||||
|
this->set_input_section_order_specified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Sort the input sections attached to an output section.
|
// Sort the input sections attached to an output section.
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -3381,7 +3413,7 @@ Output_section::sort_attached_input_sections()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gold_assert(parameters->options().section_ordering_file());
|
gold_assert(this->input_section_order_specified());
|
||||||
std::sort(sort_list.begin(), sort_list.end(),
|
std::sort(sort_list.begin(), sort_list.end(),
|
||||||
Input_section_sort_section_order_index_compare());
|
Input_section_sort_section_order_index_compare());
|
||||||
}
|
}
|
||||||
|
|
|
@ -2665,6 +2665,11 @@ class Output_section : public Output_data
|
||||||
flags() const
|
flags() const
|
||||||
{ return this->flags_; }
|
{ return this->flags_; }
|
||||||
|
|
||||||
|
typedef std::map<Section_id, unsigned int> Section_layout_order;
|
||||||
|
|
||||||
|
void
|
||||||
|
update_section_layout(const Section_layout_order& order_map);
|
||||||
|
|
||||||
// Update the output section flags based on input section flags.
|
// Update the output section flags based on input section flags.
|
||||||
void
|
void
|
||||||
update_flags_for_input_section(elfcpp::Elf_Xword flags);
|
update_flags_for_input_section(elfcpp::Elf_Xword flags);
|
||||||
|
|
271
gold/plugin.cc
271
gold/plugin.cc
|
@ -89,6 +89,29 @@ 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
|
||||||
|
@ -133,7 +156,8 @@ Plugin::load()
|
||||||
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];
|
||||||
|
|
||||||
|
@ -215,6 +239,30 @@ Plugin::load()
|
||||||
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;
|
||||||
|
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;
|
++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;
|
||||||
|
@ -326,8 +374,9 @@ Plugin_manager::~Plugin_manager()
|
||||||
// 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_)
|
||||||
|
@ -338,7 +387,7 @@ Plugin_manager::load_plugins()
|
||||||
|
|
||||||
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;
|
||||||
|
@ -350,6 +399,9 @@ Plugin_manager::claim_file(Input_file* input_file, off_t offset,
|
||||||
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();
|
||||||
|
@ -358,9 +410,11 @@ Plugin_manager::claim_file(Input_file* input_file, off_t offset,
|
||||||
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.
|
||||||
|
@ -369,6 +423,7 @@ Plugin_manager::claim_file(Input_file* input_file, off_t offset,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->in_claim_file_handler_ = false;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,7 +457,7 @@ Plugin_manager::save_input_group(Input_group* input_group)
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
@ -411,7 +466,6 @@ Plugin_manager::all_symbols_read(Workqueue* workqueue, Task* task,
|
||||||
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;
|
||||||
|
@ -599,12 +653,20 @@ 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;
|
||||||
}
|
}
|
||||||
|
@ -616,7 +678,7 @@ 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;
|
||||||
|
|
||||||
|
@ -634,7 +696,11 @@ Plugin_manager::get_input_file(unsigned int handle,
|
||||||
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;
|
||||||
|
|
||||||
|
@ -642,13 +708,30 @@ Plugin_manager::release_input_file(unsigned int handle)
|
||||||
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_;
|
||||||
|
@ -659,7 +742,9 @@ Plugin_manager::get_view(unsigned int handle, const void **viewp)
|
||||||
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();
|
||||||
|
@ -1226,7 +1311,6 @@ Plugin_hook::run(Workqueue* 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_);
|
||||||
|
@ -1320,11 +1404,14 @@ 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.
|
||||||
|
@ -1384,6 +1471,158 @@ message(int level, const char* format, ...)
|
||||||
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.
|
||||||
|
|
|
@ -131,6 +131,7 @@ class Plugin_manager
|
||||||
: plugins_(), objects_(), deferred_layout_objects_(), input_file_(NULL),
|
: plugins_(), objects_(), deferred_layout_objects_(), input_file_(NULL),
|
||||||
plugin_input_file_(), rescannable_(), undefined_symbols_(),
|
plugin_input_file_(), rescannable_(), undefined_symbols_(),
|
||||||
any_claimed_(false), in_replacement_phase_(false), any_added_(false),
|
any_claimed_(false), in_replacement_phase_(false), any_added_(false),
|
||||||
|
in_claim_file_handler_(false),
|
||||||
options_(options), workqueue_(NULL), task_(NULL), input_objects_(NULL),
|
options_(options), workqueue_(NULL), task_(NULL), input_objects_(NULL),
|
||||||
symtab_(NULL), layout_(NULL), dirpath_(NULL), mapfile_(NULL),
|
symtab_(NULL), layout_(NULL), dirpath_(NULL), mapfile_(NULL),
|
||||||
this_blocker_(NULL), extra_search_path_()
|
this_blocker_(NULL), extra_search_path_()
|
||||||
|
@ -153,11 +154,22 @@ class Plugin_manager
|
||||||
|
|
||||||
// Load all plugin libraries.
|
// Load all plugin libraries.
|
||||||
void
|
void
|
||||||
load_plugins();
|
load_plugins(Layout* layout);
|
||||||
|
|
||||||
// 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*
|
||||||
claim_file(Input_file* input_file, off_t offset, off_t filesize);
|
claim_file(Input_file* input_file, off_t offset, off_t filesize,
|
||||||
|
Object* elf_object);
|
||||||
|
|
||||||
|
// Get the object associated with the handle and check if it is an elf object.
|
||||||
|
// If it is not a Pluginobj, it is an elf object.
|
||||||
|
Object*
|
||||||
|
get_elf_object(const void* handle);
|
||||||
|
|
||||||
|
// True if the claim_file handler of the plugins is being called.
|
||||||
|
bool
|
||||||
|
in_claim_file_handler()
|
||||||
|
{ return in_claim_file_handler_; }
|
||||||
|
|
||||||
// Let the plugin manager save an archive for later rescanning.
|
// Let the plugin manager save an archive for later rescanning.
|
||||||
// This takes ownership of the Archive pointer.
|
// This takes ownership of the Archive pointer.
|
||||||
|
@ -173,7 +185,7 @@ class Plugin_manager
|
||||||
void
|
void
|
||||||
all_symbols_read(Workqueue* workqueue, Task* task,
|
all_symbols_read(Workqueue* workqueue, Task* task,
|
||||||
Input_objects* input_objects, Symbol_table* symtab,
|
Input_objects* input_objects, Symbol_table* symtab,
|
||||||
Layout* layout, Dirsearch* dirpath, Mapfile* mapfile,
|
Dirsearch* dirpath, Mapfile* mapfile,
|
||||||
Task_token** last_blocker);
|
Task_token** last_blocker);
|
||||||
|
|
||||||
// Tell the plugin manager that we've a new undefined symbol which
|
// Tell the plugin manager that we've a new undefined symbol which
|
||||||
|
@ -218,8 +230,8 @@ class Plugin_manager
|
||||||
Pluginobj*
|
Pluginobj*
|
||||||
make_plugin_object(unsigned int handle);
|
make_plugin_object(unsigned int handle);
|
||||||
|
|
||||||
// Return the Pluginobj associated with the given HANDLE.
|
// Return the object associated with the given HANDLE.
|
||||||
Pluginobj*
|
Object*
|
||||||
object(unsigned int handle) const
|
object(unsigned int handle) const
|
||||||
{
|
{
|
||||||
if (handle >= this->objects_.size())
|
if (handle >= this->objects_.size())
|
||||||
|
@ -265,6 +277,14 @@ class Plugin_manager
|
||||||
in_replacement_phase() const
|
in_replacement_phase() const
|
||||||
{ return this->in_replacement_phase_; }
|
{ return this->in_replacement_phase_; }
|
||||||
|
|
||||||
|
Input_objects*
|
||||||
|
input_objects() const
|
||||||
|
{ return this->input_objects_; }
|
||||||
|
|
||||||
|
Layout*
|
||||||
|
layout()
|
||||||
|
{ return this->layout_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Plugin_manager(const Plugin_manager&);
|
Plugin_manager(const Plugin_manager&);
|
||||||
Plugin_manager& operator=(const Plugin_manager&);
|
Plugin_manager& operator=(const Plugin_manager&);
|
||||||
|
@ -293,7 +313,7 @@ class Plugin_manager
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::list<Plugin*> Plugin_list;
|
typedef std::list<Plugin*> Plugin_list;
|
||||||
typedef std::vector<Pluginobj*> Object_list;
|
typedef std::vector<Object*> Object_list;
|
||||||
typedef std::vector<Relobj*> Deferred_layout_list;
|
typedef std::vector<Relobj*> Deferred_layout_list;
|
||||||
typedef std::vector<Rescannable> Rescannable_list;
|
typedef std::vector<Rescannable> Rescannable_list;
|
||||||
typedef std::vector<Symbol*> Undefined_symbol_list;
|
typedef std::vector<Symbol*> Undefined_symbol_list;
|
||||||
|
@ -340,6 +360,9 @@ class Plugin_manager
|
||||||
// Whether any input files or libraries were added by a plugin.
|
// Whether any input files or libraries were added by a plugin.
|
||||||
bool any_added_;
|
bool any_added_;
|
||||||
|
|
||||||
|
// Set to true when the claim_file handler of a plugin is called.
|
||||||
|
bool in_claim_file_handler_;
|
||||||
|
|
||||||
const General_options& options_;
|
const General_options& options_;
|
||||||
Workqueue* workqueue_;
|
Workqueue* workqueue_;
|
||||||
Task* task_;
|
Task* task_;
|
||||||
|
|
|
@ -320,12 +320,33 @@ Read_symbols::do_read_symbols(Workqueue* workqueue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object* elf_obj = NULL;
|
||||||
|
bool unconfigured;
|
||||||
|
bool* punconfigured = NULL;
|
||||||
|
if (is_elf)
|
||||||
|
{
|
||||||
|
// This is an ELF object.
|
||||||
|
|
||||||
|
unconfigured = false;
|
||||||
|
punconfigured = (input_file->will_search_for()
|
||||||
|
? &unconfigured
|
||||||
|
: NULL);
|
||||||
|
elf_obj = make_elf_object(input_file->filename(),
|
||||||
|
input_file, 0, ehdr, read_size,
|
||||||
|
punconfigured);
|
||||||
|
}
|
||||||
|
|
||||||
if (parameters->options().has_plugins())
|
if (parameters->options().has_plugins())
|
||||||
{
|
{
|
||||||
Pluginobj* obj = parameters->options().plugins()->claim_file(input_file,
|
Pluginobj* obj = parameters->options().plugins()->claim_file(input_file,
|
||||||
0, filesize);
|
0, filesize,
|
||||||
|
elf_obj);
|
||||||
if (obj != NULL)
|
if (obj != NULL)
|
||||||
{
|
{
|
||||||
|
// Delete the elf_obj, this file has been claimed.
|
||||||
|
if (elf_obj != NULL)
|
||||||
|
delete elf_obj;
|
||||||
|
|
||||||
// The input file was claimed by a plugin, and its symbols
|
// The input file was claimed by a plugin, and its symbols
|
||||||
// have been provided by the plugin.
|
// have been provided by the plugin.
|
||||||
|
|
||||||
|
@ -359,14 +380,7 @@ Read_symbols::do_read_symbols(Workqueue* workqueue)
|
||||||
{
|
{
|
||||||
// This is an ELF object.
|
// This is an ELF object.
|
||||||
|
|
||||||
bool unconfigured = false;
|
if (elf_obj == NULL)
|
||||||
bool* punconfigured = (input_file->will_search_for()
|
|
||||||
? &unconfigured
|
|
||||||
: NULL);
|
|
||||||
Object* obj = make_elf_object(input_file->filename(),
|
|
||||||
input_file, 0, ehdr, read_size,
|
|
||||||
punconfigured);
|
|
||||||
if (obj == NULL)
|
|
||||||
{
|
{
|
||||||
if (unconfigured)
|
if (unconfigured)
|
||||||
{
|
{
|
||||||
|
@ -382,7 +396,7 @@ Read_symbols::do_read_symbols(Workqueue* workqueue)
|
||||||
}
|
}
|
||||||
|
|
||||||
Read_symbols_data* sd = new Read_symbols_data;
|
Read_symbols_data* sd = new Read_symbols_data;
|
||||||
obj->read_symbols(sd);
|
elf_obj->read_symbols(sd);
|
||||||
|
|
||||||
// Opening the file locked it, so now we need to unlock it. We
|
// Opening the file locked it, so now we need to unlock it. We
|
||||||
// need to unlock it before queuing the Add_symbols task,
|
// need to unlock it before queuing the Add_symbols task,
|
||||||
|
@ -397,7 +411,7 @@ Read_symbols::do_read_symbols(Workqueue* workqueue)
|
||||||
if (this->member_ != NULL)
|
if (this->member_ != NULL)
|
||||||
{
|
{
|
||||||
this->member_->sd_ = sd;
|
this->member_->sd_ = sd;
|
||||||
this->member_->obj_ = obj;
|
this->member_->obj_ = elf_obj;
|
||||||
this->member_->arg_serial_ =
|
this->member_->arg_serial_ =
|
||||||
this->input_argument_->file().arg_serial();
|
this->input_argument_->file().arg_serial();
|
||||||
return true;
|
return true;
|
||||||
|
@ -412,7 +426,7 @@ Read_symbols::do_read_symbols(Workqueue* workqueue)
|
||||||
this->dirindex_,
|
this->dirindex_,
|
||||||
this->mapfile_,
|
this->mapfile_,
|
||||||
this->input_argument_,
|
this->input_argument_,
|
||||||
obj,
|
elf_obj,
|
||||||
NULL,
|
NULL,
|
||||||
sd,
|
sd,
|
||||||
this->this_blocker_,
|
this->this_blocker_,
|
||||||
|
|
|
@ -60,6 +60,12 @@ static ld_plugin_add_input_file add_input_file = NULL;
|
||||||
static ld_plugin_message message = NULL;
|
static ld_plugin_message message = NULL;
|
||||||
static ld_plugin_get_input_file get_input_file = NULL;
|
static ld_plugin_get_input_file get_input_file = NULL;
|
||||||
static ld_plugin_release_input_file release_input_file = NULL;
|
static ld_plugin_release_input_file release_input_file = NULL;
|
||||||
|
static ld_plugin_get_input_section_count get_input_section_count = NULL;
|
||||||
|
static ld_plugin_get_input_section_type get_input_section_type = NULL;
|
||||||
|
static ld_plugin_get_input_section_name get_input_section_name = NULL;
|
||||||
|
static ld_plugin_get_input_section_contents get_input_section_contents = NULL;
|
||||||
|
static ld_plugin_update_section_order update_section_order = NULL;
|
||||||
|
static ld_plugin_allow_section_ordering allow_section_ordering = NULL;
|
||||||
|
|
||||||
#define MAXOPTS 10
|
#define MAXOPTS 10
|
||||||
|
|
||||||
|
@ -126,6 +132,24 @@ onload(struct ld_plugin_tv *tv)
|
||||||
case LDPT_RELEASE_INPUT_FILE:
|
case LDPT_RELEASE_INPUT_FILE:
|
||||||
release_input_file = entry->tv_u.tv_release_input_file;
|
release_input_file = entry->tv_u.tv_release_input_file;
|
||||||
break;
|
break;
|
||||||
|
case LDPT_GET_INPUT_SECTION_COUNT:
|
||||||
|
get_input_section_count = *entry->tv_u.tv_get_input_section_count;
|
||||||
|
break;
|
||||||
|
case LDPT_GET_INPUT_SECTION_TYPE:
|
||||||
|
get_input_section_type = *entry->tv_u.tv_get_input_section_type;
|
||||||
|
break;
|
||||||
|
case LDPT_GET_INPUT_SECTION_NAME:
|
||||||
|
get_input_section_name = *entry->tv_u.tv_get_input_section_name;
|
||||||
|
break;
|
||||||
|
case LDPT_GET_INPUT_SECTION_CONTENTS:
|
||||||
|
get_input_section_contents = *entry->tv_u.tv_get_input_section_contents;
|
||||||
|
break;
|
||||||
|
case LDPT_UPDATE_SECTION_ORDER:
|
||||||
|
update_section_order = *entry->tv_u.tv_update_section_order;
|
||||||
|
break;
|
||||||
|
case LDPT_ALLOW_SECTION_ORDERING:
|
||||||
|
allow_section_ordering = *entry->tv_u.tv_allow_section_ordering;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -179,6 +203,42 @@ onload(struct ld_plugin_tv *tv)
|
||||||
return LDPS_ERR;
|
return LDPS_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (get_input_section_count == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "tv_get_input_section_count interface missing\n");
|
||||||
|
return LDPS_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_input_section_type == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "tv_get_input_section_type interface missing\n");
|
||||||
|
return LDPS_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_input_section_name == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "tv_get_input_section_name interface missing\n");
|
||||||
|
return LDPS_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_input_section_contents == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "tv_get_input_section_contents interface missing\n");
|
||||||
|
return LDPS_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update_section_order == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "tv_update_section_order interface missing\n");
|
||||||
|
return LDPS_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allow_section_ordering == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "tv_allow_section_ordering interface missing\n");
|
||||||
|
return LDPS_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
return LDPS_OK;
|
return LDPS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,26 @@
|
||||||
|
2011-07-13 Sriraman Tallam <tmsriram@google.com>
|
||||||
|
|
||||||
|
* plugin-api.h
|
||||||
|
(ld_plugin_section): New struct.
|
||||||
|
(ld_plugin_get_section_count): New typedef.
|
||||||
|
(ld_plugin_get_section_type): New typedef.
|
||||||
|
(ld_plugin_get_section_name): New typedef.
|
||||||
|
(ld_plugin_get_section_contents): New typedef.
|
||||||
|
(ld_plugin_update_section_order): New typedef.
|
||||||
|
(ld_plugin_allow_section_ordering): New typedef.
|
||||||
|
(LDPT_GET_SECTION_COUNT): New enum value.
|
||||||
|
(LDPT_GET_SECTION_TYPE): New enum value.
|
||||||
|
(LDPT_GET_SECTION_NAME): New enum value.
|
||||||
|
(LDPT_GET_SECTION_CONTENTS): New enum value.
|
||||||
|
(LDPT_UPDATE_SECTION_ORDER): New enum value.
|
||||||
|
(LDPT_ALLOW_SECTION_ORDERING): New enum value.
|
||||||
|
(tv_get_section_count): New struct members.
|
||||||
|
(tv_get_section_type): New struct members.
|
||||||
|
(tv_get_section_name): New struct members.
|
||||||
|
(tv_get_section_contents): New struct members.
|
||||||
|
(tv_update_section_order): New struct members.
|
||||||
|
(tv_allow_section_ordering): New struct members.
|
||||||
|
|
||||||
2011-07-11 Catherine Moore <clm@codesourcery.com>
|
2011-07-11 Catherine Moore <clm@codesourcery.com>
|
||||||
|
|
||||||
* bfdlink.h (flag_type): New enumeration.
|
* bfdlink.h (flag_type): New enumeration.
|
||||||
|
|
|
@ -93,6 +93,14 @@ struct ld_plugin_symbol
|
||||||
int resolution;
|
int resolution;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* An object's section. */
|
||||||
|
|
||||||
|
struct ld_plugin_section
|
||||||
|
{
|
||||||
|
const void* handle;
|
||||||
|
unsigned int shndx;
|
||||||
|
};
|
||||||
|
|
||||||
/* Whether the symbol is a definition, reference, or common, weak or not. */
|
/* Whether the symbol is a definition, reference, or common, weak or not. */
|
||||||
|
|
||||||
enum ld_plugin_symbol_kind
|
enum ld_plugin_symbol_kind
|
||||||
|
@ -244,6 +252,65 @@ typedef
|
||||||
enum ld_plugin_status
|
enum ld_plugin_status
|
||||||
(*ld_plugin_message) (int level, const char *format, ...);
|
(*ld_plugin_message) (int level, const char *format, ...);
|
||||||
|
|
||||||
|
/* The linker's interface for retrieving the number of sections in an object.
|
||||||
|
The handle is obtained in the claim_file handler. This interface should
|
||||||
|
only be invoked in the claim_file handler. This function sets *COUNT to
|
||||||
|
the number of sections in the object. */
|
||||||
|
|
||||||
|
typedef
|
||||||
|
enum ld_plugin_status
|
||||||
|
(*ld_plugin_get_input_section_count) (const void* handle, unsigned int *count);
|
||||||
|
|
||||||
|
/* The linker's interface for retrieving the section type of a specific
|
||||||
|
section in an object. This interface should only be invoked in the
|
||||||
|
claim_file handler. This function sets *TYPE to an ELF SHT_xxx value. */
|
||||||
|
|
||||||
|
typedef
|
||||||
|
enum ld_plugin_status
|
||||||
|
(*ld_plugin_get_input_section_type) (const struct ld_plugin_section section,
|
||||||
|
unsigned int *type);
|
||||||
|
|
||||||
|
/* The linker's interface for retrieving the name of a specific section in
|
||||||
|
an object. This interface should only be invoked in the claim_file handler.
|
||||||
|
This function sets *SECTION_NAME_PTR to a null-terminated buffer allocated
|
||||||
|
by malloc. The plugin must free *SECTION_NAME_PTR. */
|
||||||
|
|
||||||
|
typedef
|
||||||
|
enum ld_plugin_status
|
||||||
|
(*ld_plugin_get_input_section_name) (const struct ld_plugin_section section,
|
||||||
|
char **section_name_ptr);
|
||||||
|
|
||||||
|
/* The linker's interface for retrieving the contents of a specific section
|
||||||
|
in an object. This interface should only be invoked in the claim_file
|
||||||
|
handler. This function sets *SECTION_CONTENTS to point to a buffer that is
|
||||||
|
valid until clam_file handler returns. It sets *LEN to the size of the
|
||||||
|
buffer. */
|
||||||
|
|
||||||
|
typedef
|
||||||
|
enum ld_plugin_status
|
||||||
|
(*ld_plugin_get_input_section_contents) (const struct ld_plugin_section section,
|
||||||
|
const unsigned char **section_contents,
|
||||||
|
size_t* len);
|
||||||
|
|
||||||
|
/* The linker's interface for specifying the desired order of sections.
|
||||||
|
The sections should be specifed using the array SECTION_LIST in the
|
||||||
|
order in which they should appear in the final layout. NUM_SECTIONS
|
||||||
|
specifies the number of entries in each array. This should be invoked
|
||||||
|
in the all_symbols_read handler. */
|
||||||
|
|
||||||
|
typedef
|
||||||
|
enum ld_plugin_status
|
||||||
|
(*ld_plugin_update_section_order) (const struct ld_plugin_section *section_list,
|
||||||
|
unsigned int num_sections);
|
||||||
|
|
||||||
|
/* The linker's interface for specifying that reordering of sections is
|
||||||
|
desired so that the linker can prepare for it. This should be invoked
|
||||||
|
before update_section_order, preferably in the claim_file handler. */
|
||||||
|
|
||||||
|
typedef
|
||||||
|
enum ld_plugin_status
|
||||||
|
(*ld_plugin_allow_section_ordering) (void);
|
||||||
|
|
||||||
enum ld_plugin_level
|
enum ld_plugin_level
|
||||||
{
|
{
|
||||||
LDPL_INFO,
|
LDPL_INFO,
|
||||||
|
@ -274,7 +341,13 @@ enum ld_plugin_tag
|
||||||
LDPT_OUTPUT_NAME,
|
LDPT_OUTPUT_NAME,
|
||||||
LDPT_SET_EXTRA_LIBRARY_PATH,
|
LDPT_SET_EXTRA_LIBRARY_PATH,
|
||||||
LDPT_GNU_LD_VERSION,
|
LDPT_GNU_LD_VERSION,
|
||||||
LDPT_GET_VIEW
|
LDPT_GET_VIEW,
|
||||||
|
LDPT_GET_INPUT_SECTION_COUNT,
|
||||||
|
LDPT_GET_INPUT_SECTION_TYPE,
|
||||||
|
LDPT_GET_INPUT_SECTION_NAME,
|
||||||
|
LDPT_GET_INPUT_SECTION_CONTENTS,
|
||||||
|
LDPT_UPDATE_SECTION_ORDER,
|
||||||
|
LDPT_ALLOW_SECTION_ORDERING
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The plugin transfer vector. */
|
/* The plugin transfer vector. */
|
||||||
|
@ -298,6 +371,12 @@ struct ld_plugin_tv
|
||||||
ld_plugin_release_input_file tv_release_input_file;
|
ld_plugin_release_input_file tv_release_input_file;
|
||||||
ld_plugin_add_input_library tv_add_input_library;
|
ld_plugin_add_input_library tv_add_input_library;
|
||||||
ld_plugin_set_extra_library_path tv_set_extra_library_path;
|
ld_plugin_set_extra_library_path tv_set_extra_library_path;
|
||||||
|
ld_plugin_get_input_section_count tv_get_input_section_count;
|
||||||
|
ld_plugin_get_input_section_type tv_get_input_section_type;
|
||||||
|
ld_plugin_get_input_section_name tv_get_input_section_name;
|
||||||
|
ld_plugin_get_input_section_contents tv_get_input_section_contents;
|
||||||
|
ld_plugin_update_section_order tv_update_section_order;
|
||||||
|
ld_plugin_allow_section_ordering tv_allow_section_ordering;
|
||||||
} tv_u;
|
} tv_u;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue