Skip to content

Commit 981f308

Browse files
committed
[BOLT] support AArch64 JUMP26 createRelocation
Add R_AARCH64_JUMP26 implementation for createRelocation, which could significantly reduce the number of failed scan-refs cases.
1 parent 6e41d60 commit 981f308

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

bolt/lib/Core/Relocation.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,14 @@ static uint64_t encodeValueAArch64(uint64_t Type, uint64_t Value, uint64_t PC) {
381381
// OP 1001_01 goes in bits 31:26 of BL.
382382
Value = ((Value >> 2) & 0x3ffffff) | 0x94000000ULL;
383383
break;
384+
case ELF::R_AARCH64_JUMP26:
385+
Value -= PC;
386+
assert(isInt<28>(Value) &&
387+
"only PC +/- 128MB is allowed for direct branch");
388+
// Immediate goes in bits 25:0 of B.
389+
// OP 0001_01 goes in bits 31:26 of B.
390+
Value = ((Value >> 2) & 0x3ffffff) | 0x14000000ULL;
391+
break;
384392
}
385393
return Value;
386394
}

bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,6 +1629,9 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
16291629
uint64_t RelType;
16301630
if (Fixup.getKind() == MCFixupKind(AArch64::fixup_aarch64_pcrel_call26))
16311631
RelType = ELF::R_AARCH64_CALL26;
1632+
else if (Fixup.getKind() ==
1633+
MCFixupKind(AArch64::fixup_aarch64_pcrel_branch26))
1634+
RelType = ELF::R_AARCH64_JUMP26;
16321635
else if (FKI.Flags & MCFixupKindInfo::FKF_IsPCRel) {
16331636
switch (FKI.TargetSize) {
16341637
default:

bolt/unittests/Core/BinaryContext.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,48 @@ TEST_P(BinaryContextTester, FlushPendingRelocCALL26) {
104104
EXPECT_FALSE(memcmp(Func2Call, &Vect[12], 4)) << "Wrong forward call value\n";
105105
}
106106

107+
TEST_P(BinaryContextTester, FlushPendingRelocJUMP26) {
108+
if (GetParam() != Triple::aarch64)
109+
GTEST_SKIP();
110+
111+
// This test checks that encodeValueAArch64 used by flushPendingRelocations
112+
// returns correctly encoded values for R_AARCH64_JUMP26 relocation for both
113+
// backward and forward branches.
114+
//
115+
// The offsets layout is:
116+
// 4: func1
117+
// 8: b func1
118+
// 12: b func2
119+
// 16: func2
120+
121+
char Data[20] = {};
122+
BinarySection &BS = BC->registerOrUpdateSection(
123+
".text", ELF::SHT_PROGBITS, ELF::SHF_EXECINSTR | ELF::SHF_ALLOC,
124+
(uint8_t *)Data, sizeof(Data), 4);
125+
MCSymbol *RelSymbol1 = BC->getOrCreateGlobalSymbol(4, "Func1");
126+
ASSERT_TRUE(RelSymbol1);
127+
BS.addRelocation(8, RelSymbol1, ELF::R_AARCH64_JUMP26, 0, 0, true);
128+
MCSymbol *RelSymbol2 = BC->getOrCreateGlobalSymbol(16, "Func2");
129+
ASSERT_TRUE(RelSymbol2);
130+
BS.addRelocation(12, RelSymbol2, ELF::R_AARCH64_JUMP26, 0, 0, true);
131+
132+
std::error_code EC;
133+
SmallVector<char> Vect(sizeof(Data));
134+
raw_svector_ostream OS(Vect);
135+
136+
BS.flushPendingRelocations(OS, [&](const MCSymbol *S) {
137+
return S == RelSymbol1 ? 4 : S == RelSymbol2 ? 16 : 0;
138+
});
139+
140+
const uint8_t Func1Call[4] = {255, 255, 255, 23};
141+
const uint8_t Func2Call[4] = {1, 0, 0, 20};
142+
143+
EXPECT_FALSE(memcmp(Func1Call, &Vect[8], 4))
144+
<< "Wrong backward branch value\n";
145+
EXPECT_FALSE(memcmp(Func2Call, &Vect[12], 4))
146+
<< "Wrong forward branch value\n";
147+
}
148+
107149
#endif
108150

109151
TEST_P(BinaryContextTester, BaseAddress) {

0 commit comments

Comments
 (0)