diff options
Diffstat (limited to 'binutils-2.20.1/gold/icf.h')
-rw-r--r-- | binutils-2.20.1/gold/icf.h | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/binutils-2.20.1/gold/icf.h b/binutils-2.20.1/gold/icf.h new file mode 100644 index 00000000..1a4d1be9 --- /dev/null +++ b/binutils-2.20.1/gold/icf.h @@ -0,0 +1,179 @@ +// icf.h -- Identical Code Folding + +// Copyright 2009, 2010 Free Software Foundation, Inc. +// Written by Sriraman Tallam <tmsriram@google.com>. + +// This file is part of gold. + +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +// MA 02110-1301, USA. + +#ifndef GOLD_ICF_H +#define GOLD_ICF_H + +#include <vector> + +#include "elfcpp.h" +#include "symtab.h" +#include "object.h" + +namespace gold +{ + +class Object; +class Input_objects; +class Symbol_table; + +class Icf +{ + public: + typedef std::vector<Section_id> Sections_reachable_info; + typedef std::vector<Symbol*> Symbol_info; + typedef std::vector<std::pair<long long, long long> > Addend_info; + typedef std::vector<uint64_t> Offset_info; + typedef std::vector<unsigned int> Reloc_addend_size_info; + typedef Unordered_map<Section_id, + unsigned int, + Section_id_hash> Uniq_secn_id_map; + typedef Unordered_set<Section_id, Section_id_hash> 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<Section_id, Reloc_info, + Section_id_hash> Reloc_info_list; + + Icf() + : id_section_(), section_id_(), kept_section_id_(), + fptr_section_id_(), + num_tracked_relocs(NULL), 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); + + // Forms groups of identical sections where the first member + // of each group is the kept section during folding. + void + find_identical_sections(const Input_objects* input_objects, + Symbol_table* symtab); + + // This is set when ICF has been run and the groups of + // identical sections have been formed. + void + icf_ready() + { this->icf_ready_ = true; } + + // Returns true if ICF has been run. + bool + is_icf_ready() + { return this->icf_ready_; } + + // Unfolds the section denoted by OBJ and SHNDX if folded. + void + unfold_section(Object* obj, unsigned int shndx); + + // Returns the kept section corresponding to the + // given section. + bool + is_section_folded(Object* 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) + { + 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(Object *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 mapping of each section to a unique integer. + Uniq_secn_id_map& + section_to_int_map() + { return this->section_id_; } + + private: + + // Maps integers to sections. + std::vector<Section_id> id_section_; + // Does the reverse. + Uniq_secn_id_map section_id_; + // Given a section id, this maps it to the id of the kept + // section. If the id's are the same then this section is + // not folded. + std::vector<unsigned int> kept_section_id_; + // 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_; + 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_; +}; + +// 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. +inline bool +is_section_foldable_candidate(const char* section_name) +{ + return (is_prefix_of(".text", section_name) + || is_prefix_of(".gnu.linkonce.t", section_name)); +} + +} // End of namespace gold. + +#endif |