X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;ds=sidebyside;f=gold%2Ficf.h;h=893349b7c1e5ebabecf1a776d5942d2e2c1eccb4;hb=78f2c40a12179d26d3065c09f054b7e751b2732f;hp=de0fbe088f53c34546ea941166eee2c45dca3c54;hpb=55a2bb35466651972b102f5f8b5ec53a17be5b55;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/icf.h b/gold/icf.h index de0fbe088f..893349b7c1 100644 --- a/gold/icf.h +++ b/gold/icf.h @@ -1,6 +1,6 @@ // icf.h -- Identical Code Folding -// Copyright 2009, 2010 Free Software Foundation, Inc. +// Copyright (C) 2009-2020 Free Software Foundation, Inc. // Written by Sriraman Tallam . // This file is part of gold. @@ -27,6 +27,7 @@ #include "elfcpp.h" #include "symtab.h" +#include "object.h" namespace gold { @@ -35,40 +36,58 @@ class Object; class Input_objects; class Symbol_table; -typedef std::pair Section_id; - class Icf { public: - struct Section_id_hash - { - size_t operator()(const Section_id& loc) const - { return reinterpret_cast(loc.first) ^ loc.second; } - }; - - typedef std::vector Sections_reachable_list; + typedef std::vector Sections_reachable_info; typedef std::vector Symbol_info; typedef std::vector > Addend_info; - typedef Unordered_map Section_list; - typedef Unordered_map Symbol_list; - typedef Unordered_map Addend_list; + typedef std::vector Offset_info; + typedef std::vector Reloc_addend_size_info; typedef Unordered_map Uniq_secn_id_map; + typedef Unordered_set Secn_fptr_taken_set; + + typedef struct + { + // This stores the section corresponding to the reloc. + Sections_reachable_info section_info; + // This stores the symbol corresponding to the reloc. + Symbol_info symbol_info; + // This stores the symbol value and the addend for a reloc. + Addend_info addend_info; + Offset_info offset_info; + Reloc_addend_size_info reloc_addend_size_info; + } Reloc_info; + + typedef Unordered_map Reloc_info_list; + + // A region of some other section that should be considered part of + // a section for ICF purposes. This is used to avoid folding sections + // that have identical text and relocations but different .eh_frame + // information. + typedef struct + { + Section_id section; + section_offset_type offset; + section_size_type length; + } Extra_identity_info; + + typedef std::multimap Extra_identity_list; Icf() : id_section_(), section_id_(), kept_section_id_(), - num_tracked_relocs(NULL), icf_ready_(false), - section_reloc_list_(), symbol_reloc_list_(), - addend_reloc_list_() + fptr_section_id_(), + icf_ready_(false), + reloc_info_list_() { } // Returns the kept folded identical section corresponding to // dup_obj and dup_shndx. Section_id - get_folded_section(Object* dup_obj, unsigned int dup_shndx); + get_folded_section(Relobj* dup_obj, unsigned int dup_shndx); // Forms groups of identical sections where the first member // of each group is the kept section during folding. @@ -89,31 +108,54 @@ class Icf // Unfolds the section denoted by OBJ and SHNDX if folded. void - unfold_section(Object* obj, unsigned int shndx); + unfold_section(Relobj* obj, unsigned int shndx); - // Returns the kept section corresponding to the + // Returns the kept section corresponding to the // given section. bool - is_section_folded(Object* obj, unsigned int shndx); - - // Returns a map of a section to a list of all sections referenced - // by its relocations. - Section_list& - section_reloc_list() - { return this->section_reloc_list_; } - - // Returns a map of a section to a list of all symbols referenced - // by its relocations. - Symbol_list& - symbol_reloc_list() - { return this->symbol_reloc_list_; } - - // Returns a maps of a section to a list of symbol values and addends - // of its relocations. - Addend_list& - addend_reloc_list() - { return this->addend_reloc_list_; } - + is_section_folded(Relobj* obj, unsigned int shndx); + + // Given an object and a section index, this returns true if the + // pointer of the function defined in this section is taken. + bool + section_has_function_pointers(Relobj* obj, unsigned int shndx) + { + return (this->fptr_section_id_.find(Section_id(obj, shndx)) + != this->fptr_section_id_.end()); + } + + // Records that a pointer of the function defined in this section + // is taken. + void + set_section_has_function_pointers(Relobj* obj, unsigned int shndx) + { + this->fptr_section_id_.insert(Section_id(obj, shndx)); + } + + // Checks if the section_name should be searched for relocs + // corresponding to taken function pointers. Ignores eh_frame + // and vtable sections. + inline bool + check_section_for_function_pointers(const std::string& section_name, + Target* target) + { + return (parameters->options().icf_safe_folding() + && target->can_check_for_function_pointers() + && target->section_may_have_icf_unsafe_pointers( + section_name.c_str())); + } + + // Returns a map of a section to info (Reloc_info) about its relocations. + Reloc_info_list& + reloc_info_list() + { return this->reloc_info_list_; } + + // Returns a map from section to region of a different section that should + // be considered part of the key section for ICF purposes. + Extra_identity_list& + extra_identity_list() + { return this->extra_identity_list_; } + // Returns a mapping of each section to a unique integer. Uniq_secn_id_map& section_to_int_map() @@ -121,6 +163,10 @@ class Icf private: + bool + add_ehframe_links(Relobj* object, unsigned int ehframe_shndx, + Reloc_info& ehframe_relocs); + // Maps integers to sections. std::vector id_section_; // Does the reverse. @@ -129,25 +175,33 @@ class Icf // section. If the id's are the same then this section is // not folded. std::vector kept_section_id_; - unsigned int* num_tracked_relocs; + // Given a section id, this says if the pointer to this + // function is taken in which case it is dangerous to fold + // this function. + Secn_fptr_taken_set fptr_section_id_; // Flag to indicate if ICF has been run. bool icf_ready_; - - // These lists are populated by gc_process_relocs in gc.h. - Section_list section_reloc_list_; - Symbol_list symbol_reloc_list_; - Addend_list addend_reloc_list_; + // This list is populated by gc_process_relocs in gc.h. + Reloc_info_list reloc_info_list_; + // Regions of other sections that should be considered part of + // each section for ICF purposes. + Extra_identity_list extra_identity_list_; }; // This function returns true if this section corresponds to a function that // should be considered by icf as a possible candidate for folding. Some // earlier gcc versions, like 4.0.3, put constructors and destructors in // .gnu.linkonce.t sections and hence should be included too. +// The mechanism used to safely fold functions referenced by .eh_frame +// requires folding .gcc_except_table sections as well; see "Notes regarding +// C++ exception handling" at the top of icf.cc for an explanation why. inline bool -is_section_foldable_candidate(const char* section_name) +is_section_foldable_candidate(const std::string& section_name) { - return (is_prefix_of(".text", section_name) - || is_prefix_of(".gnu.linkonce.t", section_name)); + const char* section_name_cstr = section_name.c_str(); + return (is_prefix_of(".text", section_name_cstr) + || is_prefix_of(".gcc_except_table", section_name_cstr) + || is_prefix_of(".gnu.linkonce.t", section_name_cstr)); } } // End of namespace gold.