[llvm] [JITLink][AArch32] Add dynamic lookup for relocation fixup infos (PR #71649)
Stefan Gränitz via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 8 10:19:04 PST 2023
https://github.com/weliveindetail updated https://github.com/llvm/llvm-project/pull/71649
>From 7458391ec700bf50601cc49b2b2950267407201f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eymen=20=C3=9Cnay?= <eymenunay at outlook.com>
Date: Thu, 26 Oct 2023 18:26:50 +0300
Subject: [PATCH 1/5] [JITLink][AArch32] Add support for
ELF::R_ARM_THM_MOV{W_PREL_NC,T_ABS}
Support for ELF::R_ARM_THM_MOVW_PREL_NC and ELF::R_ARM_THM_MOVW_PREL_NC
is added. Move instructions with PC-relative immediates can be handled
in Thumb mode with this addition.
---
.../llvm/ExecutionEngine/JITLink/aarch32.h | 10 +++++-
.../ExecutionEngine/JITLink/ELF_aarch32.cpp | 8 +++++
llvm/lib/ExecutionEngine/JITLink/aarch32.cpp | 18 +++++++++++
.../JITLink/AArch32/ELF_static_thumb_reloc.s | 31 ++++++++++++++++++-
4 files changed, 65 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
index 3f36b53d6684a79..97999a61dfe7334 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
@@ -89,7 +89,15 @@ enum EdgeKind_aarch32 : Edge::Kind {
/// Write immediate value to the top halfword of the destination register
Thumb_MovtAbs,
- LastThumbRelocation = Thumb_MovtAbs,
+ /// Write PC-relative immediate value to the lower halfword of the destination
+ /// register
+ Thumb_MovwPrelNC,
+
+ /// Write PC-relative immediate value to the top halfword of the destination
+ /// register
+ Thumb_MovtPrel,
+
+ LastThumbRelocation = Thumb_MovtPrel,
};
/// Flags enum for AArch32-specific symbol properties
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp
index 6359ceb4c51749c..b6b63691d8408ea 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp
@@ -53,6 +53,10 @@ Expected<aarch32::EdgeKind_aarch32> getJITLinkEdgeKind(uint32_t ELFType) {
return aarch32::Thumb_MovwAbsNC;
case ELF::R_ARM_THM_MOVT_ABS:
return aarch32::Thumb_MovtAbs;
+ case ELF::R_ARM_THM_MOVW_PREL_NC:
+ return aarch32::Thumb_MovwPrelNC;
+ case ELF::R_ARM_THM_MOVT_PREL:
+ return aarch32::Thumb_MovtPrel;
}
return make_error<JITLinkError>(
@@ -83,6 +87,10 @@ Expected<uint32_t> getELFRelocationType(Edge::Kind Kind) {
return ELF::R_ARM_THM_MOVW_ABS_NC;
case aarch32::Thumb_MovtAbs:
return ELF::R_ARM_THM_MOVT_ABS;
+ case aarch32::Thumb_MovwPrelNC:
+ return ELF::R_ARM_THM_MOVW_PREL_NC;
+ case aarch32::Thumb_MovtPrel:
+ return ELF::R_ARM_THM_MOVT_PREL;
}
return make_error<JITLinkError>(formatv("Invalid aarch32 edge {0:d}: ",
diff --git a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
index 4aed64966654420..c3823f985ce182d 100644
--- a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
@@ -377,12 +377,14 @@ Expected<int64_t> readAddendThumb(LinkGraph &G, Block &B, const Edge &E,
: decodeImmBT4BlT1BlxT2(R.Hi, R.Lo);
case Thumb_MovwAbsNC:
+ case Thumb_MovwPrelNC:
if (!checkOpcode<Thumb_MovwAbsNC>(R))
return makeUnexpectedOpcodeError(G, R, Kind);
// Initial addend is interpreted as a signed value
return SignExtend64<16>(decodeImmMovtT1MovwT3(R.Hi, R.Lo));
case Thumb_MovtAbs:
+ case Thumb_MovtPrel:
if (!checkOpcode<Thumb_MovtAbs>(R))
return makeUnexpectedOpcodeError(G, R, Kind);
// Initial addend is interpreted as a signed value
@@ -610,6 +612,20 @@ Error applyFixupThumb(LinkGraph &G, Block &B, const Edge &E,
writeImmediate<Thumb_MovtAbs>(R, encodeImmMovtT1MovwT3(Value));
return Error::success();
}
+ case Thumb_MovwPrelNC: {
+ if (!checkOpcode<Thumb_MovwAbsNC>(R))
+ return makeUnexpectedOpcodeError(G, R, Kind);
+ uint16_t Value = ((TargetAddress + Addend - FixupAddress) & 0xffff);
+ writeImmediate<Thumb_MovwAbsNC>(R, encodeImmMovtT1MovwT3(Value));
+ return Error::success();
+ }
+ case Thumb_MovtPrel: {
+ if (!checkOpcode<Thumb_MovtAbs>(R))
+ return makeUnexpectedOpcodeError(G, R, Kind);
+ uint16_t Value = (((TargetAddress + Addend - FixupAddress) >> 16) & 0xffff);
+ writeImmediate<Thumb_MovtAbs>(R, encodeImmMovtT1MovwT3(Value));
+ return Error::success();
+ }
default:
return make_error<JITLinkError>(
@@ -659,6 +675,8 @@ const char *getEdgeKindName(Edge::Kind K) {
KIND_NAME_CASE(Thumb_Jump24)
KIND_NAME_CASE(Thumb_MovwAbsNC)
KIND_NAME_CASE(Thumb_MovtAbs)
+ KIND_NAME_CASE(Thumb_MovwPrelNC)
+ KIND_NAME_CASE(Thumb_MovtPrel)
default:
return getGenericEdgeKindName(K);
}
diff --git a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_static_thumb_reloc.s b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_static_thumb_reloc.s
index c694a65ae1061aa..a523ada96ed32a6 100644
--- a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_static_thumb_reloc.s
+++ b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_static_thumb_reloc.s
@@ -2,7 +2,8 @@
# RUN: llvm-objdump -r %t.o | FileCheck --check-prefix=CHECK-TYPE %s
# RUN: llvm-objdump --disassemble %t.o | FileCheck --check-prefix=CHECK-INSTR %s
# RUN: llvm-jitlink -noexec -slab-address 0x76ff0000 -slab-allocate 10Kb \
-# RUN: -slab-page-size 4096 -show-entry-es -check %s %t.o
+# RUN: -slab-page-size 4096 -abs external_func=0x76bbe880 \
+# RUN: -check %s %t.o
.text
@@ -95,6 +96,34 @@ data_symbol:
.text
+# CHECK-TYPE: {{[0-9a-f]+}} R_ARM_THM_MOVW_PREL_NC external_func
+# CHECK-INSTR: 00000014 <movw_prel>:
+# CHECK-INSTR: 14: f240 0000 movw r0, #0x0
+# jitlink-check: decode_operand(movw_prel, 1) = \
+# jitlink-check: ((external_func - next_pc(movw_prel) + 4)&0x0000ffff)
+.globl movw_prel
+.type movw_prel,%function
+.p2align 1
+.code 16
+.thumb_func
+movw_prel:
+ movw r0, :lower16:external_func - .
+ .size movw_prel, .-movw_prel
+
+# CHECK-TYPE: {{[0-9a-f]+}} R_ARM_THM_MOVT_PREL external_func
+# CHECK-INSTR: 00000018 <movt_prel>:
+# CHECK-INSTR: 18: f2c0 0000 movt r0, #0x0
+# jitlink-check: decode_operand(movt_prel, 2) = \
+# jitlink-check: ((external_func - next_pc(movt_prel) + 4)&0xffff0000>>16)
+.globl movt_prel
+.type movt_prel,%function
+.p2align 1
+.code 16
+.thumb_func
+movt_prel:
+ movt r0, :upper16:external_func - .
+ .size movt_prel, .-movt_prel
+
# Empty main function for jitlink to be happy
.globl main
.type main,%function
>From f94662f6412e2ba3debd33aa04f2b63b277d5dbc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= <stefan.graenitz at gmail.com>
Date: Tue, 7 Nov 2023 18:50:35 +0100
Subject: [PATCH 2/5] [JITLink][AArch32] Add dynamic lookup for relocation
fixup infos
---
.../llvm/ExecutionEngine/JITLink/aarch32.h | 94 ++++++++++++---
.../ExecutionEngine/JITLink/ELF_aarch32.cpp | 2 +
llvm/lib/ExecutionEngine/JITLink/aarch32.cpp | 114 +++++++++---------
3 files changed, 136 insertions(+), 74 deletions(-)
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
index 97999a61dfe7334..95782e9bc6f1228 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
@@ -163,49 +163,83 @@ struct HalfWords {
const uint16_t Lo; // Second halfword
};
-/// Collection of named constants per fixup kind. It may contain but is not
-/// limited to the following entries:
+struct FixupInfoBaseArm {
+ virtual ~FixupInfoBaseArm() {}
+ virtual bool checkOpcode(uint32_t Wd) const = 0;
+};
+
+struct FixupInfoBaseThumb {
+ virtual ~FixupInfoBaseThumb() {}
+ virtual bool checkOpcode(uint16_t Hi, uint16_t Lo) const = 0;
+};
+
+template <EdgeKind_aarch32 Kind> struct FixupInfoArm : public FixupInfoBaseArm {
+ bool checkOpcode(uint32_t Wd) const override;
+};
+
+template <EdgeKind_aarch32 Kind> struct FixupInfoThumb : public FixupInfoBaseThumb {
+ bool checkOpcode(uint16_t Hi, uint16_t Lo) const override;
+};
+
+/// Collection of named constants per fixup kind
///
+/// Mandatory entries:
/// Opcode - Values of the op-code bits in the instruction, with
/// unaffected bits nulled
/// OpcodeMask - Mask with all bits set that encode the op-code
+///
+/// Other common entries:
/// ImmMask - Mask with all bits set that encode the immediate value
/// RegMask - Mask with all bits set that encode the register
///
+/// Specializations can add further custom fields without restrictions.
+///
template <EdgeKind_aarch32 Kind> struct FixupInfo {};
-template <> struct FixupInfo<Arm_Jump24> {
+namespace {
+template <EdgeKind_aarch32 Kind>
+struct FixupInfoArmBranch : public FixupInfoArm<Kind> {
static constexpr uint32_t Opcode = 0x0a000000;
- static constexpr uint32_t OpcodeMask = 0x0f000000;
static constexpr uint32_t ImmMask = 0x00ffffff;
- static constexpr uint32_t Unconditional = 0xe0000000;
- static constexpr uint32_t CondMask = 0xe0000000; // excluding BLX bit
+};
+} // namespace
+
+template <> struct FixupInfo<Arm_Jump24> : public FixupInfoArmBranch<Arm_Jump24> {
+ static constexpr uint32_t OpcodeMask = 0x0f000000;
};
-template <> struct FixupInfo<Arm_Call> : public FixupInfo<Arm_Jump24> {
+template <> struct FixupInfo<Arm_Call> : public FixupInfoArmBranch<Arm_Call> {
static constexpr uint32_t OpcodeMask = 0x0e000000;
+ static constexpr uint32_t CondMask = 0xe0000000; // excluding BLX bit
+ static constexpr uint32_t Unconditional = 0xe0000000;
static constexpr uint32_t BitH = 0x01000000;
static constexpr uint32_t BitBlx = 0x10000000;
};
-template <> struct FixupInfo<Arm_MovtAbs> {
- static constexpr uint32_t Opcode = 0x03400000;
+namespace {
+template <EdgeKind_aarch32 Kind>
+struct FixupInfoArmMov : public FixupInfoArm<Kind> {
static constexpr uint32_t OpcodeMask = 0x0ff00000;
static constexpr uint32_t ImmMask = 0x000f0fff;
static constexpr uint32_t RegMask = 0x0000f000;
};
+} // namespace
+
+template <> struct FixupInfo<Arm_MovtAbs> : public FixupInfoArmMov<Arm_MovtAbs> {
+ static constexpr uint32_t Opcode = 0x03400000;
+};
-template <> struct FixupInfo<Arm_MovwAbsNC> : public FixupInfo<Arm_MovtAbs> {
+template <> struct FixupInfo<Arm_MovwAbsNC> : public FixupInfoArmMov<Arm_MovwAbsNC> {
static constexpr uint32_t Opcode = 0x03000000;
};
-template <> struct FixupInfo<Thumb_Jump24> {
+template <> struct FixupInfo<Thumb_Jump24> : public FixupInfoThumb<Thumb_Jump24> {
static constexpr HalfWords Opcode{0xf000, 0x8000};
static constexpr HalfWords OpcodeMask{0xf800, 0x8000};
static constexpr HalfWords ImmMask{0x07ff, 0x2fff};
};
-template <> struct FixupInfo<Thumb_Call> {
+template <> struct FixupInfo<Thumb_Call> : public FixupInfoThumb<Thumb_Call> {
static constexpr HalfWords Opcode{0xf000, 0xc000};
static constexpr HalfWords OpcodeMask{0xf800, 0xc000};
static constexpr HalfWords ImmMask{0x07ff, 0x2fff};
@@ -213,18 +247,48 @@ template <> struct FixupInfo<Thumb_Call> {
static constexpr uint16_t LoBitNoBlx = 0x1000;
};
-template <> struct FixupInfo<Thumb_MovtAbs> {
- static constexpr HalfWords Opcode{0xf2c0, 0x0000};
+namespace {
+template <EdgeKind_aarch32 Kind>
+struct FixupInfoThumbMov : public FixupInfoThumb<Kind> {
static constexpr HalfWords OpcodeMask{0xfbf0, 0x8000};
static constexpr HalfWords ImmMask{0x040f, 0x70ff};
static constexpr HalfWords RegMask{0x0000, 0x0f00};
};
+} // namespace
+
+template <>
+struct FixupInfo<Thumb_MovtAbs> : public FixupInfoThumbMov<Thumb_MovtAbs> {
+ static constexpr HalfWords Opcode{0xf2c0, 0x0000};
+};
+
+template <>
+struct FixupInfo<Thumb_MovtPrel> : public FixupInfoThumbMov<Thumb_MovtPrel> {
+ static constexpr HalfWords Opcode{0xf2c0, 0x0000};
+};
+
+template <>
+struct FixupInfo<Thumb_MovwAbsNC> : public FixupInfoThumbMov<Thumb_MovwAbsNC> {
+ static constexpr HalfWords Opcode{0xf240, 0x0000};
+};
template <>
-struct FixupInfo<Thumb_MovwAbsNC> : public FixupInfo<Thumb_MovtAbs> {
+struct FixupInfo<Thumb_MovwPrelNC> : public FixupInfoThumbMov<Thumb_MovwPrelNC> {
static constexpr HalfWords Opcode{0xf240, 0x0000};
};
+template <EdgeKind_aarch32 Kind>
+bool FixupInfoArm<Kind>::checkOpcode(uint32_t Wd) const {
+ return (Wd & FixupInfo<Kind>::OpcodeMask) == FixupInfo<Kind>::Opcode;
+}
+
+template <EdgeKind_aarch32 Kind>
+bool FixupInfoThumb<Kind>::checkOpcode(uint16_t Hi, uint16_t Lo) const {
+ return (Hi & FixupInfo<Kind>::OpcodeMask.Hi) == FixupInfo<Kind>::Opcode.Hi &&
+ (Lo & FixupInfo<Kind>::OpcodeMask.Lo) == FixupInfo<Kind>::Opcode.Lo;
+}
+
+void populateFixupInfos();
+
/// Helper function to read the initial addend for Data-class relocations.
Expected<int64_t> readAddendData(LinkGraph &G, Block &B, const Edge &E);
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp
index b6b63691d8408ea..f5d24817595dd7d 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp
@@ -233,6 +233,8 @@ createLinkGraphFromELFObject_aarch32(MemoryBufferRef ObjectBuffer) {
<< ObjectBuffer.getBufferIdentifier() << "...\n";
});
+ aarch32::populateFixupInfos();
+
auto ELFObj = ObjectFile::createELFObjectFile(ObjectBuffer);
if (!ELFObj)
return ELFObj.takeError();
diff --git a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
index c3823f985ce182d..303dac19da2b99f 100644
--- a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
@@ -224,7 +224,6 @@ struct WritableArmRelocation {
};
struct ArmRelocation {
-
ArmRelocation(const char *FixupPtr)
: Wd{*reinterpret_cast<const support::ulittle32_t *>(FixupPtr)} {}
@@ -248,15 +247,49 @@ Error makeUnexpectedOpcodeError(const LinkGraph &G, const ArmRelocation &R,
static_cast<uint32_t>(R.Wd), G.getEdgeKindName(Kind)));
}
-template <EdgeKind_aarch32 Kind> bool checkOpcode(const ThumbRelocation &R) {
- uint16_t Hi = R.Hi & FixupInfo<Kind>::OpcodeMask.Hi;
- uint16_t Lo = R.Lo & FixupInfo<Kind>::OpcodeMask.Lo;
- return Hi == FixupInfo<Kind>::Opcode.Hi && Lo == FixupInfo<Kind>::Opcode.Lo;
+static auto &getFixupInfoTableArm() {
+ static constexpr size_t Items = LastArmRelocation - FirstArmRelocation + 1;
+ static std::array<std::unique_ptr<FixupInfoBaseArm>, Items> FixupInfoTableArm;
+ return FixupInfoTableArm;
+}
+
+static auto &getFixupInfoTableThumb() {
+ static constexpr size_t Items = LastThumbRelocation - FirstThumbRelocation + 1;
+ static std::array<std::unique_ptr<FixupInfoBaseThumb>, Items> FixupInfoTableThumb;
+ return FixupInfoTableThumb;
}
-template <EdgeKind_aarch32 Kind> bool checkOpcode(const ArmRelocation &R) {
- uint32_t Wd = R.Wd & FixupInfo<Kind>::OpcodeMask;
- return Wd == FixupInfo<Kind>::Opcode;
+template <EdgeKind_aarch32 It, EdgeKind_aarch32 Last, typename TableT>
+void populateFixupInfos(TableT &Table, size_t Idx = 0) {
+ Table[Idx] = std::make_unique<FixupInfo<It>>();
+ if constexpr (It < Last) {
+ constexpr auto Next = EdgeKind_aarch32((Edge::Kind)It + 1);
+ populateFixupInfos<Next, Last>(Table, Idx + 1);
+ }
+}
+
+void populateFixupInfos() {
+ static std::once_flag Flag;
+ std::call_once(Flag, []() {
+ populateFixupInfos<FirstArmRelocation, LastArmRelocation>(getFixupInfoTableArm());
+ populateFixupInfos<FirstThumbRelocation, LastThumbRelocation>(getFixupInfoTableThumb());
+ });
+}
+
+static bool checkOpcode(const ArmRelocation &R, Edge::Kind Kind) {
+ assert(Kind >= FirstArmRelocation && Kind <= LastArmRelocation &&
+ "Edge kind is no Arm relocation");
+ assert(getFixupInfoTableArm().at(Kind - FirstArmRelocation) != nullptr &&
+ "Call populateFixupInfos() before dynamic access");
+ return getFixupInfoTableArm()[Kind - FirstArmRelocation]->checkOpcode(R.Wd);
+}
+
+static bool checkOpcode(const ThumbRelocation &R, Edge::Kind Kind) {
+ assert(Kind >= FirstThumbRelocation && Kind <= LastThumbRelocation &&
+ "Edge kind is no Thumb relocation");
+ assert(getFixupInfoTableThumb().at(Kind - FirstThumbRelocation) != nullptr &&
+ "Call populateFixupInfos() before dynamic access");
+ return getFixupInfoTableThumb()[Kind - FirstThumbRelocation]->checkOpcode(R.Hi, R.Lo);
}
template <EdgeKind_aarch32 Kind>
@@ -326,26 +359,16 @@ Expected<int64_t> readAddendData(LinkGraph &G, Block &B, const Edge &E) {
Expected<int64_t> readAddendArm(LinkGraph &G, Block &B, const Edge &E) {
ArmRelocation R(B.getContent().data() + E.getOffset());
Edge::Kind Kind = E.getKind();
+ if (!checkOpcode(R, Kind))
+ return makeUnexpectedOpcodeError(G, R, Kind);
switch (Kind) {
case Arm_Call:
- if (!checkOpcode<Arm_Call>(R))
- return makeUnexpectedOpcodeError(G, R, Kind);
- return decodeImmBA1BlA1BlxA2(R.Wd);
-
case Arm_Jump24:
- if (!checkOpcode<Arm_Jump24>(R))
- return makeUnexpectedOpcodeError(G, R, Kind);
return decodeImmBA1BlA1BlxA2(R.Wd);
- case Arm_MovwAbsNC:
- if (!checkOpcode<Arm_MovwAbsNC>(R))
- return makeUnexpectedOpcodeError(G, R, Kind);
- return decodeImmMovtA1MovwA2(R.Wd);
-
case Arm_MovtAbs:
- if (!checkOpcode<Arm_MovtAbs>(R))
- return makeUnexpectedOpcodeError(G, R, Kind);
+ case Arm_MovwAbsNC:
return decodeImmMovtA1MovwA2(R.Wd);
default:
@@ -360,33 +383,23 @@ Expected<int64_t> readAddendThumb(LinkGraph &G, Block &B, const Edge &E,
const ArmConfig &ArmCfg) {
ThumbRelocation R(B.getContent().data() + E.getOffset());
Edge::Kind Kind = E.getKind();
+ if (!checkOpcode(R, Kind))
+ return makeUnexpectedOpcodeError(G, R, Kind);
switch (Kind) {
case Thumb_Call:
- if (!checkOpcode<Thumb_Call>(R))
- return makeUnexpectedOpcodeError(G, R, Kind);
+ case Thumb_Jump24:
return LLVM_LIKELY(ArmCfg.J1J2BranchEncoding)
? decodeImmBT4BlT1BlxT2_J1J2(R.Hi, R.Lo)
: decodeImmBT4BlT1BlxT2(R.Hi, R.Lo);
- case Thumb_Jump24:
- if (!checkOpcode<Thumb_Jump24>(R))
- return makeUnexpectedOpcodeError(G, R, Kind);
- return LLVM_LIKELY(ArmCfg.J1J2BranchEncoding)
- ? decodeImmBT4BlT1BlxT2_J1J2(R.Hi, R.Lo)
- : decodeImmBT4BlT1BlxT2(R.Hi, R.Lo);
-
case Thumb_MovwAbsNC:
case Thumb_MovwPrelNC:
- if (!checkOpcode<Thumb_MovwAbsNC>(R))
- return makeUnexpectedOpcodeError(G, R, Kind);
// Initial addend is interpreted as a signed value
return SignExtend64<16>(decodeImmMovtT1MovwT3(R.Hi, R.Lo));
case Thumb_MovtAbs:
case Thumb_MovtPrel:
- if (!checkOpcode<Thumb_MovtAbs>(R))
- return makeUnexpectedOpcodeError(G, R, Kind);
// Initial addend is interpreted as a signed value
return SignExtend64<16>(decodeImmMovtT1MovwT3(R.Hi, R.Lo));
@@ -448,6 +461,9 @@ Error applyFixupData(LinkGraph &G, Block &B, const Edge &E) {
Error applyFixupArm(LinkGraph &G, Block &B, const Edge &E) {
WritableArmRelocation R(B.getAlreadyMutableContent().data() + E.getOffset());
Edge::Kind Kind = E.getKind();
+ if (!checkOpcode(R, Kind))
+ return makeUnexpectedOpcodeError(G, R, Kind);
+
uint64_t FixupAddress = (B.getAddress() + E.getOffset()).getValue();
int64_t Addend = E.getAddend();
Symbol &TargetSymbol = E.getTarget();
@@ -455,8 +471,6 @@ Error applyFixupArm(LinkGraph &G, Block &B, const Edge &E) {
switch (Kind) {
case Arm_Jump24: {
- if (!checkOpcode<Arm_Jump24>(R))
- return makeUnexpectedOpcodeError(G, R, Kind);
if (hasTargetFlags(TargetSymbol, ThumbSymbol))
return make_error<JITLinkError>("Branch relocation needs interworking "
"stub when bridging to Thumb: " +
@@ -471,8 +485,6 @@ Error applyFixupArm(LinkGraph &G, Block &B, const Edge &E) {
return Error::success();
}
case Arm_Call: {
- if (!checkOpcode<Arm_Call>(R))
- return makeUnexpectedOpcodeError(G, R, Kind);
if ((R.Wd & FixupInfo<Arm_Call>::CondMask) !=
FixupInfo<Arm_Call>::Unconditional)
return make_error<JITLinkError>("Relocation expects an unconditional "
@@ -503,15 +515,11 @@ Error applyFixupArm(LinkGraph &G, Block &B, const Edge &E) {
return Error::success();
}
case Arm_MovwAbsNC: {
- if (!checkOpcode<Arm_MovwAbsNC>(R))
- return makeUnexpectedOpcodeError(G, R, Kind);
uint16_t Value = (TargetAddress + Addend) & 0xffff;
writeImmediate<Arm_MovwAbsNC>(R, encodeImmMovtA1MovwA2(Value));
return Error::success();
}
case Arm_MovtAbs: {
- if (!checkOpcode<Arm_MovtAbs>(R))
- return makeUnexpectedOpcodeError(G, R, Kind);
uint16_t Value = ((TargetAddress + Addend) >> 16) & 0xffff;
writeImmediate<Arm_MovtAbs>(R, encodeImmMovtA1MovwA2(Value));
return Error::success();
@@ -528,8 +536,10 @@ Error applyFixupThumb(LinkGraph &G, Block &B, const Edge &E,
const ArmConfig &ArmCfg) {
WritableThumbRelocation R(B.getAlreadyMutableContent().data() +
E.getOffset());
-
Edge::Kind Kind = E.getKind();
+ if (!checkOpcode(R, Kind))
+ return makeUnexpectedOpcodeError(G, R, Kind);
+
uint64_t FixupAddress = (B.getAddress() + E.getOffset()).getValue();
int64_t Addend = E.getAddend();
Symbol &TargetSymbol = E.getTarget();
@@ -537,8 +547,6 @@ Error applyFixupThumb(LinkGraph &G, Block &B, const Edge &E,
switch (Kind) {
case Thumb_Jump24: {
- if (!checkOpcode<Thumb_Jump24>(R))
- return makeUnexpectedOpcodeError(G, R, Kind);
if (!hasTargetFlags(TargetSymbol, ThumbSymbol))
return make_error<JITLinkError>("Branch relocation needs interworking "
"stub when bridging to ARM: " +
@@ -559,9 +567,6 @@ Error applyFixupThumb(LinkGraph &G, Block &B, const Edge &E,
}
case Thumb_Call: {
- if (!checkOpcode<Thumb_Call>(R))
- return makeUnexpectedOpcodeError(G, R, Kind);
-
int64_t Value = TargetAddress - FixupAddress + Addend;
// The call instruction itself is Thumb. The call destination can either be
@@ -598,32 +603,23 @@ Error applyFixupThumb(LinkGraph &G, Block &B, const Edge &E,
}
case Thumb_MovwAbsNC: {
- if (!checkOpcode<Thumb_MovwAbsNC>(R))
- return makeUnexpectedOpcodeError(G, R, Kind);
uint16_t Value = (TargetAddress + Addend) & 0xffff;
writeImmediate<Thumb_MovwAbsNC>(R, encodeImmMovtT1MovwT3(Value));
return Error::success();
}
-
case Thumb_MovtAbs: {
- if (!checkOpcode<Thumb_MovtAbs>(R))
- return makeUnexpectedOpcodeError(G, R, Kind);
uint16_t Value = ((TargetAddress + Addend) >> 16) & 0xffff;
writeImmediate<Thumb_MovtAbs>(R, encodeImmMovtT1MovwT3(Value));
return Error::success();
}
case Thumb_MovwPrelNC: {
- if (!checkOpcode<Thumb_MovwAbsNC>(R))
- return makeUnexpectedOpcodeError(G, R, Kind);
uint16_t Value = ((TargetAddress + Addend - FixupAddress) & 0xffff);
- writeImmediate<Thumb_MovwAbsNC>(R, encodeImmMovtT1MovwT3(Value));
+ writeImmediate<Thumb_MovwPrelNC>(R, encodeImmMovtT1MovwT3(Value));
return Error::success();
}
case Thumb_MovtPrel: {
- if (!checkOpcode<Thumb_MovtAbs>(R))
- return makeUnexpectedOpcodeError(G, R, Kind);
uint16_t Value = (((TargetAddress + Addend - FixupAddress) >> 16) & 0xffff);
- writeImmediate<Thumb_MovtAbs>(R, encodeImmMovtT1MovwT3(Value));
+ writeImmediate<Thumb_MovtPrel>(R, encodeImmMovtT1MovwT3(Value));
return Error::success();
}
>From cd9e35a6d745b2e0e501e213867fc9513477465c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= <stefan.graenitz at gmail.com>
Date: Wed, 8 Nov 2023 13:56:05 +0100
Subject: [PATCH 3/5] Add root class FixupInfoBase for both, Arm and Thumb, and
store all fixup infos in one table
---
.../llvm/ExecutionEngine/JITLink/aarch32.h | 33 +++++++-------
llvm/lib/ExecutionEngine/JITLink/aarch32.cpp | 43 +++++++++----------
2 files changed, 37 insertions(+), 39 deletions(-)
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
index 95782e9bc6f1228..78381ab10f53ee8 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
@@ -98,6 +98,7 @@ enum EdgeKind_aarch32 : Edge::Kind {
Thumb_MovtPrel,
LastThumbRelocation = Thumb_MovtPrel,
+ LastRelocation = LastThumbRelocation,
};
/// Flags enum for AArch32-specific symbol properties
@@ -163,22 +164,31 @@ struct HalfWords {
const uint16_t Lo; // Second halfword
};
-struct FixupInfoBaseArm {
- virtual ~FixupInfoBaseArm() {}
+struct FixupInfoBase {
+ virtual ~FixupInfoBase() {}
+};
+
+struct FixupInfoBaseArm : public FixupInfoBase {
virtual bool checkOpcode(uint32_t Wd) const = 0;
};
-struct FixupInfoBaseThumb {
- virtual ~FixupInfoBaseThumb() {}
+struct FixupInfoBaseThumb : public FixupInfoBase {
virtual bool checkOpcode(uint16_t Hi, uint16_t Lo) const = 0;
};
+template <EdgeKind_aarch32 Kind> struct FixupInfo;
+
template <EdgeKind_aarch32 Kind> struct FixupInfoArm : public FixupInfoBaseArm {
- bool checkOpcode(uint32_t Wd) const override;
+ bool checkOpcode(uint32_t Wd) const override {
+ return (Wd & FixupInfo<Kind>::OpcodeMask) == FixupInfo<Kind>::Opcode;
+ }
};
template <EdgeKind_aarch32 Kind> struct FixupInfoThumb : public FixupInfoBaseThumb {
- bool checkOpcode(uint16_t Hi, uint16_t Lo) const override;
+ bool checkOpcode(uint16_t Hi, uint16_t Lo) const override {
+ return (Hi & FixupInfo<Kind>::OpcodeMask.Hi) == FixupInfo<Kind>::Opcode.Hi &&
+ (Lo & FixupInfo<Kind>::OpcodeMask.Lo) == FixupInfo<Kind>::Opcode.Lo;
+ }
};
/// Collection of named constants per fixup kind
@@ -276,17 +286,6 @@ struct FixupInfo<Thumb_MovwPrelNC> : public FixupInfoThumbMov<Thumb_MovwPrelNC>
static constexpr HalfWords Opcode{0xf240, 0x0000};
};
-template <EdgeKind_aarch32 Kind>
-bool FixupInfoArm<Kind>::checkOpcode(uint32_t Wd) const {
- return (Wd & FixupInfo<Kind>::OpcodeMask) == FixupInfo<Kind>::Opcode;
-}
-
-template <EdgeKind_aarch32 Kind>
-bool FixupInfoThumb<Kind>::checkOpcode(uint16_t Hi, uint16_t Lo) const {
- return (Hi & FixupInfo<Kind>::OpcodeMask.Hi) == FixupInfo<Kind>::Opcode.Hi &&
- (Lo & FixupInfo<Kind>::OpcodeMask.Lo) == FixupInfo<Kind>::Opcode.Lo;
-}
-
void populateFixupInfos();
/// Helper function to read the initial addend for Data-class relocations.
diff --git a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
index 303dac19da2b99f..332eda0c69b09c5 100644
--- a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
@@ -247,49 +247,48 @@ Error makeUnexpectedOpcodeError(const LinkGraph &G, const ArmRelocation &R,
static_cast<uint32_t>(R.Wd), G.getEdgeKindName(Kind)));
}
-static auto &getFixupInfoTableArm() {
- static constexpr size_t Items = LastArmRelocation - FirstArmRelocation + 1;
- static std::array<std::unique_ptr<FixupInfoBaseArm>, Items> FixupInfoTableArm;
- return FixupInfoTableArm;
-}
-
-static auto &getFixupInfoTableThumb() {
- static constexpr size_t Items = LastThumbRelocation - FirstThumbRelocation + 1;
- static std::array<std::unique_ptr<FixupInfoBaseThumb>, Items> FixupInfoTableThumb;
- return FixupInfoTableThumb;
+static auto &getFixupInfoTable() {
+ static constexpr size_t Items = LastRelocation + 1;
+ static std::array<std::unique_ptr<FixupInfoBase>, Items> FixupInfoTable;
+ return FixupInfoTable;
}
template <EdgeKind_aarch32 It, EdgeKind_aarch32 Last, typename TableT>
-void populateFixupInfos(TableT &Table, size_t Idx = 0) {
- Table[Idx] = std::make_unique<FixupInfo<It>>();
+void populateFixupInfos(TableT &Table) {
+ assert(It < Table.size() && Table.at(It) == nullptr && "Once set, entries are immutable");
+ Table[It] = std::make_unique<FixupInfo<It>>();
if constexpr (It < Last) {
- constexpr auto Next = EdgeKind_aarch32((Edge::Kind)It + 1);
- populateFixupInfos<Next, Last>(Table, Idx + 1);
+ constexpr auto Next = static_cast<EdgeKind_aarch32>(It + 1);
+ populateFixupInfos<Next, Last>(Table);
}
}
void populateFixupInfos() {
static std::once_flag Flag;
std::call_once(Flag, []() {
- populateFixupInfos<FirstArmRelocation, LastArmRelocation>(getFixupInfoTableArm());
- populateFixupInfos<FirstThumbRelocation, LastThumbRelocation>(getFixupInfoTableThumb());
+ populateFixupInfos<FirstArmRelocation, LastArmRelocation>(getFixupInfoTable());
+ populateFixupInfos<FirstThumbRelocation, LastThumbRelocation>(getFixupInfoTable());
});
}
+template <typename TargetModeSubclass>
+const TargetModeSubclass &getDynFixupInfo(Edge::Kind K) {
+ assert(K >= Edge::FirstRelocation && "Invalid value for edge kind");
+ assert(K <= LastRelocation && "Invalid value for edge kind");
+ assert(getFixupInfoTable().at(K) && "Call populateFixupInfos() first");
+ return *static_cast<TargetModeSubclass *>(getFixupInfoTable().at(K).get());
+}
+
static bool checkOpcode(const ArmRelocation &R, Edge::Kind Kind) {
assert(Kind >= FirstArmRelocation && Kind <= LastArmRelocation &&
"Edge kind is no Arm relocation");
- assert(getFixupInfoTableArm().at(Kind - FirstArmRelocation) != nullptr &&
- "Call populateFixupInfos() before dynamic access");
- return getFixupInfoTableArm()[Kind - FirstArmRelocation]->checkOpcode(R.Wd);
+ return getDynFixupInfo<FixupInfoBaseArm>(Kind).checkOpcode(R.Wd);
}
static bool checkOpcode(const ThumbRelocation &R, Edge::Kind Kind) {
assert(Kind >= FirstThumbRelocation && Kind <= LastThumbRelocation &&
"Edge kind is no Thumb relocation");
- assert(getFixupInfoTableThumb().at(Kind - FirstThumbRelocation) != nullptr &&
- "Call populateFixupInfos() before dynamic access");
- return getFixupInfoTableThumb()[Kind - FirstThumbRelocation]->checkOpcode(R.Hi, R.Lo);
+ return getDynFixupInfo<FixupInfoBaseThumb>(Kind).checkOpcode(R.Hi, R.Lo);
}
template <EdgeKind_aarch32 Kind>
>From 25a19075711bae2e2ff429898178d1181a6297c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= <stefan.graenitz at gmail.com>
Date: Wed, 8 Nov 2023 19:01:59 +0100
Subject: [PATCH 4/5] [JITLink][AArch32] For better performance, assign
checkOpcode() implementations as function pointers during initialization
---
llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h | 8 ++++----
llvm/lib/ExecutionEngine/JITLink/aarch32.cpp | 4 +++-
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
index 78381ab10f53ee8..7310f3869fb3025 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
@@ -169,23 +169,23 @@ struct FixupInfoBase {
};
struct FixupInfoBaseArm : public FixupInfoBase {
- virtual bool checkOpcode(uint32_t Wd) const = 0;
+ bool (*checkOpcode)(uint32_t Wd) = nullptr;
};
struct FixupInfoBaseThumb : public FixupInfoBase {
- virtual bool checkOpcode(uint16_t Hi, uint16_t Lo) const = 0;
+ bool (*checkOpcode)(uint16_t Hi, uint16_t Lo) = nullptr;
};
template <EdgeKind_aarch32 Kind> struct FixupInfo;
template <EdgeKind_aarch32 Kind> struct FixupInfoArm : public FixupInfoBaseArm {
- bool checkOpcode(uint32_t Wd) const override {
+ static bool checkOpcodeImpl(uint32_t Wd) {
return (Wd & FixupInfo<Kind>::OpcodeMask) == FixupInfo<Kind>::Opcode;
}
};
template <EdgeKind_aarch32 Kind> struct FixupInfoThumb : public FixupInfoBaseThumb {
- bool checkOpcode(uint16_t Hi, uint16_t Lo) const override {
+ static bool checkOpcodeImpl(uint16_t Hi, uint16_t Lo) {
return (Hi & FixupInfo<Kind>::OpcodeMask.Hi) == FixupInfo<Kind>::Opcode.Hi &&
(Lo & FixupInfo<Kind>::OpcodeMask.Lo) == FixupInfo<Kind>::Opcode.Lo;
}
diff --git a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
index 332eda0c69b09c5..356cf6d8ae11de8 100644
--- a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
@@ -256,7 +256,9 @@ static auto &getFixupInfoTable() {
template <EdgeKind_aarch32 It, EdgeKind_aarch32 Last, typename TableT>
void populateFixupInfos(TableT &Table) {
assert(It < Table.size() && Table.at(It) == nullptr && "Once set, entries are immutable");
- Table[It] = std::make_unique<FixupInfo<It>>();
+ auto Entry = std::make_unique<FixupInfo<It>>();
+ Entry->checkOpcode = FixupInfo<It>::checkOpcodeImpl;
+ Table[It] = std::move(Entry);
if constexpr (It < Last) {
constexpr auto Next = static_cast<EdgeKind_aarch32>(It + 1);
populateFixupInfos<Next, Last>(Table);
>From 961aeaaccd8bbfcd07e0620b07effb6859174d33 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= <stefan.graenitz at gmail.com>
Date: Wed, 8 Nov 2023 19:18:30 +0100
Subject: [PATCH 5/5] Fix formatting and polish
---
.../llvm/ExecutionEngine/JITLink/aarch32.h | 28 +++++++++++--------
llvm/lib/ExecutionEngine/JITLink/aarch32.cpp | 16 ++++++-----
2 files changed, 26 insertions(+), 18 deletions(-)
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
index 7310f3869fb3025..b7eed7527d2d765 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
@@ -176,18 +176,19 @@ struct FixupInfoBaseThumb : public FixupInfoBase {
bool (*checkOpcode)(uint16_t Hi, uint16_t Lo) = nullptr;
};
-template <EdgeKind_aarch32 Kind> struct FixupInfo;
+template <EdgeKind_aarch32 K> struct FixupInfo;
-template <EdgeKind_aarch32 Kind> struct FixupInfoArm : public FixupInfoBaseArm {
+template <EdgeKind_aarch32 K> struct FixupInfoArm : public FixupInfoBaseArm {
static bool checkOpcodeImpl(uint32_t Wd) {
- return (Wd & FixupInfo<Kind>::OpcodeMask) == FixupInfo<Kind>::Opcode;
+ return (Wd & FixupInfo<K>::OpcodeMask) == FixupInfo<K>::Opcode;
}
};
-template <EdgeKind_aarch32 Kind> struct FixupInfoThumb : public FixupInfoBaseThumb {
+template <EdgeKind_aarch32 K>
+struct FixupInfoThumb : public FixupInfoBaseThumb {
static bool checkOpcodeImpl(uint16_t Hi, uint16_t Lo) {
- return (Hi & FixupInfo<Kind>::OpcodeMask.Hi) == FixupInfo<Kind>::Opcode.Hi &&
- (Lo & FixupInfo<Kind>::OpcodeMask.Lo) == FixupInfo<Kind>::Opcode.Lo;
+ return (Hi & FixupInfo<K>::OpcodeMask.Hi) == FixupInfo<K>::Opcode.Hi &&
+ (Lo & FixupInfo<K>::OpcodeMask.Lo) == FixupInfo<K>::Opcode.Lo;
}
};
@@ -214,7 +215,8 @@ struct FixupInfoArmBranch : public FixupInfoArm<Kind> {
};
} // namespace
-template <> struct FixupInfo<Arm_Jump24> : public FixupInfoArmBranch<Arm_Jump24> {
+template <>
+struct FixupInfo<Arm_Jump24> : public FixupInfoArmBranch<Arm_Jump24> {
static constexpr uint32_t OpcodeMask = 0x0f000000;
};
@@ -235,15 +237,18 @@ struct FixupInfoArmMov : public FixupInfoArm<Kind> {
};
} // namespace
-template <> struct FixupInfo<Arm_MovtAbs> : public FixupInfoArmMov<Arm_MovtAbs> {
+template <>
+struct FixupInfo<Arm_MovtAbs> : public FixupInfoArmMov<Arm_MovtAbs> {
static constexpr uint32_t Opcode = 0x03400000;
};
-template <> struct FixupInfo<Arm_MovwAbsNC> : public FixupInfoArmMov<Arm_MovwAbsNC> {
+template <>
+struct FixupInfo<Arm_MovwAbsNC> : public FixupInfoArmMov<Arm_MovwAbsNC> {
static constexpr uint32_t Opcode = 0x03000000;
};
-template <> struct FixupInfo<Thumb_Jump24> : public FixupInfoThumb<Thumb_Jump24> {
+template <>
+struct FixupInfo<Thumb_Jump24> : public FixupInfoThumb<Thumb_Jump24> {
static constexpr HalfWords Opcode{0xf000, 0x8000};
static constexpr HalfWords OpcodeMask{0xf800, 0x8000};
static constexpr HalfWords ImmMask{0x07ff, 0x2fff};
@@ -282,7 +287,8 @@ struct FixupInfo<Thumb_MovwAbsNC> : public FixupInfoThumbMov<Thumb_MovwAbsNC> {
};
template <>
-struct FixupInfo<Thumb_MovwPrelNC> : public FixupInfoThumbMov<Thumb_MovwPrelNC> {
+struct FixupInfo<Thumb_MovwPrelNC>
+ : public FixupInfoThumbMov<Thumb_MovwPrelNC> {
static constexpr HalfWords Opcode{0xf240, 0x0000};
};
diff --git a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
index 356cf6d8ae11de8..fe2c6ac82009449 100644
--- a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
@@ -255,7 +255,8 @@ static auto &getFixupInfoTable() {
template <EdgeKind_aarch32 It, EdgeKind_aarch32 Last, typename TableT>
void populateFixupInfos(TableT &Table) {
- assert(It < Table.size() && Table.at(It) == nullptr && "Once set, entries are immutable");
+ assert(It < Table.size() && "Index out of range");
+ assert(Table.at(It) == nullptr && "Initialized entries are immutable");
auto Entry = std::make_unique<FixupInfo<It>>();
Entry->checkOpcode = FixupInfo<It>::checkOpcodeImpl;
Table[It] = std::move(Entry);
@@ -268,8 +269,9 @@ void populateFixupInfos(TableT &Table) {
void populateFixupInfos() {
static std::once_flag Flag;
std::call_once(Flag, []() {
- populateFixupInfos<FirstArmRelocation, LastArmRelocation>(getFixupInfoTable());
- populateFixupInfos<FirstThumbRelocation, LastThumbRelocation>(getFixupInfoTable());
+ auto &Table = getFixupInfoTable();
+ populateFixupInfos<FirstArmRelocation, LastArmRelocation>(Table);
+ populateFixupInfos<FirstThumbRelocation, LastThumbRelocation>(Table);
});
}
@@ -361,7 +363,7 @@ Expected<int64_t> readAddendArm(LinkGraph &G, Block &B, const Edge &E) {
ArmRelocation R(B.getContent().data() + E.getOffset());
Edge::Kind Kind = E.getKind();
if (!checkOpcode(R, Kind))
- return makeUnexpectedOpcodeError(G, R, Kind);
+ return makeUnexpectedOpcodeError(G, R, Kind);
switch (Kind) {
case Arm_Call:
@@ -385,7 +387,7 @@ Expected<int64_t> readAddendThumb(LinkGraph &G, Block &B, const Edge &E,
ThumbRelocation R(B.getContent().data() + E.getOffset());
Edge::Kind Kind = E.getKind();
if (!checkOpcode(R, Kind))
- return makeUnexpectedOpcodeError(G, R, Kind);
+ return makeUnexpectedOpcodeError(G, R, Kind);
switch (Kind) {
case Thumb_Call:
@@ -463,7 +465,7 @@ Error applyFixupArm(LinkGraph &G, Block &B, const Edge &E) {
WritableArmRelocation R(B.getAlreadyMutableContent().data() + E.getOffset());
Edge::Kind Kind = E.getKind();
if (!checkOpcode(R, Kind))
- return makeUnexpectedOpcodeError(G, R, Kind);
+ return makeUnexpectedOpcodeError(G, R, Kind);
uint64_t FixupAddress = (B.getAddress() + E.getOffset()).getValue();
int64_t Addend = E.getAddend();
@@ -539,7 +541,7 @@ Error applyFixupThumb(LinkGraph &G, Block &B, const Edge &E,
E.getOffset());
Edge::Kind Kind = E.getKind();
if (!checkOpcode(R, Kind))
- return makeUnexpectedOpcodeError(G, R, Kind);
+ return makeUnexpectedOpcodeError(G, R, Kind);
uint64_t FixupAddress = (B.getAddress() + E.getOffset()).getValue();
int64_t Addend = E.getAddend();
More information about the llvm-commits
mailing list