@@ -348,6 +348,13 @@ static cl::opt<bool> ClSkipPromotableAllocas(
348
348
cl::desc (" Do not instrument promotable allocas" ), cl::Hidden,
349
349
cl::init(true ));
350
350
351
+ static cl::opt<AsanCtorKind> ClConstructorKind (
352
+ " asan-constructor-kind" ,
353
+ cl::desc (" Sets the ASan constructor kind" ),
354
+ cl::values(clEnumValN(AsanCtorKind::None, " none" , " No constructors" ),
355
+ clEnumValN(AsanCtorKind::Global, " global" ,
356
+ " Use global constructors" )),
357
+ cl::init(AsanCtorKind::Global), cl::Hidden);
351
358
// These flags allow to change the shadow mapping.
352
359
// The shadow mapping looks like
353
360
// Shadow = (Mem >> scale) + offset
@@ -767,8 +774,9 @@ class ModuleAddressSanitizer {
767
774
public:
768
775
ModuleAddressSanitizer (Module &M, bool CompileKernel = false ,
769
776
bool Recover = false , bool UseGlobalsGC = true ,
770
- bool UseOdrIndicator = false ,
771
- AsanDtorKind DestructorKind = AsanDtorKind::Global)
777
+ bool UseOdrIndicator = true ,
778
+ AsanDtorKind DestructorKind = AsanDtorKind::Global,
779
+ AsanCtorKind ConstructorKind = AsanCtorKind::Global)
772
780
: CompileKernel(ClEnableKasan.getNumOccurrences() > 0 ? ClEnableKasan
773
781
: CompileKernel),
774
782
Recover (ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover),
@@ -784,7 +792,8 @@ class ModuleAddressSanitizer {
784
792
// ClWithComdat and ClUseGlobalsGC unless the frontend says it's ok to
785
793
// do globals-gc.
786
794
UseCtorComdat(UseGlobalsGC && ClWithComdat && !this ->CompileKernel),
787
- DestructorKind(DestructorKind) {
795
+ DestructorKind(DestructorKind),
796
+ ConstructorKind(ConstructorKind) {
788
797
C = &(M.getContext ());
789
798
int LongSize = M.getDataLayout ().getPointerSizeInBits ();
790
799
IntptrTy = Type::getIntNTy (*C, LongSize);
@@ -842,6 +851,7 @@ class ModuleAddressSanitizer {
842
851
bool UseOdrIndicator;
843
852
bool UseCtorComdat;
844
853
AsanDtorKind DestructorKind;
854
+ AsanCtorKind ConstructorKind;
845
855
Type *IntptrTy;
846
856
LLVMContext *C;
847
857
Triple TargetTriple;
@@ -1123,15 +1133,18 @@ void AddressSanitizerPass::printPipeline(
1123
1133
1124
1134
AddressSanitizerPass::AddressSanitizerPass (
1125
1135
const AddressSanitizerOptions &Options, bool UseGlobalGC,
1126
- bool UseOdrIndicator, AsanDtorKind DestructorKind)
1136
+ bool UseOdrIndicator, AsanDtorKind DestructorKind,
1137
+ AsanCtorKind ConstructorKind)
1127
1138
: Options(Options), UseGlobalGC(UseGlobalGC),
1128
- UseOdrIndicator(UseOdrIndicator), DestructorKind(DestructorKind) {}
1139
+ UseOdrIndicator(UseOdrIndicator), DestructorKind(DestructorKind),
1140
+ ConstructorKind(ClConstructorKind) {}
1129
1141
1130
1142
PreservedAnalyses AddressSanitizerPass::run (Module &M,
1131
1143
ModuleAnalysisManager &MAM) {
1132
1144
ModuleAddressSanitizer ModuleSanitizer (M, Options.CompileKernel ,
1133
1145
Options.Recover , UseGlobalGC,
1134
- UseOdrIndicator, DestructorKind);
1146
+ UseOdrIndicator, DestructorKind,
1147
+ ConstructorKind);
1135
1148
bool Modified = false ;
1136
1149
auto &FAM = MAM.getResult <FunctionAnalysisManagerModuleProxy>(M).getManager ();
1137
1150
const StackSafetyGlobalInfo *const SSGI =
@@ -2089,7 +2102,8 @@ void ModuleAddressSanitizer::InstrumentGlobalsELF(
2089
2102
StopELFMetadata->setVisibility (GlobalVariable::HiddenVisibility);
2090
2103
2091
2104
// Create a call to register the globals with the runtime.
2092
- IRB.CreateCall (AsanRegisterElfGlobals,
2105
+ if (ConstructorKind == AsanCtorKind::Global)
2106
+ IRB.CreateCall (AsanRegisterElfGlobals,
2093
2107
{IRB.CreatePointerCast (RegisteredFlag, IntptrTy),
2094
2108
IRB.CreatePointerCast (StartELFMetadata, IntptrTy),
2095
2109
IRB.CreatePointerCast (StopELFMetadata, IntptrTy)});
@@ -2152,7 +2166,8 @@ void ModuleAddressSanitizer::InstrumentGlobalsMachO(
2152
2166
ConstantInt::get (IntptrTy, 0 ), kAsanGlobalsRegisteredFlagName );
2153
2167
RegisteredFlag->setVisibility (GlobalVariable::HiddenVisibility);
2154
2168
2155
- IRB.CreateCall (AsanRegisterImageGlobals,
2169
+ if (ConstructorKind == AsanCtorKind::Global)
2170
+ IRB.CreateCall (AsanRegisterImageGlobals,
2156
2171
{IRB.CreatePointerCast (RegisteredFlag, IntptrTy)});
2157
2172
2158
2173
// We also need to unregister globals at the end, e.g., when a shared library
@@ -2181,7 +2196,8 @@ void ModuleAddressSanitizer::InstrumentGlobalsWithMetadataArray(
2181
2196
if (Mapping.Scale > 3 )
2182
2197
AllGlobals->setAlignment (Align (1ULL << Mapping.Scale ));
2183
2198
2184
- IRB.CreateCall (AsanRegisterGlobals,
2199
+ if (ConstructorKind == AsanCtorKind::Global)
2200
+ IRB.CreateCall (AsanRegisterGlobals,
2185
2201
{IRB.CreatePointerCast (AllGlobals, IntptrTy),
2186
2202
ConstantInt::get (IntptrTy, N)});
2187
2203
@@ -2436,24 +2452,32 @@ bool ModuleAddressSanitizer::instrumentModule(Module &M) {
2436
2452
2437
2453
// Create a module constructor. A destructor is created lazily because not all
2438
2454
// platforms, and not all modules need it.
2439
- if (CompileKernel) {
2440
- // The kernel always builds with its own runtime, and therefore does not
2441
- // need the init and version check calls.
2442
- AsanCtorFunction = createSanitizerCtor (M, kAsanModuleCtorName );
2443
- } else {
2444
- std::string AsanVersion = std::to_string (GetAsanVersion (M));
2445
- std::string VersionCheckName =
2446
- ClInsertVersionCheck ? (kAsanVersionCheckNamePrefix + AsanVersion) : " " ;
2447
- std::tie (AsanCtorFunction, std::ignore) =
2448
- createSanitizerCtorAndInitFunctions (M, kAsanModuleCtorName ,
2449
- kAsanInitName , /* InitArgTypes=*/ {},
2450
- /* InitArgs=*/ {}, VersionCheckName);
2455
+ if (ConstructorKind == AsanCtorKind::Global) {
2456
+ if (CompileKernel) {
2457
+ // The kernel always builds with its own runtime, and therefore does not
2458
+ // need the init and version check calls.
2459
+ AsanCtorFunction = createSanitizerCtor (M, kAsanModuleCtorName );
2460
+ } else {
2461
+ std::string AsanVersion = std::to_string (GetAsanVersion (M));
2462
+ std::string VersionCheckName =
2463
+ ClInsertVersionCheck ? (kAsanVersionCheckNamePrefix + AsanVersion) : " " ;
2464
+ std::tie (AsanCtorFunction, std::ignore) =
2465
+ createSanitizerCtorAndInitFunctions (M, kAsanModuleCtorName ,
2466
+ kAsanInitName , /* InitArgTypes=*/ {},
2467
+ /* InitArgs=*/ {}, VersionCheckName);
2468
+ }
2451
2469
}
2452
2470
2453
2471
bool CtorComdat = true ;
2454
2472
if (ClGlobals) {
2455
- IRBuilder<> IRB (AsanCtorFunction->getEntryBlock ().getTerminator ());
2456
- InstrumentGlobals (IRB, M, &CtorComdat);
2473
+ assert (AsanCtorFunction || ConstructorKind == AsanCtorKind::None);
2474
+ if (AsanCtorFunction) {
2475
+ IRBuilder<> IRB (AsanCtorFunction->getEntryBlock ().getTerminator ());
2476
+ InstrumentGlobals (IRB, M, &CtorComdat);
2477
+ } else {
2478
+ IRBuilder<> IRB (*C);
2479
+ InstrumentGlobals (IRB, M, &CtorComdat);
2480
+ }
2457
2481
}
2458
2482
2459
2483
const uint64_t Priority = GetCtorAndDtorPriority (TargetTriple);
@@ -2462,14 +2486,17 @@ bool ModuleAddressSanitizer::instrumentModule(Module &M) {
2462
2486
// (1) global instrumentation is not TU-specific
2463
2487
// (2) target is ELF.
2464
2488
if (UseCtorComdat && TargetTriple.isOSBinFormatELF () && CtorComdat) {
2465
- AsanCtorFunction->setComdat (M.getOrInsertComdat (kAsanModuleCtorName ));
2466
- appendToGlobalCtors (M, AsanCtorFunction, Priority, AsanCtorFunction);
2489
+ if (AsanCtorFunction) {
2490
+ AsanCtorFunction->setComdat (M.getOrInsertComdat (kAsanModuleCtorName ));
2491
+ appendToGlobalCtors (M, AsanCtorFunction, Priority, AsanCtorFunction);
2492
+ }
2467
2493
if (AsanDtorFunction) {
2468
2494
AsanDtorFunction->setComdat (M.getOrInsertComdat (kAsanModuleDtorName ));
2469
2495
appendToGlobalDtors (M, AsanDtorFunction, Priority, AsanDtorFunction);
2470
2496
}
2471
2497
} else {
2472
- appendToGlobalCtors (M, AsanCtorFunction, Priority);
2498
+ if (AsanCtorFunction)
2499
+ appendToGlobalCtors (M, AsanCtorFunction, Priority);
2473
2500
if (AsanDtorFunction)
2474
2501
appendToGlobalDtors (M, AsanDtorFunction, Priority);
2475
2502
}
0 commit comments