Skip to content

Commit b86420c

Browse files
[JITLink][AArch32] Add dynamic lookup for relocation fixup infos (#71649)
Specifying relocation fixup constants with name and type facilitates readability and compile-time checks. The `FixupInfo<EdgeKind>` facade organizes the information into entries per relocation type and provides uniform access across Arm and Thumb relocations. Since it uses template specializations, it doesn't limit potential entries. We cannot access the entries dynamically though, because `EdgeKind` must be given as a compile-time constant. With this patch we populate a static lookup table on-demand and use it for dynamic access in opcode-checks.
1 parent 95dcb8b commit b86420c

File tree

3 files changed

+186
-75
lines changed

3 files changed

+186
-75
lines changed

llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h

Lines changed: 59 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ enum EdgeKind_aarch32 : Edge::Kind {
9898
Thumb_MovtPrel,
9999

100100
LastThumbRelocation = Thumb_MovtPrel,
101+
LastRelocation = LastThumbRelocation,
101102
};
102103

103104
/// Flags enum for AArch32-specific symbol properties
@@ -163,65 +164,107 @@ struct HalfWords {
163164
const uint16_t Lo; // Second halfword
164165
};
165166

166-
/// Collection of named constants per fixup kind. It may contain but is not
167-
/// limited to the following entries:
167+
/// FixupInfo base class is required for dynamic lookups.
168+
struct FixupInfoBase {
169+
static const FixupInfoBase *getDynFixupInfo(Edge::Kind K);
170+
virtual ~FixupInfoBase() {}
171+
};
172+
173+
/// FixupInfo checks for Arm edge kinds work on 32-bit words
174+
struct FixupInfoArm : public FixupInfoBase {
175+
bool (*checkOpcode)(uint32_t Wd) = nullptr;
176+
};
177+
178+
/// FixupInfo check for Thumb32 edge kinds work on a pair of 16-bit halfwords
179+
struct FixupInfoThumb : public FixupInfoBase {
180+
bool (*checkOpcode)(uint16_t Hi, uint16_t Lo) = nullptr;
181+
};
182+
183+
/// Collection of named constants per fixup kind
168184
///
185+
/// Mandatory entries:
169186
/// Opcode - Values of the op-code bits in the instruction, with
170187
/// unaffected bits nulled
171188
/// OpcodeMask - Mask with all bits set that encode the op-code
189+
///
190+
/// Other common entries:
172191
/// ImmMask - Mask with all bits set that encode the immediate value
173192
/// RegMask - Mask with all bits set that encode the register
174193
///
194+
/// Specializations can add further custom fields without restrictions.
195+
///
175196
template <EdgeKind_aarch32 Kind> struct FixupInfo {};
176197

177-
template <> struct FixupInfo<Arm_Jump24> {
198+
namespace {
199+
struct FixupInfoArmBranch : public FixupInfoArm {
178200
static constexpr uint32_t Opcode = 0x0a000000;
179-
static constexpr uint32_t OpcodeMask = 0x0f000000;
180201
static constexpr uint32_t ImmMask = 0x00ffffff;
181-
static constexpr uint32_t Unconditional = 0xe0000000;
182-
static constexpr uint32_t CondMask = 0xe0000000; // excluding BLX bit
202+
};
203+
} // namespace
204+
205+
template <> struct FixupInfo<Arm_Jump24> : public FixupInfoArmBranch {
206+
static constexpr uint32_t OpcodeMask = 0x0f000000;
183207
};
184208

185-
template <> struct FixupInfo<Arm_Call> : public FixupInfo<Arm_Jump24> {
209+
template <> struct FixupInfo<Arm_Call> : public FixupInfoArmBranch {
186210
static constexpr uint32_t OpcodeMask = 0x0e000000;
211+
static constexpr uint32_t CondMask = 0xe0000000; // excluding BLX bit
212+
static constexpr uint32_t Unconditional = 0xe0000000;
187213
static constexpr uint32_t BitH = 0x01000000;
188214
static constexpr uint32_t BitBlx = 0x10000000;
189215
};
190216

191-
template <> struct FixupInfo<Arm_MovtAbs> {
192-
static constexpr uint32_t Opcode = 0x03400000;
217+
namespace {
218+
struct FixupInfoArmMov : public FixupInfoArm {
193219
static constexpr uint32_t OpcodeMask = 0x0ff00000;
194220
static constexpr uint32_t ImmMask = 0x000f0fff;
195221
static constexpr uint32_t RegMask = 0x0000f000;
196222
};
223+
} // namespace
224+
225+
template <> struct FixupInfo<Arm_MovtAbs> : public FixupInfoArmMov {
226+
static constexpr uint32_t Opcode = 0x03400000;
227+
};
197228

198-
template <> struct FixupInfo<Arm_MovwAbsNC> : public FixupInfo<Arm_MovtAbs> {
229+
template <> struct FixupInfo<Arm_MovwAbsNC> : public FixupInfoArmMov {
199230
static constexpr uint32_t Opcode = 0x03000000;
200231
};
201232

202-
template <> struct FixupInfo<Thumb_Jump24> {
233+
template <> struct FixupInfo<Thumb_Jump24> : public FixupInfoThumb {
203234
static constexpr HalfWords Opcode{0xf000, 0x9000};
204235
static constexpr HalfWords OpcodeMask{0xf800, 0x9000};
205236
static constexpr HalfWords ImmMask{0x07ff, 0x2fff};
206237
};
207238

208-
template <> struct FixupInfo<Thumb_Call> {
239+
template <> struct FixupInfo<Thumb_Call> : public FixupInfoThumb {
209240
static constexpr HalfWords Opcode{0xf000, 0xc000};
210241
static constexpr HalfWords OpcodeMask{0xf800, 0xc000};
211242
static constexpr HalfWords ImmMask{0x07ff, 0x2fff};
212243
static constexpr uint16_t LoBitH = 0x0001;
213244
static constexpr uint16_t LoBitNoBlx = 0x1000;
214245
};
215246

216-
template <> struct FixupInfo<Thumb_MovtAbs> {
217-
static constexpr HalfWords Opcode{0xf2c0, 0x0000};
247+
namespace {
248+
struct FixupInfoThumbMov : public FixupInfoThumb {
218249
static constexpr HalfWords OpcodeMask{0xfbf0, 0x8000};
219250
static constexpr HalfWords ImmMask{0x040f, 0x70ff};
220251
static constexpr HalfWords RegMask{0x0000, 0x0f00};
221252
};
253+
} // namespace
222254

223-
template <>
224-
struct FixupInfo<Thumb_MovwAbsNC> : public FixupInfo<Thumb_MovtAbs> {
255+
template <> struct FixupInfo<Thumb_MovtAbs> : public FixupInfoThumbMov {
256+
static constexpr HalfWords Opcode{0xf2c0, 0x0000};
257+
};
258+
259+
template <> struct FixupInfo<Thumb_MovtPrel> : public FixupInfoThumbMov {
260+
static constexpr HalfWords Opcode{0xf2c0, 0x0000};
261+
};
262+
263+
template <> struct FixupInfo<Thumb_MovwAbsNC> : public FixupInfoThumbMov {
264+
static constexpr HalfWords Opcode{0xf240, 0x0000};
265+
};
266+
267+
template <> struct FixupInfo<Thumb_MovwPrelNC> : public FixupInfoThumbMov {
225268
static constexpr HalfWords Opcode{0xf240, 0x0000};
226269
};
227270

0 commit comments

Comments
 (0)