aarch64-reloc-property.h 7.0 KB

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