52
52
// behavior can be disabled for these globals by marking them with the
53
53
// `AllowDirectAccessInHotPatchFunction`.
54
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
+ //
55
103
// References
56
104
//
57
105
// * "Hotpatching on Windows":
@@ -184,14 +232,14 @@ bool WindowsSecureHotPatching::doInitialization(Module &M) {
184
232
continue ;
185
233
186
234
if (HotPatchFunctionsSet.contains (F.getName ()))
187
- F.addFnAttr (Attribute::MarkedForWindowsHotPatching );
235
+ F.addFnAttr (Attribute::MarkedForWindowsSecureHotPatching );
188
236
}
189
237
}
190
238
191
239
SmallDenseMap<GlobalVariable *, GlobalVariable *> RefMapping;
192
240
bool MadeChanges = false ;
193
241
for (auto &F : M.functions ()) {
194
- if (F.hasFnAttribute (Attribute::MarkedForWindowsHotPatching )) {
242
+ if (F.hasFnAttribute (Attribute::MarkedForWindowsSecureHotPatching )) {
195
243
if (runOnFunction (F, RefMapping))
196
244
MadeChanges = true ;
197
245
}
@@ -249,56 +297,6 @@ static bool globalVariableNeedsRedirect(GlobalVariable *GV) {
249
297
return TypeContainsPointers (GV->getValueType ());
250
298
}
251
299
252
- /*
253
-
254
- Rewriting references to global variables has some complexity.
255
-
256
- For ordinary instructions that reference GlobalVariables, we rewrite the
257
- operand of the instruction to a Load of the __ref_* variable.
258
-
259
- For constant expressions, we have to convert the constant expression (and
260
- transitively all constant expressions in its parent chain) to non-constant
261
- expressions, i.e. to a sequence of instructions.
262
-
263
- Pass 1:
264
- * Enumerate all instructions in all basic blocks.
265
-
266
- * If an instruction references a GlobalVariable (and it is not marked
267
- as being ignored), then we create (if necessary) the __ref_* variable
268
- for the GlobalVariable reference. However, we do not yet modify the
269
- Instruction.
270
-
271
- * If an instruction has an operand that is a ConstantExpr and the
272
- ConstantExpression tree contains a reference to a GlobalVariable, then
273
- we similarly create __ref_*. Similarly, we do not yet modify the Instruction
274
- or the ConstantExpr tree.
275
-
276
- After Pass 1 completes, we will know whether we found any references to
277
- globals in this pass. If the function does not use any globals (and most
278
- functions do not use any globals), then we return immediately.
279
-
280
- If a function does reference globals, then we iterate the list of globals
281
- used by this function and we generate Load instructions for each (unique)
282
- global.
283
-
284
- Next, we do another pass over all instructions:
285
-
286
- Pass 2:
287
- * Re-visit the instructions that were found in Pass 1.
288
-
289
- * If an instruction operand is a GlobalVariable, then look up the replacement
290
- __ref_* global variable and the Value that came from the Load instruction
291
- for it. Replace the operand of the GlobalVariable with the Load Value.
292
-
293
- * If an instruction operand is a ConstantExpr, then recursively examine the
294
- operands of all instructions in the ConstantExpr tree. If an operand is
295
- a GlobalVariable, then replace the operand with the result of the load
296
- *and* convert the ConstantExpr to a non-constant instruction. This
297
- instruction will need to be inserted into the BB of the instruction whose
298
- operand is being modified, ideally immediately before the instruction
299
- being modified.
300
- */
301
-
302
300
// Get or create a new global variable that points to the old one and whose
303
301
// name begins with `__ref_`.
304
302
//
@@ -308,7 +306,7 @@ Pass 2:
308
306
// that all code (both unpatched and patched) is using the same instances of
309
307
// global variables.
310
308
//
311
- // The Windows hot-patch infrastructure handles initializing these __ref_*
309
+ // The Windows hot-patch infrastructure handles modifying these __ref_*
312
310
// variables. By default, they are initialized with pointers to the equivalent
313
311
// global variables, so when a hot-patch module is loaded *as* a base image
314
312
// (such as after a system reboot), hot-patch functions will access the
@@ -428,27 +426,6 @@ static Value *rewriteGlobalVariablesInConstant(
428
426
return NewInst;
429
427
}
430
428
431
- // Processes a function that is marked for hot-patching.
432
- //
433
- // If a function is marked for hot-patching, we generate an S_HOTPATCHFUNC
434
- // CodeView debug symbol. Tools that generate hot-patches look for
435
- // S_HOTPATCHFUNC in final PDBs so that they can find functions that have been
436
- // hot-patched and so that they can distinguish hot-patched functions from
437
- // non-hot-patched functions.
438
- //
439
- // Also, in functions that are hot-patched, we must indirect all access to
440
- // (mutable) global variables through a pointer. This pointer may point into the
441
- // unpatched ("base") binary or may point into the patched image, depending on
442
- // whether a hot-patch was loaded as a patch or as a base image. These
443
- // indirections go through a new global variable, named `__ref_<Foo>` where
444
- // `<Foo>` is the original symbol name of the global variable.
445
- //
446
- // This function handles rewriting accesses to global variables, but the
447
- // generation of S_HOTPATCHFUNC occurs in
448
- // CodeViewDebug::emitHotPatchInformation().
449
- //
450
- // Returns true if any global variable references were found.
451
-
452
429
static bool searchConstantExprForGlobalVariables (
453
430
Value *V, SmallDenseMap<GlobalVariable *, Value *> &GVLoadMap,
454
431
SmallVector<GlobalVariableUse> &GVUses) {
@@ -479,6 +456,26 @@ static bool searchConstantExprForGlobalVariables(
479
456
}
480
457
}
481
458
459
+ // Processes a function that is marked for hot-patching.
460
+ //
461
+ // If a function is marked for hot-patching, we generate an S_HOTPATCHFUNC
462
+ // CodeView debug symbol. Tools that generate hot-patches look for
463
+ // S_HOTPATCHFUNC in final PDBs so that they can find functions that have been
464
+ // hot-patched and so that they can distinguish hot-patched functions from
465
+ // non-hot-patched functions.
466
+ //
467
+ // Also, in functions that are hot-patched, we must indirect all access to
468
+ // (mutable) global variables through a pointer. This pointer may point into the
469
+ // unpatched ("base") binary or may point into the patched image, depending on
470
+ // whether a hot-patch was loaded as a patch or as a base image. These
471
+ // indirections go through a new global variable, named `__ref_<Foo>` where
472
+ // `<Foo>` is the original symbol name of the global variable.
473
+ //
474
+ // This function handles rewriting accesses to global variables, but the
475
+ // generation of S_HOTPATCHFUNC occurs in
476
+ // CodeViewDebug::emitHotPatchInformation().
477
+ //
478
+ // Returns true if any global variable references were found and rewritten.
482
479
bool WindowsSecureHotPatching::runOnFunction (
483
480
Function &F,
484
481
SmallDenseMap<GlobalVariable *, GlobalVariable *> &RefMapping) {
0 commit comments