1 // aarch64-reloc-property.h -- AArch64 relocation properties -*- C++ -*-
3 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
4 // Written by Han Shen <shenhan@google.com> and Jing Yu <jingyu@google.com>.
6 // This file is part of gold.
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.
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.
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.
23 #ifndef GOLD_AARCH64_RELOC_PROPERTY_H
24 #define GOLD_AARCH64_RELOC_PROPERTY_H
33 // The AArch64_reloc_property class is to store information about a particular
36 class AArch64_reloc_property
39 // Types of relocation codes.
41 RT_NONE
, // No relocation type.
42 RT_STATIC
, // Relocations processed by static linkers.
43 RT_DYNAMIC
, // Relocations processed by dynamic linkers.
46 // Classes of relocation codes.
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
56 // Instructions that are associated with relocations.
59 INST_MOVW
= 1, // movz, movk, movn
60 INST_LD
= 2, // ld literal
62 INST_ADRP
= 4, // adrp
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
72 // Types of bases of relative addressing relocation codes.
73 // enum Relative_address_base {
74 // RAB_NONE, // Relocation is not relative addressing
77 typedef bool (*rvalue_checkup_func_p
)(int64_t);
78 typedef uint64_t (*rvalue_bit_select_func
)(uint64_t);
80 // Relocation code represented by this.
83 { return this->code_
; }
85 // Name of the relocation code.
88 { return this->name_
; }
90 // Type of relocation code.
93 { return this->reloc_type_
; }
95 // Class of relocation code.
98 { return this->reloc_class_
; }
100 // Whether this code is implemented in gold.
102 is_implemented() const
103 { return this->is_implemented_
; }
105 // If code is a group relocation code, return the group number, otherwise -1.
108 { return this->group_index_
; }
110 // Return alignment of relocation.
113 { return this->align_
; }
116 reference_flags() const
117 { return this->reference_flags_
; }
119 // Instruction associated with this relocation.
122 { return this->reloc_inst_
; }
124 // Check overflow of x
125 bool checkup_x_value(int64_t x
) const
126 { return this->rvalue_checkup_func_(x
); }
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
); }
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
,
140 Reloc_inst reloc_inst
,
141 rvalue_checkup_func_p rvalue_checkup_func
,
142 rvalue_bit_select_func rvalue_bit_select
);
144 friend class AArch64_reloc_property_table
;
147 // Copying is not allowed.
148 AArch64_reloc_property(const AArch64_reloc_property
&);
149 AArch64_reloc_property
& operator=(const AArch64_reloc_property
&);
152 const unsigned int code_
;
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.
161 // Size of relocation.
163 // Alignment of relocation.
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_
;
180 class AArch64_reloc_property_table
183 AArch64_reloc_property_table();
185 const AArch64_reloc_property
*
186 get_reloc_property(unsigned int code
) const
188 unsigned int idx
= code_to_array_index(code
);
189 return this->table_
[idx
];
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
197 unsigned int idx
= code_to_array_index(code
);
198 const AArch64_reloc_property
* arp
= this->table_
[idx
];
200 && (arp
->reloc_type() == AArch64_reloc_property::RT_STATIC
)
201 && arp
->is_implemented())
206 // Return a string describing the relocation code that is not
207 // an implemented static reloc code.
209 reloc_name_in_error_message(unsigned int code
);
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
&);
216 // Map aarch64 rtypes into range(0,300) as following
217 // 256 ~ 313 -> 0 ~ 57
218 // 512 ~ 573 -> 128 ~ 189
220 code_to_array_index(unsigned int code
) const
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
)))
228 gold_error(_("Invalid/unrecognized reloc reloc %d."), code
);
230 unsigned int rv
= -1;
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
);
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
243 } // End namespace gold.
245 #endif // !defined(GOLD_AARCH64_RELOC_PROPERTY_H)