|
7 | 7 | //===----------------------------------------------------------------------===//
|
8 | 8 |
|
9 | 9 | #include "bolt/Core/BinaryContext.h"
|
| 10 | +#include "bolt/Utils/CommandLineOpts.h" |
10 | 11 | #include "llvm/BinaryFormat/ELF.h"
|
11 | 12 | #include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
12 | 13 | #include "llvm/Support/TargetSelect.h"
|
@@ -161,6 +162,67 @@ TEST_P(BinaryContextTester, FlushPendingRelocJUMP26) {
|
161 | 162 | << "Wrong forward branch value\n";
|
162 | 163 | }
|
163 | 164 |
|
| 165 | +TEST_P(BinaryContextTester, |
| 166 | + FlushOptionalOutOfRangePendingRelocCALL26_ForcePatchOff) { |
| 167 | + if (GetParam() != Triple::aarch64) |
| 168 | + GTEST_SKIP(); |
| 169 | + |
| 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 | + Relocation Reloc{8, RelSymbol, ELF::R_AARCH64_CALL26, 0, 0}; |
| 181 | + Reloc.setOptional(); |
| 182 | + BS.addPendingRelocation(Reloc); |
| 183 | + |
| 184 | + SmallVector<char> Vect; |
| 185 | + raw_svector_ostream OS(Vect); |
| 186 | + |
| 187 | + // Resolve relocation symbol to a high value so encoding will be out of range. |
| 188 | + EXPECT_EXIT(BS.flushPendingRelocations( |
| 189 | + OS, [&](const MCSymbol *S) { return 0x800000F; }), |
| 190 | + ::testing::ExitedWithCode(1), |
| 191 | + "BOLT-ERROR: cannot encode relocation for symbol Func0x4 as it is" |
| 192 | + " out-of-range. To proceed must use -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; |
| 203 | + |
| 204 | + opts::Verbosity = 1; |
| 205 | + testing::internal::CaptureStdout(); |
| 206 | + |
| 207 | + BinarySection &BS = BC->registerOrUpdateSection( |
| 208 | + ".text", ELF::SHT_PROGBITS, ELF::SHF_EXECINSTR | ELF::SHF_ALLOC); |
| 209 | + MCSymbol *RelSymbol = BC->getOrCreateGlobalSymbol(4, "Func"); |
| 210 | + ASSERT_TRUE(RelSymbol); |
| 211 | + Relocation Reloc{8, RelSymbol, ELF::R_AARCH64_CALL26, 0, 0}; |
| 212 | + Reloc.setOptional(); |
| 213 | + BS.addPendingRelocation(Reloc); |
| 214 | + |
| 215 | + SmallVector<char> Vect; |
| 216 | + raw_svector_ostream OS(Vect); |
| 217 | + |
| 218 | + // Resolve relocation symbol to a high value so encoding will be out of range. |
| 219 | + BS.flushPendingRelocations(OS, [&](const MCSymbol *S) { return 0x800000F; }); |
| 220 | + outs().flush(); |
| 221 | + std::string CapturedStdOut = testing::internal::GetCapturedStdout(); |
| 222 | + EXPECT_EQ(CapturedStdOut, |
| 223 | + "BOLT-INFO: skipped 1 out-of-range optional relocations\n"); |
| 224 | +} |
| 225 | + |
164 | 226 | #endif
|
165 | 227 |
|
166 | 228 | TEST_P(BinaryContextTester, BaseAddress) {
|
|
0 commit comments