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
151using 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.
156static 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.
162static 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
168namespace {
169
170struct GlobalVariableUse {
171 // GlobalVariable *GV;
172 Instruction *User;
173 unsigned Op;
174};
175
176class WindowsSecureHotPatching : public ModulePass {
177public:
178 static char ID;
179
180 WindowsSecureHotPatching() : ModulePass(ID) {}
181
182 void getAnalysisUsage(AnalysisUsage &AU) const override {
183 AU.setPreservesCFG();
184 }
185
186 bool doInitialization(Module &) override;
187 bool runOnModule(Module &M) override { return false; }
188
189private:
190 bool
191 runOnFunction(Function &F,
192 SmallDenseMap<GlobalVariable *, GlobalVariable *> &RefMapping);
193};
194
195} // end anonymous namespace
196
197char WindowsSecureHotPatching::ID = 0;
198
199INITIALIZE_PASS(WindowsSecureHotPatching, "windows-secure-hot-patch",
200 "Mark functions for Windows hot patch support", false, false)
201ModulePass *llvm::createWindowsSecureHotPatchingPass() {
202 return new WindowsSecureHotPatching();
203}
204
205// Find functions marked with Attribute::MarkedForWindowsHotPatching and modify
206// their code (if necessary) to account for accesses to global variables.
207//
208// This runs during doInitialization() instead of runOnModule() because it needs
209// to run before CodeViewDebug::collectGlobalVariableInfo().
210bool WindowsSecureHotPatching::doInitialization(Module &M) {
211 // The front end may have already marked functions for hot-patching. However,
212 // we also allow marking functions by passing -ms-hotpatch-functions-file or
213 // -ms-hotpatch-functions-list directly to LLVM. This allows hot-patching to
214 // work with languages that have not yet updated their front-ends.
215 if (!LLVMMSSecureHotPatchFunctionsFile.empty() ||
216 !LLVMMSSecureHotPatchFunctionsList.empty()) {
217 std::vector<std::string> HotPatchFunctionsList;
218
219 if (!LLVMMSSecureHotPatchFunctionsFile.empty()) {
220 auto BufOrErr = MemoryBuffer::getFile(Filename: LLVMMSSecureHotPatchFunctionsFile);
221 if (BufOrErr) {
222 const MemoryBuffer &FileBuffer = **BufOrErr;
223 for (line_iterator I(FileBuffer.getMemBufferRef(), true), E; I != E;
224 ++I)
225 HotPatchFunctionsList.push_back(x: std::string{*I});
226 } else {
227 M.getContext().diagnose(DI: DiagnosticInfoGeneric{
228 Twine("failed to open hotpatch functions file "
229 "(--ms-hotpatch-functions-file): ") +
230 LLVMMSSecureHotPatchFunctionsFile + Twine(" : ") +
231 BufOrErr.getError().message()});
232 }
233 }
234
235 if (!LLVMMSSecureHotPatchFunctionsList.empty())
236 for (const auto &FuncName : LLVMMSSecureHotPatchFunctionsList)
237 HotPatchFunctionsList.push_back(x: FuncName);
238
239 // Build a set for quick lookups. This points into HotPatchFunctionsList, so
240 // HotPatchFunctionsList must live longer than HotPatchFunctionsSet.
241 SmallSet<StringRef, 16> HotPatchFunctionsSet;
242 for (const auto &FuncName : HotPatchFunctionsList)
243 HotPatchFunctionsSet.insert(V: StringRef{FuncName});
244
245 // Iterate through all of the functions and check whether they need to be
246 // marked for hotpatching using the list provided directly to LLVM.
247 for (auto &F : M.functions()) {
248 // Ignore declarations that are not definitions.
249 if (F.isDeclarationForLinker())
250 continue;
251
252 if (HotPatchFunctionsSet.contains(V: F.getName()))
253 F.addFnAttr(Kind: "marked_for_windows_hot_patching");
254 }
255 }
256
257 SmallDenseMap<GlobalVariable *, GlobalVariable *> RefMapping;
258 bool MadeChanges = false;
259 for (auto &F : M.functions()) {
260 if (F.hasFnAttribute(Kind: "marked_for_windows_hot_patching")) {
261 if (runOnFunction(F, RefMapping))
262 MadeChanges = true;
263 }
264 }
265 return MadeChanges;
266}
267
268static bool TypeContainsPointers(Type *ty) {
269 switch (ty->getTypeID()) {
270 case Type::PointerTyID:
271 return true;
272
273 case Type::ArrayTyID:
274 return TypeContainsPointers(ty: ty->getArrayElementType());
275
276 case Type::StructTyID: {
277 unsigned NumElements = ty->getStructNumElements();
278 for (unsigned I = 0; I < NumElements; ++I) {
279 if (TypeContainsPointers(ty: ty->getStructElementType(N: I))) {
280 return true;
281 }
282 }
283 return false;
284 }
285
286 default:
287 return false;
288 }
289}
290
291// Returns true if GV needs redirection through a __ref_* variable.
292static bool globalVariableNeedsRedirect(GlobalVariable *GV) {
293 // If a global variable is explictly marked as allowing access in hot-patched
294 // functions, then do not redirect it.
295 if (GV->hasAttribute(Kind: "allow_direct_access_in_hot_patch_function"))
296 return false;
297
298 // If the global variable is not a constant, then we want to redirect it.
299 if (!GV->isConstant()) {
300 if (GV->getName().starts_with(Prefix: "??_R")) {
301 // This is the name mangling prefix that MSVC uses for RTTI data.
302 // Clang is currently generating RTTI data that is marked non-constant.
303 // We override that and treat it like it is constant.
304 return false;
305 }
306
307 // In general, if a global variable is not a constant, then redirect it.
308 return true;
309 }
310
311 // If the type of GV cannot contain pointers, then it cannot point to
312 // other global variables. In this case, there is no need for redirects.
313 // For example, string literals do not contain pointers.
314 return TypeContainsPointers(ty: GV->getValueType());
315}
316
317// Get or create a new global variable that points to the old one and whose
318// name begins with `__ref_`.
319//
320// In hot-patched images, the __ref_* variables point to global variables in
321// the original (unpatched) image. Hot-patched functions in the hot-patch
322// image use these __ref_* variables to access global variables. This ensures
323// that all code (both unpatched and patched) is using the same instances of
324// global variables.
325//
326// The Windows hot-patch infrastructure handles modifying these __ref_*
327// variables. By default, they are initialized with pointers to the equivalent
328// global variables, so when a hot-patch module is loaded *as* a base image
329// (such as after a system reboot), hot-patch functions will access the
330// instances of global variables that are compiled into the hot-patch image.
331// This is the desired outcome, since in this situation (normal boot) the
332// hot-patch image *is* the base image.
333//
334// When we create the GlobalVariable for the __ref_* variable, we must create
335// it as a *non-constant* global variable. The __ref_* pointers will not change
336// during the runtime of the program, so it is tempting to think that they
337// should be constant. However, they still need to be updateable by the
338// hot-patching infrastructure. Also, if the GlobalVariable is created as a
339// constant, then the LLVM optimizer will assume that it can dereference the
340// definition of the __ref_* variable at compile time, which defeats the
341// purpose of the indirection (pointer).
342//
343// The RefMapping table spans the entire module, not just a single function.
344static GlobalVariable *getOrCreateRefVariable(
345 Function &F, SmallDenseMap<GlobalVariable *, GlobalVariable *> &RefMapping,
346 GlobalVariable *GV) {
347 GlobalVariable *&ReplaceWithRefGV = RefMapping.try_emplace(Key: GV).first->second;
348 if (ReplaceWithRefGV != nullptr) {
349 // We have already created a __ref_* pointer for this GlobalVariable.
350 return ReplaceWithRefGV;
351 }
352
353 Module *M = F.getParent();
354
355 const DISubprogram *Subprogram = F.getSubprogram();
356 DICompileUnit *Unit = Subprogram != nullptr ? Subprogram->getUnit() : nullptr;
357 DIFile *File = Subprogram != nullptr ? Subprogram->getFile() : nullptr;
358 DIBuilder DebugInfo{*F.getParent(), true, Unit};
359
360 auto PtrTy = PointerType::get(C&: M->getContext(), AddressSpace: 0);
361
362 Constant *AddrOfOldGV =
363 ConstantExpr::getGetElementPtr(Ty: PtrTy, C: GV, IdxList: ArrayRef<Value *>{});
364
365 GlobalVariable *RefGV =
366 new GlobalVariable(*M, PtrTy, false, GlobalValue::LinkOnceAnyLinkage,
367 AddrOfOldGV, Twine("__ref_").concat(Suffix: GV->getName()),
368 nullptr, GlobalVariable::NotThreadLocal);
369
370 // RefGV is created with isConstant = false, but we want to place RefGV into
371 // .rdata, not .data. It is important that the GlobalVariable be mutable
372 // from the compiler's point of view, so that the optimizer does not remove
373 // the global variable entirely and replace all references to it with its
374 // initial value.
375 //
376 // When the Windows hot-patch loader applies a hot-patch, it maps the
377 // pages of .rdata as read/write so that it can set each __ref_* variable
378 // to point to the original variable in the base image. Afterward, pages in
379 // .rdata are remapped as read-only. This protects the __ref_* variables from
380 // being overwritten during execution.
381 RefGV->setSection(".rdata");
382
383 // Create debug info for the replacement global variable.
384 DataLayout Layout = M->getDataLayout();
385 DIType *DebugType = DebugInfo.createPointerType(
386 PointeeTy: nullptr, SizeInBits: Layout.getTypeSizeInBits(Ty: GV->getValueType()));
387 DIGlobalVariableExpression *GVE = DebugInfo.createGlobalVariableExpression(
388 Context: Unit, Name: RefGV->getName(), LinkageName: StringRef{}, File,
389 /*LineNo*/ 0, Ty: DebugType,
390 /*IsLocalToUnit*/ false);
391 RefGV->addDebugInfo(GV: GVE);
392
393 // Store the __ref_* in RefMapping so that future calls use the same RefGV.
394 ReplaceWithRefGV = RefGV;
395
396 return RefGV;
397}
398
399// Given a ConstantExpr, this searches for GlobalVariable references within
400// the expression tree. If found, it will generate instructions and will
401// return a non-null Value* that points to the new root instruction.
402//
403// If C does not contain any GlobalVariable references, this returns nullptr.
404//
405// If this function creates new instructions, then it will insert them
406// before InsertionPoint.
407static Value *rewriteGlobalVariablesInConstant(
408 Constant *C, SmallDenseMap<GlobalVariable *, Value *> &GVLoadMap,
409 IRBuilder<> &IRBuilderAtEntry) {
410 if (C->getValueID() == Value::GlobalVariableVal) {
411 GlobalVariable *GV = cast<GlobalVariable>(Val: C);
412 if (globalVariableNeedsRedirect(GV)) {
413 return GVLoadMap.at(Val: GV);
414 } else {
415 return nullptr;
416 }
417 }
418
419 // Scan the operands of this expression.
420
421 SmallVector<Value *, 8> ReplacedValues;
422 bool ReplacedAnyOperands = false;
423
424 unsigned NumOperands = C->getNumOperands();
425 for (unsigned OpIndex = 0; OpIndex < NumOperands; ++OpIndex) {
426 Value *OldValue = C->getOperand(i: OpIndex);
427 Value *ReplacedValue = nullptr;
428 if (Constant *OldConstant = dyn_cast<Constant>(Val: OldValue)) {
429 ReplacedValue = rewriteGlobalVariablesInConstant(C: OldConstant, GVLoadMap,
430 IRBuilderAtEntry);
431 }
432 // Do not use short-circuiting, here. We need to traverse the whole tree.
433 ReplacedAnyOperands |= ReplacedValue != nullptr;
434 ReplacedValues.push_back(Elt: ReplacedValue);
435 }
436
437 // If none of our operands were replaced, then don't rewrite this expression.
438 if (!ReplacedAnyOperands) {
439 return nullptr;
440 }
441
442 // We need to rewrite this expression. Convert this constant expression
443 // to an instruction, then replace any operands as needed.
444 Instruction *NewInst = cast<ConstantExpr>(Val: C)->getAsInstruction();
445 for (unsigned OpIndex = 0; OpIndex < NumOperands; ++OpIndex) {
446 Value *ReplacedValue = ReplacedValues[OpIndex];
447 if (ReplacedValue != nullptr) {
448 NewInst->setOperand(i: OpIndex, Val: ReplacedValue);
449 }
450 }
451
452 // Insert the new instruction before the reference instruction.
453 IRBuilderAtEntry.Insert(I: NewInst);
454
455 return NewInst;
456}
457
458static bool searchConstantExprForGlobalVariables(
459 Value *V, SmallDenseMap<GlobalVariable *, Value *> &GVLoadMap,
460 SmallVector<GlobalVariableUse> &GVUses) {
461
462 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Val: V)) {
463 if (globalVariableNeedsRedirect(GV)) {
464 GVLoadMap[GV] = nullptr;
465 return true;
466 } else {
467 return false;
468 }
469 }
470
471 if (User *U = dyn_cast<User>(Val: V)) {
472 unsigned NumOperands = U->getNumOperands();
473 bool FoundAny = false;
474 for (unsigned OpIndex = 0; OpIndex < NumOperands; ++OpIndex) {
475 Value *Op = U->getOperand(i: OpIndex);
476 // Do not use short-circuiting, here. We need to traverse the whole tree.
477 FoundAny |= searchConstantExprForGlobalVariables(V: Op, GVLoadMap, GVUses);
478 }
479 return FoundAny;
480 } else {
481 return false;
482 }
483}
484
485// Processes a function that is marked for hot-patching.
486//
487// If a function is marked for hot-patching, we generate an S_HOTPATCHFUNC
488// CodeView debug symbol. Tools that generate hot-patches look for
489// S_HOTPATCHFUNC in final PDBs so that they can find functions that have been
490// hot-patched and so that they can distinguish hot-patched functions from
491// non-hot-patched functions.
492//
493// Also, in functions that are hot-patched, we must indirect all access to
494// (mutable) global variables through a pointer. This pointer may point into the
495// unpatched ("base") binary or may point into the patched image, depending on
496// whether a hot-patch was loaded as a patch or as a base image. These
497// indirections go through a new global variable, named `__ref_<Foo>` where
498// `<Foo>` is the original symbol name of the global variable.
499//
500// This function handles rewriting accesses to global variables, but the
501// generation of S_HOTPATCHFUNC occurs in
502// CodeViewDebug::emitHotPatchInformation().
503//
504// Returns true if any global variable references were found and rewritten.
505bool WindowsSecureHotPatching::runOnFunction(
506 Function &F,
507 SmallDenseMap<GlobalVariable *, GlobalVariable *> &RefMapping) {
508 // Scan the function for references to global variables. If we find such a
509 // reference, create (if necessary) the __ref_* variable, then add an entry
510 // to the GVUses table.
511 //
512 // We ignore references to global variables if the variable is marked with
513 // AllowDirectAccessInHotPatchFunction.
514
515 SmallDenseMap<GlobalVariable *, Value *> GVLoadMap;
516 SmallVector<GlobalVariableUse> GVUses;
517
518 for (auto &I : instructions(F)) {
519 unsigned NumOperands = I.getNumOperands();
520 for (unsigned OpIndex = 0; OpIndex < NumOperands; ++OpIndex) {
521 Value *V = I.getOperand(i: OpIndex);
522
523 bool FoundAnyGVUses = false;
524
525 switch (V->getValueID()) {
526 case Value::GlobalVariableVal: {
527 // Discover all uses of GlobalVariable, these will need to be replaced.
528 GlobalVariable *GV = cast<GlobalVariable>(Val: V);
529 if (globalVariableNeedsRedirect(GV)) {
530 GVLoadMap.insert(KV: std::make_pair(x&: GV, y: nullptr));
531 FoundAnyGVUses = true;
532 }
533 break;
534 }
535
536 case Value::ConstantExprVal: {
537 ConstantExpr *CE = cast<ConstantExpr>(Val: V);
538 if (searchConstantExprForGlobalVariables(V: CE, GVLoadMap, GVUses)) {
539 FoundAnyGVUses = true;
540 }
541 break;
542 }
543
544 default:
545 break;
546 }
547
548 if (FoundAnyGVUses) {
549 GVUses.push_back(Elt: GlobalVariableUse{.User: &I, .Op: OpIndex});
550 }
551 }
552 }
553
554 // If this function did not reference any global variables then we have no
555 // work to do. Most functions do not access global variables.
556 if (GVUses.empty()) {
557 return false;
558 }
559
560 // We know that there is at least one instruction that needs to be rewritten.
561 // Generate a Load instruction for each unique GlobalVariable used by this
562 // function. The Load instructions are inserted at the beginning of the
563 // entry block. Since entry blocks cannot contain PHI instructions, there is
564 // no need to skip PHI instructions.
565
566 // We use a single IRBuilder for inserting Load instructions as well as the
567 // constants that we convert to instructions. Because constants do not
568 // depend on any dynamic values (they're constant, after all!), it is safe
569 // to move them to the start of entry BB.
570
571 auto &EntryBlock = F.getEntryBlock();
572 IRBuilder<> IRBuilderAtEntry(&EntryBlock, EntryBlock.begin());
573
574 for (auto &[GV, LoadValue] : GVLoadMap) {
575 assert(LoadValue == nullptr);
576 GlobalVariable *RefGV = getOrCreateRefVariable(F, RefMapping, GV);
577 LoadValue = IRBuilderAtEntry.CreateLoad(Ty: RefGV->getValueType(), Ptr: RefGV);
578 }
579
580 const DISubprogram *Subprogram = F.getSubprogram();
581 DICompileUnit *Unit = Subprogram != nullptr ? Subprogram->getUnit() : nullptr;
582 DIBuilder DebugInfo{*F.getParent(), true, Unit};
583
584 // Go back to the instructions and rewrite their uses of GlobalVariable.
585 // Because a ConstantExpr can be a tree, it may reference more than one
586 // GlobalVariable.
587
588 for (auto &GVUse : GVUses) {
589 Value *OldOperandValue = GVUse.User->getOperand(i: GVUse.Op);
590 Value *NewOperandValue;
591
592 switch (OldOperandValue->getValueID()) {
593 case Value::GlobalVariableVal: {
594 // This is easy. Look up the replacement value and store the operand.
595 Value *OperandValue = GVUse.User->getOperand(i: GVUse.Op);
596 GlobalVariable *GV = cast<GlobalVariable>(Val: OperandValue);
597 NewOperandValue = GVLoadMap.at(Val: GV);
598 break;
599 }
600
601 case Value::ConstantExprVal: {
602 // Walk the recursive tree of the ConstantExpr. If we find a
603 // GlobalVariable then replace it with the loaded value and rewrite
604 // the ConstantExpr to an Instruction and insert it before the
605 // current instruction.
606 Value *OperandValue = GVUse.User->getOperand(i: GVUse.Op);
607 ConstantExpr *CE = cast<ConstantExpr>(Val: OperandValue);
608 NewOperandValue =
609 rewriteGlobalVariablesInConstant(C: CE, GVLoadMap, IRBuilderAtEntry);
610 assert(NewOperandValue != nullptr);
611 break;
612 }
613
614 default:
615 // We should only ever get here because a GVUse was created in the first
616 // pass, and this only happens for GlobalVariableVal and ConstantExprVal.
617 llvm_unreachable_internal(
618 msg: "unexpected Value in second pass of hot-patching");
619 break;
620 }
621
622 GVUse.User->setOperand(i: GVUse.Op, Val: NewOperandValue);
623 }
624
625 return true;
626}
627