Skip to content

Commit 7998df6

Browse files
[JITLink][AArch32] Add dynamic lookup for relocation fixup infos
1 parent 962829b commit 7998df6

File tree

3 files changed

+169
-75
lines changed

3 files changed

+169
-75
lines changed

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

Lines changed: 61 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,109 @@ 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+
/// 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
168186
///
187+
/// Mandatory entries:
169188
/// Opcode - Values of the op-code bits in the instruction, with
170189
/// unaffected bits nulled
171190
/// OpcodeMask - Mask with all bits set that encode the op-code
191+
///
192+
/// Other common entries:
172193
/// ImmMask - Mask with all bits set that encode the immediate value
173194
/// RegMask - Mask with all bits set that encode the register
174195
///
196+
/// Specializations can add further custom fields without restrictions.
197+
///
175198
template <EdgeKind_aarch32 Kind> struct FixupInfo {};
176199

177-
template <> struct FixupInfo<Arm_Jump24> {
200+
namespace {
201+
struct FixupInfoArmBranch : public FixupInfoArm {
178202
static constexpr uint32_t Opcode = 0x0a000000;
179-
static constexpr uint32_t OpcodeMask = 0x0f000000;
180203
static constexpr uint32_t ImmMask = 0x00ffffff;
181-
static constexpr uint32_t Unconditional = 0xe0000000;
182-
static constexpr uint32_t CondMask = 0xe0000000; // excluding BLX bit
183204
};
205+
} // namespace
184206

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 {
186212
static constexpr uint32_t OpcodeMask = 0x0e000000;
213+
static constexpr uint32_t CondMask = 0xe0000000; // excluding BLX bit
214+
static constexpr uint32_t Unconditional = 0xe0000000;
187215
static constexpr uint32_t BitH = 0x01000000;
188216
static constexpr uint32_t BitBlx = 0x10000000;
189217
};
190218

191-
template <> struct FixupInfo<Arm_MovtAbs> {
192-
static constexpr uint32_t Opcode = 0x03400000;
219+
namespace {
220+
struct FixupInfoArmMov : public FixupInfoArm {
193221
static constexpr uint32_t OpcodeMask = 0x0ff00000;
194222
static constexpr uint32_t ImmMask = 0x000f0fff;
195223
static constexpr uint32_t RegMask = 0x0000f000;
196224
};
225+
} // namespace
226+
227+
template <> struct FixupInfo<Arm_MovtAbs> : public FixupInfoArmMov {
228+
static constexpr uint32_t Opcode = 0x03400000;
229+
};
197230

198-
template <> struct FixupInfo<Arm_MovwAbsNC> : public FixupInfo<Arm_MovtAbs> {
231+
template <> struct FixupInfo<Arm_MovwAbsNC> : public FixupInfoArmMov {
199232
static constexpr uint32_t Opcode = 0x03000000;
200233
};
201234

202-
template <> struct FixupInfo<Thumb_Jump24> {
235+
template <> struct FixupInfo<Thumb_Jump24> : public FixupInfoThumb {
203236
static constexpr HalfWords Opcode{0xf000, 0x9000};
204237
static constexpr HalfWords OpcodeMask{0xf800, 0x9000};
205238
static constexpr HalfWords ImmMask{0x07ff, 0x2fff};
206239
};
207240

208-
template <> struct FixupInfo<Thumb_Call> {
241+
template <> struct FixupInfo<Thumb_Call> : public FixupInfoThumb {
209242
static constexpr HalfWords Opcode{0xf000, 0xc000};
210243
static constexpr HalfWords OpcodeMask{0xf800, 0xc000};
211244
static constexpr HalfWords ImmMask{0x07ff, 0x2fff};
212245
static constexpr uint16_t LoBitH = 0x0001;
213246
static constexpr uint16_t LoBitNoBlx = 0x1000;
214247
};
215248

216-
template <> struct FixupInfo<Thumb_MovtAbs> {
217-
static constexpr HalfWords Opcode{0xf2c0, 0x0000};
249+
namespace {
250+
struct FixupInfoThumbMov : public FixupInfoThumb {
218251
static constexpr HalfWords OpcodeMask{0xfbf0, 0x8000};
219252
static constexpr HalfWords ImmMask{0x040f, 0x70ff};
220253
static constexpr HalfWords RegMask{0x0000, 0x0f00};
221254
};
255+
} // namespace
222256

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 {
225270
static constexpr HalfWords Opcode{0xf240, 0x0000};
226271
};
227272

llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ createLinkGraphFromELFObject_aarch32(MemoryBufferRef ObjectBuffer) {
232232
<< ObjectBuffer.getBufferIdentifier() << "...\n";
233233
});
234234

235+
aarch32::populateFixupInfos();
236+
235237
auto ELFObj = ObjectFile::createELFObjectFile(ObjectBuffer);
236238
if (!ELFObj)
237239
return ELFObj.takeError();

0 commit comments

Comments
 (0)