//===------ WindowsHotPatch.cpp - Support for Windows hotpatching ---------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Provides support for the Windows "Secure Hot-Patching" feature.
//
// Windows contains technology, called "Secure Hot-Patching" (SHP), for securely
// applying hot-patches to a running system. Hot-patches may be applied to the
// kernel, kernel-mode components, device drivers, user-mode system services,
// etc.
//
// SHP relies on integration between many tools, including compiler, linker,
// hot-patch generation tools, and the Windows kernel. This file implements that
// part of the workflow needed in compilers / code generators.
//
// SHP is not intended for productivity scenarios such as Edit-and-Continue or
// interactive development. SHP is intended to minimize downtime during
// installation of Windows OS patches.
//
// In order to work with SHP, LLVM must do all of the following:
//
// * On some architectures (X86, AMD64), the function prolog must begin with
//   hot-patchable instructions. This is handled by the MSVC `/hotpatch` option
//   and the equivalent `-fms-hotpatch` function. This is necessary because we
//   generally cannot anticipate which functions will need to be patched in the
//   future. This option ensures that a function can be hot-patched in the
//   future, but does not actually generate any hot-patch for it.
//
// * For a selected set of functions that are being hot-patched (which are
//   identified using command-line options), LLVM must generate the
//   `S_HOTPATCHFUNC` CodeView record (symbol). This record indicates that a
//   function was compiled with hot-patching enabled.
//
//   This implementation uses the `MarkedForWindowsHotPatching` attribute to
//   annotate those functions that were marked for hot-patching by command-line
//   parameters. The attribute may be specified by a language front-end by
//   setting an attribute when a function is created in LLVM IR, or it may be
//   set by passing LLVM arguments.
//
// * For those functions that are hot-patched, LLVM must rewrite references to
//   global variables so that they are indirected through a `__ref_*` pointer
//   variable.  For each global variable, that is accessed by a hot-patched
//   function, e.g. `FOO`, a `__ref_FOO` global pointer variable is created and
//   all references to the original `FOO` are rewritten as dereferences of the
//   `__ref_FOO` pointer.
//
//   Some globals do not need `__ref_*` indirection. The pointer indirection
//   behavior can be disabled for these globals by marking them with the
//   `AllowDirectAccessInHotPatchFunction`.
//
// Rewriting references to global variables has some complexity.
//
// For ordinary instructions that reference GlobalVariables, we rewrite the
// operand of the instruction to a Load of the __ref_* variable.
//
// For constant expressions, we have to convert the constant expression (and
// transitively all constant expressions in its parent chain) to non-constant
// expressions, i.e. to a sequence of instructions.
//
// Pass 1:
//   * Enumerate all instructions in all basic blocks.
//
//   * If an instruction references a GlobalVariable (and it is not marked
//     as being ignored), then we create (if necessary) the __ref_* variable
//     for the GlobalVariable reference. However, we do not yet modify the
//     Instruction.
//
//   * If an instruction has an operand that is a ConstantExpr and the
//     ConstantExpression tree contains a reference to a GlobalVariable, then
//     we similarly create __ref_*. Similarly, we do not yet modify the
//     Instruction or the ConstantExpr tree.
//
// After Pass 1 completes, we will know whether we found any references to
// globals in this pass.  If the function does not use any globals (and most
// functions do not use any globals), then we return immediately.
//
// If a function does reference globals, then we iterate the list of globals
// used by this function and we generate Load instructions for each (unique)
// global.
//
// Next, we do another pass over all instructions:
//
// Pass 2:
//   * Re-visit the instructions that were found in Pass 1.
//
//   * If an instruction operand is a GlobalVariable, then look up the
//   replacement
//     __ref_* global variable and the Value that came from the Load instruction
//     for it.  Replace the operand of the GlobalVariable with the Load Value.
//
//   * If an instruction operand is a ConstantExpr, then recursively examine the
//     operands of all instructions in the ConstantExpr tree.  If an operand is
//     a GlobalVariable, then replace the operand with the result of the load
//     *and* convert the ConstantExpr to a non-constant instruction.  This
//     instruction will need to be inserted into the BB of the instruction whose
//     operand is being modified, ideally immediately before the instruction
//     being modified.
//
// Limitations
//
// This feature is not intended to work in every situation. There are many
// legitimate code changes (patches) for which it is not possible to generate
// a hot-patch. Developers who are writing hot-patches are expected to
// understand the limitations.
//
// Tools which generate hot-patch metadata may also check that certain
// variables are upheld, and some of these invariants may be global (may require
// whole-program knowledge, not available in any single compiland). However,
// such tools are not required to be perfect; they are also best-effort.
//
// For these reasons, the hot-patching support implemented in this file is
// "best effort". It does not recognize every possible code pattern that could
// be patched, nor does it generate diagnostics for certain code patterns that
// could result in a binary that does not work with hot-patching. For example,
// const GlobalVariables that point to other non-const GlobalVariables are not
// compatible with hot-patching because they cannot use __ref_*-based
// redirection.
//
// References
//
// * "Hotpatching on Windows":
//   https://techcommunity.microsoft.com/blog/windowsosplatform/hotpatching-on-windows/2959541
//
// * "Hotpatch for Windows client now available":
//   https://techcommunity.microsoft.com/blog/windows-itpro-blog/hotpatch-for-windows-client-now-available/4399808
//
// * "Get hotpatching for Windows Server":
//   https://www.microsoft.com/en-us/windows-server/blog/2025/04/24/tired-of-all-the-restarts-get-hotpatching-for-windows-server/
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/SmallSet.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Module.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/MemoryBuffer.h"

