diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
commit | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (patch) | |
tree | 012bb94d777798f1f56ac1cec429509766d05181 /contrib/libs/llvm12/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp | |
parent | 6751af0b0c1b952fede40b19b71da8025b5d8bcf (diff) | |
download | ydb-2598ef1d0aee359b4b6d5fdd1758916d5907d04f.tar.gz |
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/llvm12/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp')
-rw-r--r-- | contrib/libs/llvm12/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp | 176 |
1 files changed, 88 insertions, 88 deletions
diff --git a/contrib/libs/llvm12/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp b/contrib/libs/llvm12/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp index 810fee052b..e419f45405 100644 --- a/contrib/libs/llvm12/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp +++ b/contrib/libs/llvm12/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp @@ -42,7 +42,7 @@ #include "X86TargetMachine.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringRef.h" @@ -105,9 +105,9 @@ static cl::opt<bool> EmitDotVerify( cl::init(false), cl::Hidden); static llvm::sys::DynamicLibrary OptimizeDL; -typedef int (*OptimizeCutT)(unsigned int *Nodes, unsigned int NodesSize, - unsigned int *Edges, int *EdgeValues, - int *CutEdges /* out */, unsigned int EdgesSize); +typedef int (*OptimizeCutT)(unsigned int *Nodes, unsigned int NodesSize, + unsigned int *Edges, int *EdgeValues, + int *CutEdges /* out */, unsigned int EdgesSize); static OptimizeCutT OptimizeCut = nullptr; namespace { @@ -149,8 +149,8 @@ public: private: using GraphBuilder = ImmutableGraphBuilder<MachineGadgetGraph>; - using Edge = MachineGadgetGraph::Edge; - using Node = MachineGadgetGraph::Node; + using Edge = MachineGadgetGraph::Edge; + using Node = MachineGadgetGraph::Node; using EdgeSet = MachineGadgetGraph::EdgeSet; using NodeSet = MachineGadgetGraph::NodeSet; @@ -164,8 +164,8 @@ private: const MachineDominanceFrontier &MDF) const; int hardenLoadsWithPlugin(MachineFunction &MF, std::unique_ptr<MachineGadgetGraph> Graph) const; - int hardenLoadsWithHeuristic(MachineFunction &MF, - std::unique_ptr<MachineGadgetGraph> Graph) const; + int hardenLoadsWithHeuristic(MachineFunction &MF, + std::unique_ptr<MachineGadgetGraph> Graph) const; int elimMitigatedEdgesAndNodes(MachineGadgetGraph &G, EdgeSet &ElimEdges /* in, out */, NodeSet &ElimNodes /* in, out */) const; @@ -198,7 +198,7 @@ struct DOTGraphTraits<MachineGadgetGraph *> : DefaultDOTGraphTraits { using ChildIteratorType = typename Traits::ChildIteratorType; using ChildEdgeIteratorType = typename Traits::ChildEdgeIteratorType; - DOTGraphTraits(bool IsSimple = false) : DefaultDOTGraphTraits(IsSimple) {} + DOTGraphTraits(bool IsSimple = false) : DefaultDOTGraphTraits(IsSimple) {} std::string getNodeLabel(NodeRef Node, GraphType *) { if (Node->getValue() == MachineGadgetGraph::ArgNodeSentinel) @@ -243,7 +243,7 @@ void X86LoadValueInjectionLoadHardeningPass::getAnalysisUsage( AU.setPreservesCFG(); } -static void writeGadgetGraph(raw_ostream &OS, MachineFunction &MF, +static void writeGadgetGraph(raw_ostream &OS, MachineFunction &MF, MachineGadgetGraph *G) { WriteGraph(OS, G, /*ShortNames*/ false, "Speculative gadgets for \"" + MF.getName() + "\" function"); @@ -279,7 +279,7 @@ bool X86LoadValueInjectionLoadHardeningPass::runOnMachineFunction( return false; // didn't find any gadgets if (EmitDotVerify) { - writeGadgetGraph(outs(), MF, Graph.get()); + writeGadgetGraph(outs(), MF, Graph.get()); return false; } @@ -292,7 +292,7 @@ bool X86LoadValueInjectionLoadHardeningPass::runOnMachineFunction( raw_fd_ostream FileOut(FileName, FileError); if (FileError) errs() << FileError.message(); - writeGadgetGraph(FileOut, MF, Graph.get()); + writeGadgetGraph(FileOut, MF, Graph.get()); FileOut.close(); LLVM_DEBUG(dbgs() << "Emitting gadget graph... Done\n"); if (EmitDotOnly) @@ -313,7 +313,7 @@ bool X86LoadValueInjectionLoadHardeningPass::runOnMachineFunction( } FencesInserted = hardenLoadsWithPlugin(MF, std::move(Graph)); } else { // Use the default greedy heuristic - FencesInserted = hardenLoadsWithHeuristic(MF, std::move(Graph)); + FencesInserted = hardenLoadsWithHeuristic(MF, std::move(Graph)); } if (FencesInserted > 0) @@ -367,7 +367,7 @@ X86LoadValueInjectionLoadHardeningPass::getGadgetGraph( // Use RDF to find all the uses of `Def` rdf::NodeSet Uses; - RegisterRef DefReg = Def.Addr->getRegRef(DFG); + RegisterRef DefReg = Def.Addr->getRegRef(DFG); for (auto UseID : L.getAllReachedUses(DefReg, Def)) { auto Use = DFG.addr<UseNode *>(UseID); if (Use.Addr->getFlags() & NodeAttrs::PhiRef) { // phi node @@ -540,17 +540,17 @@ X86LoadValueInjectionLoadHardeningPass::getGadgetGraph( // Returns the number of remaining gadget edges that could not be eliminated int X86LoadValueInjectionLoadHardeningPass::elimMitigatedEdgesAndNodes( - MachineGadgetGraph &G, EdgeSet &ElimEdges /* in, out */, - NodeSet &ElimNodes /* in, out */) const { + MachineGadgetGraph &G, EdgeSet &ElimEdges /* in, out */, + NodeSet &ElimNodes /* in, out */) const { if (G.NumFences > 0) { // Eliminate fences and CFG edges that ingress and egress the fence, as // they are trivially mitigated. - for (const Edge &E : G.edges()) { - const Node *Dest = E.getDest(); + for (const Edge &E : G.edges()) { + const Node *Dest = E.getDest(); if (isFence(Dest->getValue())) { ElimNodes.insert(*Dest); ElimEdges.insert(E); - for (const Edge &DE : Dest->edges()) + for (const Edge &DE : Dest->edges()) ElimEdges.insert(DE); } } @@ -558,28 +558,28 @@ int X86LoadValueInjectionLoadHardeningPass::elimMitigatedEdgesAndNodes( // Find and eliminate gadget edges that have been mitigated. int MitigatedGadgets = 0, RemainingGadgets = 0; - NodeSet ReachableNodes{G}; - for (const Node &RootN : G.nodes()) { + NodeSet ReachableNodes{G}; + for (const Node &RootN : G.nodes()) { if (llvm::none_of(RootN.edges(), MachineGadgetGraph::isGadgetEdge)) continue; // skip this node if it isn't a gadget source // Find all of the nodes that are CFG-reachable from RootN using DFS ReachableNodes.clear(); - std::function<void(const Node *, bool)> FindReachableNodes = - [&](const Node *N, bool FirstNode) { - if (!FirstNode) - ReachableNodes.insert(*N); - for (const Edge &E : N->edges()) { - const Node *Dest = E.getDest(); - if (MachineGadgetGraph::isCFGEdge(E) && !ElimEdges.contains(E) && - !ReachableNodes.contains(*Dest)) - FindReachableNodes(Dest, false); - } - }; + std::function<void(const Node *, bool)> FindReachableNodes = + [&](const Node *N, bool FirstNode) { + if (!FirstNode) + ReachableNodes.insert(*N); + for (const Edge &E : N->edges()) { + const Node *Dest = E.getDest(); + if (MachineGadgetGraph::isCFGEdge(E) && !ElimEdges.contains(E) && + !ReachableNodes.contains(*Dest)) + FindReachableNodes(Dest, false); + } + }; FindReachableNodes(&RootN, true); // Any gadget whose sink is unreachable has been mitigated - for (const Edge &E : RootN.edges()) { + for (const Edge &E : RootN.edges()) { if (MachineGadgetGraph::isGadgetEdge(E)) { if (ReachableNodes.contains(*E.getDest())) { // This gadget's sink is reachable @@ -597,8 +597,8 @@ int X86LoadValueInjectionLoadHardeningPass::elimMitigatedEdgesAndNodes( std::unique_ptr<MachineGadgetGraph> X86LoadValueInjectionLoadHardeningPass::trimMitigatedEdges( std::unique_ptr<MachineGadgetGraph> Graph) const { - NodeSet ElimNodes{*Graph}; - EdgeSet ElimEdges{*Graph}; + NodeSet ElimNodes{*Graph}; + EdgeSet ElimEdges{*Graph}; int RemainingGadgets = elimMitigatedEdgesAndNodes(*Graph, ElimEdges, ElimNodes); if (ElimEdges.empty() && ElimNodes.empty()) { @@ -629,11 +629,11 @@ int X86LoadValueInjectionLoadHardeningPass::hardenLoadsWithPlugin( auto Edges = std::make_unique<unsigned int[]>(Graph->edges_size()); auto EdgeCuts = std::make_unique<int[]>(Graph->edges_size()); auto EdgeValues = std::make_unique<int[]>(Graph->edges_size()); - for (const Node &N : Graph->nodes()) { + for (const Node &N : Graph->nodes()) { Nodes[Graph->getNodeIndex(N)] = Graph->getEdgeIndex(*N.edges_begin()); } Nodes[Graph->nodes_size()] = Graph->edges_size(); // terminator node - for (const Edge &E : Graph->edges()) { + for (const Edge &E : Graph->edges()) { Edges[Graph->getEdgeIndex(E)] = Graph->getNodeIndex(*E.getDest()); EdgeValues[Graph->getEdgeIndex(E)] = E.getValue(); } @@ -650,67 +650,67 @@ int X86LoadValueInjectionLoadHardeningPass::hardenLoadsWithPlugin( LLVM_DEBUG(dbgs() << "Inserting LFENCEs... Done\n"); LLVM_DEBUG(dbgs() << "Inserted " << FencesInserted << " fences\n"); - Graph = GraphBuilder::trim(*Graph, NodeSet{*Graph}, CutEdges); + Graph = GraphBuilder::trim(*Graph, NodeSet{*Graph}, CutEdges); } while (true); return FencesInserted; } -int X86LoadValueInjectionLoadHardeningPass::hardenLoadsWithHeuristic( +int X86LoadValueInjectionLoadHardeningPass::hardenLoadsWithHeuristic( MachineFunction &MF, std::unique_ptr<MachineGadgetGraph> Graph) const { - // If `MF` does not have any fences, then no gadgets would have been - // mitigated at this point. - if (Graph->NumFences > 0) { - LLVM_DEBUG(dbgs() << "Eliminating mitigated paths...\n"); - Graph = trimMitigatedEdges(std::move(Graph)); - LLVM_DEBUG(dbgs() << "Eliminating mitigated paths... Done\n"); - } - + // If `MF` does not have any fences, then no gadgets would have been + // mitigated at this point. + if (Graph->NumFences > 0) { + LLVM_DEBUG(dbgs() << "Eliminating mitigated paths...\n"); + Graph = trimMitigatedEdges(std::move(Graph)); + LLVM_DEBUG(dbgs() << "Eliminating mitigated paths... Done\n"); + } + if (Graph->NumGadgets == 0) return 0; LLVM_DEBUG(dbgs() << "Cutting edges...\n"); - EdgeSet CutEdges{*Graph}; - - // Begin by collecting all ingress CFG edges for each node - DenseMap<const Node *, SmallVector<const Edge *, 2>> IngressEdgeMap; - for (const Edge &E : Graph->edges()) - if (MachineGadgetGraph::isCFGEdge(E)) - IngressEdgeMap[E.getDest()].push_back(&E); - - // For each gadget edge, make cuts that guarantee the gadget will be - // mitigated. A computationally efficient way to achieve this is to either: - // (a) cut all egress CFG edges from the gadget source, or - // (b) cut all ingress CFG edges to the gadget sink. - // - // Moreover, the algorithm tries not to make a cut into a loop by preferring - // to make a (b)-type cut if the gadget source resides at a greater loop depth - // than the gadget sink, or an (a)-type cut otherwise. - for (const Node &N : Graph->nodes()) { - for (const Edge &E : N.edges()) { - if (!MachineGadgetGraph::isGadgetEdge(E)) + EdgeSet CutEdges{*Graph}; + + // Begin by collecting all ingress CFG edges for each node + DenseMap<const Node *, SmallVector<const Edge *, 2>> IngressEdgeMap; + for (const Edge &E : Graph->edges()) + if (MachineGadgetGraph::isCFGEdge(E)) + IngressEdgeMap[E.getDest()].push_back(&E); + + // For each gadget edge, make cuts that guarantee the gadget will be + // mitigated. A computationally efficient way to achieve this is to either: + // (a) cut all egress CFG edges from the gadget source, or + // (b) cut all ingress CFG edges to the gadget sink. + // + // Moreover, the algorithm tries not to make a cut into a loop by preferring + // to make a (b)-type cut if the gadget source resides at a greater loop depth + // than the gadget sink, or an (a)-type cut otherwise. + for (const Node &N : Graph->nodes()) { + for (const Edge &E : N.edges()) { + if (!MachineGadgetGraph::isGadgetEdge(E)) continue; - SmallVector<const Edge *, 2> EgressEdges; - SmallVector<const Edge *, 2> &IngressEdges = IngressEdgeMap[E.getDest()]; - for (const Edge &EgressEdge : N.edges()) - if (MachineGadgetGraph::isCFGEdge(EgressEdge)) - EgressEdges.push_back(&EgressEdge); - - int EgressCutCost = 0, IngressCutCost = 0; - for (const Edge *EgressEdge : EgressEdges) - if (!CutEdges.contains(*EgressEdge)) - EgressCutCost += EgressEdge->getValue(); - for (const Edge *IngressEdge : IngressEdges) - if (!CutEdges.contains(*IngressEdge)) - IngressCutCost += IngressEdge->getValue(); - - auto &EdgesToCut = - IngressCutCost < EgressCutCost ? IngressEdges : EgressEdges; - for (const Edge *E : EdgesToCut) - CutEdges.insert(*E); + SmallVector<const Edge *, 2> EgressEdges; + SmallVector<const Edge *, 2> &IngressEdges = IngressEdgeMap[E.getDest()]; + for (const Edge &EgressEdge : N.edges()) + if (MachineGadgetGraph::isCFGEdge(EgressEdge)) + EgressEdges.push_back(&EgressEdge); + + int EgressCutCost = 0, IngressCutCost = 0; + for (const Edge *EgressEdge : EgressEdges) + if (!CutEdges.contains(*EgressEdge)) + EgressCutCost += EgressEdge->getValue(); + for (const Edge *IngressEdge : IngressEdges) + if (!CutEdges.contains(*IngressEdge)) + IngressCutCost += IngressEdge->getValue(); + + auto &EdgesToCut = + IngressCutCost < EgressCutCost ? IngressEdges : EgressEdges; + for (const Edge *E : EdgesToCut) + CutEdges.insert(*E); } - } + } LLVM_DEBUG(dbgs() << "Cutting edges... Done\n"); LLVM_DEBUG(dbgs() << "Cut " << CutEdges.count() << " edges\n"); @@ -726,8 +726,8 @@ int X86LoadValueInjectionLoadHardeningPass::insertFences( MachineFunction &MF, MachineGadgetGraph &G, EdgeSet &CutEdges /* in, out */) const { int FencesInserted = 0; - for (const Node &N : G.nodes()) { - for (const Edge &E : N.edges()) { + for (const Node &N : G.nodes()) { + for (const Edge &E : N.edges()) { if (CutEdges.contains(E)) { MachineInstr *MI = N.getValue(), *Prev; MachineBasicBlock *MBB; // Insert an LFENCE in this MBB @@ -743,7 +743,7 @@ int X86LoadValueInjectionLoadHardeningPass::insertFences( Prev = MI->getPrevNode(); // Remove all egress CFG edges from this branch because the inserted // LFENCE prevents gadgets from crossing the branch. - for (const Edge &E : N.edges()) { + for (const Edge &E : N.edges()) { if (MachineGadgetGraph::isCFGEdge(E)) CutEdges.insert(E); } |