123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- // arm-reloc-property.h -- ARM relocation properties -*- C++ -*-
- // Copyright (C) 2010-2015 Free Software Foundation, Inc.
- // Written by Doug Kwan <dougkwan@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_ARM_RELOC_PROPERTY_H
- #define GOLD_ARM_RELOC_PROPERTY_H
- namespace gold
- {
- // The Arm_reloc_property class is to store information about a particular
- // relocation code.
- class Arm_reloc_property
- {
- public:
- // Types of relocation codes.
- enum Reloc_type {
- RT_NONE, // No relocation type.
- RT_STATIC, // Relocations processed by static linkers.
- RT_DYNAMIC, // Relocations processed by dynamic linkers.
- RT_PRIVATE, // Private relocations, not supported by gold.
- RT_OBSOLETE // Obsolete relocations that should not be used.
- };
- // Classes of relocation codes.
- enum Reloc_class {
- RC_NONE, // No relocation class.
- RC_DATA, // Data relocation.
- RC_ARM, // ARM instruction relocation.
- RC_THM16, // 16-bit THUMB instruction relocation.
- RC_THM32, // 32-bit THUMB instruction relocation.
- RC_MISC // Miscellaneous class.
- };
- // Types of bases of relative addressing relocation codes.
- enum Relative_address_base {
- RAB_NONE, // Relocation is not relative addressing
- RAB_B_S, // Address origin of output segment of defining symbol.
- RAB_DELTA_B_S, // Change of address origin.
- RAB_GOT_ORG, // Origin of GOT.
- RAB_P, // Address of the place being relocated.
- RAB_Pa, // Adjusted address (P & 0xfffffffc).
- RAB_TLS, // Thread local storage.
- RAB_tp // Thread pointer.
- };
- // Relocation code represented by this.
- unsigned int
- code() const
- { return this->code_; }
- // Name of the relocation code.
- const std::string&
- name() const
- { return this->name_; }
-
- // Type of relocation code.
- Reloc_type
- reloc_type() const
- { return this->reloc_type_; }
- // Whether this code is deprecated.
- bool
- is_deprecated() const
- { return this->is_deprecated_; }
- // Class of relocation code.
- Reloc_class
- reloc_class() const
- { return this->reloc_class_; }
- // Whether this code is implemented in gold.
- bool
- is_implemented() const
- { return this->is_implemented_; }
- // If code is a group relocation code, return the group number, otherwise -1.
- int
- group_index() const
- { return this->group_index_; }
- // Whether relocation checks for overflow.
- bool
- checks_overflow() const
- { return this->checks_overflow_; }
- // Return size of relocation.
- size_t
- size() const
- { return this->size_; }
- // Return alignment of relocation.
- size_t
- align() const
- { return this->align_; }
- // Whether relocation use a GOT entry.
- bool
- uses_got_entry() const
- { return this->uses_got_entry_; }
- // Whether relocation use a GOT origin.
- bool
- uses_got_origin() const
- { return this->uses_got_origin_; }
-
- // Whether relocation uses the Thumb-bit in a symbol address.
- bool
- uses_thumb_bit() const
- { return this->uses_thumb_bit_; }
- // Whether relocation uses the symbol base.
- bool
- uses_symbol_base() const
- { return this->uses_symbol_base_; }
- // Whether relocation uses the symbol.
- bool
- uses_symbol() const
- { return this->uses_symbol_; }
- // Return the type of relative address base or RAB_NONE if this
- // is not a relative addressing relocation.
- Relative_address_base
- relative_address_base() const
- { return this->relative_address_base_; }
- protected:
- // These are protected. We only allow Arm_reloc_property_table to
- // manage Arm_reloc_property.
- Arm_reloc_property(unsigned int code, const char* name, Reloc_type rtype,
- bool is_deprecated, Reloc_class rclass,
- const std::string& operation, bool is_implemented,
- int group_index, bool checks_overflow);
- friend class Arm_reloc_property_table;
-
- private:
- // Copying is not allowed.
- Arm_reloc_property(const Arm_reloc_property&);
- Arm_reloc_property& operator=(const Arm_reloc_property&);
- // The Tree_node class is used to represent parsed relocation operations.
- // We look at Trees to extract information about relocation operations.
- class Tree_node
- {
- public:
- typedef std::vector<Tree_node*> Tree_node_vector;
- // Construct a leaf node.
- Tree_node(const char* name)
- : is_leaf_(true), name_(name), children_()
- { }
- // Construct an internal node. A node owns all its children and is
- // responsible for releasing them at its own destruction.
- Tree_node(Tree_node_vector::const_iterator begin,
- Tree_node_vector::const_iterator end)
- : is_leaf_(false), name_(), children_()
- {
- for (Tree_node_vector::const_iterator p = begin; p != end; ++p)
- this->children_.push_back(*p);
- }
- ~Tree_node()
- {
- for(size_t i = 0; i <this->children_.size(); ++i)
- delete this->children_[i];
- }
- // Whether this is a leaf node.
- bool
- is_leaf() const
- { return this->is_leaf_; }
- // Return name of this. This is only valid for a leaf node.
- const std::string&
- name() const
- {
- gold_assert(this->is_leaf_);
- return this->name_;
- }
- // Return the number of children. This is only valid for a non-leaf node.
- size_t
- number_of_children() const
- {
- gold_assert(!this->is_leaf_);
- return this->children_.size();
- }
- // Return the i-th child of this. This is only valid for a non-leaf node.
- Tree_node*
- child(size_t i) const
- {
- gold_assert(!this->is_leaf_ && i < this->children_.size());
- return this->children_[i];
- }
- // Parse an S-expression string and build a tree and return the root node.
- // Caller is responsible for releasing tree after use.
- static Tree_node*
- make_tree(const std::string&);
- // Convert a tree back to an S-expression string.
- std::string
- s_expression() const
- {
- if (this->is_leaf_)
- return this->name_;
- // Concatenate S-expressions of children. Enclose them with
- // a pair of parentheses and use space as token delimiters.
- std::string s("(");
- for(size_t i = 0; i <this->children_.size(); ++i)
- s = s + " " + this->children_[i]->s_expression();
- return s + " )";
- }
- private:
- // Whether this is a leaf node.
- bool is_leaf_;
- // Name of this if this is a leaf node.
- std::string name_;
- // Children of this if this a non-leaf node.
- Tree_node_vector children_;
- };
- // Relocation code.
- unsigned int code_;
- // Relocation name.
- std::string name_;
- // Type of relocation.
- Reloc_type reloc_type_;
- // Class of relocation.
- Reloc_class reloc_class_;
- // Group index (0, 1, or 2) if this is a group relocation or -1 otherwise.
- int group_index_;
- // Size of relocation.
- size_t size_;
- // Alignment of relocation.
- size_t align_;
- // Relative address base.
- Relative_address_base relative_address_base_;
- // Whether this is deprecated.
- bool is_deprecated_ : 1;
- // Whether this is implemented in gold.
- bool is_implemented_ : 1;
- // Whether this checks overflow.
- bool checks_overflow_ : 1;
- // Whether this uses a GOT entry.
- bool uses_got_entry_ : 1;
- // Whether this uses a GOT origin.
- bool uses_got_origin_ : 1;
- // Whether this uses a PLT entry.
- bool uses_plt_entry_ : 1;
- // Whether this uses the THUMB bit in symbol address.
- bool uses_thumb_bit_ : 1;
- // Whether this uses the symbol base.
- bool uses_symbol_base_ : 1;
- // Whether this uses an addend.
- bool uses_addend_ : 1;
- // Whether this uses the symbol.
- bool uses_symbol_ : 1;
- };
- // Arm_reloc_property_table. This table is used for looking up properties
- // of relocation types. The table entries are initialized using information
- // from arm-reloc.def.
- class Arm_reloc_property_table
- {
- public:
- Arm_reloc_property_table();
- // Return an Arm_reloc_property object for CODE if it is a valid relocation
- // code or NULL otherwise.
- const Arm_reloc_property*
- get_reloc_property(unsigned int code) const
- {
- gold_assert(code < Property_table_size);
- return this->table_[code];
- }
- // Like get_reloc_property but only return non-NULL if relocation code is
- // static and implemented.
- const Arm_reloc_property*
- get_implemented_static_reloc_property(unsigned int code) const
- {
- gold_assert(code < Property_table_size);
- const Arm_reloc_property* arp = this->table_[code];
- return ((arp != NULL
- && (arp->reloc_type() == Arm_reloc_property::RT_STATIC)
- && arp->is_implemented())
- ? arp
- : NULL);
- }
-
- // Return a string describing the relocation code that is not
- // an implemented static reloc code.
- std::string
- reloc_name_in_error_message(unsigned int code);
- private:
- // Copying is not allowed.
- Arm_reloc_property_table(const Arm_reloc_property_table&);
- Arm_reloc_property_table& operator=(const Arm_reloc_property_table&);
- // The Parse_expression class is used to convert relocation operations in
- // arm-reloc.def into S-expression strings, which are parsed again to
- // build actual expression trees. We do not build the expression trees
- // directly because the parser for operations in arm-reloc.def is simpler
- // this way. Conversion from S-expressions to trees is simple.
- class Parse_expression
- {
- public:
- // Construction a Parse_expression with an S-expression string.
- Parse_expression(const std::string& s_expression)
- : s_expression_(s_expression)
- { }
- // Value of this expression as an S-expression string.
- const std::string&
- s_expression() const
- { return this->s_expression_; }
- // We want to overload operators used in relocation operations so
- // that we can execute operations in arm-reloc.def to generate
- // S-expressions directly.
- #define DEF_OPERATOR_OVERLOAD(op) \
- Parse_expression \
- operator op (const Parse_expression& e) \
- { \
- return Parse_expression("( " #op " " + this->s_expression_ + " " + \
- e.s_expression_ + " )"); \
- }
- // Operator appearing in relocation operations in arm-reloc.def.
- DEF_OPERATOR_OVERLOAD(+)
- DEF_OPERATOR_OVERLOAD(-)
- DEF_OPERATOR_OVERLOAD(|)
-
- private:
- // This represented as an S-expression string.
- std::string s_expression_;
- };
- #define DEF_RELOC_FUNC(name) \
- static Parse_expression \
- (name)(const Parse_expression& arg) \
- { return Parse_expression("( " #name " " + arg.s_expression() + " )"); }
- // Functions appearing in relocation operations in arm-reloc.def.
- DEF_RELOC_FUNC(B)
- DEF_RELOC_FUNC(DELTA_B)
- DEF_RELOC_FUNC(GOT)
- DEF_RELOC_FUNC(Module)
- DEF_RELOC_FUNC(PLT)
- static const unsigned int Property_table_size = 256;
- // The property table.
- Arm_reloc_property* table_[Property_table_size];
- };
- } // End namespace gold.
- #endif // !defined(GOLD_ARM_RELOC_PROPERTY_H)
|