@@ -148,6 +148,32 @@ static cl::opt<int> ClDebugMax("asan-debug-max", cl::desc("Debug man inst"),
148
148
cl::Hidden, cl::init(-1 ));
149
149
150
150
namespace {
151
+ // / A set of dynamically initialized globals extracted from metadata.
152
+ class SetOfDynamicallyInitializedGlobals {
153
+ public:
154
+ void Init (Module& M) {
155
+ // Clang generates metadata identifying all dynamically initialized globals.
156
+ NamedMDNode *DynamicGlobals =
157
+ M.getNamedMetadata (" llvm.asan.dynamically_initialized_globals" );
158
+ if (!DynamicGlobals)
159
+ return ;
160
+ for (int i = 0 , n = DynamicGlobals->getNumOperands (); i < n; ++i) {
161
+ MDNode *MDN = DynamicGlobals->getOperand (i);
162
+ assert (MDN->getNumOperands () == 1 );
163
+ Value *VG = MDN->getOperand (0 );
164
+ // The optimizer may optimize away a global entirely, in which case we
165
+ // cannot instrument access to it.
166
+ if (!VG)
167
+ continue ;
168
+ DynInitGlobals.insert (cast<GlobalVariable>(VG));
169
+ }
170
+ }
171
+ bool Contains (GlobalVariable *G) { return DynInitGlobals.count (G) != 0 ; }
172
+ private:
173
+ SmallSet<GlobalValue*, 32 > DynInitGlobals;
174
+ };
175
+
176
+
151
177
// / AddressSanitizer: instrument the code in module to find memory bugs.
152
178
struct AddressSanitizer : public FunctionPass {
153
179
AddressSanitizer ();
@@ -195,7 +221,6 @@ struct AddressSanitizer : public FunctionPass {
195
221
Value *ShadowBase, bool DoPoison);
196
222
bool LooksLikeCodeInBug11395 (Instruction *I);
197
223
void FindDynamicInitializers (Module &M);
198
- bool HasDynamicInitializer (GlobalVariable *G);
199
224
200
225
LLVMContext *C;
201
226
DataLayout *TD;
@@ -214,8 +239,8 @@ struct AddressSanitizer : public FunctionPass {
214
239
// This array is indexed by AccessIsWrite and log2(AccessSize).
215
240
Function *AsanErrorCallback[2 ][kNumberOfAccessSizes ];
216
241
InlineAsm *EmptyAsm;
217
- SmallSet<GlobalValue*, 32 > DynamicallyInitializedGlobals;
218
242
SmallSet<GlobalValue*, 32 > GlobalsCreatedByAsan;
243
+ SetOfDynamicallyInitializedGlobals DynamicallyInitializedGlobals;
219
244
};
220
245
221
246
} // namespace
@@ -328,30 +353,6 @@ static Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite) {
328
353
return NULL ;
329
354
}
330
355
331
- void AddressSanitizer::FindDynamicInitializers (Module& M) {
332
- // Clang generates metadata identifying all dynamically initialized globals.
333
- NamedMDNode *DynamicGlobals =
334
- M.getNamedMetadata (" llvm.asan.dynamically_initialized_globals" );
335
- if (!DynamicGlobals)
336
- return ;
337
- for (int i = 0 , n = DynamicGlobals->getNumOperands (); i < n; ++i) {
338
- MDNode *MDN = DynamicGlobals->getOperand (i);
339
- assert (MDN->getNumOperands () == 1 );
340
- Value *VG = MDN->getOperand (0 );
341
- // The optimizer may optimize away a global entirely, in which case we
342
- // cannot instrument access to it.
343
- if (!VG)
344
- continue ;
345
-
346
- GlobalVariable *G = cast<GlobalVariable>(VG);
347
- DynamicallyInitializedGlobals.insert (G);
348
- }
349
- }
350
- // Returns true if a global variable is initialized dynamically in this TU.
351
- bool AddressSanitizer::HasDynamicInitializer (GlobalVariable *G) {
352
- return DynamicallyInitializedGlobals.count (G);
353
- }
354
-
355
356
void AddressSanitizer::instrumentMop (Instruction *I) {
356
357
bool IsWrite = false ;
357
358
Value *Addr = isInterestingMemoryAccess (I, &IsWrite);
@@ -367,7 +368,7 @@ void AddressSanitizer::instrumentMop(Instruction *I) {
367
368
// assume it has dynamic initialization, as it may have an initializer
368
369
// in a different TU.
369
370
if (G->getLinkage () != GlobalVariable::ExternalLinkage &&
370
- !HasDynamicInitializer (G))
371
+ !DynamicallyInitializedGlobals. Contains (G))
371
372
return ;
372
373
}
373
374
}
@@ -590,9 +591,6 @@ bool AddressSanitizer::insertGlobalRedzones(Module &M) {
590
591
591
592
IRBuilder<> IRB (CtorInsertBefore);
592
593
593
- if (ClInitializers)
594
- FindDynamicInitializers (M);
595
-
596
594
// The addresses of the first and last dynamically initialized globals in
597
595
// this TU. Used in initialization order checking.
598
596
Value *FirstDynamic = 0 , *LastDynamic = 0 ;
@@ -606,7 +604,8 @@ bool AddressSanitizer::insertGlobalRedzones(Module &M) {
606
604
(RedzoneSize - (SizeInBytes % RedzoneSize));
607
605
Type *RightRedZoneTy = ArrayType::get (IRB.getInt8Ty (), RightRedzoneSize);
608
606
// Determine whether this global should be poisoned in initialization.
609
- bool GlobalHasDynamicInitializer = HasDynamicInitializer (G);
607
+ bool GlobalHasDynamicInitializer =
608
+ DynamicallyInitializedGlobals.Contains (G);
610
609
// Don't check initialization order if this global is blacklisted.
611
610
GlobalHasDynamicInitializer &= !BL->isInInit (*G);
612
611
@@ -704,6 +703,7 @@ bool AddressSanitizer::doInitialization(Module &M) {
704
703
if (!TD)
705
704
return false ;
706
705
BL.reset (new BlackList (ClBlackListFile));
706
+ DynamicallyInitializedGlobals.Init (M);
707
707
708
708
C = &(M.getContext ());
709
709
LongSize = TD->getPointerSizeInBits ();
0 commit comments