xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/WindowsSecureHotPatching.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
1 //===------ WindowsHotPatch.cpp - Support for Windows hotpatching ---------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Provides support for the Windows "Secure Hot-Patching" feature.
10 //
11 // Windows contains technology, called "Secure Hot-Patching" (SHP), for securely
12 // applying hot-patches to a running system. Hot-patches may be applied to the
13 // kernel, kernel-mode components, device drivers, user-mode system services,
14 // etc.
15 //
16 // SHP relies on integration between many tools, including compiler, linker,
17 // hot-patch generation tools, and the Windows kernel. This file implements that
18 // part of the workflow needed in compilers / code generators.
19 //
20 // SHP is not intended for productivity scenarios such as Edit-and-Continue or
21 // interactive development. SHP is intended to minimize downtime during
22 // installation of Windows OS patches.
23 //
24 // In order to work with SHP, LLVM must do all of the following:
25 //
26 // * On some architectures (X86, AMD64), the function prolog must begin with
27 //   hot-patchable instructions. This is handled by the MSVC `/hotpatch` option
28 //   and the equivalent `-fms-hotpatch` function. This is necessary because we
29 //   generally cannot anticipate which functions will need to be patched in the
30 //   future. This option ensures that a function can be hot-patched in the
31 //   future, but does not actually generate any hot-patch for it.
32 //
33 // * For a selected set of functions that are being hot-patched (which are
34 //   identified using command-line options), LLVM must generate the
35 //   `S_HOTPATCHFUNC` CodeView record (symbol). This record indicates that a
36 //   function was compiled with hot-patching enabled.
37 //
38 //   This implementation uses the `MarkedForWindowsHotPatching` attribute to
39 //   annotate those functions that were marked for hot-patching by command-line
40 //   parameters. The attribute may be specified by a language front-end by
41 //   setting an attribute when a function is created in LLVM IR, or it may be
42 //   set by passing LLVM arguments.
43 //
44 // * For those functions that are hot-patched, LLVM must rewrite references to
45 //   global variables so that they are indirected through a `__ref_*` pointer
46 //   variable.  For each global variable, that is accessed by a hot-patched
47 //   function, e.g. `FOO`, a `__ref_FOO` global pointer variable is created and
48 //   all references to the original `FOO` are rewritten as dereferences of the
49 //   `__ref_FOO` pointer.
50 //
51 //   Some globals do not need `__ref_*` indirection. The pointer indirection
52 //   behavior can be disabled for these globals by marking them with the
53 //   `AllowDirectAccessInHotPatchFunction`.
54 //
55 // Rewriting references to global variables has some complexity.
56 //
57 // For ordinary instructions that reference GlobalVariables, we rewrite the
58 // operand of the instruction to a Load of the __ref_* variable.
59 //
60 // For constant expressions, we have to convert the constant expression (and
61 // transitively all constant expressions in its parent chain) to non-constant
62 // expressions, i.e. to a sequence of instructions.
63 //
64 // Pass 1:
65 //   * Enumerate all instructions in all basic blocks.
66 //
67 //   * If an instruction references a GlobalVariable (and it is not marked
68 //     as being ignored), then we create (if necessary) the __ref_* variable
69 //     for the GlobalVariable reference. However, we do not yet modify the
70 //     Instruction.
71 //
72 //   * If an instruction has an operand that is a ConstantExpr and the
73 //     ConstantExpression tree contains a reference to a GlobalVariable, then
74 //     we similarly create __ref_*. Similarly, we do not yet modify the
75 //     Instruction or the ConstantExpr tree.
76 //
77 // After Pass 1 completes, we will know whether we found any references to
78 // globals in this pass.  If the function does not use any globals (and most
79 // functions do not use any globals), then we return immediately.
80 //
81 // If a function does reference globals, then we iterate the list of globals
82 // used by this function and we generate Load instructions for each (unique)
83 // global.
84 //
85 // Next, we do another pass over all instructions:
86 //
87 // Pass 2:
88 //   * Re-visit the instructions that were found in Pass 1.
89 //
90 //   * If an instruction operand is a GlobalVariable, then look up the
91 //   replacement
92 //     __ref_* global variable and the Value that came from the Load instruction
93 //     for it.  Replace the operand of the GlobalVariable with the Load Value.
94 //
95 //   * If an instruction operand is a ConstantExpr, then recursively examine the
96 //     operands of all instructions in the ConstantExpr tree.  If an operand is
97 //     a GlobalVariable, then replace the operand with the result of the load
98 //     *and* convert the ConstantExpr to a non-constant instruction.  This
99 //     instruction will need to be inserted into the BB of the instruction whose
100 //     operand is being modified, ideally immediately before the instruction
101 //     being modified.
102 //
103 // Limitations
104 //
105 // This feature is not intended to work in every situation. There are many
106 // legitimate code changes (patches) for which it is not possible to generate
107 // a hot-patch. Developers who are writing hot-patches are expected to
108 // understand the limitations.
109 //
110 // Tools which generate hot-patch metadata may also check that certain
111 // variables are upheld, and some of these invariants may be global (may require
112 // whole-program knowledge, not available in any single compiland). However,
113 // such tools are not required to be perfect; they are also best-effort.
114 //
115 // For these reasons, the hot-patching support implemented in this file is
116 // "best effort". It does not recognize every possible code pattern that could
117 // be patched, nor does it generate diagnostics for certain code patterns that
118 // could result in a binary that does not work with hot-patching. For example,
119 // const GlobalVariables that point to other non-const GlobalVariables are not
120 // compatible with hot-patching because they cannot use __ref_*-based
121 // redirection.
122 //
123 // References
124 //
125 // * "Hotpatching on Windows":
126 //   https://techcommunity.microsoft.com/blog/windowsosplatform/hotpatching-on-windows/2959541
127 //
128 // * "Hotpatch for Windows client now available":
129 //   https://techcommunity.microsoft.com/blog/windows-itpro-blog/hotpatch-for-windows-client-now-available/4399808
130 //
131 // * "Get hotpatching for Windows Server":
132 //   https://www.microsoft.com/en-us/windows-server/blog/2025/04/24/tired-of-all-the-restarts-get-hotpatching-for-windows-server/
133 //
134 //===----------------------------------------------------------------------===//
135 
136 #include "llvm/ADT/SmallSet.h"
137 #include "llvm/CodeGen/Passes.h"
138 #include "llvm/IR/Attributes.h"
139 #include "llvm/IR/DIBuilder.h"
140 #include "llvm/IR/DiagnosticInfo.h"
141 #include "llvm/IR/Function.h"
142 #include "llvm/IR/IRBuilder.h"
143 #include "llvm/IR/InstIterator.h"
144 #include "llvm/IR/Module.h"
145 #include "llvm/InitializePasses.h"
146 #include "llvm/Pass.h"
147 #include "llvm/Support/CommandLine.h"
148 #include "llvm/Support/LineIterator.h"
149 #include "llvm/Support/MemoryBuffer.h"
150 
151 using namespace llvm;
152 
153 #define DEBUG_TYPE "windows-secure-hot-patch"
154 
155 // A file containing list of mangled function names to mark for hot patching.
156 static cl::opt<std::string> LLVMMSSecureHotPatchFunctionsFile(
157     "ms-secure-hotpatch-functions-file", cl::value_desc("filename"),
158     cl::desc("A file containing list of mangled function names to mark for "
159              "Windows Secure Hot-Patching"));
160 
161 // A list of mangled function names to mark for hot patching.
162 static cl::list<std::string> LLVMMSSecureHotPatchFunctionsList(
163     "ms-secure-hotpatch-functions-list", cl::value_desc("list"),
164     cl::desc("A list of mangled function names to mark for Windows Secure "
165              "Hot-Patching"),
166     cl::CommaSeparated);
167 
168 namespace {
169 
170 struct GlobalVariableUse {
171   // GlobalVariable *GV;
172   Instruction *User;
173   unsigned Op;
174 };
175 
176 class WindowsSecureHotPatching : public ModulePass {
177 public:
178   static char ID;
179 
180   WindowsSecureHotPatching() : ModulePass(ID) {
181     initializeWindowsSecureHotPatchingPass(*PassRegistry::getPassRegistry());
182   }
183 
184   void getAnalysisUsage(AnalysisUsage &AU) const override {
185     AU.setPreservesCFG();
186   }
187 
188   bool doInitialization(Module &) override;
189   bool runOnModule(Module &M) override { return false; }
190 
191 private:
192   bool
193   runOnFunction(Function &F,
194                 SmallDenseMap<GlobalVariable *, GlobalVariable *> &RefMapping);
195 };
196 
197 } // end anonymous namespace
198 
199 char WindowsSecureHotPatching::ID = 0;
200 
201 INITIALIZE_PASS(WindowsSecureHotPatching, "windows-secure-hot-patch",
202                 "Mark functions for Windows hot patch support", false, false)
203 ModulePass *llvm::createWindowsSecureHotPatchingPass() {
204   return new WindowsSecureHotPatching();
205 }
206 
207 // Find functions marked with Attribute::MarkedForWindowsHotPatching and modify
208 // their code (if necessary) to account for accesses to global variables.
209 //
210 // This runs during doInitialization() instead of runOnModule() because it needs
211 // to run before CodeViewDebug::collectGlobalVariableInfo().
212 bool WindowsSecureHotPatching::doInitialization(Module &M) {
213   // The front end may have already marked functions for hot-patching. However,
214   // we also allow marking functions by passing -ms-hotpatch-functions-file or
215   // -ms-hotpatch-functions-list directly to LLVM. This allows hot-patching to
216   // work with languages that have not yet updated their front-ends.
217   if (!LLVMMSSecureHotPatchFunctionsFile.empty() ||
218       !LLVMMSSecureHotPatchFunctionsList.empty()) {
219     std::vector<std::string> HotPatchFunctionsList;
220 
221     if (!LLVMMSSecureHotPatchFunctionsFile.empty()) {
222       auto BufOrErr = MemoryBuffer::getFile(LLVMMSSecureHotPatchFunctionsFile);
223       if (BufOrErr) {
224         const MemoryBuffer &FileBuffer = **BufOrErr;
225         for (line_iterator I(FileBuffer.getMemBufferRef(), true), E; I != E;
226              ++I)
227           HotPatchFunctionsList.push_back(std::string{*I});
228       } else {
229         M.getContext().diagnose(DiagnosticInfoGeneric{
230             Twine("failed to open hotpatch functions file "
231                   "(--ms-hotpatch-functions-file): ") +
232             LLVMMSSecureHotPatchFunctionsFile + Twine(" : ") +
233             BufOrErr.getError().message()});
234       }
235     }
236 
237     if (!LLVMMSSecureHotPatchFunctionsList.empty())
238       for (const auto &FuncName : LLVMMSSecureHotPatchFunctionsList)
239         HotPatchFunctionsList.push_back(FuncName);
240 
241     // Build a set for quick lookups. This points into HotPatchFunctionsList, so
242     // HotPatchFunctionsList must live longer than HotPatchFunctionsSet.
243     SmallSet<StringRef, 16> HotPatchFunctionsSet;
244     for (const auto &FuncName : HotPatchFunctionsList)
245       HotPatchFunctionsSet.insert(StringRef{FuncName});
246 
247     // Iterate through all of the functions and check whether they need to be
248     // marked for hotpatching using the list provided directly to LLVM.
249     for (auto &F : M.functions()) {
250       // Ignore declarations that are not definitions.
251       if (F.isDeclarationForLinker())
252         continue;
253 
254       if (HotPatchFunctionsSet.contains(F.getName()))
255         F.addFnAttr("marked_for_windows_hot_patching");
256     }
257   }
258 
259   SmallDenseMap<GlobalVariable *, GlobalVariable *> RefMapping;
260   bool MadeChanges = false;
261   for (auto &F : M.functions()) {
262     if (F.hasFnAttribute("marked_for_windows_hot_patching")) {
263       if (runOnFunction(F, RefMapping))
264         MadeChanges = true;
265     }
266   }
267   return MadeChanges;
268 }
269 
270 static bool TypeContainsPointers(Type *ty) {
271   switch (ty->getTypeID()) {
272   case Type::PointerTyID:
273     return true;
274 
275   case Type::ArrayTyID:
276     return TypeContainsPointers(ty->getArrayElementType());
277 
278   case Type::StructTyID: {
279     unsigned NumElements = ty->getStructNumElements();
280     for (unsigned I = 0; I < NumElements; ++I) {
281       if (TypeContainsPointers(ty->getStructElementType(I))) {
282         return true;
283       }
284     }
285     return false;
286   }
287 
288   default:
289     return false;
290   }
291 }
292 
293 // Returns true if GV needs redirection through a __ref_* variable.
294 static bool globalVariableNeedsRedirect(GlobalVariable *GV) {
295   // If a global variable is explictly marked as allowing access in hot-patched
296   // functions, then do not redirect it.
297   if (GV->hasAttribute("allow_direct_access_in_hot_patch_function"))
298     return false;
299 
300   // If the global variable is not a constant, then we want to redirect it.
301   if (!GV->isConstant()) {
302     if (GV->getName().starts_with("??_R")) {
303       // This is the name mangling prefix that MSVC uses for RTTI data.
304       // Clang is currently generating RTTI data that is marked non-constant.
305       // We override that and treat it like it is constant.
306       return false;
307     }
308 
309     // In general, if a global variable is not a constant, then redirect it.
310     return true;
311   }
312 
313   // If the type of GV cannot contain pointers, then it cannot point to
314   // other global variables. In this case, there is no need for redirects.
315   // For example, string literals do not contain pointers.
316   return TypeContainsPointers(GV->getValueType());
317 }
318 
319 // Get or create a new global variable that points to the old one and whose
320 // name begins with `__ref_`.
321 //
322 // In hot-patched images, the __ref_* variables point to global variables in
323 // the original (unpatched) image. Hot-patched functions in the hot-patch
324 // image use these __ref_* variables to access global variables. This ensures
325 // that all code (both unpatched and patched) is using the same instances of
326 // global variables.
327 //
328 // The Windows hot-patch infrastructure handles modifying these __ref_*
329 // variables. By default, they are initialized with pointers to the equivalent
330 // global variables, so when a hot-patch module is loaded *as* a base image
331 // (such as after a system reboot), hot-patch functions will access the
332 // instances of global variables that are compiled into the hot-patch image.
333 // This is the desired outcome, since in this situation (normal boot) the
334 // hot-patch image *is* the base image.
335 //
336 // When we create the GlobalVariable for the __ref_* variable, we must create
337 // it as a *non-constant* global variable. The __ref_* pointers will not change
338 // during the runtime of the program, so it is tempting to think that they
339 // should be constant. However, they still need to be updateable by the
340 // hot-patching infrastructure. Also, if the GlobalVariable is created as a
341 // constant, then the LLVM optimizer will assume that it can dereference the
342 // definition of the __ref_* variable at compile time, which defeats the
343 // purpose of the indirection (pointer).
344 //
345 // The RefMapping table spans the entire module, not just a single function.
346 static GlobalVariable *getOrCreateRefVariable(
347     Function &F, SmallDenseMap<GlobalVariable *, GlobalVariable *> &RefMapping,
348     GlobalVariable *GV) {
349   GlobalVariable *&ReplaceWithRefGV = RefMapping.try_emplace(GV).first->second;
350   if (ReplaceWithRefGV != nullptr) {
351     // We have already created a __ref_* pointer for this GlobalVariable.
352     return ReplaceWithRefGV;
353   }
354 
355   Module *M = F.getParent();
356 
357   const DISubprogram *Subprogram = F.getSubprogram();
358   DICompileUnit *Unit = Subprogram != nullptr ? Subprogram->getUnit() : nullptr;
359   DIFile *File = Subprogram != nullptr ? Subprogram->getFile() : nullptr;
360   DIBuilder DebugInfo{*F.getParent(), true, Unit};
361 
362   auto PtrTy = PointerType::get(M->getContext(), 0);
363 
364   Constant *AddrOfOldGV =
365       ConstantExpr::getGetElementPtr(PtrTy, GV, ArrayRef<Value *>{});
366 
367   GlobalVariable *RefGV =
368       new GlobalVariable(*M, PtrTy, false, GlobalValue::LinkOnceAnyLinkage,
369                          AddrOfOldGV, Twine("__ref_").concat(GV->getName()),
370                          nullptr, GlobalVariable::NotThreadLocal);
371 
372   // Create debug info for the replacement global variable.
373   DataLayout Layout = M->getDataLayout();
374   DIType *DebugType = DebugInfo.createPointerType(
375       nullptr, Layout.getTypeSizeInBits(GV->getValueType()));
376   DIGlobalVariableExpression *GVE = DebugInfo.createGlobalVariableExpression(
377       Unit, RefGV->getName(), StringRef{}, File,
378       /*LineNo*/ 0, DebugType,
379       /*IsLocalToUnit*/ false);
380   RefGV->addDebugInfo(GVE);
381 
382   // Store the __ref_* in RefMapping so that future calls use the same RefGV.
383   ReplaceWithRefGV = RefGV;
384 
385   return RefGV;
386 }
387 
388 // Given a ConstantExpr, this searches for GlobalVariable references within
389 // the expression tree.  If found, it will generate instructions and will
390 // return a non-null Value* that points to the new root instruction.
391 //
392 // If C does not contain any GlobalVariable references, this returns nullptr.
393 //
394 // If this function creates new instructions, then it will insert them
395 // before InsertionPoint.
396 static Value *rewriteGlobalVariablesInConstant(
397     Constant *C, SmallDenseMap<GlobalVariable *, Value *> &GVLoadMap,
398     IRBuilder<> &IRBuilderAtEntry) {
399   if (C->getValueID() == Value::GlobalVariableVal) {
400     GlobalVariable *GV = cast<GlobalVariable>(C);
401     if (globalVariableNeedsRedirect(GV)) {
402       return GVLoadMap.at(GV);
403     } else {
404       return nullptr;
405     }
406   }
407 
408   // Scan the operands of this expression.
409 
410   SmallVector<Value *, 8> ReplacedValues;
411   bool ReplacedAnyOperands = false;
412 
413   unsigned NumOperands = C->getNumOperands();
414   for (unsigned OpIndex = 0; OpIndex < NumOperands; ++OpIndex) {
415     Value *OldValue = C->getOperand(OpIndex);
416     Value *ReplacedValue = nullptr;
417     if (Constant *OldConstant = dyn_cast<Constant>(OldValue)) {
418       ReplacedValue = rewriteGlobalVariablesInConstant(OldConstant, GVLoadMap,
419                                                        IRBuilderAtEntry);
420     }
421     // Do not use short-circuiting, here. We need to traverse the whole tree.
422     ReplacedAnyOperands |= ReplacedValue != nullptr;
423     ReplacedValues.push_back(ReplacedValue);
424   }
425 
426   // If none of our operands were replaced, then don't rewrite this expression.
427   if (!ReplacedAnyOperands) {
428     return nullptr;
429   }
430 
431   // We need to rewrite this expression. Convert this constant expression
432   // to an instruction, then replace any operands as needed.
433   Instruction *NewInst = cast<ConstantExpr>(C)->getAsInstruction();
434   for (unsigned OpIndex = 0; OpIndex < NumOperands; ++OpIndex) {
435     Value *ReplacedValue = ReplacedValues[OpIndex];
436     if (ReplacedValue != nullptr) {
437       NewInst->setOperand(OpIndex, ReplacedValue);
438     }
439   }
440 
441   // Insert the new instruction before the reference instruction.
442   IRBuilderAtEntry.Insert(NewInst);
443 
444   return NewInst;
445 }
446 
447 static bool searchConstantExprForGlobalVariables(
448     Value *V, SmallDenseMap<GlobalVariable *, Value *> &GVLoadMap,
449     SmallVector<GlobalVariableUse> &GVUses) {
450 
451   SmallVector<Value *, 8> ReplacedOperands;
452 
453   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
454     if (globalVariableNeedsRedirect(GV)) {
455       GVLoadMap[GV] = nullptr;
456       return true;
457     } else {
458       return false;
459     }
460   }
461 
462   if (User *U = dyn_cast<User>(V)) {
463     unsigned NumOperands = U->getNumOperands();
464     bool FoundAny = false;
465     for (unsigned OpIndex = 0; OpIndex < NumOperands; ++OpIndex) {
466       Value *Op = U->getOperand(OpIndex);
467       // Do not use short-circuiting, here. We need to traverse the whole tree.
468       FoundAny |= searchConstantExprForGlobalVariables(Op, GVLoadMap, GVUses);
469     }
470     return FoundAny;
471   } else {
472     return false;
473   }
474 }
475 
476 // Processes a function that is marked for hot-patching.
477 //
478 // If a function is marked for hot-patching, we generate an S_HOTPATCHFUNC
479 // CodeView debug symbol. Tools that generate hot-patches look for
480 // S_HOTPATCHFUNC in final PDBs so that they can find functions that have been
481 // hot-patched and so that they can distinguish hot-patched functions from
482 // non-hot-patched functions.
483 //
484 // Also, in functions that are hot-patched, we must indirect all access to
485 // (mutable) global variables through a pointer. This pointer may point into the
486 // unpatched ("base") binary or may point into the patched image, depending on
487 // whether a hot-patch was loaded as a patch or as a base image.  These
488 // indirections go through a new global variable, named `__ref_<Foo>` where
489 // `<Foo>` is the original symbol name of the global variable.
490 //
491 // This function handles rewriting accesses to global variables, but the
492 // generation of S_HOTPATCHFUNC occurs in
493 // CodeViewDebug::emitHotPatchInformation().
494 //
495 // Returns true if any global variable references were found and rewritten.
496 bool WindowsSecureHotPatching::runOnFunction(
497     Function &F,
498     SmallDenseMap<GlobalVariable *, GlobalVariable *> &RefMapping) {
499   // Scan the function for references to global variables. If we find such a
500   // reference, create (if necessary) the __ref_* variable, then add an entry
501   // to the GVUses table.
502   //
503   // We ignore references to global variables if the variable is marked with
504   // AllowDirectAccessInHotPatchFunction.
505 
506   SmallDenseMap<GlobalVariable *, Value *> GVLoadMap;
507   SmallVector<GlobalVariableUse> GVUses;
508 
509   for (auto &I : instructions(F)) {
510     unsigned NumOperands = I.getNumOperands();
511     for (unsigned OpIndex = 0; OpIndex < NumOperands; ++OpIndex) {
512       Value *V = I.getOperand(OpIndex);
513 
514       bool FoundAnyGVUses = false;
515 
516       switch (V->getValueID()) {
517       case Value::GlobalVariableVal: {
518         // Discover all uses of GlobalVariable, these will need to be replaced.
519         GlobalVariable *GV = cast<GlobalVariable>(V);
520         if (globalVariableNeedsRedirect(GV)) {
521           GVLoadMap.insert(std::make_pair(GV, nullptr));
522           FoundAnyGVUses = true;
523         }
524         break;
525       }
526 
527       case Value::ConstantExprVal: {
528         ConstantExpr *CE = cast<ConstantExpr>(V);
529         if (searchConstantExprForGlobalVariables(CE, GVLoadMap, GVUses)) {
530           FoundAnyGVUses = true;
531         }
532         break;
533       }
534 
535       default:
536         break;
537       }
538 
539       if (FoundAnyGVUses) {
540         GVUses.push_back(GlobalVariableUse{&I, OpIndex});
541       }
542     }
543   }
544 
545   // If this function did not reference any global variables then we have no
546   // work to do. Most functions do not access global variables.
547   if (GVUses.empty()) {
548     return false;
549   }
550 
551   // We know that there is at least one instruction that needs to be rewritten.
552   // Generate a Load instruction for each unique GlobalVariable used by this
553   // function. The Load instructions are inserted at the beginning of the
554   // entry block. Since entry blocks cannot contain PHI instructions, there is
555   // no need to skip PHI instructions.
556 
557   // We use a single IRBuilder for inserting Load instructions as well as the
558   // constants that we convert to instructions. Because constants do not
559   // depend on any dynamic values (they're constant, after all!), it is safe
560   // to move them to the start of entry BB.
561 
562   auto &EntryBlock = F.getEntryBlock();
563   IRBuilder<> IRBuilderAtEntry(&EntryBlock, EntryBlock.begin());
564 
565   for (auto &[GV, LoadValue] : GVLoadMap) {
566     assert(LoadValue == nullptr);
567     GlobalVariable *RefGV = getOrCreateRefVariable(F, RefMapping, GV);
568     LoadValue = IRBuilderAtEntry.CreateLoad(RefGV->getValueType(), RefGV);
569   }
570 
571   const DISubprogram *Subprogram = F.getSubprogram();
572   DICompileUnit *Unit = Subprogram != nullptr ? Subprogram->getUnit() : nullptr;
573   DIBuilder DebugInfo{*F.getParent(), true, Unit};
574 
575   // Go back to the instructions and rewrite their uses of GlobalVariable.
576   // Because a ConstantExpr can be a tree, it may reference more than one
577   // GlobalVariable.
578 
579   for (auto &GVUse : GVUses) {
580     Value *OldOperandValue = GVUse.User->getOperand(GVUse.Op);
581     Value *NewOperandValue;
582 
583     switch (OldOperandValue->getValueID()) {
584     case Value::GlobalVariableVal: {
585       // This is easy. Look up the replacement value and store the operand.
586       Value *OperandValue = GVUse.User->getOperand(GVUse.Op);
587       GlobalVariable *GV = cast<GlobalVariable>(OperandValue);
588       NewOperandValue = GVLoadMap.at(GV);
589       break;
590     }
591 
592     case Value::ConstantExprVal: {
593       // Walk the recursive tree of the ConstantExpr. If we find a
594       // GlobalVariable then replace it with the loaded value and rewrite
595       // the ConstantExpr to an Instruction and insert it before the
596       // current instruction.
597       Value *OperandValue = GVUse.User->getOperand(GVUse.Op);
598       ConstantExpr *CE = cast<ConstantExpr>(OperandValue);
599       NewOperandValue =
600           rewriteGlobalVariablesInConstant(CE, GVLoadMap, IRBuilderAtEntry);
601       assert(NewOperandValue != nullptr);
602       break;
603     }
604 
605     default:
606       // We should only ever get here because a GVUse was created in the first
607       // pass, and this only happens for GlobalVariableVal and ConstantExprVal.
608       llvm_unreachable_internal(
609           "unexpected Value in second pass of hot-patching");
610       break;
611     }
612 
613     GVUse.User->setOperand(GVUse.Op, NewOperandValue);
614   }
615 
616   return true;
617 }
618