X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gold%2Ficf.cc;h=ad887154dd837dbe0affc4c6e63f71489a6d1872;hb=32127f9a02101f94a3c5ae78fc35c17bc55053c8;hp=a132875873ec9ea50fdc06f2a0974107409a11ab;hpb=5f9bcf5825f56b017aacf20aaabce0ed07920454;p=platform%2Fupstream%2Fbinutils.git diff --git a/gold/icf.cc b/gold/icf.cc index a132875..ad88715 100644 --- a/gold/icf.cc +++ b/gold/icf.cc @@ -1,6 +1,6 @@ // icf.cc -- Identical Code Folding. // -// Copyright 2009, 2010 Free Software Foundation, Inc. +// Copyright (C) 2009-2014 Free Software Foundation, Inc. // Written by Sriraman Tallam . // This file is part of gold. @@ -237,20 +237,16 @@ get_section_contents(bool first_iteration, const std::vector& kept_section_id, std::vector* section_contents) { + // Lock the object so we can read from it. This is only called + // single-threaded from queue_middle_tasks, so it is OK to lock. + // Unfortunately we have no way to pass in a Task token. + const Task* dummy_task = reinterpret_cast(-1); + Task_lock_obj tl(dummy_task, secn.first); + section_size_type plen; const unsigned char* contents = NULL; - if (first_iteration) - { - // Lock the object so we can read from it. This is only called - // single-threaded from queue_middle_tasks, so it is OK to lock. - // Unfortunately we have no way to pass in a Task token. - const Task* dummy_task = reinterpret_cast(-1); - Task_lock_obj tl(dummy_task, secn.first); - contents = secn.first->section_contents(secn.second, - &plen, - false); - } + contents = secn.first->section_contents(secn.second, &plen, false); // The buffer to hold all the contents including relocs. A checksum // is then computed on this buffer. @@ -273,27 +269,46 @@ get_section_contents(bool first_iteration, if (it_reloc_info_list != reloc_info_list.end()) { - Icf::Sections_reachable_info v = + Icf::Sections_reachable_info &v = (it_reloc_info_list->second).section_info; // Stores the information of the symbol pointed to by the reloc. - Icf::Symbol_info s = (it_reloc_info_list->second).symbol_info; + const Icf::Symbol_info &s = (it_reloc_info_list->second).symbol_info; // Stores the addend and the symbol value. - Icf::Addend_info a = (it_reloc_info_list->second).addend_info; + Icf::Addend_info &a = (it_reloc_info_list->second).addend_info; // Stores the offset of the reloc. - Icf::Offset_info o = (it_reloc_info_list->second).offset_info; - Icf::Reloc_addend_size_info reloc_addend_size_info = + const Icf::Offset_info &o = (it_reloc_info_list->second).offset_info; + const Icf::Reloc_addend_size_info &reloc_addend_size_info = (it_reloc_info_list->second).reloc_addend_size_info; Icf::Sections_reachable_info::iterator it_v = v.begin(); - Icf::Symbol_info::iterator it_s = s.begin(); + Icf::Symbol_info::const_iterator it_s = s.begin(); Icf::Addend_info::iterator it_a = a.begin(); - Icf::Offset_info::iterator it_o = o.begin(); - Icf::Reloc_addend_size_info::iterator it_addend_size = + Icf::Offset_info::const_iterator it_o = o.begin(); + Icf::Reloc_addend_size_info::const_iterator it_addend_size = reloc_addend_size_info.begin(); for (; it_v != v.end(); ++it_v, ++it_s, ++it_a, ++it_o, ++it_addend_size) { + if (first_iteration + && it_v->first != NULL) + { + Symbol_location loc; + loc.object = it_v->first; + loc.shndx = it_v->second; + loc.offset = convert_types(it_a->first + + it_a->second); + // Look through function descriptors + parameters->target().function_location(&loc); + if (loc.shndx != it_v->second) + { + it_v->second = loc.shndx; + // Modify symvalue/addend to the code entry. + it_a->first = loc.offset; + it_a->second = 0; + } + } + // ADDEND_STR stores the symbol value and addend and offset, - // each atmost 16 hex digits long. it_a points to a pair + // each at most 16 hex digits long. it_a points to a pair // where first is the symbol value and second is the // addend. char addend_str[50]; @@ -373,17 +388,11 @@ get_section_contents(bool first_iteration, if (!first_iteration) continue; - // Lock the object so we can read from it. This is only called - // single-threaded from queue_middle_tasks, so it is OK to lock. - // Unfortunately we have no way to pass in a Task token. - const Task* dummy_task = reinterpret_cast(-1); - Task_lock_obj tl(dummy_task, it_v->first); - uint64_t secn_flags = (it_v->first)->section_flags(it_v->second); // This reloc points to a merge section. Hash the // contents of this section. if ((secn_flags & elfcpp::SHF_MERGE) != 0 - && parameters->target().can_icf_inline_merge_sections ()) + && parameters->target().can_icf_inline_merge_sections()) { uint64_t entsize = (it_v->first)->section_entsize(it_v->second); @@ -550,7 +559,7 @@ get_section_contents(bool first_iteration, // KEPT_SECTION_ID : Vector which maps folded sections to kept sections. // ID_SECTION : Vector mapping a section to an unique integer. // IS_SECN_OR_GROUP_UNIQUE : To check if a section or a group of identical -// sectionsis already known to be unique. +// sections is already known to be unique. // SECTION_CONTENTS : Store the section's text and relocs to non-ICF // sections. @@ -662,16 +671,17 @@ match_sections(unsigned int iteration_num, } // During safe icf (--icf=safe), only fold functions that are ctors or dtors. -// This function returns true if the mangled function name is a ctor or a -// dtor. +// This function returns true if the section name is that of a ctor or a dtor. static bool -is_function_ctor_or_dtor(const char* mangled_func_name) +is_function_ctor_or_dtor(const std::string& section_name) { - if ((is_prefix_of("_ZN", mangled_func_name) - || is_prefix_of("_ZZ", mangled_func_name)) - && (is_gnu_v3_mangled_ctor(mangled_func_name) - || is_gnu_v3_mangled_dtor(mangled_func_name))) + const char* mangled_func_name = strrchr(section_name.c_str(), '.'); + gold_assert(mangled_func_name != NULL); + if ((is_prefix_of("._ZN", mangled_func_name) + || is_prefix_of("._ZZ", mangled_func_name)) + && (is_gnu_v3_mangled_ctor(mangled_func_name + 1) + || is_gnu_v3_mangled_dtor(mangled_func_name + 1))) { return true; } @@ -706,7 +716,7 @@ Icf::find_identical_sections(const Input_objects* input_objects, for (unsigned int i = 0;i < (*p)->shnum(); ++i) { - const char* section_name = (*p)->section_name(i).c_str(); + const std::string section_name = (*p)->section_name(i); if (!is_section_foldable_candidate(section_name)) continue; if (!(*p)->is_section_included(i)) @@ -714,13 +724,11 @@ Icf::find_identical_sections(const Input_objects* input_objects, if (parameters->options().gc_sections() && symtab->gc()->is_section_garbage(*p, i)) continue; - const char* mangled_func_name = strrchr(section_name, '.'); - gold_assert(mangled_func_name != NULL); // With --icf=safe, check if the mangled function name is a ctor // or a dtor. The mangled function name can be obtained from the // section name by stripping the section prefix. if (parameters->options().icf_safe_folding() - && !is_function_ctor_or_dtor(mangled_func_name + 1) + && !is_function_ctor_or_dtor(section_name) && (!target.can_check_for_function_pointers() || section_has_function_pointers(*p, i))) {