using namespace llvm;

#define DEBUG_TYPE "windows-secure-hot-patch"

// A file containing list of mangled function names to mark for hot patching.
static cl::opt<std::string> LLVMMSSecureHotPatchFunctionsFile(
    "ms-secure-hotpatch-functions-file", cl::value_desc("filename"),
    cl::desc("A file containing list of mangled function names to mark for "
             "Windows Secure Hot-Patching"));

// A list of mangled function names to mark for hot patching.
static cl::list<std::string> LLVMMSSecureHotPatchFunctionsList(
    "ms-secure-hotpatch-functions-list", cl::value_desc("list"),
    cl::desc("A list of mangled function names to mark for Windows Secure "
             "Hot-Patching"),
    cl::CommaSeparated);

namespace {

struct GlobalVariableUse {
  // GlobalVariable *GV;
  Instruction *User;
  unsigned Op;
};

class WindowsSecureHotPatching : public ModulePass {
public:
  static char ID;

  WindowsSecureHotPatching() : ModulePass(ID) {}

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.setPreservesCFG();
  }

  bool doInitialization(Module &) override;
  bool runOnModule(Module &M) override { return false; }

private:
  bool
  runOnFunction(Function &F,
                SmallDenseMap<GlobalVariable *, GlobalVariable *> &RefMapping);
};

} // end anonymous namespace

char WindowsSecureHotPatching::ID = 0;

INITIALIZE_PASS(WindowsSecureHotPatching, "windows-secure-hot-patch",
                "Mark functions for Windows hot patch support", false, false)
ModulePass *llvm::createWindowsSecureHotPatchingPass() {
  return new WindowsSecureHotPatching();
}

