#include "bolt/Passes/FixRISCVCallsPass.h" #include "bolt/Core/ParallelUtilities.h" #include using namespace llvm; namespace llvm { namespace bolt { void FixRISCVCallsPass::runOnFunction(BinaryFunction &BF) { auto &BC = BF.getBinaryContext(); for (auto &BB : BF) { for (auto II = BB.begin(), IE = BB.end(); II != IE; ++II) { auto NextII = std::next(II); if (NextII == IE) break; if (!BC.MIB->isRISCVCall(*II, *NextII)) continue; auto L = BC.scopeLock(); // The MC layer handles R_RISCV_CALL_PLT but assumes that the immediate // in the JALR is zero (fixups are or'ed into instructions). Note that // NextII is guaranteed to point to a JALR by isRISCVCall. NextII->getOperand(2).setImm(0); } } } void FixRISCVCallsPass::runOnFunctions(BinaryContext &BC) { if (!BC.isRISCV() || !BC.HasRelocations) return; ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) { runOnFunction(BF); }; ParallelUtilities::runOnEachFunction( BC, ParallelUtilities::SchedulingPolicy::SP_INST_LINEAR, WorkFun, nullptr, "FixRISCVCalls"); } } // namespace bolt } // namespace llvm