1 // aarch64-reloc-property.h -- AArch64 relocation properties -*- C++ -*- 2 3 // Copyright (C) 2014-2016 Free Software Foundation, Inc. 4 // Written by Han Shen <shenhan (at) google.com> and Jing Yu <jingyu (at) google.com>. 5 6 // This file is part of gold. 7 8 // This program is free software; you can redistribute it and/or modify 9 // it under the terms of the GNU General Public License as published by 10 // the Free Software Foundation; either version 3 of the License, or 11 // (at your option) any later version. 12 13 // This program is distributed in the hope that it will be useful, 14 // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 // GNU General Public License for more details. 17 18 // You should have received a copy of the GNU General Public License 19 // along with this program; if not, write to the Free Software 20 // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21 // MA 02110-1301, USA. 22 23 #ifndef GOLD_AARCH64_RELOC_PROPERTY_H 24 #define GOLD_AARCH64_RELOC_PROPERTY_H 25 26 #include<vector> 27 #include<string> 28 29 #include"aarch64.h" 30 31 namespace gold 32 { 33 // The AArch64_reloc_property class is to store information about a particular 34 // relocation code. 35 36 class AArch64_reloc_property 37 { 38 public: 39 // Types of relocation codes. 40 enum Reloc_type { 41 RT_NONE, // No relocation type. 42 RT_STATIC, // Relocations processed by static linkers. 43 RT_DYNAMIC, // Relocations processed by dynamic linkers. 44 }; 45 46 // Classes of relocation codes. 47 enum Reloc_class { 48 RC_NONE, // No relocation class. 49 RC_DATA, // Data relocation. 50 RC_AARCH64, // Static AArch64 relocations 51 RC_CFLOW, // Control flow 52 RC_TLS, // Thread local storage 53 RC_DYNAMIC, // Dynamic relocation 54 }; 55 56 // Instructions that are associated with relocations. 57 enum Reloc_inst { 58 INST_DATA = 0, 59 INST_MOVW = 1, // movz, movk, movn 60 INST_LD = 2, // ld literal 61 INST_ADR = 3, // adr 62 INST_ADRP = 4, // adrp 63 INST_ADD = 5, // add 64 INST_LDST = 6, // ld/st 65 INST_TBZNZ = 7, // tbz/tbnz 66 INST_CONDB = 8, // B.cond 67 INST_B = 9, // b [25:0] 68 INST_CALL = 10, // bl [25:0] 69 INST_NUM = 11, // total number of entries in the table 70 }; 71 72 // Types of bases of relative addressing relocation codes. 73 // enum Relative_address_base { 74 // RAB_NONE, // Relocation is not relative addressing 75 // }; 76 77 typedef bool (*rvalue_checkup_func_p)(int64_t); 78 typedef uint64_t (*rvalue_bit_select_func)(uint64_t); 79 80 // Relocation code represented by this. 81 unsigned int 82 code() const 83 { return this->code_; } 84 85 // Name of the relocation code. 86 const std::string& 87 name() const 88 { return this->name_; } 89 90 // Type of relocation code. 91 Reloc_type 92 reloc_type() const 93 { return this->reloc_type_; } 94 95 // Class of relocation code. 96 Reloc_class 97 reloc_class() const 98 { return this->reloc_class_; } 99 100 // Whether this code is implemented in gold. 101 bool 102 is_implemented() const 103 { return this->is_implemented_; } 104 105 // If code is a group relocation code, return the group number, otherwise -1. 106 int 107 group_index() const 108 { return this->group_index_; } 109 110 // Return alignment of relocation. 111 size_t 112 align() const 113 { return this->align_; } 114 115 int 116 reference_flags() const 117 { return this->reference_flags_; } 118 119 // Instruction associated with this relocation. 120 Reloc_inst 121 reloc_inst() const 122 { return this->reloc_inst_; } 123 124 // Check overflow of x 125 bool checkup_x_value(int64_t x) const 126 { return this->rvalue_checkup_func_(x); } 127 128 // Return portions of x as is defined in aarch64-reloc.def. 129 uint64_t select_x_value(uint64_t x) const 130 { return this->rvalue_bit_select_func_(x); } 131 132 protected: 133 // These are protected. We only allow AArch64_reloc_property_table to 134 // manage AArch64_reloc_property. 135 AArch64_reloc_property(unsigned int code, const char* name, Reloc_type rtype, 136 Reloc_class rclass, 137 bool is_implemented, 138 int group_index, 139 int reference_flags, 140 Reloc_inst reloc_inst, 141 rvalue_checkup_func_p rvalue_checkup_func, 142 rvalue_bit_select_func rvalue_bit_select); 143 144 friend class AArch64_reloc_property_table; 145 146 private: 147 // Copying is not allowed. 148 AArch64_reloc_property(const AArch64_reloc_property&); 149 AArch64_reloc_property& operator=(const AArch64_reloc_property&); 150 151 // Relocation code. 152 const unsigned int code_; 153 // Relocation name. 154 const std::string name_; 155 // Type of relocation. 156 Reloc_type reloc_type_; 157 // Class of relocation. 158 Reloc_class reloc_class_; 159 // Group index (0, 1, or 2) if this is a group relocation or -1 otherwise. 160 int group_index_; 161 // Size of relocation. 162 size_t size_; 163 // Alignment of relocation. 164 size_t align_; 165 // Relative address base. 166 // Relative_address_base relative_address_base_; 167 // Whether this is deprecated. 168 bool is_deprecated_ : 1; 169 // Whether this is implemented in gold. 170 bool is_implemented_ : 1; 171 // Whether this checks overflow. 172 bool checks_overflow_ : 1; 173 const int reference_flags_; 174 // Instruction associated with relocation. 175 Reloc_inst reloc_inst_; 176 rvalue_checkup_func_p rvalue_checkup_func_; 177 rvalue_bit_select_func rvalue_bit_select_func_; 178 }; 179 180 class AArch64_reloc_property_table 181 { 182 public: 183 AArch64_reloc_property_table(); 184 185 const AArch64_reloc_property* 186 get_reloc_property(unsigned int code) const 187 { 188 unsigned int idx = code_to_array_index(code); 189 return this->table_[idx]; 190 } 191 192 // Like get_reloc_property but only return non-NULL if relocation code is 193 // static and implemented. 194 const AArch64_reloc_property* 195 get_implemented_static_reloc_property(unsigned int code) const 196 { 197 unsigned int idx = code_to_array_index(code); 198 const AArch64_reloc_property* arp = this->table_[idx]; 199 return ((arp != NULL 200 && (arp->reloc_type() == AArch64_reloc_property::RT_STATIC) 201 && arp->is_implemented()) 202 ? arp 203 : NULL); 204 } 205 206 // Return a string describing the relocation code that is not 207 // an implemented static reloc code. 208 std::string 209 reloc_name_in_error_message(unsigned int code); 210 211 private: 212 // Copying is not allowed. 213 AArch64_reloc_property_table(const AArch64_reloc_property_table&); 214 AArch64_reloc_property_table& operator=(const AArch64_reloc_property_table&); 215 216 // Map aarch64 rtypes into range(0,300) as following 217 // 256 ~ 313 -> 0 ~ 57 218 // 512 ~ 573 -> 128 ~ 189 219 int 220 code_to_array_index(unsigned int code) const 221 { 222 if (code == 0) return 0; 223 if (!((code >= elfcpp::R_AARCH64_ABS64 && 224 code <= elfcpp::R_AARCH64_LD64_GOTPAGE_LO15) 225 || (code >= elfcpp::R_AARCH64_TLSGD_ADR_PREL21 && 226 code <= elfcpp::R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC))) 227 { 228 gold_error(_("Invalid/unrecognized reloc reloc %d."), code); 229 } 230 unsigned int rv = -1; 231 if (code & (1 << 9)) 232 rv = 128 + code - 512; // 512 - 573 233 else if (code & (1 << 8)) 234 rv = code - 256; // 256 - 313 235 gold_assert(rv <= Property_table_size); 236 return rv; 237 } 238 239 static const unsigned int Property_table_size = 300; 240 AArch64_reloc_property* table_[Property_table_size]; 241 }; // End of class AArch64_reloc_property_table 242 243 } // End namespace gold. 244 245 #endif // !defined(GOLD_AARCH64_RELOC_PROPERTY_H) 246