// Find functions marked with Attribute::MarkedForWindowsHotPatching and modify
// their code (if necessary) to account for accesses to global variables.
//
// This runs during doInitialization() instead of runOnModule() because it needs
// to run before CodeViewDebug::collectGlobalVariableInfo().
bool WindowsSecureHotPatching::doInitialization(Module &M) {
  // The front end may have already marked functions for hot-patching. However,
  // we also allow marking functions by passing -ms-hotpatch-functions-file or
  // -ms-hotpatch-functions-list directly to LLVM. This allows hot-patching to
  // work with languages that have not yet updated their front-ends.
  if (!LLVMMSSecureHotPatchFunctionsFile.empty() ||
      !LLVMMSSecureHotPatchFunctionsList.empty()) {
    std::vector<std::string> HotPatchFunctionsList;

    if (!LLVMMSSecureHotPatchFunctionsFile.empty()) {
      auto BufOrErr = MemoryBuffer::getFile(LLVMMSSecureHotPatchFunctionsFile);
      if (BufOrErr) {
        const MemoryBuffer &FileBuffer = **BufOrErr;
        for (line_iterator I(FileBuffer.getMemBufferRef(), true), E; I != E;
             ++I)
          HotPatchFunctionsList.push_back(std::string{*I});
      } else {
        M.getContext().diagnose(DiagnosticInfoGeneric{
            Twine("failed to open hotpatch functions file "
                  "(--ms-hotpatch-functions-file): ") +
            LLVMMSSecureHotPatchFunctionsFile + Twine(" : ") +
            BufOrErr.getError().message()});
      }
    }

    if (!LLVMMSSecureHotPatchFunctionsList.empty())
      for (const auto &FuncName : LLVMMSSecureHotPatchFunctionsList)
        HotPatchFunctionsList.push_back(FuncName);

    // Build a set for quick lookups. This points into HotPatchFunctionsList, so
    // HotPatchFunctionsList must live longer than HotPatchFunctionsSet.
    SmallSet<StringRef, 16> HotPatchFunctionsSet;
    for (const auto &FuncName : HotPatchFunctionsList)
      HotPatchFunctionsSet.insert(StringRef{FuncName});

    // Iterate through all of the functions and check whether they need to be
    // marked for hotpatching using the list provided directly to LLVM.
    for (auto &F : M.functions()) {
      // Ignore declarations that are not definitions.
      if (F.isDeclarationForLinker())
        continue;

      if (HotPatchFunctionsSet.contains(F.getName()))
        F.addFnAttr("marked_for_windows_hot_patching");
    }
  }

  SmallDenseMap<GlobalVariable *, GlobalVariable *> RefMapping;
  bool MadeChanges = false;
  for (auto &F : M.functions()) {
    if (F.hasFnAttribute("marked_for_windows_hot_patching")) {
      if (runOnFunction(F, RefMapping))
        MadeChanges = true;
    }
  }
  return MadeChanges;
}

static bool TypeContainsPointers(Type *ty) {
  switch (ty->getTypeID()) {
  case Type::PointerTyID:
    return true;

  case Type::ArrayTyID:
    return TypeContainsPointers(ty->getArrayElementType());

  case Type::StructTyID: {
    unsigned NumElements = ty->getStructNumElements();
    for (unsigned I = 0; I < NumElements; ++I) {
      if (TypeContainsPointers(ty->getStructElementType(I))) {
        return true;
      }
    }
    return false;
  }

  default:
    return false;
  }
}

// Returns true if GV needs redirection through a __ref_* variable.
static bool globalVariableNeedsRedirect(GlobalVariable *GV) {
  // If a global variable is explictly marked as allowing access in hot-patched
  // functions, then do not redirect it.
  if (GV->hasAttribute("allow_direct_access_in_hot_patch_function"))
    return false;

  // If the global variable is not a constant, then we want to redirect it.
  if (!GV->isConstant()) {
    if (GV->getName().starts_with("??_R")) {
      // This is the name mangling prefix that MSVC uses for RTTI data.
      // Clang is currently generating RTTI data that is marked non-constant.
      // We override that and treat it like it is constant.
      return false;
    }

    // In general, if a global variable is not a constant, then redirect it.
    return true;
  }

  // If the type of GV cannot contain pointers, then it cannot point to
  // other global variables. In this case, there is no need for redirects.
  // For example, string literals do not contain pointers.
  return TypeContainsPointers(GV->getValueType());
}

