summaryrefslogtreecommitdiffstats
path: root/binutils-2.20.1/gold/icf.h
diff options
context:
space:
mode:
Diffstat (limited to 'binutils-2.20.1/gold/icf.h')
-rw-r--r--binutils-2.20.1/gold/icf.h179
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