73 lines · cpp
1//===- bolt/Rewrite/RSeqRewriter.cpp --------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Basic support for restartable sequences used by tcmalloc. Prevent critical10// section overrides by ignoring optimizations in containing functions.11//12// References:13// * https://google.github.io/tcmalloc/rseq.html14// * tcmalloc/internal/percpu_rseq_x86_64.S15//16//===----------------------------------------------------------------------===//17 18#include "bolt/Core/BinaryFunction.h"19#include "bolt/Rewrite/MetadataRewriter.h"20#include "bolt/Rewrite/MetadataRewriters.h"21#include "llvm/Support/Errc.h"22 23using namespace llvm;24using namespace bolt;25 26namespace {27 28class RSeqRewriter final : public MetadataRewriter {29public:30 RSeqRewriter(StringRef Name, BinaryContext &BC)31 : MetadataRewriter(Name, BC) {}32 33 Error preCFGInitializer() override {34 for (const BinarySection &Section : BC.allocatableSections()) {35 if (Section.getName() != "__rseq_cs")36 continue;37 38 auto handleRelocation = [&](const Relocation &Rel, bool IsDynamic) {39 BinaryFunction *BF = nullptr;40 if (Rel.Symbol)41 BF = BC.getFunctionForSymbol(Rel.Symbol);42 else if (Relocation::isRelative(Rel.Type))43 BF = BC.getBinaryFunctionContainingAddress(Rel.Addend);44 45 if (!BF) {46 BC.errs() << "BOLT-WARNING: no function found matching "47 << (IsDynamic ? "dynamic " : "")48 << "relocation in __rseq_cs\n";49 } else if (!BF->isIgnored()) {50 BC.outs() << "BOLT-INFO: restartable sequence reference detected in "51 << *BF << ". Function will not be optimized\n";52 BF->setIgnored();53 }54 };55 56 for (const Relocation &Rel : Section.dynamicRelocations())57 handleRelocation(Rel, /*IsDynamic*/ true);58 59 for (const Relocation &Rel : Section.relocations())60 handleRelocation(Rel, /*IsDynamic*/ false);61 }62 63 return Error::success();64 }65};66 67} // namespace68 69std::unique_ptr<MetadataRewriter>70llvm::bolt::createRSeqRewriter(BinaryContext &BC) {71 return std::make_unique<RSeqRewriter>("rseq-cs-rewriter", BC);72}73