[llvm] [BOLT] support AArch64 JUMP26 createRelocation (PR #83531)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Mar 3 22:26:56 PST 2024
https://github.com/linsinan1995 updated https://github.com/llvm/llvm-project/pull/83531
>From ff39b0722320fdd4ff7ffe26843ebba467fb07d2 Mon Sep 17 00:00:00 2001
From: Sinan Lin <sinan.lin at linux.alibaba.com>
Date: Mon, 19 Feb 2024 14:33:46 +0800
Subject: [PATCH] [BOLT] support AArch64 JUMP26 createRelocation
Add R_AARCH64_JUMP26 implementation for createRelocation, which
could significantly reduce the number of failed scan-refs cases.
---
bolt/lib/Core/Relocation.cpp | 8 ++++
.../Target/AArch64/AArch64MCPlusBuilder.cpp | 3 ++
bolt/unittests/Core/BinaryContext.cpp | 43 +++++++++++++++++++
3 files changed, 54 insertions(+)
diff --git a/bolt/lib/Core/Relocation.cpp b/bolt/lib/Core/Relocation.cpp
index ded497f3c06118..cbf95a7db08b52 100644
--- a/bolt/lib/Core/Relocation.cpp
+++ b/bolt/lib/Core/Relocation.cpp
@@ -381,6 +381,14 @@ static uint64_t encodeValueAArch64(uint64_t Type, uint64_t Value, uint64_t PC) {
// OP 1001_01 goes in bits 31:26 of BL.
Value = ((Value >> 2) & 0x3ffffff) | 0x94000000ULL;
break;
+ case ELF::R_AARCH64_JUMP26:
+ Value -= PC;
+ assert(isInt<28>(Value) &&
+ "only PC +/- 128MB is allowed for direct branch");
+ // Immediate goes in bits 25:0 of B.
+ // OP 0001_01 goes in bits 31:26 of B.
+ Value = ((Value >> 2) & 0x3ffffff) | 0x14000000ULL;
+ break;
}
return Value;
}
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index c1c09c70ab01da..9efb428a6e1bae 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -1629,6 +1629,9 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
uint64_t RelType;
if (Fixup.getKind() == MCFixupKind(AArch64::fixup_aarch64_pcrel_call26))
RelType = ELF::R_AARCH64_CALL26;
+ else if (Fixup.getKind() ==
+ MCFixupKind(AArch64::fixup_aarch64_pcrel_branch26))
+ RelType = ELF::R_AARCH64_JUMP26;
else if (FKI.Flags & MCFixupKindInfo::FKF_IsPCRel) {
switch (FKI.TargetSize) {
default:
diff --git a/bolt/unittests/Core/BinaryContext.cpp b/bolt/unittests/Core/BinaryContext.cpp
index 94ee65e63a1dcf..99568b62ca8aab 100644
--- a/bolt/unittests/Core/BinaryContext.cpp
+++ b/bolt/unittests/Core/BinaryContext.cpp
@@ -104,6 +104,49 @@ TEST_P(BinaryContextTester, FlushPendingRelocCALL26) {
EXPECT_FALSE(memcmp(Func2Call, &Vect[12], 4)) << "Wrong forward call value\n";
}
+TEST_P(BinaryContextTester, FlushPendingRelocJUMP26) {
+ if (GetParam() != Triple::aarch64)
+ GTEST_SKIP();
+
+ // This test checks that encodeValueAArch64 used by flushPendingRelocations
+ // returns correctly encoded values for R_AARCH64_JUMP26 relocation for both
+ // backward and forward branches.
+ //
+ // The offsets layout is:
+ // 4: func1
+ // 8: b func1
+ // 12: b func2
+ // 16: func2
+
+ uint64_t Size = 20;
+ char *Data = new char[Size];
+ BinarySection &BS = BC->registerOrUpdateSection(
+ ".text", ELF::SHT_PROGBITS, ELF::SHF_EXECINSTR | ELF::SHF_ALLOC,
+ (uint8_t *)Data, Size, 4);
+ MCSymbol *RelSymbol1 = BC->getOrCreateGlobalSymbol(4, "Func1");
+ ASSERT_TRUE(RelSymbol1);
+ BS.addRelocation(8, RelSymbol1, ELF::R_AARCH64_JUMP26, 0, 0, true);
+ MCSymbol *RelSymbol2 = BC->getOrCreateGlobalSymbol(16, "Func2");
+ ASSERT_TRUE(RelSymbol2);
+ BS.addRelocation(12, RelSymbol2, ELF::R_AARCH64_JUMP26, 0, 0, true);
+
+ std::error_code EC;
+ SmallVector<char> Vect(Size);
+ raw_svector_ostream OS(Vect);
+
+ BS.flushPendingRelocations(OS, [&](const MCSymbol *S) {
+ return S == RelSymbol1 ? 4 : S == RelSymbol2 ? 16 : 0;
+ });
+
+ const uint8_t Func1Call[4] = {255, 255, 255, 23};
+ const uint8_t Func2Call[4] = {1, 0, 0, 20};
+
+ EXPECT_FALSE(memcmp(Func1Call, &Vect[8], 4))
+ << "Wrong backward branch value\n";
+ EXPECT_FALSE(memcmp(Func2Call, &Vect[12], 4))
+ << "Wrong forward branch value\n";
+}
+
#endif
TEST_P(BinaryContextTester, BaseAddress) {
More information about the llvm-commits
mailing list