+// 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;
+}
+
+// Get the alignment 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_alignment(const struct ld_plugin_section section,
+ unsigned int* addralign)
+{
+ 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;
+
+ *addralign = obj->section_addralign(section.shndx);
+ return LDPS_OK;
+}
+
+// Get the size 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_size(const struct ld_plugin_section section,
+ uint64_t* secsize)
+{
+ 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;
+
+ *secsize = obj->section_size(section.shndx);
+ return LDPS_OK;
+}
+
+static enum ld_plugin_status
+get_wrap_symbols(uint64_t *count, const char ***wrap_symbols)
+{
+ gold_assert(parameters->options().has_plugins());
+ *count = parameters->options().wrap_size();
+
+ if (*count == 0)
+ return LDPS_OK;
+
+ *wrap_symbols = new const char *[*count];
+ int i = 0;
+ for (options::String_set::const_iterator
+ it = parameters->options().wrap_begin();
+ it != parameters->options().wrap_end(); ++it, ++i) {
+ (*wrap_symbols)[i] = it->c_str();
+ }
+ 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;
+
+ Layout* layout = parameters->options().plugins()->layout();
+ gold_assert (layout != NULL);
+
+ std::map<Section_id, unsigned int>* order_map
+ = layout->get_section_order_map();
+
+ /* Store the mapping from Section_id to section position in layout's
+ order_map to consult after output sections are added. */
+ for (unsigned int i = 0; i < num_sections; ++i)
+ {
+ Object* obj = parameters->options().plugins()->get_elf_object(
+ section_list[i].handle);
+ if (obj == NULL || obj->is_dynamic())
+ return LDPS_BAD_HANDLE;
+ unsigned int shndx = section_list[i].shndx;
+ Section_id secn_id(static_cast<Relobj*>(obj), shndx);
+ (*order_map)[secn_id] = i + 1;
+ }
+
+ 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;
+}
+
+// Let the linker know that a subset of sections could be mapped
+// to a unique segment.
+
+static enum ld_plugin_status
+allow_unique_segment_for_sections()
+{
+ gold_assert(parameters->options().has_plugins());
+ Layout* layout = parameters->options().plugins()->layout();
+ layout->set_unique_segment_for_sections_specified();
+ return LDPS_OK;
+}
+
+// This function should map the list of sections specified in the
+// SECTION_LIST to a unique segment. ELF segments do not have names
+// and the NAME is used to identify Output Section which should contain
+// the list of sections. This Output Section will then be mapped to
+// a unique segment. FLAGS is used to specify if any additional segment
+// flags need to be set. For instance, a specific segment flag can be
+// set to identify this segment. Unsetting segment flags is not possible.
+// ALIGN specifies the alignment of the segment.
+
+static enum ld_plugin_status
+unique_segment_for_sections(const char* segment_name,
+ uint64_t flags,
+ uint64_t align,
+ 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;
+
+ Layout* layout = parameters->options().plugins()->layout();
+ gold_assert (layout != NULL);
+
+ Layout::Unique_segment_info* s = new Layout::Unique_segment_info;
+ s->name = segment_name;
+ s->flags = flags;
+ s->align = align;
+
+ for (unsigned int i = 0; i < num_sections; ++i)
+ {
+ Object* obj = parameters->options().plugins()->get_elf_object(
+ section_list[i].handle);
+ if (obj == NULL || obj->is_dynamic())
+ return LDPS_BAD_HANDLE;
+ unsigned int shndx = section_list[i].shndx;
+ Const_section_id secn_id(static_cast<Relobj*>(obj), shndx);
+ layout->insert_section_segment_map(secn_id, s);
+ }
+
+ return LDPS_OK;
+}
+
+// Register a new_input handler.
+
+static enum ld_plugin_status
+register_new_input(ld_plugin_new_input_handler handler)
+{
+ gold_assert(parameters->options().has_plugins());
+ parameters->options().plugins()->set_new_input_handler(handler);
+ return LDPS_OK;
+}
+