1 // aarch64-reloc-property.cc -- AArch64 relocation properties -*- C++ -*-
3 // Copyright (C) 2014-2024 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.
25 #include "aarch64-reloc-property.h"
35 template<int L
, int U
>
37 rvalue_checkup(int64_t x
)
39 // We save the extra_alignment_requirement bits on [31:16] of U.
40 // "extra_alignment_requirement" could be 0, 1, 3, 7 and 15.
41 unsigned short extra_alignment_requirement
= (U
& 0xFFFF0000) >> 16;
42 // [15:0] of U indicates the upper bound check.
43 int64_t u
= U
& 0x0000FFFF;
46 // No requirement to check overflow.
48 return (x
& extra_alignment_requirement
) == 0;
51 // Check both overflow and alignment if needed.
52 int64_t low_bound
= -(L
== 0 ? 0 : ((int64_t)1 << L
));
53 int64_t up_bound
= ((int64_t)1 << u
);
54 return ((low_bound
<= x
&& x
< up_bound
)
55 && ((x
& extra_alignment_requirement
) == 0));
60 rvalue_checkup
<0, 0>(int64_t) { return true; }
65 template<int L
, int U
>
66 class Rvalue_bit_select_impl
72 return (x
& ((1ULL << (U
+1)) - 1)) >> L
;
77 class Rvalue_bit_select_impl
<L
, 63>
87 // By our convention, L=U=0 means that the whole value should be retrieved.
89 class Rvalue_bit_select_impl
<0, 0>
99 } // End anonymous namespace.
101 template<int L
, int U
>
103 rvalue_bit_select(uint64_t x
)
105 return Rvalue_bit_select_impl
<L
, U
>::calc(x
);
108 AArch64_reloc_property::AArch64_reloc_property(
116 Reloc_inst reloc_inst
,
117 rvalue_checkup_func_p rvalue_checkup_func
,
118 rvalue_bit_select_func rvalue_bit_select
)
119 : code_(code
), name_(name
), reloc_type_(rtype
), reloc_class_(rclass
),
120 group_index_(group_index
),
121 is_implemented_(is_implemented
),
122 reference_flags_(reference_flags
),
123 reloc_inst_(reloc_inst
),
124 rvalue_checkup_func_(rvalue_checkup_func
),
125 rvalue_bit_select_func_(rvalue_bit_select
)
128 AArch64_reloc_property_table::AArch64_reloc_property_table()
130 const bool Y(true), N(false);
131 for (unsigned int i
= 0; i
< Property_table_size
; ++i
)
134 #define RL_CHECK_ALIGN2 (1 << 16)
135 #define RL_CHECK_ALIGN4 (3 << 16)
136 #define RL_CHECK_ALIGN8 (7 << 16)
137 #define RL_CHECK_ALIGN16 (15 << 16)
140 #define ARD(rname, type, class, is_implemented, group_index, LB, UB, BSL, BSH, RFLAGS, inst) \
143 int tidx = code_to_array_index(elfcpp::R_AARCH64_##rname); \
144 AArch64_reloc_property * p = new AArch64_reloc_property( \
145 elfcpp::R_AARCH64_##rname, "R_AARCH64_" #rname, \
146 AArch64_reloc_property::RT_##type, \
147 AArch64_reloc_property::RC_##class, \
151 AArch64_reloc_property::INST_##inst, \
152 rvalue_checkup<LB,UB>, \
153 rvalue_bit_select<BSL,BSH>); \
157 #include"aarch64-reloc.def"
161 // Return a string describing a relocation code that fails to get a
162 // relocation property in get_implemented_static_reloc_property().
165 AArch64_reloc_property_table::reloc_name_in_error_message(unsigned int code
)
167 int tidx
= code_to_array_index(code
);
168 const AArch64_reloc_property
* arp
= this->table_
[tidx
];
173 sprintf(buffer
, _("invalid reloc %u"), code
);
174 return std::string(buffer
);
177 // gold only implements static relocation codes.
178 AArch64_reloc_property::Reloc_type reloc_type
= arp
->reloc_type();
179 gold_assert(reloc_type
== AArch64_reloc_property::RT_STATIC
180 || !arp
->is_implemented());
182 const char* prefix
= NULL
;
185 case AArch64_reloc_property::RT_STATIC
:
186 prefix
= arp
->is_implemented() ? _("reloc ") : _("unimplemented reloc ");
188 case AArch64_reloc_property::RT_DYNAMIC
:
189 prefix
= _("dynamic reloc ");
194 return std::string(prefix
) + arp
->name();