// Get or create a new global variable that points to the old one and whose
// name begins with `__ref_`.
//
// In hot-patched images, the __ref_* variables point to global variables in
// the original (unpatched) image. Hot-patched functions in the hot-patch
// image use these __ref_* variables to access global variables. This ensures
// that all code (both unpatched and patched) is using the same instances of
// global variables.
//
// The Windows hot-patch infrastructure handles modifying these __ref_*
// variables. By default, they are initialized with pointers to the equivalent
// global variables, so when a hot-patch module is loaded *as* a base image
// (such as after a system reboot), hot-patch functions will access the
// instances of global variables that are compiled into the hot-patch image.
// This is the desired outcome, since in this situation (normal boot) the
// hot-patch image *is* the base image.
//
// When we create the GlobalVariable for the __ref_* variable, we must create
// it as a *non-constant* global variable. The __ref_* pointers will not change
// during the runtime of the program, so it is tempting to think that they
// should be constant. However, they still need to be updateable by the
// hot-patching infrastructure. Also, if the GlobalVariable is created as a
// constant, then the LLVM optimizer will assume that it can dereference the
// definition of the __ref_* variable at compile time, which defeats the
// purpose of the indirection (pointer).
//
// The RefMapping table spans the entire module, not just a single function.
static GlobalVariable *getOrCreateRefVariable(
    Function &F, SmallDenseMap<GlobalVariable *, GlobalVariable *> &RefMapping,
    GlobalVariable *GV) {
  GlobalVariable *&ReplaceWithRefGV = RefMapping.try_emplace(GV).first->second;
  if (ReplaceWithRefGV != nullptr) {
    // We have already created a __ref_* pointer for this GlobalVariable.
    return ReplaceWithRefGV;
  }

  Module *M = F.getParent();

  const DISubprogram *Subprogram = F.getSubprogram();
  DICompileUnit *Unit = Subprogram != nullptr ? Subprogram->getUnit() : nullptr;
  DIFile *File = Subprogram != nullptr ? Subprogram->getFile() : nullptr;
  DIBuilder DebugInfo{*F.getParent(), true, Unit};

  auto PtrTy = PointerType::get(M->getContext(), 0);

  GlobalVariable *RefGV =
      new GlobalVariable(*M, PtrTy, false, GlobalValue::LinkOnceAnyLinkage,
                         GV, Twine("__ref_").concat(GV->getName()),
                         nullptr, GlobalVariable::NotThreadLocal);

  // RefGV is created with isConstant = false, but we want to place RefGV into
  // .rdata, not .data.  It is important that the GlobalVariable be mutable
  // from the compiler's point of view, so that the optimizer does not remove
  // the global variable entirely and replace all references to it with its
  // initial value.
  //
  // When the Windows hot-patch loader applies a hot-patch, it maps the
  // pages of .rdata as read/write so that it can set each __ref_* variable
  // to point to the original variable in the base image. Afterward, pages in
  // .rdata are remapped as read-only. This protects the __ref_* variables from
  // being overwritten during execution.
  RefGV->setSection(".rdata");

  // Create debug info for the replacement global variable.
  DataLayout Layout = M->getDataLayout();
  DIType *DebugType = DebugInfo.createPointerType(
      nullptr, Layout.getTypeSizeInBits(GV->getValueType()));
  DIGlobalVariableExpression *GVE = DebugInfo.createGlobalVariableExpression(
      Unit, RefGV->getName(), StringRef{}, File,
      /*LineNo*/ 0, DebugType,
      /*IsLocalToUnit*/ false);
  RefGV->addDebugInfo(GVE);

  // Store the __ref_* in RefMapping so that future calls use the same RefGV.
  ReplaceWithRefGV = RefGV;

  return RefGV;
}

