Skip to content

Commit d46158c

Browse files
Ensure PatchEntries runs
Allow skipping pending relocations only when `-force-patch` is set. Otherwise, exit with a relevant message.
1 parent bd3d4ff commit d46158c

File tree

3 files changed

+51
-4
lines changed

3 files changed

+51
-4
lines changed

bolt/lib/Core/BinarySection.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "bolt/Core/BinarySection.h"
1414
#include "bolt/Core/BinaryContext.h"
15+
#include "bolt/Utils/CommandLineOpts.h"
1516
#include "bolt/Utils/Utils.h"
1617
#include "llvm/MC/MCStreamer.h"
1718
#include "llvm/Support/CommandLine.h"
@@ -22,8 +23,8 @@ using namespace llvm;
2223
using namespace bolt;
2324

2425
namespace opts {
25-
extern cl::opt<bool> PrintRelocations;
2626
extern cl::opt<bool> HotData;
27+
extern cl::opt<bool> PrintRelocations;
2728
} // namespace opts
2829

2930
uint64_t BinarySection::Count = 0;
@@ -184,6 +185,18 @@ void BinarySection::flushPendingRelocations(raw_pwrite_stream &OS,
184185
// as part of an optimization.
185186
if (Optional && !Relocation::canEncodeValue(
186187
Reloc.Type, Value, SectionAddress + Reloc.Offset)) {
188+
189+
// A successful run of 'scanExternalRefs' means that all pending
190+
// relocations are flushed. Otherwise, PatchEntries should run.
191+
if (!opts::ForcePatch) {
192+
BC.errs()
193+
<< "BOLT-ERROR: Cannot fully run scanExternalRefs as pending "
194+
"relocation for symbol "
195+
<< Reloc.Symbol->getName()
196+
<< " is out-of-range. Cannot proceed without using -force-patch\n";
197+
exit(1);
198+
}
199+
187200
++SkippedPendingRelocations;
188201
continue;
189202
}

bolt/unittests/Core/BinaryContext.cpp

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "bolt/Core/BinaryContext.h"
10+
#include "bolt/Utils/CommandLineOpts.h"
1011
#include "llvm/BinaryFormat/ELF.h"
1112
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
1213
#include "llvm/Support/TargetSelect.h"
@@ -161,12 +162,44 @@ TEST_P(BinaryContextTester, FlushPendingRelocJUMP26) {
161162
<< "Wrong forward branch value\n";
162163
}
163164

164-
TEST_P(BinaryContextTester, FlushOptionalOutOfRangePendingRelocCALL26) {
165+
TEST_P(BinaryContextTester,
166+
FlushOptionalOutOfRangePendingRelocCALL26_ForcePatchOff) {
165167
if (GetParam() != Triple::aarch64)
166168
GTEST_SKIP();
167169

168-
// This test checks that flushPendingRelocations skips flushing any optional
169-
// pending relocations that cannot be encoded.
170+
// Tests that flushPendingRelocations exits if any pending relocation is out
171+
// of range and PatchEntries hasn't run. Pending relocations are added by
172+
// scanExternalRefs, so this ensures that either all scanExternalRefs
173+
// relocations were flushed or PatchEntries ran.
174+
175+
BinarySection &BS = BC->registerOrUpdateSection(
176+
".text", ELF::SHT_PROGBITS, ELF::SHF_EXECINSTR | ELF::SHF_ALLOC);
177+
// Create symbol 'Func0x4'
178+
MCSymbol *RelSymbol = BC->getOrCreateGlobalSymbol(4, "Func");
179+
ASSERT_TRUE(RelSymbol);
180+
BS.addPendingRelocation(Relocation{8, RelSymbol, ELF::R_AARCH64_CALL26, 0, 0},
181+
/*Optional*/ true);
182+
183+
SmallVector<char> Vect;
184+
raw_svector_ostream OS(Vect);
185+
186+
// Resolve relocation symbol to a high value so encoding will be out of range.
187+
EXPECT_EXIT(BS.flushPendingRelocations(
188+
OS, [&](const MCSymbol *S) { return 0x800000F; }),
189+
::testing::ExitedWithCode(1),
190+
"BOLT-ERROR: Cannot fully run scanExternalRefs as pending "
191+
"relocation for symbol Func0x4 is out-of-range. Cannot proceed "
192+
"without using -force-patch");
193+
}
194+
195+
TEST_P(BinaryContextTester,
196+
FlushOptionalOutOfRangePendingRelocCALL26_ForcePatchOn) {
197+
if (GetParam() != Triple::aarch64)
198+
GTEST_SKIP();
199+
200+
// Tests that flushPendingRelocations can skip flushing any optional pending
201+
// relocations that cannot be encoded, given that PatchEntries runs.
202+
opts::ForcePatch = true;
170203

171204
bool DebugFlagPrev = ::llvm::DebugFlag;
172205
::llvm::DebugFlag = true;

bolt/unittests/Core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ target_link_libraries(CoreTests
1919
LLVMBOLTCore
2020
LLVMBOLTRewrite
2121
LLVMBOLTProfile
22+
LLVMBOLTUtils
2223
LLVMTestingSupport
2324
)
2425

0 commit comments

Comments
 (0)