123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- // aarch64-reloc-property.h -- AArch64 relocation properties -*- C++ -*-
- // Copyright (C) 2014-2015 Free Software Foundation, Inc.
- // Written by Han Shen <shenhan@google.com> and Jing Yu <jingyu@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_AARCH64_RELOC_PROPERTY_H
- #define GOLD_AARCH64_RELOC_PROPERTY_H
- #include<vector>
- #include<string>
- #include"aarch64.h"
- namespace gold
- {
- // The AArch64_reloc_property class is to store information about a particular
- // relocation code.
- class AArch64_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.
- };
- // Classes of relocation codes.
- enum Reloc_class {
- RC_NONE, // No relocation class.
- RC_DATA, // Data relocation.
- RC_AARCH64, // Static AArch64 relocations
- RC_CFLOW, // Control flow
- RC_TLS, // Thread local storage
- RC_DYNAMIC, // Dynamic relocation
- };
- // Instructions that are associated with relocations.
- enum Reloc_inst {
- INST_DATA = 0,
- INST_MOVW = 1, // movz, movk, movn
- INST_LD = 2, // ld literal
- INST_ADR = 3, // adr
- INST_ADRP = 4, // adrp
- INST_ADD = 5, // add
- INST_LDST = 6, // ld/st
- INST_TBZNZ = 7, // tbz/tbnz
- INST_CONDB = 8, // B.cond
- INST_B = 9, // b [25:0]
- INST_CALL = 10, // bl [25:0]
- INST_NUM = 11, // total number of entries in the table
- };
- // Types of bases of relative addressing relocation codes.
- // enum Relative_address_base {
- // RAB_NONE, // Relocation is not relative addressing
- // };
- typedef bool (*rvalue_checkup_func_p)(int64_t);
- typedef uint64_t (*rvalue_bit_select_func)(uint64_t);
- // 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_; }
- // 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_; }
- // Return alignment of relocation.
- size_t
- align() const
- { return this->align_; }
- int
- reference_flags() const
- { return this->reference_flags_; }
- // Instruction associated with this relocation.
- Reloc_inst
- reloc_inst() const
- { return this->reloc_inst_; }
- // Check overflow of x
- bool checkup_x_value(int64_t x) const
- { return this->rvalue_checkup_func_(x); }
- // Return portions of x as is defined in aarch64-reloc.def.
- uint64_t select_x_value(uint64_t x) const
- { return this->rvalue_bit_select_func_(x); }
- protected:
- // These are protected. We only allow AArch64_reloc_property_table to
- // manage AArch64_reloc_property.
- AArch64_reloc_property(unsigned int code, const char* name, Reloc_type rtype,
- Reloc_class rclass,
- bool is_implemented,
- int group_index,
- int reference_flags,
- Reloc_inst reloc_inst,
- rvalue_checkup_func_p rvalue_checkup_func,
- rvalue_bit_select_func rvalue_bit_select);
- friend class AArch64_reloc_property_table;
- private:
- // Copying is not allowed.
- AArch64_reloc_property(const AArch64_reloc_property&);
- AArch64_reloc_property& operator=(const AArch64_reloc_property&);
- // Relocation code.
- const unsigned int code_;
- // Relocation name.
- const 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;
- const int reference_flags_;
- // Instruction associated with relocation.
- Reloc_inst reloc_inst_;
- rvalue_checkup_func_p rvalue_checkup_func_;
- rvalue_bit_select_func rvalue_bit_select_func_;
- };
- class AArch64_reloc_property_table
- {
- public:
- AArch64_reloc_property_table();
- const AArch64_reloc_property*
- get_reloc_property(unsigned int code) const
- {
- unsigned int idx = code_to_array_index(code);
- return this->table_[idx];
- }
- // Like get_reloc_property but only return non-NULL if relocation code is
- // static and implemented.
- const AArch64_reloc_property*
- get_implemented_static_reloc_property(unsigned int code) const
- {
- unsigned int idx = code_to_array_index(code);
- const AArch64_reloc_property* arp = this->table_[idx];
- return ((arp != NULL
- && (arp->reloc_type() == AArch64_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.
- AArch64_reloc_property_table(const AArch64_reloc_property_table&);
- AArch64_reloc_property_table& operator=(const AArch64_reloc_property_table&);
- // Map aarch64 rtypes into range(0,300) as following
- // 256 ~ 313 -> 0 ~ 57
- // 512 ~ 573 -> 128 ~ 189
- int
- code_to_array_index(unsigned int code) const
- {
- if (code == 0) return 0;
- if (!((code >= elfcpp::R_AARCH64_ABS64 &&
- code <= elfcpp::R_AARCH64_LD64_GOTPAGE_LO15)
- || (code >= elfcpp::R_AARCH64_TLSGD_ADR_PREL21 &&
- code <= elfcpp::R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC)))
- {
- gold_error(_("Invalid/unrecognized reloc reloc %d."), code);
- }
- unsigned int rv = -1;
- if (code & (1 << 9))
- rv = 128 + code - 512; // 512 - 573
- else if (code & (1 << 8))
- rv = code - 256; // 256 - 313
- gold_assert(rv <= Property_table_size);
- return rv;
- }
- static const unsigned int Property_table_size = 300;
- AArch64_reloc_property* table_[Property_table_size];
- }; // End of class AArch64_reloc_property_table
- } // End namespace gold.
- #endif // !defined(GOLD_AARCH64_RELOC_PROPERTY_H)
|