[clang] [llvm] Revert "Add support for Windows Secure Hot-Patching" (PR #145553)

Qinkun Bao via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 24 10:11:49 PDT 2025


https://github.com/qinkunbao created https://github.com/llvm/llvm-project/pull/145553

Reverts llvm/llvm-project#138972

>From 661839d189f825fbb6305e6ac5d8d1cc19ccc42e Mon Sep 17 00:00:00 2001
From: Qinkun Bao <qinkun at google.com>
Date: Tue, 24 Jun 2025 13:11:32 -0400
Subject: [PATCH] Revert "Add support for Windows Secure Hot-Patching
 (#138972)"

This reverts commit 26d318e4a9437f95b6a2e7abace5f2b867c88a3e.
---
 clang/include/clang/Basic/CodeGenOptions.h    |   7 -
 clang/include/clang/Driver/Options.td         |  18 -
 clang/lib/CodeGen/CGCall.cpp                  |   7 -
 clang/lib/CodeGen/CodeGenModule.cpp           |  29 -
 clang/lib/CodeGen/CodeGenModule.h             |   5 -
 clang/lib/Driver/ToolChains/Clang.cpp         |   8 -
 .../CodeGen/X86/ms-secure-hotpatch-bad-file.c |  18 -
 .../CodeGen/X86/ms-secure-hotpatch-cpp.cpp    |  24 -
 .../CodeGen/X86/ms-secure-hotpatch-eh.cpp     |  26 -
 .../CodeGen/X86/ms-secure-hotpatch-globals.c  | 135 ----
 .../test/CodeGen/X86/ms-secure-hotpatch-lto.c |  26 -
 clang/test/CodeGen/X86/ms-secure-hotpatch.c   |  23 -
 llvm/include/llvm/CodeGen/Passes.h            |   3 -
 .../DebugInfo/CodeView/CodeViewSymbols.def    |   2 -
 .../llvm/DebugInfo/CodeView/SymbolRecord.h    |  15 -
 llvm/include/llvm/IR/Attributes.td            |  10 -
 llvm/include/llvm/InitializePasses.h          |   1 -
 llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp |  24 -
 llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h   |   2 -
 llvm/lib/CodeGen/CMakeLists.txt               |   1 -
 llvm/lib/CodeGen/TargetPassConfig.cpp         |   3 -
 llvm/lib/CodeGen/WindowsSecureHotPatching.cpp | 617 ------------------
 llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp  |   7 -
 .../CodeView/SymbolRecordMapping.cpp          |   7 -
 llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp   |   5 -
 .../CodeGen/X86/ms-secure-hotpatch-attr.ll    |  38 --
 .../X86/ms-secure-hotpatch-bad-file.ll        |  16 -
 ...ms-secure-hotpatch-direct-global-access.ll |  39 --
 .../X86/ms-secure-hotpatch-functions-file.ll  |  39 --
 .../X86/ms-secure-hotpatch-functions-list.ll  |  38 --
 .../llvm-pdbutil/MinimalSymbolDumper.cpp      |   8 -
 31 files changed, 1201 deletions(-)
 delete mode 100644 clang/test/CodeGen/X86/ms-secure-hotpatch-bad-file.c
 delete mode 100644 clang/test/CodeGen/X86/ms-secure-hotpatch-cpp.cpp
 delete mode 100644 clang/test/CodeGen/X86/ms-secure-hotpatch-eh.cpp
 delete mode 100644 clang/test/CodeGen/X86/ms-secure-hotpatch-globals.c
 delete mode 100644 clang/test/CodeGen/X86/ms-secure-hotpatch-lto.c
 delete mode 100644 clang/test/CodeGen/X86/ms-secure-hotpatch.c
 delete mode 100644 llvm/lib/CodeGen/WindowsSecureHotPatching.cpp
 delete mode 100644 llvm/test/CodeGen/X86/ms-secure-hotpatch-attr.ll
 delete mode 100644 llvm/test/CodeGen/X86/ms-secure-hotpatch-bad-file.ll
 delete mode 100644 llvm/test/CodeGen/X86/ms-secure-hotpatch-direct-global-access.ll
 delete mode 100644 llvm/test/CodeGen/X86/ms-secure-hotpatch-functions-file.ll
 delete mode 100644 llvm/test/CodeGen/X86/ms-secure-hotpatch-functions-list.ll

diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index 77a0c559f7689..7ba21fca6dd6b 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -495,13 +495,6 @@ class CodeGenOptions : public CodeGenOptionsBase {
 
   /// A list of functions that are replacable by the loader.
   std::vector<std::string> LoaderReplaceableFunctionNames;
-  /// The name of a file that contains functions which will be compiled for
-  /// hotpatching. See -fms-secure-hotpatch-functions-file.
-  std::string MSSecureHotPatchFunctionsFile;
-
-  /// A list of functions which will be compiled for hotpatching.
-  /// See -fms-secure-hotpatch-functions-list.
-  std::vector<std::string> MSSecureHotPatchFunctionsList;
 
 public:
   // Define accessors/mutators for code generation options of enumeration type.
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 26e953f7ac613..4f91b82a3bfa6 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3838,24 +3838,6 @@ def fms_hotpatch : Flag<["-"], "fms-hotpatch">, Group<f_Group>,
   Visibility<[ClangOption, CC1Option, CLOption]>,
   HelpText<"Ensure that all functions can be hotpatched at runtime">,
   MarshallingInfoFlag<CodeGenOpts<"HotPatch">>;
-
-// See llvm/lib/CodeGen/WindowsSecureHotPatching.cpp
-def fms_secure_hotpatch_functions_file
-    : Joined<["-"], "fms-secure-hotpatch-functions-file=">,
-      Group<f_Group>,
-      Visibility<[ClangOption, CC1Option, CLOption]>,
-      MarshallingInfoString<CodeGenOpts<"MSSecureHotPatchFunctionsFile">>,
-      HelpText<"Path to a file that contains a list of mangled names of "
-               "functions that should be hot-patched for Windows Secure "
-               "Hot-Patching">;
-def fms_secure_hotpatch_functions_list
-    : CommaJoined<["-"], "fms-secure-hotpatch-functions-list=">,
-      Group<f_Group>,
-      Visibility<[ClangOption, CC1Option, CLOption]>,
-      MarshallingInfoStringVector<CodeGenOpts<"MSSecureHotPatchFunctionsList">>,
-      HelpText<"List of mangled symbol names of functions that should be "
-               "hot-patched for Windows Secure Hot-Patching">;
-
 def fpcc_struct_return : Flag<["-"], "fpcc-struct-return">, Group<f_Group>,
   Visibility<[ClangOption, CC1Option]>,
   HelpText<"Override the default ABI to return all structs on the stack">;
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index c8c3d6b20c496..fd75de42515da 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -2660,13 +2660,6 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
     // CPU/feature overrides.  addDefaultFunctionDefinitionAttributes
     // handles these separately to set them based on the global defaults.
     GetCPUAndFeaturesAttributes(CalleeInfo.getCalleeDecl(), FuncAttrs);
-
-    // Windows hotpatching support
-    if (!MSHotPatchFunctions.empty()) {
-      bool IsHotPatched = llvm::binary_search(MSHotPatchFunctions, Name);
-      if (IsHotPatched)
-        FuncAttrs.addAttribute("marked_for_windows_hot_patching");
-    }
   }
 
   // Mark functions that are replaceable by the loader.
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 96fdab212beb1..16688810d0685 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -458,35 +458,6 @@ CodeGenModule::CodeGenModule(ASTContext &C,
   if (Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
     getModule().addModuleFlag(llvm::Module::Error, "NumRegisterParameters",
                               CodeGenOpts.NumRegisterParameters);
-
-  // If there are any functions that are marked for Windows secure hot-patching,
-  // then build the list of functions now.
-  if (!CGO.MSSecureHotPatchFunctionsFile.empty() ||
-      !CGO.MSSecureHotPatchFunctionsList.empty()) {
-    if (!CGO.MSSecureHotPatchFunctionsFile.empty()) {
-      auto BufOrErr =
-          llvm::MemoryBuffer::getFile(CGO.MSSecureHotPatchFunctionsFile);
-      if (BufOrErr) {
-        const llvm::MemoryBuffer &FileBuffer = **BufOrErr;
-        for (llvm::line_iterator I(FileBuffer.getMemBufferRef(), true), E;
-             I != E; ++I)
-          this->MSHotPatchFunctions.push_back(std::string{*I});
-      } else {
-        auto &DE = Context.getDiagnostics();
-        unsigned DiagID =
-            DE.getCustomDiagID(DiagnosticsEngine::Error,
-                               "failed to open hotpatch functions file "
-                               "(-fms-hotpatch-functions-file): %0 : %1");
-        DE.Report(DiagID) << CGO.MSSecureHotPatchFunctionsFile
-                          << BufOrErr.getError().message();
-      }
-    }
-
-    for (const auto &FuncName : CGO.MSSecureHotPatchFunctionsList)
-      this->MSHotPatchFunctions.push_back(FuncName);
-
-    llvm::sort(this->MSHotPatchFunctions);
-  }
 }
 
 CodeGenModule::~CodeGenModule() {}
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index cb013feb769fc..1b67d4354efc0 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -678,11 +678,6 @@ class CodeGenModule : public CodeGenTypeCache {
 
   AtomicOptions AtomicOpts;
 
-  // A set of functions which should be hot-patched; see
-  // -fms-hotpatch-functions-file (and -list). This will nearly always be empty.
-  // The list is sorted for binary-searching.
-  std::vector<std::string> MSHotPatchFunctions;
-
 public:
   CodeGenModule(ASTContext &C, IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
                 const HeaderSearchOptions &headersearchopts,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index be9c1c466fbfb..87d04a42fcd70 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6803,14 +6803,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
 
   Args.AddLastArg(CmdArgs, options::OPT_fms_hotpatch);
 
-  if (Arg *A = Args.getLastArg(options::OPT_fms_secure_hotpatch_functions_file))
-    Args.AddLastArg(CmdArgs, options::OPT_fms_secure_hotpatch_functions_file);
-
-  for (const auto &A :
-       Args.getAllArgValues(options::OPT_fms_secure_hotpatch_functions_list))
-    CmdArgs.push_back(
-        Args.MakeArgString("-fms-secure-hotpatch-functions-list=" + Twine(A)));
-
   if (TC.SupportsProfiling()) {
     Args.AddLastArg(CmdArgs, options::OPT_pg);
 
diff --git a/clang/test/CodeGen/X86/ms-secure-hotpatch-bad-file.c b/clang/test/CodeGen/X86/ms-secure-hotpatch-bad-file.c
deleted file mode 100644
index 839dd44f7ff61..0000000000000
--- a/clang/test/CodeGen/X86/ms-secure-hotpatch-bad-file.c
+++ /dev/null
@@ -1,18 +0,0 @@
-// REQUIRES: x86-registered-target
-
-// This verifies that we correctly handle a -fms-secure-hotpatch-functions-file argument that points
-// to a missing file.
-//
-// RUN: not %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 -fms-secure-hotpatch-functions-file=%S/this-file-is-intentionally-missing-do-not-create-it.txt /Fo%t.obj %s 2>&1 | FileCheck %s
-// CHECK: failed to open hotpatch functions file
-
-void this_might_have_side_effects();
-
-int __declspec(noinline) this_gets_hotpatched() {
-    this_might_have_side_effects();
-    return 42;
-}
-
-int __declspec(noinline) this_does_not_get_hotpatched() {
-    return this_gets_hotpatched() + 100;
-}
diff --git a/clang/test/CodeGen/X86/ms-secure-hotpatch-cpp.cpp b/clang/test/CodeGen/X86/ms-secure-hotpatch-cpp.cpp
deleted file mode 100644
index 3dc75c95d76f7..0000000000000
--- a/clang/test/CodeGen/X86/ms-secure-hotpatch-cpp.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-// REQUIRES: x86-registered-target
-
-// This verifies that hotpatch function attributes are correctly propagated when compiling directly to OBJ,
-// and that name mangling works as expected.
-//
-// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 -fms-secure-hotpatch-functions-list=?this_gets_hotpatched@@YAHXZ /Fo%t.obj %s
-// RUN: llvm-readobj --codeview %t.obj | FileCheck %s
-
-void this_might_have_side_effects();
-
-int __declspec(noinline) this_gets_hotpatched() {
-    this_might_have_side_effects();
-    return 42;
-}
-
-// CHECK: Kind: S_HOTPATCHFUNC (0x1169)
-// CHECK-NEXT: Function: this_gets_hotpatched
-// CHECK-NEXT: Name: ?this_gets_hotpatched@@YAHXZ
-
-extern "C" int __declspec(noinline) this_does_not_get_hotpatched() {
-    return this_gets_hotpatched() + 100;
-}
-
-// CHECK-NOT: S_HOTPATCHFUNC
diff --git a/clang/test/CodeGen/X86/ms-secure-hotpatch-eh.cpp b/clang/test/CodeGen/X86/ms-secure-hotpatch-eh.cpp
deleted file mode 100644
index 69704626c8cb6..0000000000000
--- a/clang/test/CodeGen/X86/ms-secure-hotpatch-eh.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-// REQUIRES: x86-registered-target
-
-// Global constant data such as exception handler tables should not be redirected by Windows Secure Hot-Patching
-//
-// RUN: %clang_cl -c --target=x86_64-windows-msvc /EHsc -O2 -fms-secure-hotpatch-functions-list=this_gets_hotpatched /Fo%t.obj /clang:-S /clang:-o- %s 2>& 1 | FileCheck %s
-
-class Foo {
-public:
-    int x;
-};
-
-void this_might_throw();
-
-extern "C" int this_gets_hotpatched(int k) {
-    int ret;
-    try {
-        this_might_throw();
-        ret = 1;
-    } catch (Foo& f) {
-        ret = 2;
-    }
-    return ret;
-}
-
-// We expect that RTTI data is not redirected.
-// CHECK-NOT: "__ref_??_R0?AVFoo@@@8"
diff --git a/clang/test/CodeGen/X86/ms-secure-hotpatch-globals.c b/clang/test/CodeGen/X86/ms-secure-hotpatch-globals.c
deleted file mode 100644
index d76d2aa6d8acc..0000000000000
--- a/clang/test/CodeGen/X86/ms-secure-hotpatch-globals.c
+++ /dev/null
@@ -1,135 +0,0 @@
-// REQUIRES: x86-registered-target
-
-// This verifies that global variable redirection works correctly when using hotpatching.
-//
-// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 \
-// RUN:   -fms-secure-hotpatch-functions-list=hp1,hp2,hp3,hp4,hp5_phi_ptr_mixed,hp_phi_ptr_both,hp_const_ptr_sub \
-// RUN:   /clang:-S /clang:-o- %s | FileCheck %s
-
-#ifdef __clang__
-#define NO_TAIL __attribute__((disable_tail_calls))
-#else
-#define NO_TAIL
-#endif
-
-extern int g_data[10];
-
-struct SomeData {
-    int x;
-    int y;
-};
-
-const struct SomeData g_this_is_const = { 100, 200 };
-
-struct HasPointers {
-    int* ptr;
-    int x;
-};
-
-extern struct HasPointers g_has_pointers;
-
-void take_data(const void* p);
-
-void do_side_effects();
-void do_other_side_effects();
-
-void hp1() NO_TAIL {
-    take_data(&g_data[5]);
-}
-
-// CHECK: hp1:
-// CHECK: mov rcx, qword ptr [rip + __ref_g_data]
-// CHECK: add rcx, 20
-// CHECK: call take_data
-// CHECK: .seh_endproc
-
-void hp2() NO_TAIL {
-    // We do not expect string literals to be redirected.
-    take_data("hello, world!");
-}
-
-// CHECK: hp2:
-// CHECK: lea rcx, [rip + "??_C at _0O@KJBLMJCB at hello?0?5world?$CB?$AA@"]
-// CHECK: call take_data
-// CHECK: .seh_endproc
-
-void hp3() NO_TAIL {
-    // We do not expect g_this_is_const to be redirected because it is const
-    // and contains no pointers.
-    take_data(&g_this_is_const);
-}
-
-// CHECK: hp3:
-// CHECK: lea rcx, [rip + g_this_is_const]
-// CHECK: call take_data
-// CHECK-NOT: __ref_g_this_is_const
-// CHECK: .seh_endproc
-
-void hp4() NO_TAIL {
-    take_data(&g_has_pointers);
-    // We expect &g_has_pointers to be redirected.
-}
-
-// CHECK: hp4:
-// CHECK: mov rcx, qword ptr [rip + __ref_g_has_pointers]
-// CHECK: call take_data
-// CHECK: .seh_endproc
-
-// This case checks that global variable redirection interacts correctly with PHI nodes.
-// The IR for this generates a "phi ptr g_has_pointers, g_this_is_const" node.
-// We expect g_has_pointers to be redirected, but not g_this_is_const.
-void hp5_phi_ptr_mixed(int x) NO_TAIL {
-    const void* y;
-    if (x) {
-        y = &g_has_pointers;
-        do_side_effects();
-    } else {
-        y = &g_this_is_const;
-        do_other_side_effects();
-    }
-    take_data(y);
-}
-
-// CHECK: hp5_phi_ptr_mixed
-// CHECK: .seh_endprologue
-// CHECK: test ecx, ecx
-// CHECK: mov rsi, qword ptr [rip + __ref_g_has_pointers]
-// CHECK: call do_side_effects
-// CHECK: jmp
-// CHECK: call do_other_side_effects
-// CHECK: lea rsi, [rip + g_this_is_const]
-// CHECK: mov rcx, rsi
-// CHECK: call take_data
-// CHECK: .seh_endproc
-
-// This case tests that global variable redirection interacts correctly with PHI nodes,
-// where two (all) operands of a given PHI node are globabl variables that redirect.
-void hp_phi_ptr_both(int x) NO_TAIL {
-    const void* y;
-    if (x) {
-        y = &g_has_pointers;
-        do_side_effects();
-    } else {
-        y = &g_data[5];
-        do_other_side_effects();
-    }
-    take_data(y);
-}
-
-// CHECK: hp_phi_ptr_both:
-// CHECK: .seh_endprologue
-// CHECK: test ecx, ecx
-// CHECK: mov rsi, qword ptr [rip + __ref_g_has_pointers]
-// CHECK: mov rsi, qword ptr [rip + __ref_g_data]
-// CHECK: take_data
-// CHECK: .seh_endproc
-
-// Test a constant expression which references global variable addresses.
-size_t hp_const_ptr_sub() NO_TAIL {
-    return (unsigned char*)&g_has_pointers - (unsigned char*)&g_data;
-}
-
-// CHECK: hp_const_ptr_sub:
-// CHECK: mov rax, qword ptr [rip + __ref_g_has_pointers]
-// CHECK: sub rax, qword ptr [rip + __ref_g_data]
-// CHECK: ret
diff --git a/clang/test/CodeGen/X86/ms-secure-hotpatch-lto.c b/clang/test/CodeGen/X86/ms-secure-hotpatch-lto.c
deleted file mode 100644
index 6adb0b1818e31..0000000000000
--- a/clang/test/CodeGen/X86/ms-secure-hotpatch-lto.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// REQUIRES: x86-registered-target
-
-// This verifies that hotpatch function attributes are correctly propagated through LLVM IR when compiling with LTO.
-//
-// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 -fms-secure-hotpatch-functions-list=this_gets_hotpatched -flto /Fo%t.bc %s
-// RUN: llvm-dis %t.bc -o - | FileCheck %s
-//
-// CHECK-LABEL: define dso_local noundef i32 @this_gets_hotpatched()
-// CHECK-SAME: #0
-//
-// CHECK-LABEL: define dso_local noundef i32 @this_does_not_get_hotpatched()
-// CHECK-SAME: #1
-
-// CHECK: attributes #0
-// CHECK-SAME: "marked_for_windows_hot_patching"
-
-// CHECK: attributes #1
-// CHECK-NOT: "marked_for_windows_hot_patching"
-
-int __declspec(noinline) this_gets_hotpatched() {
-    return 42;
-}
-
-int __declspec(noinline) this_does_not_get_hotpatched() {
-    return this_gets_hotpatched() + 100;
-}
diff --git a/clang/test/CodeGen/X86/ms-secure-hotpatch.c b/clang/test/CodeGen/X86/ms-secure-hotpatch.c
deleted file mode 100644
index b829e5acc5c83..0000000000000
--- a/clang/test/CodeGen/X86/ms-secure-hotpatch.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// REQUIRES: x86-registered-target
-
-// This verifies that hotpatch function attributes are correctly propagated when compiling directly to OBJ.
-//
-// RUN: echo this_gets_hotpatched > %t.patch-functions.txt
-// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 -fms-secure-hotpatch-functions-file=%t.patch-functions.txt /Fo%t.obj %s
-// RUN: llvm-readobj --codeview %t.obj | FileCheck %s
-
-void this_might_have_side_effects();
-
-int __declspec(noinline) this_gets_hotpatched() {
-    this_might_have_side_effects();
-    return 42;
-}
-
-// CHECK: Kind: S_HOTPATCHFUNC (0x1169)
-// CHECK-NEXT: Function: this_gets_hotpatched
-
-int __declspec(noinline) this_does_not_get_hotpatched() {
-    return this_gets_hotpatched() + 100;
-}
-
-// CHECK-NOT: S_HOTPATCHFUNC
diff --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h
index 18df5d657064a..990452fa11fec 100644
--- a/llvm/include/llvm/CodeGen/Passes.h
+++ b/llvm/include/llvm/CodeGen/Passes.h
@@ -618,9 +618,6 @@ LLVM_ABI FunctionPass *createSelectOptimizePass();
 
 LLVM_ABI FunctionPass *createCallBrPass();
 
-/// Creates Windows Secure Hot Patch pass. \see WindowsSecureHotPatching.cpp
-ModulePass *createWindowsSecureHotPatchingPass();
-
 /// Lowers KCFI operand bundles for indirect calls.
 LLVM_ABI FunctionPass *createKCFIPass();
 } // namespace llvm
diff --git a/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def b/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
index b38bdb482df43..9d85acc49fa02 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
+++ b/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
@@ -256,8 +256,6 @@ SYMBOL_RECORD_ALIAS(S_GTHREAD32     , 0x1113, GlobalTLS, ThreadLocalDataSym)
 SYMBOL_RECORD(S_UNAMESPACE    , 0x1124, UsingNamespaceSym)
 SYMBOL_RECORD(S_ANNOTATION    , 0x1019, AnnotationSym)
 
-SYMBOL_RECORD(S_HOTPATCHFUNC  , 0x1169, HotPatchFuncSym)
-
 #undef CV_SYMBOL
 #undef SYMBOL_RECORD
 #undef SYMBOL_RECORD_ALIAS
diff --git a/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
index f5f6fe69430cc..5b4f0d31e6427 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
@@ -177,21 +177,6 @@ class CallerSym : public SymbolRecord {
   uint32_t RecordOffset = 0;
 };
 
-class HotPatchFuncSym : public SymbolRecord {
-public:
-  explicit HotPatchFuncSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
-  HotPatchFuncSym(uint32_t RecordOffset)
-      : SymbolRecord(SymbolRecordKind::HotPatchFuncSym),
-        RecordOffset(RecordOffset) {}
-
-  // This is an ItemID in the IPI stream, which points to an LF_FUNC_ID or
-  // LF_MFUNC_ID record.
-  TypeIndex Function;
-  StringRef Name;
-
-  uint32_t RecordOffset = 0;
-};
-
 struct DecodedAnnotation {
   StringRef Name;
   ArrayRef<uint8_t> Bytes;
diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td
index 0bcd15eeed879..d488c5f419b82 100644
--- a/llvm/include/llvm/IR/Attributes.td
+++ b/llvm/include/llvm/IR/Attributes.td
@@ -389,16 +389,6 @@ def CoroDestroyOnlyWhenComplete : EnumAttr<"coro_only_destroy_when_complete", In
 /// pipeline to perform elide on the call or invoke instruction.
 def CoroElideSafe : EnumAttr<"coro_elide_safe", IntersectPreserve, [FnAttr]>;
 
-/// Function is marked for Windows Hot Patching
-def MarkedForWindowsSecureHotPatching
-    : StrBoolAttr<"marked_for_windows_hot_patching">;
-
-/// Global variable should not be accessed through a "__ref_" global variable in
-/// a hot patching function This attribute is applied to the global variable
-/// decl, not the hotpatched function.
-def AllowDirectAccessInHotPatchFunction
-    : StrBoolAttr<"allow_direct_access_in_hot_patch_function">;
-
 /// Target-independent string attributes.
 def LessPreciseFPMAD : StrBoolAttr<"less-precise-fpmad">;
 def NoInfsFPMath : StrBoolAttr<"no-infs-fp-math">;
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index 1c4ed3843b390..1b5b1d5888824 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -336,7 +336,6 @@ LLVM_ABI void initializeVerifierLegacyPassPass(PassRegistry &);
 LLVM_ABI void initializeVirtRegMapWrapperLegacyPass(PassRegistry &);
 LLVM_ABI void initializeVirtRegRewriterLegacyPass(PassRegistry &);
 LLVM_ABI void initializeWasmEHPreparePass(PassRegistry &);
-LLVM_ABI void initializeWindowsSecureHotPatchingPass(PassRegistry &);
 LLVM_ABI void initializeWinEHPreparePass(PassRegistry &);
 LLVM_ABI void initializeWriteBitcodePassPass(PassRegistry &);
 LLVM_ABI void initializeXRayInstrumentationLegacyPass(PassRegistry &);
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 5e1b313b4d2fa..ea57a8fa1f793 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -669,8 +669,6 @@ void CodeViewDebug::endModule() {
   if (!Asm)
     return;
 
-  emitSecureHotPatchInformation();
-
   emitInlineeLinesSubsection();
 
   // Emit per-function debug information.
@@ -825,28 +823,6 @@ void CodeViewDebug::emitObjName() {
   endSymbolRecord(CompilerEnd);
 }
 
-void CodeViewDebug::emitSecureHotPatchInformation() {
-  MCSymbol *hotPatchInfo = nullptr;
-
-  for (const auto &F : MMI->getModule()->functions()) {
-    if (!F.isDeclarationForLinker() &&
-        F.hasFnAttribute("marked_for_windows_hot_patching")) {
-      if (hotPatchInfo == nullptr)
-        hotPatchInfo = beginCVSubsection(DebugSubsectionKind::Symbols);
-      MCSymbol *HotPatchEnd = beginSymbolRecord(SymbolKind::S_HOTPATCHFUNC);
-      auto *SP = F.getSubprogram();
-      OS.AddComment("Function");
-      OS.emitInt32(getFuncIdForSubprogram(SP).getIndex());
-      OS.AddComment("Name");
-      emitNullTerminatedSymbolName(OS, F.getName());
-      endSymbolRecord(HotPatchEnd);
-    }
-  }
-
-  if (hotPatchInfo != nullptr)
-    endCVSubsection(hotPatchInfo);
-}
-
 namespace {
 struct Version {
   int Part[4];
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
index c862802d835d7..5f4f30271d9cb 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -337,8 +337,6 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
 
   void emitCompilerInformation();
 
-  void emitSecureHotPatchInformation();
-
   void emitBuildInfo();
 
   void emitInlineeLinesSubsection();
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt
index f8f9bbba53e43..5dd6413431255 100644
--- a/llvm/lib/CodeGen/CMakeLists.txt
+++ b/llvm/lib/CodeGen/CMakeLists.txt
@@ -250,7 +250,6 @@ add_llvm_component_library(LLVMCodeGen
   VirtRegMap.cpp
   WasmEHPrepare.cpp
   WindowScheduler.cpp
-  WindowsSecureHotPatching.cpp
   WinEHPrepare.cpp
   XRayInstrumentation.cpp
   ${GeneratedMLSources}
diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp
index 7d7c6e743fa76..4ae52b056d844 100644
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -893,9 +893,6 @@ void TargetPassConfig::addIRPasses() {
 
   if (EnableGlobalMergeFunc)
     addPass(createGlobalMergeFuncPass());
-
-  if (TM->getTargetTriple().isOSWindows())
-    addPass(createWindowsSecureHotPatchingPass());
 }
 
 /// Turn exception handling constructs into something the code generators can
diff --git a/llvm/lib/CodeGen/WindowsSecureHotPatching.cpp b/llvm/lib/CodeGen/WindowsSecureHotPatching.cpp
deleted file mode 100644
index 6267207dbcbff..0000000000000
--- a/llvm/lib/CodeGen/WindowsSecureHotPatching.cpp
+++ /dev/null
@@ -1,617 +0,0 @@
-//===------ 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) {
-    initializeWindowsSecureHotPatchingPass(*PassRegistry::getPassRegistry());
-  }
-
-  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);
-
-  Constant *AddrOfOldGV =
-      ConstantExpr::getGetElementPtr(PtrTy, GV, ArrayRef<Value *>{});
-
-  GlobalVariable *RefGV =
-      new GlobalVariable(*M, PtrTy, false, GlobalValue::LinkOnceAnyLinkage,
-                         AddrOfOldGV, Twine("__ref_").concat(GV->getName()),
-                         nullptr, GlobalVariable::NotThreadLocal);
-
-  // 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) {
-
-  SmallVector<Value *, 8> ReplacedOperands;
-
-  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, 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;
-}
diff --git a/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp b/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
index 9cb3bca8d6e5e..f56739db7c75f 100644
--- a/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
+++ b/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
@@ -672,13 +672,6 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
   return Error::success();
 }
 
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
-                                           HotPatchFuncSym &HotPatchFunc) {
-  printTypeIndex("Function", HotPatchFunc.Function);
-  W.printString("Name", HotPatchFunc.Name);
-  return Error::success();
-}
-
 Error CVSymbolDumperImpl::visitUnknownSymbol(CVSymbol &CVR) {
   W.printNumber("Length", CVR.length());
   return Error::success();
diff --git a/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp b/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
index 525343b90a3ae..b5e366b965a95 100644
--- a/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
+++ b/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
@@ -496,13 +496,6 @@ Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
   return Error::success();
 }
 
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
-                                            HotPatchFuncSym &HotPatchFunc) {
-  error(IO.mapInteger(HotPatchFunc.Function));
-  error(IO.mapStringZ(HotPatchFunc.Name));
-  return Error::success();
-}
-
 RegisterId codeview::decodeFramePtrReg(EncodedFramePtrReg EncodedReg,
                                        CPUType CPU) {
   assert(unsigned(EncodedReg) < 4);
diff --git a/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp b/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
index 3056251809308..b15919f68725f 100644
--- a/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
+++ b/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
@@ -605,11 +605,6 @@ template <> void SymbolRecordImpl<JumpTableSym>::map(IO &IO) {
   IO.mapRequired("EntriesCount", Symbol.EntriesCount);
 }
 
-template <> void SymbolRecordImpl<HotPatchFuncSym>::map(IO &IO) {
-  IO.mapRequired("Function", Symbol.Function);
-  IO.mapRequired("Name", Symbol.Name);
-}
-
 } // end namespace detail
 } // end namespace CodeViewYAML
 } // end namespace llvm
diff --git a/llvm/test/CodeGen/X86/ms-secure-hotpatch-attr.ll b/llvm/test/CodeGen/X86/ms-secure-hotpatch-attr.ll
deleted file mode 100644
index 7e60e6a047507..0000000000000
--- a/llvm/test/CodeGen/X86/ms-secure-hotpatch-attr.ll
+++ /dev/null
@@ -1,38 +0,0 @@
-; This tests directly annotating a function with marked_for_windows_hot_patching.
-;
-; RUN: llc -mtriple=x86_64-windows < %s | FileCheck %s
-
-source_filename = ".\\ms-secure-hotpatch-attr.ll"
-target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-pc-windows-msvc19.36.32537"
-
- at some_global_var = external global i32
-
-define noundef i32 @this_gets_hotpatched() #0 {
-    %1 = load i32, ptr @some_global_var
-    %2 = add i32 %1, 1
-    ret i32 %2
-}
-
-attributes #0 = { "marked_for_windows_hot_patching" mustprogress noinline nounwind optnone uwtable }
-
-; CHECK: this_gets_hotpatched: # @this_gets_hotpatched
-; CHECK-NEXT: bb.0:
-; CHECK-NEXT: movq __ref_some_global_var(%rip), %rax
-; CHECK-NEXT: movl (%rax), %eax
-; CHECK-NEXT: addl $1, %eax
-; CHECK-NEXT: retq
-
-define noundef i32 @this_does_not_get_hotpatched() #1 {
-    %1 = load i32, ptr @some_global_var
-    %2 = add i32 %1, 1
-    ret i32 %2
-}
-
-attributes #1 = { mustprogress noinline nounwind optnone uwtable }
-
-; CHECK: this_does_not_get_hotpatched: # @this_does_not_get_hotpatched
-; CHECK-NEXT: bb.0:
-; CHECK-NEXT: movl some_global_var(%rip), %eax
-; CHECK-NEXT: addl $1, %eax
-; CHECK-NEXT: retq
diff --git a/llvm/test/CodeGen/X86/ms-secure-hotpatch-bad-file.ll b/llvm/test/CodeGen/X86/ms-secure-hotpatch-bad-file.ll
deleted file mode 100644
index 5fec1c48495a2..0000000000000
--- a/llvm/test/CodeGen/X86/ms-secure-hotpatch-bad-file.ll
+++ /dev/null
@@ -1,16 +0,0 @@
-; RUN: not llc -mtriple=x86_64-windows --ms-secure-hotpatch-functions-file=%S/this-file-is-intentionally-missing-do-not-create-it.txt < %s 2>&1 | FileCheck %s
-; CHECK: failed to open hotpatch functions file
-
-source_filename = ".\\ms-secure-hotpatch.ll"
-target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-pc-windows-msvc19.36.32537"
-
- at some_global_var = external global i32
-
-define noundef i32 @this_gets_hotpatched() #0 {
-    %1 = load i32, ptr @some_global_var
-    %2 = add i32 %1, 1
-    ret i32 %2
-}
-
-attributes #0 = { "marked_for_windows_hot_patching" mustprogress noinline nounwind optnone uwtable }
diff --git a/llvm/test/CodeGen/X86/ms-secure-hotpatch-direct-global-access.ll b/llvm/test/CodeGen/X86/ms-secure-hotpatch-direct-global-access.ll
deleted file mode 100644
index 5606b03760be1..0000000000000
--- a/llvm/test/CodeGen/X86/ms-secure-hotpatch-direct-global-access.ll
+++ /dev/null
@@ -1,39 +0,0 @@
-; This tests hotpatching functions that bypass double-indirection for global variables.
-;
-; RUN: llc -mtriple=x86_64-windows < %s | FileCheck %s
-
-source_filename = ".\\ms-secure-hotpatch-direct-global-access.ll"
-target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-pc-windows-msvc19.36.32537"
-
- at some_global_var = external global i32 #2
-
-define noundef i32 @this_gets_hotpatched() #0 {
-    %1 = load i32, ptr @some_global_var
-    %2 = add i32 %1, 1
-    ret i32 %2
-}
-
-attributes #0 = { "marked_for_windows_hot_patching" mustprogress noinline nounwind optnone uwtable }
-
-; CHECK: this_gets_hotpatched: # @this_gets_hotpatched
-; CHECK-NEXT: bb.0:
-; CHECK-NEXT: movl some_global_var(%rip), %eax
-; CHECK-NEXT: addl $1, %eax
-; CHECK-NEXT: retq
-
-define noundef i32 @this_does_not_get_hotpatched() #1 {
-    %1 = load i32, ptr @some_global_var
-    %2 = add i32 %1, 1
-    ret i32 %2
-}
-
-attributes #1 = { mustprogress noinline nounwind optnone uwtable }
-
-attributes #2 = { "allow_direct_access_in_hot_patch_function" }
-
-; CHECK: this_does_not_get_hotpatched: # @this_does_not_get_hotpatched
-; CHECK-NEXT: bb.0:
-; CHECK-NEXT: movl some_global_var(%rip), %eax
-; CHECK-NEXT: addl $1, %eax
-; CHECK-NEXT: retq
diff --git a/llvm/test/CodeGen/X86/ms-secure-hotpatch-functions-file.ll b/llvm/test/CodeGen/X86/ms-secure-hotpatch-functions-file.ll
deleted file mode 100644
index bb79e08683aa7..0000000000000
--- a/llvm/test/CodeGen/X86/ms-secure-hotpatch-functions-file.ll
+++ /dev/null
@@ -1,39 +0,0 @@
-; This tests annotating a function with marked_for_windows_hot_patching by using --ms-hotpatch-functions-file.
-;
-; RUN: echo this_gets_hotpatched > %t.patch-functions.txt
-; RUN: llc -mtriple=x86_64-windows --ms-secure-hotpatch-functions-file=%t.patch-functions.txt < %s | FileCheck %s
-
-source_filename = ".\\ms-secure-hotpatch-functions-file.ll"
-target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-pc-windows-msvc19.36.32537"
-
- at some_global_var = external global i32
-
-define noundef i32 @this_gets_hotpatched() #0 {
-    %1 = load i32, ptr @some_global_var
-    %2 = add i32 %1, 1
-    ret i32 %2
-}
-
-attributes #0 = { mustprogress noinline nounwind optnone uwtable }
-
-; CHECK: this_gets_hotpatched: # @this_gets_hotpatched
-; CHECK-NEXT: bb.0:
-; CHECK-NEXT: movq __ref_some_global_var(%rip), %rax
-; CHECK-NEXT: movl (%rax), %eax
-; CHECK-NEXT: addl $1, %eax
-; CHECK-NEXT: retq
-
-define noundef i32 @this_does_not_get_hotpatched() #1 {
-    %1 = load i32, ptr @some_global_var
-    %2 = add i32 %1, 1
-    ret i32 %2
-}
-
-attributes #1 = { mustprogress noinline nounwind optnone uwtable }
-
-; CHECK: this_does_not_get_hotpatched: # @this_does_not_get_hotpatched
-; CHECK-NEXT: bb.0:
-; CHECK-NEXT: movl some_global_var(%rip), %eax
-; CHECK-NEXT: addl $1, %eax
-; CHECK-NEXT: retq
diff --git a/llvm/test/CodeGen/X86/ms-secure-hotpatch-functions-list.ll b/llvm/test/CodeGen/X86/ms-secure-hotpatch-functions-list.ll
deleted file mode 100644
index b1da1a2db66dc..0000000000000
--- a/llvm/test/CodeGen/X86/ms-secure-hotpatch-functions-list.ll
+++ /dev/null
@@ -1,38 +0,0 @@
-; This tests annotating a function with marked_for_windows_hot_patching by using --ms-hotpatch-functions-list.
-;
-; RUN: llc -mtriple=x86_64-windows --ms-secure-hotpatch-functions-list=this_gets_hotpatched < %s | FileCheck %s
-
-source_filename = ".\\ms-secure-hotpatch-functions-list.ll"
-target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-pc-windows-msvc19.36.32537"
-
- at some_global_var = external global i32
-
-define noundef i32 @this_gets_hotpatched() #0 {
-    %1 = load i32, ptr @some_global_var
-    %2 = add i32 %1, 1
-    ret i32 %2
-}
-
-attributes #0 = { mustprogress noinline nounwind optnone uwtable }
-
-; CHECK: this_gets_hotpatched: # @this_gets_hotpatched
-; CHECK-NEXT: bb.0:
-; CHECK-NEXT: movq __ref_some_global_var(%rip), %rax
-; CHECK-NEXT: movl (%rax), %eax
-; CHECK-NEXT: addl $1, %eax
-; CHECK-NEXT: retq
-
-define noundef i32 @this_does_not_get_hotpatched() #1 {
-    %1 = load i32, ptr @some_global_var
-    %2 = add i32 %1, 1
-    ret i32 %2
-}
-
-attributes #1 = { mustprogress noinline nounwind optnone uwtable }
-
-; CHECK: this_does_not_get_hotpatched: # @this_does_not_get_hotpatched
-; CHECK-NEXT: bb.0:
-; CHECK-NEXT: movl some_global_var(%rip), %eax
-; CHECK-NEXT: addl $1, %eax
-; CHECK-NEXT: retq
diff --git a/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp b/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
index 66a091f50d6b2..479d025835188 100644
--- a/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
+++ b/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
@@ -955,11 +955,3 @@ Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
       JumpTable.EntriesCount);
   return Error::success();
 }
-
-Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
-                                            HotPatchFuncSym &JumpTable) {
-  AutoIndent Indent(P, 7);
-  P.formatLine("function = {0}, name = {1}", typeIndex(JumpTable.Function),
-               JumpTable.Name);
-  return Error::success();
-}



More information about the cfe-commits mailing list