X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gold%2Ficf.h;h=893349b7c1e5ebabecf1a776d5942d2e2c1eccb4;hb=41792d688a5a1f158d6e9ecda2b603ae122d69a1;hp=c1db8e586f512dbf420efe5ad8534336d17d4ce8;hpb=b487ad64e5aa3da0c80b8648f7079b5415c45a3a;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/icf.h b/gold/icf.h index c1db8e586f..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. @@ -43,6 +43,7 @@ class Icf typedef std::vector Symbol_info; typedef std::vector > Addend_info; typedef std::vector Offset_info; + typedef std::vector Reloc_addend_size_info; typedef Unordered_map Uniq_secn_id_map; @@ -57,22 +58,36 @@ class Icf // 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_(), fptr_section_id_(), - num_tracked_relocs(NULL), icf_ready_(false), + 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. @@ -93,17 +108,17 @@ 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); + 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(Object *obj, unsigned int shndx) + section_has_function_pointers(Relobj* obj, unsigned int shndx) { return (this->fptr_section_id_.find(Section_id(obj, shndx)) != this->fptr_section_id_.end()); @@ -112,7 +127,7 @@ class Icf // Records that a pointer of the function defined in this section // is taken. void - set_section_has_function_pointers(Object *obj, unsigned int shndx) + set_section_has_function_pointers(Relobj* obj, unsigned int shndx) { this->fptr_section_id_.insert(Section_id(obj, shndx)); } @@ -121,20 +136,26 @@ class Icf // corresponding to taken function pointers. Ignores eh_frame // and vtable sections. inline bool - check_section_for_function_pointers(std::string section_name, + check_section_for_function_pointers(const std::string& section_name, Target* target) { return (parameters->options().icf_safe_folding() && target->can_check_for_function_pointers() - && !is_prefix_of(".rodata._ZTV", section_name.c_str()) - && !is_prefix_of(".eh_frame", section_name.c_str())); + && 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() @@ -142,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. @@ -154,22 +179,29 @@ class Icf // function is taken in which case it is dangerous to fold // this function. Secn_fptr_taken_set fptr_section_id_; - unsigned int* num_tracked_relocs; // Flag to indicate if ICF has been run. bool icf_ready_; // 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.