// Given a ConstantExpr, this searches for GlobalVariable references within
// the expression tree.  If found, it will generate instructions and will
// return a non-null Value* that points to the new root instruction.
//
// If C does not contain any GlobalVariable references, this returns nullptr.
//
// If this function creates new instructions, then it will insert them
// before InsertionPoint.
static Value *rewriteGlobalVariablesInConstant(
    Constant *C, SmallDenseMap<GlobalVariable *, Value *> &GVLoadMap,
    IRBuilder<> &IRBuilderAtEntry) {
  if (C->getValueID() == Value::GlobalVariableVal) {
    GlobalVariable *GV = cast<GlobalVariable>(C);
    if (globalVariableNeedsRedirect(GV)) {
      return GVLoadMap.at(GV);
    } else {
      return nullptr;
    }
  }

  // Scan the operands of this expression.

  SmallVector<Value *, 8> ReplacedValues;
  bool ReplacedAnyOperands = false;

  unsigned NumOperands = C->getNumOperands();
  for (unsigned OpIndex = 0; OpIndex < NumOperands; ++OpIndex) {
    Value *OldValue = C->getOperand(OpIndex);
    Value *ReplacedValue = nullptr;
    if (Constant *OldConstant = dyn_cast<Constant>(OldValue)) {
      ReplacedValue = rewriteGlobalVariablesInConstant(OldConstant, GVLoadMap,
                                                       IRBuilderAtEntry);
    }
    // Do not use short-circuiting, here. We need to traverse the whole tree.
    ReplacedAnyOperands |= ReplacedValue != nullptr;
    ReplacedValues.push_back(ReplacedValue);
  }

  // If none of our operands were replaced, then don't rewrite this expression.
  if (!ReplacedAnyOperands) {
    return nullptr;
  }

  // We need to rewrite this expression. Convert this constant expression
  // to an instruction, then replace any operands as needed.
  Instruction *NewInst = cast<ConstantExpr>(C)->getAsInstruction();
  for (unsigned OpIndex = 0; OpIndex < NumOperands; ++OpIndex) {
    Value *ReplacedValue = ReplacedValues[OpIndex];
    if (ReplacedValue != nullptr) {
      NewInst->setOperand(OpIndex, ReplacedValue);
    }
  }

  // Insert the new instruction before the reference instruction.
  IRBuilderAtEntry.Insert(NewInst);

  return NewInst;
}

static bool searchConstantExprForGlobalVariables(
    Value *V, SmallDenseMap<GlobalVariable *, Value *> &GVLoadMap,
    SmallVector<GlobalVariableUse> &GVUses) {

  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
    if (globalVariableNeedsRedirect(GV)) {
      GVLoadMap[GV] = nullptr;
      return true;
    } else {
      return false;
    }
  }

  if (User *U = dyn_cast<User>(V)) {
    unsigned NumOperands = U->getNumOperands();
    bool FoundAny = false;
    for (unsigned OpIndex = 0; OpIndex < NumOperands; ++OpIndex) {
      Value *Op = U->getOperand(OpIndex);
      // Do not use short-circuiting, here. We need to traverse the whole tree.
      FoundAny |= searchConstantExprForGlobalVariables(Op, GVLoadMap, GVUses);
    }
    return FoundAny;
  } else {
    return false;
  }
}

