LLVM 22.0.0git
WindowsSecureHotPatching.cpp
Go to the documentation of this file.
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"
141#include "llvm/IR/Function.h"
142#include "llvm/IR/IRBuilder.h"
143#include "llvm/IR/InstIterator.h"
144#include "llvm/IR/Module.h"
146#include "llvm/Pass.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.
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.
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"),
167
168namespace {
169
170struct GlobalVariableUse {
171 // GlobalVariable *GV;
173 unsigned Op;
174};
175
176class WindowsSecureHotPatching : public ModulePass {
177public:
178 static char ID;
179
180 WindowsSecureHotPatching() : ModulePass(ID) {
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
191private:
192 bool
195};
196
197} // end anonymous namespace
198
199char WindowsSecureHotPatching::ID = 0;
200
201INITIALIZE_PASS(WindowsSecureHotPatching, "windows-secure-hot-patch",
202 "Mark functions for Windows hot patch support", false, false)
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().
212bool 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.
219 std::vector<std::string> HotPatchFunctionsList;
220
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): ") +
233 BufOrErr.getError().message()});
234 }
235 }
236
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
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
270static bool TypeContainsPointers(Type *ty) {
271 switch (ty->getTypeID()) {
273 return true;
274
275 case Type::ArrayTyID:
277
278 case Type::StructTyID: {
279 unsigned NumElements = ty->getStructNumElements();
280 for (unsigned I = 0; I < NumElements; ++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.
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.
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.
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 =
366
367 GlobalVariable *RefGV =
369 AddrOfOldGV, Twine("__ref_").concat(GV->getName()),
370 nullptr, GlobalVariable::NotThreadLocal);
371
372 // RefGV is created with isConstant = false, but we want to place RefGV into
373 // .rdata, not .data. It is important that the GlobalVariable be mutable
374 // from the compiler's point of view, so that the optimizer does not remove
375 // the global variable entirely and replace all references to it with its
376 // initial value.
377 //
378 // When the Windows hot-patch loader applies a hot-patch, it maps the
379 // pages of .rdata as read/write so that it can set each __ref_* variable
380 // to point to the original variable in the base image. Afterward, pages in
381 // .rdata are remapped as read-only. This protects the __ref_* variables from
382 // being overwritten during execution.
383 RefGV->setSection(".rdata");
384
385 // Create debug info for the replacement global variable.
386 DataLayout Layout = M->getDataLayout();
387 DIType *DebugType = DebugInfo.createPointerType(
388 nullptr, Layout.getTypeSizeInBits(GV->getValueType()));
389 DIGlobalVariableExpression *GVE = DebugInfo.createGlobalVariableExpression(
390 Unit, RefGV->getName(), StringRef{}, File,
391 /*LineNo*/ 0, DebugType,
392 /*IsLocalToUnit*/ false);
393 RefGV->addDebugInfo(GVE);
394
395 // Store the __ref_* in RefMapping so that future calls use the same RefGV.
396 ReplaceWithRefGV = RefGV;
397
398 return RefGV;
399}
400
401// Given a ConstantExpr, this searches for GlobalVariable references within
402// the expression tree. If found, it will generate instructions and will
403// return a non-null Value* that points to the new root instruction.
404//
405// If C does not contain any GlobalVariable references, this returns nullptr.
406//
407// If this function creates new instructions, then it will insert them
408// before InsertionPoint.
411 IRBuilder<> &IRBuilderAtEntry) {
412 if (C->getValueID() == Value::GlobalVariableVal) {
413 GlobalVariable *GV = cast<GlobalVariable>(C);
415 return GVLoadMap.at(GV);
416 } else {
417 return nullptr;
418 }
419 }
420
421 // Scan the operands of this expression.
422
423 SmallVector<Value *, 8> ReplacedValues;
424 bool ReplacedAnyOperands = false;
425
426 unsigned NumOperands = C->getNumOperands();
427 for (unsigned OpIndex = 0; OpIndex < NumOperands; ++OpIndex) {
428 Value *OldValue = C->getOperand(OpIndex);
429 Value *ReplacedValue = nullptr;
430 if (Constant *OldConstant = dyn_cast<Constant>(OldValue)) {
431 ReplacedValue = rewriteGlobalVariablesInConstant(OldConstant, GVLoadMap,
432 IRBuilderAtEntry);
433 }
434 // Do not use short-circuiting, here. We need to traverse the whole tree.
435 ReplacedAnyOperands |= ReplacedValue != nullptr;
436 ReplacedValues.push_back(ReplacedValue);
437 }
438
439 // If none of our operands were replaced, then don't rewrite this expression.
440 if (!ReplacedAnyOperands) {
441 return nullptr;
442 }
443
444 // We need to rewrite this expression. Convert this constant expression
445 // to an instruction, then replace any operands as needed.
446 Instruction *NewInst = cast<ConstantExpr>(C)->getAsInstruction();
447 for (unsigned OpIndex = 0; OpIndex < NumOperands; ++OpIndex) {
448 Value *ReplacedValue = ReplacedValues[OpIndex];
449 if (ReplacedValue != nullptr) {
450 NewInst->setOperand(OpIndex, ReplacedValue);
451 }
452 }
453
454 // Insert the new instruction before the reference instruction.
455 IRBuilderAtEntry.Insert(NewInst);
456
457 return NewInst;
458}
459
463
464 SmallVector<Value *, 8> ReplacedOperands;
465
466 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
468 GVLoadMap[GV] = nullptr;
469 return true;
470 } else {
471 return false;
472 }
473 }
474
475 if (User *U = dyn_cast<User>(V)) {
476 unsigned NumOperands = U->getNumOperands();
477 bool FoundAny = false;
478 for (unsigned OpIndex = 0; OpIndex < NumOperands; ++OpIndex) {
479 Value *Op = U->getOperand(OpIndex);
480 // Do not use short-circuiting, here. We need to traverse the whole tree.
481 FoundAny |= searchConstantExprForGlobalVariables(Op, GVLoadMap, GVUses);
482 }
483 return FoundAny;
484 } else {
485 return false;
486 }
487}
488
489// Processes a function that is marked for hot-patching.
490//
491// If a function is marked for hot-patching, we generate an S_HOTPATCHFUNC
492// CodeView debug symbol. Tools that generate hot-patches look for
493// S_HOTPATCHFUNC in final PDBs so that they can find functions that have been
494// hot-patched and so that they can distinguish hot-patched functions from
495// non-hot-patched functions.
496//
497// Also, in functions that are hot-patched, we must indirect all access to
498// (mutable) global variables through a pointer. This pointer may point into the
499// unpatched ("base") binary or may point into the patched image, depending on
500// whether a hot-patch was loaded as a patch or as a base image. These
501// indirections go through a new global variable, named `__ref_<Foo>` where
502// `<Foo>` is the original symbol name of the global variable.
503//
504// This function handles rewriting accesses to global variables, but the
505// generation of S_HOTPATCHFUNC occurs in
506// CodeViewDebug::emitHotPatchInformation().
507//
508// Returns true if any global variable references were found and rewritten.
509bool WindowsSecureHotPatching::runOnFunction(
510 Function &F,
512 // Scan the function for references to global variables. If we find such a
513 // reference, create (if necessary) the __ref_* variable, then add an entry
514 // to the GVUses table.
515 //
516 // We ignore references to global variables if the variable is marked with
517 // AllowDirectAccessInHotPatchFunction.
518
521
522 for (auto &I : instructions(F)) {
523 unsigned NumOperands = I.getNumOperands();
524 for (unsigned OpIndex = 0; OpIndex < NumOperands; ++OpIndex) {
525 Value *V = I.getOperand(OpIndex);
526
527 bool FoundAnyGVUses = false;
528
529 switch (V->getValueID()) {
530 case Value::GlobalVariableVal: {
531 // Discover all uses of GlobalVariable, these will need to be replaced.
532 GlobalVariable *GV = cast<GlobalVariable>(V);
534 GVLoadMap.insert(std::make_pair(GV, nullptr));
535 FoundAnyGVUses = true;
536 }
537 break;
538 }
539
540 case Value::ConstantExprVal: {
541 ConstantExpr *CE = cast<ConstantExpr>(V);
542 if (searchConstantExprForGlobalVariables(CE, GVLoadMap, GVUses)) {
543 FoundAnyGVUses = true;
544 }
545 break;
546 }
547
548 default:
549 break;
550 }
551
552 if (FoundAnyGVUses) {
553 GVUses.push_back(GlobalVariableUse{&I, OpIndex});
554 }
555 }
556 }
557
558 // If this function did not reference any global variables then we have no
559 // work to do. Most functions do not access global variables.
560 if (GVUses.empty()) {
561 return false;
562 }
563
564 // We know that there is at least one instruction that needs to be rewritten.
565 // Generate a Load instruction for each unique GlobalVariable used by this
566 // function. The Load instructions are inserted at the beginning of the
567 // entry block. Since entry blocks cannot contain PHI instructions, there is
568 // no need to skip PHI instructions.
569
570 // We use a single IRBuilder for inserting Load instructions as well as the
571 // constants that we convert to instructions. Because constants do not
572 // depend on any dynamic values (they're constant, after all!), it is safe
573 // to move them to the start of entry BB.
574
575 auto &EntryBlock = F.getEntryBlock();
576 IRBuilder<> IRBuilderAtEntry(&EntryBlock, EntryBlock.begin());
577
578 for (auto &[GV, LoadValue] : GVLoadMap) {
579 assert(LoadValue == nullptr);
580 GlobalVariable *RefGV = getOrCreateRefVariable(F, RefMapping, GV);
581 LoadValue = IRBuilderAtEntry.CreateLoad(RefGV->getValueType(), RefGV);
582 }
583
584 const DISubprogram *Subprogram = F.getSubprogram();
585 DICompileUnit *Unit = Subprogram != nullptr ? Subprogram->getUnit() : nullptr;
586 DIBuilder DebugInfo{*F.getParent(), true, Unit};
587
588 // Go back to the instructions and rewrite their uses of GlobalVariable.
589 // Because a ConstantExpr can be a tree, it may reference more than one
590 // GlobalVariable.
591
592 for (auto &GVUse : GVUses) {
593 Value *OldOperandValue = GVUse.User->getOperand(GVUse.Op);
594 Value *NewOperandValue;
595
596 switch (OldOperandValue->getValueID()) {
597 case Value::GlobalVariableVal: {
598 // This is easy. Look up the replacement value and store the operand.
599 Value *OperandValue = GVUse.User->getOperand(GVUse.Op);
600 GlobalVariable *GV = cast<GlobalVariable>(OperandValue);
601 NewOperandValue = GVLoadMap.at(GV);
602 break;
603 }
604
605 case Value::ConstantExprVal: {
606 // Walk the recursive tree of the ConstantExpr. If we find a
607 // GlobalVariable then replace it with the loaded value and rewrite
608 // the ConstantExpr to an Instruction and insert it before the
609 // current instruction.
610 Value *OperandValue = GVUse.User->getOperand(GVUse.Op);
611 ConstantExpr *CE = cast<ConstantExpr>(OperandValue);
612 NewOperandValue =
613 rewriteGlobalVariablesInConstant(CE, GVLoadMap, IRBuilderAtEntry);
614 assert(NewOperandValue != nullptr);
615 break;
616 }
617
618 default:
619 // We should only ever get here because a GVUse was created in the first
620 // pass, and this only happens for GlobalVariableVal and ConstantExprVal.
622 "unexpected Value in second pass of hot-patching");
623 break;
624 }
625
626 GVUse.User->setOperand(GVUse.Op, NewOperandValue);
627 }
628
629 return true;
630}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Expand Atomic instructions
This file contains the simple types necessary to represent the attributes associated with functions a...
static bool runOnFunction(Function &F, bool PostInlining)
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:56
unsigned OpIndex
This file defines the SmallSet class.
static GlobalVariable * getOrCreateRefVariable(Function &F, SmallDenseMap< GlobalVariable *, GlobalVariable * > &RefMapping, GlobalVariable *GV)
static bool globalVariableNeedsRedirect(GlobalVariable *GV)
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)
static bool searchConstantExprForGlobalVariables(Value *V, SmallDenseMap< GlobalVariable *, Value * > &GVLoadMap, SmallVector< GlobalVariableUse > &GVUses)
static Value * rewriteGlobalVariablesInConstant(Constant *C, SmallDenseMap< GlobalVariable *, Value * > &GVLoadMap, IRBuilder<> &IRBuilderAtEntry)
static bool TypeContainsPointers(Type *ty)
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"))
Represent the analysis usage information of a pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:270
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
A constant value that is initialized with an expression using other constant values.
Definition: Constants.h:1120
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, GEPNoWrapFlags NW=GEPNoWrapFlags::none(), std::optional< ConstantRange > InRange=std::nullopt, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
Definition: Constants.h:1274
This is an important base class in LLVM.
Definition: Constant.h:43
A pair of DIGlobalVariable and DIExpression.
DIFile * getFile() const
Subprogram description. Uses SubclassData1.
Base class for types.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
Definition: DataLayout.h:674
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition: DenseMap.h:245
const ValueT & at(const_arg_type_t< KeyT > Val) const
at - Return the entry for the specified key, or abort if no such entry exists.
Definition: DenseMap.h:221
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:230
@ LinkOnceAnyLinkage
Keep one copy of function when linking (inline)
Definition: GlobalValue.h:55
Type * getValueType() const
Definition: GlobalValue.h:298
bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
InstTy * Insert(InstTy *I, const Twine &Name="") const
Insert and return the specified instruction.
Definition: IRBuilder.h:172
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2780
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:52
MemoryBufferRef getMemBufferRef() const
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:255
virtual bool runOnModule(Module &M)=0
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: Pass.cpp:112
virtual bool doInitialization(Module &)
doInitialization - Virtual method overridden by subclasses to do any necessary initialization before ...
Definition: Pass.h:128
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:134
bool contains(const T &V) const
Check if the SmallSet contains the given element.
Definition: SmallSet.h:227
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:182
bool empty() const
Definition: SmallVector.h:82
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:269
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
Type * getArrayElementType() const
Definition: Type.h:408
@ ArrayTyID
Arrays.
Definition: Type.h:74
@ StructTyID
Structures.
Definition: Type.h:73
@ PointerTyID
Pointers.
Definition: Type.h:72
TypeID getTypeID() const
Return the type id for the type.
Definition: Type.h:136
LLVM_ABI Type * getStructElementType(unsigned N) const
LLVM_ABI unsigned getStructNumElements() const
void setOperand(unsigned i, Value *Val)
Definition: User.h:237
LLVM Value Representation.
Definition: Value.h:75
unsigned getValueID() const
Return an ID for the concrete type of this object.
Definition: Value.h:543
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:322
A forward iterator which reads text lines from a buffer.
Definition: LineIterator.h:34
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ CE
Windows NT (Windows on ARM)
@ CommaSeparated
Definition: CommandLine.h:164
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
Definition: STLExtras.h:1197
LLVM_ABI void llvm_unreachable_internal(const char *msg=nullptr, const char *file=nullptr, unsigned line=0)
This function calls abort(), and prints the optional message to stderr.
LLVM_ABI void initializeWindowsSecureHotPatchingPass(PassRegistry &)
LLVM_ABI ModulePass * createWindowsSecureHotPatchingPass()
Creates Windows Secure Hot Patch pass.