From c8a927696cf4e39a813be4c42fe5b48bfbddcc76 Mon Sep 17 00:00:00 2001 From: Maksim Panchenko Date: Wed, 3 Apr 2019 22:31:12 -0700 Subject: [PATCH] [BOLT] Detect internal references into a middle of instruction Summary: Some instructions in assembly-written functions could reference 8-byte constants from another instructions using 4-byte offsets, presumably to save a couple of bytes. Detect such cases, and skip processing such functions until we teach BOLT how to handle references into a middle of instruction. (cherry picked from FBD14768212) --- bolt/src/BinaryFunction.cpp | 25 ++++++++++++++++++++++++- bolt/src/BinaryFunction.h | 3 +++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/bolt/src/BinaryFunction.cpp b/bolt/src/BinaryFunction.cpp index 37c4536b34b7..711d7282e30d 100644 --- a/bolt/src/BinaryFunction.cpp +++ b/bolt/src/BinaryFunction.cpp @@ -1464,9 +1464,32 @@ add_instruction: updateState(State::Disassembled); + postProcessEntryPoints(); + postProcessJumpTables(); } +void BinaryFunction::postProcessEntryPoints() { + for (auto Offset : EntryOffsets) { + if (!getInstructionAtOffset(Offset)) { + // On AArch64 there are legitimate reasons to have references past the + // end of the function, e.g. jump tables. + if (BC.isAArch64() && Offset == getSize()) { + continue; + } + + errs() << "BOLT-WARNING: reference in the middle of instruction " + "detected in function " << *this + << " at offset 0x" << Twine::utohexstr(Offset) << '\n'; + if (BC.HasRelocations) { + errs() << "BOLT-ERROR: unable to keep processing in relocation mode\n"; + exit(1); + } + setSimple(false); + } + } +} + void BinaryFunction::postProcessJumpTables() { // Create labels for all entries. for (auto &JTI : JumpTables) { @@ -1683,7 +1706,7 @@ bool BinaryFunction::buildCFG() { return false; } - if (!(CurrentState == State::Disassembled)) + if (CurrentState != State::Disassembled) return false; assert(BasicBlocks.empty() && "basic block list should be empty"); diff --git a/bolt/src/BinaryFunction.h b/bolt/src/BinaryFunction.h index be33aab8c50f..5d117e1d14d9 100644 --- a/bolt/src/BinaryFunction.h +++ b/bolt/src/BinaryFunction.h @@ -1960,6 +1960,9 @@ public: /// Returns false if disassembly failed. void disassemble(ArrayRef FunctionData); + /// Validate entry points. + void postProcessEntryPoints(); + /// Post-processing for jump tables after disassembly. Since their /// boundaries are not known until all call sites are seen, we need this /// extra pass to perform any final adjustments.