arm-reloc-property.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. // arm-reloc-property.h -- ARM relocation properties -*- C++ -*-
  2. // Copyright (C) 2010-2022 Free Software Foundation, Inc.
  3. // Written by Doug Kwan <dougkwan@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_ARM_RELOC_PROPERTY_H
  18. #define GOLD_ARM_RELOC_PROPERTY_H
  19. namespace gold
  20. {
  21. // The Arm_reloc_property class is to store information about a particular
  22. // relocation code.
  23. class Arm_reloc_property
  24. {
  25. public:
  26. // Types of relocation codes.
  27. enum Reloc_type {
  28. RT_NONE, // No relocation type.
  29. RT_STATIC, // Relocations processed by static linkers.
  30. RT_DYNAMIC, // Relocations processed by dynamic linkers.
  31. RT_PRIVATE, // Private relocations, not supported by gold.
  32. RT_OBSOLETE // Obsolete relocations that should not be used.
  33. };
  34. // Classes of relocation codes.
  35. enum Reloc_class {
  36. RC_NONE, // No relocation class.
  37. RC_DATA, // Data relocation.
  38. RC_ARM, // ARM instruction relocation.
  39. RC_THM16, // 16-bit THUMB instruction relocation.
  40. RC_THM32, // 32-bit THUMB instruction relocation.
  41. RC_MISC // Miscellaneous class.
  42. };
  43. // Types of bases of relative addressing relocation codes.
  44. enum Relative_address_base {
  45. RAB_NONE, // Relocation is not relative addressing
  46. RAB_B_S, // Address origin of output segment of defining symbol.
  47. RAB_DELTA_B_S, // Change of address origin.
  48. RAB_GOT_ORG, // Origin of GOT.
  49. RAB_P, // Address of the place being relocated.
  50. RAB_Pa, // Adjusted address (P & 0xfffffffc).
  51. RAB_TLS, // Thread local storage.
  52. RAB_tp // Thread pointer.
  53. };
  54. // Relocation code represented by this.
  55. unsigned int
  56. code() const
  57. { return this->code_; }
  58. // Name of the relocation code.
  59. const std::string&
  60. name() const
  61. { return this->name_; }
  62. // Type of relocation code.
  63. Reloc_type
  64. reloc_type() const
  65. { return this->reloc_type_; }
  66. // Whether this code is deprecated.
  67. bool
  68. is_deprecated() const
  69. { return this->is_deprecated_; }
  70. // Class of relocation code.
  71. Reloc_class
  72. reloc_class() const
  73. { return this->reloc_class_; }
  74. // Whether this code is implemented in gold.
  75. bool
  76. is_implemented() const
  77. { return this->is_implemented_; }
  78. // If code is a group relocation code, return the group number, otherwise -1.
  79. int
  80. group_index() const
  81. { return this->group_index_; }
  82. // Whether relocation checks for overflow.
  83. bool
  84. checks_overflow() const
  85. { return this->checks_overflow_; }
  86. // Return size of relocation.
  87. size_t
  88. size() const
  89. { return this->size_; }
  90. // Return alignment of relocation.
  91. size_t
  92. align() const
  93. { return this->align_; }
  94. // Whether relocation use a GOT entry.
  95. bool
  96. uses_got_entry() const
  97. { return this->uses_got_entry_; }
  98. // Whether relocation use a GOT origin.
  99. bool
  100. uses_got_origin() const
  101. { return this->uses_got_origin_; }
  102. // Whether relocation uses the Thumb-bit in a symbol address.
  103. bool
  104. uses_thumb_bit() const
  105. { return this->uses_thumb_bit_; }
  106. // Whether relocation uses the symbol base.
  107. bool
  108. uses_symbol_base() const
  109. { return this->uses_symbol_base_; }
  110. // Whether relocation uses the symbol.
  111. bool
  112. uses_symbol() const
  113. { return this->uses_symbol_; }
  114. // Return the type of relative address base or RAB_NONE if this
  115. // is not a relative addressing relocation.
  116. Relative_address_base
  117. relative_address_base() const
  118. { return this->relative_address_base_; }
  119. protected:
  120. // These are protected. We only allow Arm_reloc_property_table to
  121. // manage Arm_reloc_property.
  122. Arm_reloc_property(unsigned int code, const char* name, Reloc_type rtype,
  123. bool is_deprecated, Reloc_class rclass,
  124. const std::string& operation, bool is_implemented,
  125. int group_index, bool checks_overflow);
  126. friend class Arm_reloc_property_table;
  127. private:
  128. // Copying is not allowed.
  129. Arm_reloc_property(const Arm_reloc_property&);
  130. Arm_reloc_property& operator=(const Arm_reloc_property&);
  131. // The Tree_node class is used to represent parsed relocation operations.
  132. // We look at Trees to extract information about relocation operations.
  133. class Tree_node
  134. {
  135. public:
  136. typedef std::vector<Tree_node*> Tree_node_vector;
  137. // Construct a leaf node.
  138. Tree_node(const char* name)
  139. : is_leaf_(true), name_(name), children_()
  140. { }
  141. // Construct an internal node. A node owns all its children and is
  142. // responsible for releasing them at its own destruction.
  143. Tree_node(Tree_node_vector::const_iterator begin,
  144. Tree_node_vector::const_iterator end)
  145. : is_leaf_(false), name_(), children_()
  146. {
  147. for (Tree_node_vector::const_iterator p = begin; p != end; ++p)
  148. this->children_.push_back(*p);
  149. }
  150. ~Tree_node()
  151. {
  152. for(size_t i = 0; i <this->children_.size(); ++i)
  153. delete this->children_[i];
  154. }
  155. // Whether this is a leaf node.
  156. bool
  157. is_leaf() const
  158. { return this->is_leaf_; }
  159. // Return name of this. This is only valid for a leaf node.
  160. const std::string&
  161. name() const
  162. {
  163. gold_assert(this->is_leaf_);
  164. return this->name_;
  165. }
  166. // Return the number of children. This is only valid for a non-leaf node.
  167. size_t
  168. number_of_children() const
  169. {
  170. gold_assert(!this->is_leaf_);
  171. return this->children_.size();
  172. }
  173. // Return the i-th child of this. This is only valid for a non-leaf node.
  174. Tree_node*
  175. child(size_t i) const
  176. {
  177. gold_assert(!this->is_leaf_ && i < this->children_.size());
  178. return this->children_[i];
  179. }
  180. // Parse an S-expression string and build a tree and return the root node.
  181. // Caller is responsible for releasing tree after use.
  182. static Tree_node*
  183. make_tree(const std::string&);
  184. // Convert a tree back to an S-expression string.
  185. std::string
  186. s_expression() const
  187. {
  188. if (this->is_leaf_)
  189. return this->name_;
  190. // Concatenate S-expressions of children. Enclose them with
  191. // a pair of parentheses and use space as token delimiters.
  192. std::string s("(");
  193. for(size_t i = 0; i <this->children_.size(); ++i)
  194. s = s + " " + this->children_[i]->s_expression();
  195. return s + " )";
  196. }
  197. private:
  198. // Whether this is a leaf node.
  199. bool is_leaf_;
  200. // Name of this if this is a leaf node.
  201. std::string name_;
  202. // Children of this if this a non-leaf node.
  203. Tree_node_vector children_;
  204. };
  205. // Relocation code.
  206. unsigned int code_;
  207. // Relocation name.
  208. std::string name_;
  209. // Type of relocation.
  210. Reloc_type reloc_type_;
  211. // Class of relocation.
  212. Reloc_class reloc_class_;
  213. // Group index (0, 1, or 2) if this is a group relocation or -1 otherwise.
  214. int group_index_;
  215. // Size of relocation.
  216. size_t size_;
  217. // Alignment of relocation.
  218. size_t align_;
  219. // Relative address base.
  220. Relative_address_base relative_address_base_;
  221. // Whether this is deprecated.
  222. bool is_deprecated_ : 1;
  223. // Whether this is implemented in gold.
  224. bool is_implemented_ : 1;
  225. // Whether this checks overflow.
  226. bool checks_overflow_ : 1;
  227. // Whether this uses a GOT entry.
  228. bool uses_got_entry_ : 1;
  229. // Whether this uses a GOT origin.
  230. bool uses_got_origin_ : 1;
  231. // Whether this uses a PLT entry.
  232. bool uses_plt_entry_ : 1;
  233. // Whether this uses the THUMB bit in symbol address.
  234. bool uses_thumb_bit_ : 1;
  235. // Whether this uses the symbol base.
  236. bool uses_symbol_base_ : 1;
  237. // Whether this uses an addend.
  238. bool uses_addend_ : 1;
  239. // Whether this uses the symbol.
  240. bool uses_symbol_ : 1;
  241. };
  242. // Arm_reloc_property_table. This table is used for looking up properties
  243. // of relocation types. The table entries are initialized using information
  244. // from arm-reloc.def.
  245. class Arm_reloc_property_table
  246. {
  247. public:
  248. Arm_reloc_property_table();
  249. // Return an Arm_reloc_property object for CODE if it is a valid relocation
  250. // code or NULL otherwise.
  251. const Arm_reloc_property*
  252. get_reloc_property(unsigned int code) const
  253. {
  254. gold_assert(code < Property_table_size);
  255. return this->table_[code];
  256. }
  257. // Like get_reloc_property but only return non-NULL if relocation code is
  258. // static and implemented.
  259. const Arm_reloc_property*
  260. get_implemented_static_reloc_property(unsigned int code) const
  261. {
  262. gold_assert(code < Property_table_size);
  263. const Arm_reloc_property* arp = this->table_[code];
  264. return ((arp != NULL
  265. && (arp->reloc_type() == Arm_reloc_property::RT_STATIC)
  266. && arp->is_implemented())
  267. ? arp
  268. : NULL);
  269. }
  270. // Return a string describing the relocation code that is not
  271. // an implemented static reloc code.
  272. std::string
  273. reloc_name_in_error_message(unsigned int code);
  274. private:
  275. // Copying is not allowed.
  276. Arm_reloc_property_table(const Arm_reloc_property_table&);
  277. Arm_reloc_property_table& operator=(const Arm_reloc_property_table&);
  278. // The Parse_expression class is used to convert relocation operations in
  279. // arm-reloc.def into S-expression strings, which are parsed again to
  280. // build actual expression trees. We do not build the expression trees
  281. // directly because the parser for operations in arm-reloc.def is simpler
  282. // this way. Conversion from S-expressions to trees is simple.
  283. class Parse_expression
  284. {
  285. public:
  286. // Construction a Parse_expression with an S-expression string.
  287. Parse_expression(const std::string& s_expression)
  288. : s_expression_(s_expression)
  289. { }
  290. // Value of this expression as an S-expression string.
  291. const std::string&
  292. s_expression() const
  293. { return this->s_expression_; }
  294. // We want to overload operators used in relocation operations so
  295. // that we can execute operations in arm-reloc.def to generate
  296. // S-expressions directly.
  297. #define DEF_OPERATOR_OVERLOAD(op) \
  298. Parse_expression \
  299. operator op (const Parse_expression& e) \
  300. { \
  301. return Parse_expression("( " #op " " + this->s_expression_ + " " + \
  302. e.s_expression_ + " )"); \
  303. }
  304. // Operator appearing in relocation operations in arm-reloc.def.
  305. DEF_OPERATOR_OVERLOAD(+)
  306. DEF_OPERATOR_OVERLOAD(-)
  307. DEF_OPERATOR_OVERLOAD(|)
  308. private:
  309. // This represented as an S-expression string.
  310. std::string s_expression_;
  311. };
  312. #define DEF_RELOC_FUNC(name) \
  313. static Parse_expression \
  314. (name)(const Parse_expression& arg) \
  315. { return Parse_expression("( " #name " " + arg.s_expression() + " )"); }
  316. // Functions appearing in relocation operations in arm-reloc.def.
  317. DEF_RELOC_FUNC(B)
  318. DEF_RELOC_FUNC(DELTA_B)
  319. DEF_RELOC_FUNC(GOT)
  320. DEF_RELOC_FUNC(Module)
  321. DEF_RELOC_FUNC(PLT)
  322. static const unsigned int Property_table_size = 256;
  323. // The property table.
  324. Arm_reloc_property* table_[Property_table_size];
  325. };
  326. } // End namespace gold.
  327. #endif // !defined(GOLD_ARM_RELOC_PROPERTY_H)