@@ -98,6 +98,7 @@ enum EdgeKind_aarch32 : Edge::Kind {
98
98
Thumb_MovtPrel,
99
99
100
100
LastThumbRelocation = Thumb_MovtPrel,
101
+ LastRelocation = LastThumbRelocation,
101
102
};
102
103
103
104
// / Flags enum for AArch32-specific symbol properties
@@ -163,65 +164,109 @@ struct HalfWords {
163
164
const uint16_t Lo; // Second halfword
164
165
};
165
166
166
- // / Collection of named constants per fixup kind. It may contain but is not
167
- // / limited to the following entries:
167
+ // / Initialize the lookup table for dynamic FixupInfo checks, e.g. checkOpcode()
168
+ void populateFixupInfos ();
169
+
170
+ // / FixupInfo base class is required for dynamic lookups.
171
+ struct FixupInfoBase {
172
+ virtual ~FixupInfoBase () {}
173
+ };
174
+
175
+ // / FixupInfo checks for Arm edge kinds work on 32-bit words
176
+ struct FixupInfoArm : public FixupInfoBase {
177
+ bool (*checkOpcode)(uint32_t Wd) = nullptr ;
178
+ };
179
+
180
+ // / FixupInfo check for Thumb32 edge kinds work on a pair of 16-bit halfwords
181
+ struct FixupInfoThumb : public FixupInfoBase {
182
+ bool (*checkOpcode)(uint16_t Hi, uint16_t Lo) = nullptr ;
183
+ };
184
+
185
+ // / Collection of named constants per fixup kind
168
186
// /
187
+ // / Mandatory entries:
169
188
// / Opcode - Values of the op-code bits in the instruction, with
170
189
// / unaffected bits nulled
171
190
// / OpcodeMask - Mask with all bits set that encode the op-code
191
+ // /
192
+ // / Other common entries:
172
193
// / ImmMask - Mask with all bits set that encode the immediate value
173
194
// / RegMask - Mask with all bits set that encode the register
174
195
// /
196
+ // / Specializations can add further custom fields without restrictions.
197
+ // /
175
198
template <EdgeKind_aarch32 Kind> struct FixupInfo {};
176
199
177
- template <> struct FixupInfo <Arm_Jump24> {
200
+ namespace {
201
+ struct FixupInfoArmBranch : public FixupInfoArm {
178
202
static constexpr uint32_t Opcode = 0x0a000000 ;
179
- static constexpr uint32_t OpcodeMask = 0x0f000000 ;
180
203
static constexpr uint32_t ImmMask = 0x00ffffff ;
181
- static constexpr uint32_t Unconditional = 0xe0000000 ;
182
- static constexpr uint32_t CondMask = 0xe0000000 ; // excluding BLX bit
183
204
};
205
+ } // namespace
184
206
185
- template <> struct FixupInfo <Arm_Call> : public FixupInfo<Arm_Jump24> {
207
+ template <> struct FixupInfo <Arm_Jump24> : public FixupInfoArmBranch {
208
+ static constexpr uint32_t OpcodeMask = 0x0f000000 ;
209
+ };
210
+
211
+ template <> struct FixupInfo <Arm_Call> : public FixupInfoArmBranch {
186
212
static constexpr uint32_t OpcodeMask = 0x0e000000 ;
213
+ static constexpr uint32_t CondMask = 0xe0000000 ; // excluding BLX bit
214
+ static constexpr uint32_t Unconditional = 0xe0000000 ;
187
215
static constexpr uint32_t BitH = 0x01000000 ;
188
216
static constexpr uint32_t BitBlx = 0x10000000 ;
189
217
};
190
218
191
- template <> struct FixupInfo <Arm_MovtAbs> {
192
- static constexpr uint32_t Opcode = 0x03400000 ;
219
+ namespace {
220
+ struct FixupInfoArmMov : public FixupInfoArm {
193
221
static constexpr uint32_t OpcodeMask = 0x0ff00000 ;
194
222
static constexpr uint32_t ImmMask = 0x000f0fff ;
195
223
static constexpr uint32_t RegMask = 0x0000f000 ;
196
224
};
225
+ } // namespace
226
+
227
+ template <> struct FixupInfo <Arm_MovtAbs> : public FixupInfoArmMov {
228
+ static constexpr uint32_t Opcode = 0x03400000 ;
229
+ };
197
230
198
- template <> struct FixupInfo <Arm_MovwAbsNC> : public FixupInfo<Arm_MovtAbs> {
231
+ template <> struct FixupInfo <Arm_MovwAbsNC> : public FixupInfoArmMov {
199
232
static constexpr uint32_t Opcode = 0x03000000 ;
200
233
};
201
234
202
- template <> struct FixupInfo <Thumb_Jump24> {
235
+ template <> struct FixupInfo <Thumb_Jump24> : public FixupInfoThumb {
203
236
static constexpr HalfWords Opcode{0xf000 , 0x9000 };
204
237
static constexpr HalfWords OpcodeMask{0xf800 , 0x9000 };
205
238
static constexpr HalfWords ImmMask{0x07ff , 0x2fff };
206
239
};
207
240
208
- template <> struct FixupInfo <Thumb_Call> {
241
+ template <> struct FixupInfo <Thumb_Call> : public FixupInfoThumb {
209
242
static constexpr HalfWords Opcode{0xf000 , 0xc000 };
210
243
static constexpr HalfWords OpcodeMask{0xf800 , 0xc000 };
211
244
static constexpr HalfWords ImmMask{0x07ff , 0x2fff };
212
245
static constexpr uint16_t LoBitH = 0x0001 ;
213
246
static constexpr uint16_t LoBitNoBlx = 0x1000 ;
214
247
};
215
248
216
- template <> struct FixupInfo <Thumb_MovtAbs> {
217
- static constexpr HalfWords Opcode{ 0xf2c0 , 0x0000 };
249
+ namespace {
250
+ struct FixupInfoThumbMov : public FixupInfoThumb {
218
251
static constexpr HalfWords OpcodeMask{0xfbf0 , 0x8000 };
219
252
static constexpr HalfWords ImmMask{0x040f , 0x70ff };
220
253
static constexpr HalfWords RegMask{0x0000 , 0x0f00 };
221
254
};
255
+ } // namespace
222
256
223
- template <>
224
- struct FixupInfo <Thumb_MovwAbsNC> : public FixupInfo<Thumb_MovtAbs> {
257
+ template <> struct FixupInfo <Thumb_MovtAbs> : public FixupInfoThumbMov {
258
+ static constexpr HalfWords Opcode{0xf2c0 , 0x0000 };
259
+ };
260
+
261
+ template <> struct FixupInfo <Thumb_MovtPrel> : public FixupInfoThumbMov {
262
+ static constexpr HalfWords Opcode{0xf2c0 , 0x0000 };
263
+ };
264
+
265
+ template <> struct FixupInfo <Thumb_MovwAbsNC> : public FixupInfoThumbMov {
266
+ static constexpr HalfWords Opcode{0xf240 , 0x0000 };
267
+ };
268
+
269
+ template <> struct FixupInfo <Thumb_MovwPrelNC> : public FixupInfoThumbMov {
225
270
static constexpr HalfWords Opcode{0xf240 , 0x0000 };
226
271
};
227
272
0 commit comments