@@ -349,6 +349,13 @@ static cl::opt<bool> ClSkipPromotableAllocas(
349
349
cl::desc (" Do not instrument promotable allocas" ), cl::Hidden,
350
350
cl::init(true ));
351
351
352
+ static cl::opt<AsanCtorKind> ClConstructorKind (
353
+ " asan-constructor-kind" ,
354
+ cl::desc (" Sets the ASan constructor kind" ),
355
+ cl::values(clEnumValN(AsanCtorKind::None, " none" , " No constructors" ),
356
+ clEnumValN(AsanCtorKind::Global, " global" ,
357
+ " Use global constructors" )),
358
+ cl::init(AsanCtorKind::Global), cl::Hidden);
352
359
// These flags allow to change the shadow mapping.
353
360
// The shadow mapping looks like
354
361
// Shadow = (Mem >> scale) + offset
@@ -772,7 +779,8 @@ class ModuleAddressSanitizer {
772
779
ModuleAddressSanitizer (Module &M, bool CompileKernel = false ,
773
780
bool Recover = false , bool UseGlobalsGC = true ,
774
781
bool UseOdrIndicator = true ,
775
- AsanDtorKind DestructorKind = AsanDtorKind::Global)
782
+ AsanDtorKind DestructorKind = AsanDtorKind::Global,
783
+ AsanCtorKind ConstructorKind = AsanCtorKind::Global)
776
784
: CompileKernel(ClEnableKasan.getNumOccurrences() > 0 ? ClEnableKasan
777
785
: CompileKernel),
778
786
Recover (ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover),
@@ -792,7 +800,8 @@ class ModuleAddressSanitizer {
792
800
// ClWithComdat and ClUseGlobalsGC unless the frontend says it's ok to
793
801
// do globals-gc.
794
802
UseCtorComdat(UseGlobalsGC && ClWithComdat && !this ->CompileKernel),
795
- DestructorKind(DestructorKind) {
803
+ DestructorKind(DestructorKind),
804
+ ConstructorKind(ConstructorKind) {
796
805
C = &(M.getContext ());
797
806
int LongSize = M.getDataLayout ().getPointerSizeInBits ();
798
807
IntptrTy = Type::getIntNTy (*C, LongSize);
@@ -850,6 +859,7 @@ class ModuleAddressSanitizer {
850
859
bool UseOdrIndicator;
851
860
bool UseCtorComdat;
852
861
AsanDtorKind DestructorKind;
862
+ AsanCtorKind ConstructorKind;
853
863
Type *IntptrTy;
854
864
LLVMContext *C;
855
865
Triple TargetTriple;
@@ -1131,15 +1141,18 @@ void AddressSanitizerPass::printPipeline(
1131
1141
1132
1142
AddressSanitizerPass::AddressSanitizerPass (
1133
1143
const AddressSanitizerOptions &Options, bool UseGlobalGC,
1134
- bool UseOdrIndicator, AsanDtorKind DestructorKind)
1144
+ bool UseOdrIndicator, AsanDtorKind DestructorKind,
1145
+ AsanCtorKind ConstructorKind)
1135
1146
: Options(Options), UseGlobalGC(UseGlobalGC),
1136
- UseOdrIndicator(UseOdrIndicator), DestructorKind(DestructorKind) {}
1147
+ UseOdrIndicator(UseOdrIndicator), DestructorKind(DestructorKind),
1148
+ ConstructorKind(ClConstructorKind) {}
1137
1149
1138
1150
PreservedAnalyses AddressSanitizerPass::run (Module &M,
1139
1151
ModuleAnalysisManager &MAM) {
1140
1152
ModuleAddressSanitizer ModuleSanitizer (M, Options.CompileKernel ,
1141
1153
Options.Recover , UseGlobalGC,
1142
- UseOdrIndicator, DestructorKind);
1154
+ UseOdrIndicator, DestructorKind,
1155
+ ConstructorKind);
1143
1156
bool Modified = false ;
1144
1157
auto &FAM = MAM.getResult <FunctionAnalysisManagerModuleProxy>(M).getManager ();
1145
1158
const StackSafetyGlobalInfo *const SSGI =
@@ -2095,7 +2108,8 @@ void ModuleAddressSanitizer::InstrumentGlobalsELF(
2095
2108
StopELFMetadata->setVisibility (GlobalVariable::HiddenVisibility);
2096
2109
2097
2110
// Create a call to register the globals with the runtime.
2098
- IRB.CreateCall (AsanRegisterElfGlobals,
2111
+ if (ConstructorKind == AsanCtorKind::Global)
2112
+ IRB.CreateCall (AsanRegisterElfGlobals,
2099
2113
{IRB.CreatePointerCast (RegisteredFlag, IntptrTy),
2100
2114
IRB.CreatePointerCast (StartELFMetadata, IntptrTy),
2101
2115
IRB.CreatePointerCast (StopELFMetadata, IntptrTy)});
@@ -2158,7 +2172,8 @@ void ModuleAddressSanitizer::InstrumentGlobalsMachO(
2158
2172
ConstantInt::get (IntptrTy, 0 ), kAsanGlobalsRegisteredFlagName );
2159
2173
RegisteredFlag->setVisibility (GlobalVariable::HiddenVisibility);
2160
2174
2161
- IRB.CreateCall (AsanRegisterImageGlobals,
2175
+ if (ConstructorKind == AsanCtorKind::Global)
2176
+ IRB.CreateCall (AsanRegisterImageGlobals,
2162
2177
{IRB.CreatePointerCast (RegisteredFlag, IntptrTy)});
2163
2178
2164
2179
// We also need to unregister globals at the end, e.g., when a shared library
@@ -2187,7 +2202,8 @@ void ModuleAddressSanitizer::InstrumentGlobalsWithMetadataArray(
2187
2202
if (Mapping.Scale > 3 )
2188
2203
AllGlobals->setAlignment (Align (1ULL << Mapping.Scale ));
2189
2204
2190
- IRB.CreateCall (AsanRegisterGlobals,
2205
+ if (ConstructorKind == AsanCtorKind::Global)
2206
+ IRB.CreateCall (AsanRegisterGlobals,
2191
2207
{IRB.CreatePointerCast (AllGlobals, IntptrTy),
2192
2208
ConstantInt::get (IntptrTy, N)});
2193
2209
@@ -2443,24 +2459,32 @@ bool ModuleAddressSanitizer::instrumentModule(Module &M) {
2443
2459
2444
2460
// Create a module constructor. A destructor is created lazily because not all
2445
2461
// platforms, and not all modules need it.
2446
- if (CompileKernel) {
2447
- // The kernel always builds with its own runtime, and therefore does not
2448
- // need the init and version check calls.
2449
- AsanCtorFunction = createSanitizerCtor (M, kAsanModuleCtorName );
2450
- } else {
2451
- std::string AsanVersion = std::to_string (GetAsanVersion (M));
2452
- std::string VersionCheckName =
2453
- ClInsertVersionCheck ? (kAsanVersionCheckNamePrefix + AsanVersion) : " " ;
2454
- std::tie (AsanCtorFunction, std::ignore) =
2455
- createSanitizerCtorAndInitFunctions (M, kAsanModuleCtorName ,
2456
- kAsanInitName , /* InitArgTypes=*/ {},
2457
- /* InitArgs=*/ {}, VersionCheckName);
2462
+ if (ConstructorKind == AsanCtorKind::Global) {
2463
+ if (CompileKernel) {
2464
+ // The kernel always builds with its own runtime, and therefore does not
2465
+ // need the init and version check calls.
2466
+ AsanCtorFunction = createSanitizerCtor (M, kAsanModuleCtorName );
2467
+ } else {
2468
+ std::string AsanVersion = std::to_string (GetAsanVersion (M));
2469
+ std::string VersionCheckName =
2470
+ ClInsertVersionCheck ? (kAsanVersionCheckNamePrefix + AsanVersion) : " " ;
2471
+ std::tie (AsanCtorFunction, std::ignore) =
2472
+ createSanitizerCtorAndInitFunctions (M, kAsanModuleCtorName ,
2473
+ kAsanInitName , /* InitArgTypes=*/ {},
2474
+ /* InitArgs=*/ {}, VersionCheckName);
2475
+ }
2458
2476
}
2459
2477
2460
2478
bool CtorComdat = true ;
2461
2479
if (ClGlobals) {
2462
- IRBuilder<> IRB (AsanCtorFunction->getEntryBlock ().getTerminator ());
2463
- InstrumentGlobals (IRB, M, &CtorComdat);
2480
+ assert (AsanCtorFunction || ConstructorKind == AsanCtorKind::None);
2481
+ if (AsanCtorFunction) {
2482
+ IRBuilder<> IRB (AsanCtorFunction->getEntryBlock ().getTerminator ());
2483
+ InstrumentGlobals (IRB, M, &CtorComdat);
2484
+ } else {
2485
+ IRBuilder<> IRB (*C);
2486
+ InstrumentGlobals (IRB, M, &CtorComdat);
2487
+ }
2464
2488
}
2465
2489
2466
2490
const uint64_t Priority = GetCtorAndDtorPriority (TargetTriple);
@@ -2469,14 +2493,17 @@ bool ModuleAddressSanitizer::instrumentModule(Module &M) {
2469
2493
// (1) global instrumentation is not TU-specific
2470
2494
// (2) target is ELF.
2471
2495
if (UseCtorComdat && TargetTriple.isOSBinFormatELF () && CtorComdat) {
2472
- AsanCtorFunction->setComdat (M.getOrInsertComdat (kAsanModuleCtorName ));
2473
- appendToGlobalCtors (M, AsanCtorFunction, Priority, AsanCtorFunction);
2496
+ if (AsanCtorFunction) {
2497
+ AsanCtorFunction->setComdat (M.getOrInsertComdat (kAsanModuleCtorName ));
2498
+ appendToGlobalCtors (M, AsanCtorFunction, Priority, AsanCtorFunction);
2499
+ }
2474
2500
if (AsanDtorFunction) {
2475
2501
AsanDtorFunction->setComdat (M.getOrInsertComdat (kAsanModuleDtorName ));
2476
2502
appendToGlobalDtors (M, AsanDtorFunction, Priority, AsanDtorFunction);
2477
2503
}
2478
2504
} else {
2479
- appendToGlobalCtors (M, AsanCtorFunction, Priority);
2505
+ if (AsanCtorFunction)
2506
+ appendToGlobalCtors (M, AsanCtorFunction, Priority);
2480
2507
if (AsanDtorFunction)
2481
2508
appendToGlobalDtors (M, AsanDtorFunction, Priority);
2482
2509
}
0 commit comments