// Processes a function that is marked for hot-patching.
//
// If a function is marked for hot-patching, we generate an S_HOTPATCHFUNC
// CodeView debug symbol. Tools that generate hot-patches look for
// S_HOTPATCHFUNC in final PDBs so that they can find functions that have been
// hot-patched and so that they can distinguish hot-patched functions from
// non-hot-patched functions.
//
// Also, in functions that are hot-patched, we must indirect all access to
// (mutable) global variables through a pointer. This pointer may point into the
// unpatched ("base") binary or may point into the patched image, depending on
// whether a hot-patch was loaded as a patch or as a base image.  These
// indirections go through a new global variable, named `__ref_<Foo>` where
// `<Foo>` is the original symbol name of the global variable.
//
// This function handles rewriting accesses to global variables, but the
// generation of S_HOTPATCHFUNC occurs in
// CodeViewDebug::emitHotPatchInformation().
//
// Returns true if any global variable references were found and rewritten.
bool WindowsSecureHotPatching::runOnFunction(
    Function &F,
    SmallDenseMap<GlobalVariable *, GlobalVariable *> &RefMapping) {
  // Scan the function for references to global variables. If we find such a
  // reference, create (if necessary) the __ref_* variable, then add an entry
  // to the GVUses table.
  //
  // We ignore references to global variables if the variable is marked with
  // AllowDirectAccessInHotPatchFunction.

  SmallDenseMap<GlobalVariable *, Value *> GVLoadMap;
  SmallVector<GlobalVariableUse> GVUses;

  for (auto &I : instructions(F)) {
    unsigned NumOperands = I.getNumOperands();
    for (unsigned OpIndex = 0; OpIndex < NumOperands; ++OpIndex) {
      Value *V = I.getOperand(OpIndex);

      bool FoundAnyGVUses = false;

      switch (V->getValueID()) {
      case Value::GlobalVariableVal: {
        // Discover all uses of GlobalVariable, these will need to be replaced.
        GlobalVariable *GV = cast<GlobalVariable>(V);
        if (globalVariableNeedsRedirect(GV)) {
          GVLoadMap.insert(std::make_pair(GV, nullptr));
          FoundAnyGVUses = true;
        }
        break;
      }

      case Value::ConstantExprVal: {
        ConstantExpr *CE = cast<ConstantExpr>(V);
        if (searchConstantExprForGlobalVariables(CE, GVLoadMap, GVUses)) {
          FoundAnyGVUses = true;
        }
        break;
      }

      default:
        break;
      }

      if (FoundAnyGVUses) {
        GVUses.push_back(GlobalVariableUse{&I, OpIndex});
      }
    }
  }

  // If this function did not reference any global variables then we have no
  // work to do. Most functions do not access global variables.
  if (GVUses.empty()) {
    return false;
  }

  // We know that there is at least one instruction that needs to be rewritten.
  // Generate a Load instruction for each unique GlobalVariable used by this
  // function. The Load instructions are inserted at the beginning of the
  // entry block. Since entry blocks cannot contain PHI instructions, there is
  // no need to skip PHI instructions.

  // We use a single IRBuilder for inserting Load instructions as well as the
  // constants that we convert to instructions. Because constants do not
  // depend on any dynamic values (they're constant, after all!), it is safe
  // to move them to the start of entry BB.

  auto &EntryBlock = F.getEntryBlock();
  IRBuilder<> IRBuilderAtEntry(EntryBlock.begin());

  for (auto &[GV, LoadValue] : GVLoadMap) {
    assert(LoadValue == nullptr);
    GlobalVariable *RefGV = getOrCreateRefVariable(F, RefMapping, GV);
    LoadValue = IRBuilderAtEntry.CreateLoad(RefGV->getValueType(), RefGV);
  }

  const DISubprogram *Subprogram = F.getSubprogram();
  DICompileUnit *Unit = Subprogram != nullptr ? Subprogram->getUnit() : nullptr;
  DIBuilder DebugInfo{*F.getParent(), true, Unit};

  // Go back to the instructions and rewrite their uses of GlobalVariable.
  // Because a ConstantExpr can be a tree, it may reference more than one
  // GlobalVariable.

  for (auto &GVUse : GVUses) {
    Value *OldOperandValue = GVUse.User->getOperand(GVUse.Op);
    Value *NewOperandValue;

    switch (OldOperandValue->getValueID()) {
    case Value::GlobalVariableVal: {
      // This is easy. Look up the replacement value and store the operand.
      Value *OperandValue = GVUse.User->getOperand(GVUse.Op);
      GlobalVariable *GV = cast<GlobalVariable>(OperandValue);
      NewOperandValue = GVLoadMap.at(GV);
      break;
    }

    case Value::ConstantExprVal: {
      // Walk the recursive tree of the ConstantExpr. If we find a
      // GlobalVariable then replace it with the loaded value and rewrite
      // the ConstantExpr to an Instruction and insert it before the
      // current instruction.
      Value *OperandValue = GVUse.User->getOperand(GVUse.Op);
      ConstantExpr *CE = cast<ConstantExpr>(OperandValue);
      NewOperandValue =
          rewriteGlobalVariablesInConstant(CE, GVLoadMap, IRBuilderAtEntry);
      assert(NewOperandValue != nullptr);
      break;
    }

    default:
      // We should only ever get here because a GVUse was created in the first
      // pass, and this only happens for GlobalVariableVal and ConstantExprVal.
      llvm_unreachable_internal(
          "unexpected Value in second pass of hot-patching");
      break;
    }

    GVUse.User->setOperand(GVUse.Op, NewOperandValue);
  }

  return true;
}
