llvm/llvm/lib/Target/X86/X86SpeculativeExecutionSideEffectSuppression.cpp

//===-- X86SpeculativeExecutionSideEffectSuppression.cpp ------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
///
/// This file contains the X86 implementation of the speculative execution side
/// effect suppression mitigation.
///
/// This must be used with the -mlvi-cfi flag in order to mitigate indirect
/// branches and returns.
//===----------------------------------------------------------------------===//

#include "X86.h"
#include "X86InstrInfo.h"
#include "X86Subtarget.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Pass.h"
#include "llvm/Target/TargetMachine.h"
usingnamespacellvm;

#define DEBUG_TYPE

STATISTIC(NumLFENCEsInserted, "Number of lfence instructions inserted");

static cl::opt<bool> EnableSpeculativeExecutionSideEffectSuppression(
    "x86-seses-enable-without-lvi-cfi",
    cl::desc("Force enable speculative execution side effect suppression. "
             "(Note: User must pass -mlvi-cfi in order to mitigate indirect "
             "branches and returns.)"),
    cl::init(false), cl::Hidden);

static cl::opt<bool> OneLFENCEPerBasicBlock(
    "x86-seses-one-lfence-per-bb",
    cl::desc(
        "Omit all lfences other than the first to be placed in a basic block."),
    cl::init(false), cl::Hidden);

static cl::opt<bool> OnlyLFENCENonConst(
    "x86-seses-only-lfence-non-const",
    cl::desc("Only lfence before groups of terminators where at least one "
             "branch instruction has an input to the addressing mode that is a "
             "register other than %rip."),
    cl::init(false), cl::Hidden);

static cl::opt<bool>
    OmitBranchLFENCEs("x86-seses-omit-branch-lfences",
                      cl::desc("Omit all lfences before branch instructions."),
                      cl::init(false), cl::Hidden);

namespace {

class X86SpeculativeExecutionSideEffectSuppression
    : public MachineFunctionPass {};
} // namespace

char X86SpeculativeExecutionSideEffectSuppression::ID =;

// This function returns whether the passed instruction uses a memory addressing
// mode that is constant. We treat all memory addressing modes that read
// from a register that is not %rip as non-constant. Note that the use
// of the EFLAGS register results in an addressing mode being considered
// non-constant, therefore all JCC instructions will return false from this
// function since one of their operands will always be the EFLAGS register.
static bool hasConstantAddressingMode(const MachineInstr &MI) {}

bool X86SpeculativeExecutionSideEffectSuppression::runOnMachineFunction(
    MachineFunction &MF) {}

FunctionPass *llvm::createX86SpeculativeExecutionSideEffectSuppression() {}

INITIALIZE_PASS()