X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gold%2Fplugin.cc;h=026748f42076b59b5aa012a01cd3cb47f21f5da0;hb=945e0f82dad31db89a107b496532886fe215c011;hp=1588f34c477cb1d8f57f77ce03a6191316a0da1c;hpb=efc6fa128f00d61014f56530724767ea048bf594;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/plugin.cc b/gold/plugin.cc index 1588f34c47..026748f420 100644 --- a/gold/plugin.cc +++ b/gold/plugin.cc @@ -1,6 +1,6 @@ // plugin.cc -- plugin manager for gold -*- C++ -*- -// Copyright (C) 2008-2015 Free Software Foundation, Inc. +// Copyright (C) 2008-2016 Free Software Foundation, Inc. // Written by Cary Coutant . // This file is part of gold. @@ -111,6 +111,9 @@ get_symbols(const void *handle, int nsyms, struct ld_plugin_symbol *syms); static enum ld_plugin_status get_symbols_v2(const void *handle, int nsyms, struct ld_plugin_symbol *syms); +static enum ld_plugin_status +get_symbols_v3(const void *handle, int nsyms, struct ld_plugin_symbol *syms); + static enum ld_plugin_status add_input_file(const char *pathname); @@ -155,6 +158,15 @@ unique_segment_for_sections(const char* segment_name, uint64_t align, const struct ld_plugin_section *section_list, unsigned int num_sections); + +static enum ld_plugin_status +get_input_section_alignment(const struct ld_plugin_section section, + unsigned int* addralign); + +static enum ld_plugin_status +get_input_section_size(const struct ld_plugin_section section, + uint64_t* secsize); + }; #endif // ENABLE_PLUGINS @@ -199,7 +211,7 @@ Plugin::load() sscanf(ver, "%d.%d", &major, &minor); // Allocate and populate a transfer vector. - const int tv_fixed_size = 26; + const int tv_fixed_size = 29; int tv_size = this->args_.size() + tv_fixed_size; ld_plugin_tv* tv = new ld_plugin_tv[tv_size]; @@ -276,6 +288,10 @@ Plugin::load() tv[i].tv_tag = LDPT_GET_SYMBOLS_V2; tv[i].tv_u.tv_get_symbols = get_symbols_v2; + ++i; + tv[i].tv_tag = LDPT_GET_SYMBOLS_V3; + tv[i].tv_u.tv_get_symbols = get_symbols_v3; + ++i; tv[i].tv_tag = LDPT_ADD_INPUT_FILE; tv[i].tv_u.tv_add_input_file = add_input_file; @@ -321,6 +337,14 @@ Plugin::load() tv[i].tv_tag = LDPT_UNIQUE_SEGMENT_FOR_SECTIONS; tv[i].tv_u.tv_unique_segment_for_sections = unique_segment_for_sections; + ++i; + tv[i].tv_tag = LDPT_GET_INPUT_SECTION_ALIGNMENT; + tv[i].tv_u.tv_get_input_section_alignment = get_input_section_alignment; + + ++i; + tv[i].tv_tag = LDPT_GET_INPUT_SECTION_SIZE; + tv[i].tv_u.tv_get_input_section_size = get_input_section_size; + ++i; tv[i].tv_tag = LDPT_NULL; tv[i].tv_u.tv_val = 0; @@ -937,7 +961,7 @@ Pluginobj::get_symbol_resolution_info(Symbol_table* symtab, gold_assert(this->symbols_.size() == 0); for (int i = 0; i < nsyms; i++) syms[i].resolution = LDPR_PREEMPTED_REG; - return LDPS_OK; + return version > 2 ? LDPS_NO_SYMS : LDPS_OK; } for (int i = 0; i < nsyms; i++) @@ -1155,6 +1179,8 @@ Sized_pluginobj::do_should_include_member( for (int i = 0; i < this->nsyms_; ++i) { const struct ld_plugin_symbol& sym = this->syms_[i]; + if (sym.def == LDPK_UNDEF || sym.def == LDPK_WEAKUNDEF) + continue; const char* name = sym.name; Symbol* symbol; Archive::Should_include t = Archive::should_include_member(symtab, @@ -1545,6 +1571,26 @@ get_symbols_v2(const void* handle, int nsyms, ld_plugin_symbol* syms) return plugin_obj->get_symbol_resolution_info(symtab, nsyms, syms, 2); } +// Version 3 of the above. The only difference from v2 is that it +// returns LDPS_NO_SYMS instead of LDPS_OK for the objects we never +// decided to include. + +static enum ld_plugin_status +get_symbols_v3(const void* handle, int nsyms, ld_plugin_symbol* syms) +{ + gold_assert(parameters->options().has_plugins()); + Plugin_manager* plugins = parameters->options().plugins(); + Object* obj = plugins->object( + static_cast(reinterpret_cast(handle))); + if (obj == NULL) + return LDPS_ERR; + Pluginobj* plugin_obj = obj->pluginobj(); + if (plugin_obj == NULL) + return LDPS_ERR; + Symbol_table* symtab = plugins->symtab(); + return plugin_obj->get_symbol_resolution_info(symtab, nsyms, syms, 3); +} + // Add a new (real) input file generated by a plugin. static enum ld_plugin_status @@ -1703,6 +1749,53 @@ get_input_section_contents(const struct ld_plugin_section section, 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; +} + + // 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.