Index: lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1697,6 +1697,12 @@ if (G->hasSection()) { StringRef Section = G->getSection(); + // There are many non-default sections in the kernel, many of which contain + // arrays of structures and pointers, which are merged together and + // traversed at runtime. Instrumenting them would break the kernel. + if (CompileKernel) + return false; + // Globals from llvm.metadata aren't emitted, do not instrument them. if (Section == "llvm.metadata") return false; // Do not instrument globals from special LLVM sections. @@ -2251,7 +2257,9 @@ (UseGlobalsGC && TargetTriple.isOSBinFormatELF()) ? getUniqueModuleId(&M) : ""; - if (!ELFUniqueModuleId.empty()) { + // Clang emits invalid flags for section directives when trying to instrument + // kernel globals with InstrumentGlobalsELF(). + if (!ELFUniqueModuleId.empty() && !CompileKernel) { InstrumentGlobalsELF(IRB, M, NewGlobals, Initializers, ELFUniqueModuleId); *CtorComdat = true; } else if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF()) { @@ -2288,20 +2296,22 @@ Mapping = getShadowMapping(TargetTriple, LongSize, CompileKernel); initializeCallbacks(M); - if (CompileKernel) - return false; + // No need to emit __asan_init and __asan_version_mismatch_check_vXX for the + // kernel. + std::string VersionCheckName = + CompileKernel + ? "" + : kAsanVersionCheckNamePrefix + std::to_string(GetAsanVersion(M)); + std::string InitName = CompileKernel ? "" : kAsanInitName; // Create a module constructor. A destructor is created lazily because not all // platforms, and not all modules need it. - std::string VersionCheckName = - kAsanVersionCheckNamePrefix + std::to_string(GetAsanVersion(M)); std::tie(AsanCtorFunction, std::ignore) = createSanitizerCtorAndInitFunctions( - M, kAsanModuleCtorName, kAsanInitName, /*InitArgTypes=*/{}, + M, kAsanModuleCtorName, InitName, /*InitArgTypes=*/{}, /*InitArgs=*/{}, VersionCheckName); bool CtorComdat = true; bool Changed = false; - // TODO(glider): temporarily disabled globals instrumentation for KASan. if (ClGlobals) { IRBuilder<> IRB(AsanCtorFunction->getEntryBlock().getTerminator()); Changed |= InstrumentGlobals(IRB, M, &CtorComdat); @@ -2311,9 +2321,13 @@ // (1) global instrumentation is not TU-specific // (2) target is ELF. if (UseCtorComdat && TargetTriple.isOSBinFormatELF() && CtorComdat) { - AsanCtorFunction->setComdat(M.getOrInsertComdat(kAsanModuleCtorName)); - appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndDtorPriority, - AsanCtorFunction); + // When building the kernel, don't emit the constructor if there're no + // globals. + if (!CompileKernel || Changed) { + AsanCtorFunction->setComdat(M.getOrInsertComdat(kAsanModuleCtorName)); + appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndDtorPriority, + AsanCtorFunction); + } if (AsanDtorFunction) { AsanDtorFunction->setComdat(M.getOrInsertComdat(kAsanModuleDtorName)); appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndDtorPriority, Index: lib/Transforms/Utils/ModuleUtils.cpp =================================================================== --- lib/Transforms/Utils/ModuleUtils.cpp +++ lib/Transforms/Utils/ModuleUtils.cpp @@ -155,14 +155,17 @@ assert(!InitName.empty() && "Expected init function name"); assert(InitArgs.size() == InitArgTypes.size() && "Sanitizer's init function expects different number of arguments"); - Function *InitFunction = - declareSanitizerInitFunction(M, InitName, InitArgTypes); + Function *InitFunction = nullptr; + Function *Ctor = Function::Create( FunctionType::get(Type::getVoidTy(M.getContext()), false), GlobalValue::InternalLinkage, CtorName, &M); BasicBlock *CtorBB = BasicBlock::Create(M.getContext(), "", Ctor); IRBuilder<> IRB(ReturnInst::Create(M.getContext(), CtorBB)); - IRB.CreateCall(InitFunction, InitArgs); + if (!InitName.empty()) { + InitFunction = declareSanitizerInitFunction(M, InitName, InitArgTypes); + IRB.CreateCall(InitFunction, InitArgs); + } if (!VersionCheckName.empty()) { Function *VersionCheckFunction = checkSanitizerInterfaceFunction(M.getOrInsertFunction( Index: test/Instrumentation/AddressSanitizer/adaptive_global_redzones.ll =================================================================== --- test/Instrumentation/AddressSanitizer/adaptive_global_redzones.ll +++ test/Instrumentation/AddressSanitizer/adaptive_global_redzones.ll @@ -1,5 +1,6 @@ ; RUN: opt < %s -asan -asan-module -S | FileCheck %s ; RUN: opt < %s -asan -asan-module -asan-mapping-scale=5 -S | FileCheck %s +; RUN: opt < %s -asan -asan-module -asan-kernel=1 -S | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target triple = "x86_64-unknown-linux-gnu"