Merge remote-tracking branch 'origin/vendor/LDNS'
[dragonfly.git] / contrib / binutils-2.27 / gold / aarch64-reloc-property.h
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@google.com> and Jing Yu <jingyu@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)