kstoimenov created this revision. Herald added subscribers: ormris, hiraditya. kstoimenov requested review of this revision. Herald added projects: clang, LLVM. Herald added subscribers: llvm-commits, cfe-commits.
Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D112732 Files: clang/lib/CodeGen/BackendUtil.cpp clang/test/CodeGen/asan-stack-safety-analysis.c llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h llvm/lib/Passes/PassBuilder.cpp llvm/lib/Passes/PassRegistry.def llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp llvm/test/Instrumentation/MemorySanitizer/msan_eager.ll.rej
Index: llvm/test/Instrumentation/MemorySanitizer/msan_eager.ll.rej =================================================================== --- /dev/null +++ llvm/test/Instrumentation/MemorySanitizer/msan_eager.ll.rej @@ -0,0 +1,22 @@ +--- msan_eager.ll ++++ msan_eager.ll +@@ -69,8 +69,8 @@ + + define void @NormalArgAfterNoUndef(i32 noundef %a, i32 %b) nounwind uwtable sanitize_memory { + ; CHECK-LABEL: @NormalArgAfterNoUndef( +-; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* bitcast ([100 x i64]* @__msan_param_tls to i32*), align 8 +-; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__msan_param_origin_tls, i32 0, i32 0), align 4 ++; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__msan_param_tls to i64), i64 8) to i32*), align 8 ++; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* inttoptr (i64 add (i64 ptrtoint ([200 x i32]* @__msan_param_origin_tls to i64), i64 8) to i32*), align 4 + ; CHECK-NEXT: call void @llvm.donothing() + ; CHECK-NEXT: [[P:%.*]] = inttoptr i64 0 to i32* + ; CHECK-NEXT: [[TMP3:%.*]] = ptrtoint i32* [[P]] to i64 +@@ -135,7 +135,7 @@ + ; CHECK-LABEL: @CallNormalArgAfterNoUndef( + ; CHECK-NEXT: call void @llvm.donothing() + ; CHECK-NEXT: [[R:%.*]] = call i32 @NormalRet() #[[ATTR0]] +-; CHECK-NEXT: store i32 0, i32* bitcast ([100 x i64]* @__msan_param_tls to i32*), align 8 ++; CHECK-NEXT: store i32 0, i32* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__msan_param_tls to i64), i64 8) to i32*), align 8 + ; CHECK-NEXT: call void @NormalArgAfterNoUndef(i32 [[R]], i32 [[R]]) #[[ATTR0]] + ; CHECK-NEXT: ret void + ; Index: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1254,35 +1254,6 @@ return GlobalsMetadata(M); } -PreservedAnalyses AddressSanitizerPass::run(Function &F, - AnalysisManager<Function> &AM) { - auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F); - Module &M = *F.getParent(); - if (auto *R = MAMProxy.getCachedResult<ASanGlobalsMetadataAnalysis>(M)) { - const TargetLibraryInfo *TLI = &AM.getResult<TargetLibraryAnalysis>(F); - AddressSanitizer Sanitizer(M, R, Options.CompileKernel, Options.Recover, - Options.UseAfterScope, Options.UseAfterReturn); - if (Sanitizer.instrumentFunction(F, TLI)) - return PreservedAnalyses::none(); - return PreservedAnalyses::all(); - } - - report_fatal_error( - "The ASanGlobalsMetadataAnalysis is required to run before " - "AddressSanitizer can run"); - return PreservedAnalyses::all(); -} - -void AddressSanitizerPass::printPipeline( - raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) { - static_cast<PassInfoMixin<AddressSanitizerPass> *>(this)->printPipeline( - OS, MapClassName2PassName); - OS << "<"; - if (Options.CompileKernel) - OS << "kernel"; - OS << ">"; -} - void ModuleAddressSanitizerPass::printPipeline( raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) { static_cast<PassInfoMixin<ModuleAddressSanitizerPass> *>(this)->printPipeline( @@ -1295,9 +1266,11 @@ ModuleAddressSanitizerPass::ModuleAddressSanitizerPass( bool CompileKernel, bool Recover, bool UseGlobalGC, bool UseOdrIndicator, - AsanDtorKind DestructorKind) + AsanDtorKind DestructorKind, bool UseAfterScope, + AsanDetectStackUseAfterReturnMode UseAfterReturn) : CompileKernel(CompileKernel), Recover(Recover), UseGlobalGC(UseGlobalGC), - UseOdrIndicator(UseOdrIndicator), DestructorKind(DestructorKind) {} + UseOdrIndicator(UseOdrIndicator), DestructorKind(DestructorKind), + UseAfterScope(UseAfterScope), UseAfterReturn(UseAfterReturn) {} PreservedAnalyses ModuleAddressSanitizerPass::run(Module &M, AnalysisManager<Module> &AM) { @@ -1305,7 +1278,14 @@ ModuleAddressSanitizer Sanitizer(M, &GlobalsMD, CompileKernel, Recover, UseGlobalGC, UseOdrIndicator, DestructorKind); - if (Sanitizer.instrumentModule(M)) + bool Modified = Sanitizer.instrumentModule(M); + const TargetLibraryInfo *TLI = &AM.getResult<TargetLibraryAnalysis>(M); + for (Function &F : M) { + AddressSanitizer Sanitizer(M, &GlobalsMD, CompileKernel, Recover, + UseAfterScope, UseAfterReturn); + Modified |= Sanitizer.instrumentFunction(F, TLI); + } + if (Modified) return PreservedAnalyses::none(); return PreservedAnalyses::all(); } Index: llvm/lib/Passes/PassRegistry.def =================================================================== --- llvm/lib/Passes/PassRegistry.def +++ llvm/lib/Passes/PassRegistry.def @@ -393,13 +393,6 @@ "no-profile-peeling;profile-peeling;" "no-runtime;runtime;" "no-upperbound;upperbound") -FUNCTION_PASS_WITH_PARAMS("asan", - "AddressSanitizerPass", - [](AddressSanitizerOptions Opts) { - return AddressSanitizerPass(Opts); - }, - parseASanPassOptions, - "kernel") FUNCTION_PASS_WITH_PARAMS("msan", "MemorySanitizerPass", [](MemorySanitizerOptions Opts) { Index: llvm/lib/Passes/PassBuilder.cpp =================================================================== --- llvm/lib/Passes/PassBuilder.cpp +++ llvm/lib/Passes/PassBuilder.cpp @@ -584,24 +584,6 @@ return parseSinglePassOption(Params, "kernel", "ModuleAddressSanitizer"); } -Expected<AddressSanitizerOptions> parseASanPassOptions(StringRef Params) { - AddressSanitizerOptions Result; - while (!Params.empty()) { - StringRef ParamName; - std::tie(ParamName, Params) = Params.split(';'); - - if (ParamName == "kernel") { - Result.CompileKernel = true; - } else { - return make_error<StringError>( - formatv("invalid AddressSanitizer pass parameter '{0}' ", ParamName) - .str(), - inconvertibleErrorCode()); - } - } - return Result; -} - Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) { HWAddressSanitizerOptions Result; while (!Params.empty()) { Index: llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h =================================================================== --- llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h +++ llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h @@ -89,40 +89,6 @@ static AnalysisKey Key; }; -struct AddressSanitizerOptions { - AddressSanitizerOptions() - : AddressSanitizerOptions(false, false, false, - AsanDetectStackUseAfterReturnMode::Runtime){}; - AddressSanitizerOptions(bool CompileKernel, bool Recover, bool UseAfterScope, - AsanDetectStackUseAfterReturnMode UseAfterReturn) - : CompileKernel(CompileKernel), Recover(Recover), - UseAfterScope(UseAfterScope), UseAfterReturn(UseAfterReturn){}; - bool CompileKernel; - bool Recover; - bool UseAfterScope; - AsanDetectStackUseAfterReturnMode UseAfterReturn; -}; - -/// Public interface to the address sanitizer pass for instrumenting code to -/// check for various memory errors at runtime. -/// -/// The sanitizer itself is a function pass that works by inserting various -/// calls to the ASan runtime library functions. The runtime library essentially -/// replaces malloc() and free() with custom implementations that allow regions -/// surrounding requested memory to be checked for invalid accesses. -class AddressSanitizerPass : public PassInfoMixin<AddressSanitizerPass> { -public: - explicit AddressSanitizerPass(AddressSanitizerOptions Options) - : Options(Options){}; - PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); - void printPipeline(raw_ostream &OS, - function_ref<StringRef(StringRef)> MapClassName2PassName); - static bool isRequired() { return true; } - -private: - AddressSanitizerOptions Options; -}; - /// Public interface to the address sanitizer module pass for instrumenting code /// to check for various memory errors. /// @@ -134,7 +100,10 @@ explicit ModuleAddressSanitizerPass( bool CompileKernel = false, bool Recover = false, bool UseGlobalGC = true, bool UseOdrIndicator = false, - AsanDtorKind DestructorKind = AsanDtorKind::Global); + AsanDtorKind DestructorKind = AsanDtorKind::Global, + bool UseAfterScope = false, + AsanDetectStackUseAfterReturnMode UseAfterReturn = + AsanDetectStackUseAfterReturnMode::Runtime); PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); void printPipeline(raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName); @@ -146,6 +115,8 @@ bool UseGlobalGC; bool UseOdrIndicator; AsanDtorKind DestructorKind; + bool UseAfterScope; + AsanDetectStackUseAfterReturnMode UseAfterReturn; }; // Insert AddressSanitizer (address sanity checking) instrumentation Index: clang/test/CodeGen/asan-stack-safety-analysis.c =================================================================== --- /dev/null +++ clang/test/CodeGen/asan-stack-safety-analysis.c @@ -0,0 +1,16 @@ +// REQUIRES: x86_64-pc-linux-gnu + +// RUN: %clang -fno-legacy-pass-manager -fsanitize=address -fsanitize-address-outline-instrumentation -target x86_64-pc-linux-gnu -S -emit-llvm -mllvm -asan-use-stack-safety=true -O2 %s -o - | FileCheck %s --check-prefix=SAFETY +// RUN: %clang -fno-legacy-pass-manager -fsanitize=address -fsanitize-address-outline-instrumentation -target x86_64-pc-linux-gnu -S -emit-llvm -mllvm -asan-use-stack-safety=false -O2 %s -o - | FileCheck %s --check-prefix=NOSAFETY + +// RUN: %clang -flegacy-pass-manager -fsanitize=address -target x86_64-pc-linux-gnu -S -emit-llvm -mllvm -asan-use-stack-safety=true -O2 %s -o - | FileCheck %s --check-prefix=SAFETY +// RUN: %clang -flegacy-pass-manager -fsanitize=address -target x86_64-pc-linux-gnu -S -emit-llvm -mllvm -asan-use-stack-safety=false -O2 %s -o - | FileCheck %s --check-prefix=NOSAFETY + +int main(int argc, char **argv) { + char buf[10]; + volatile char *x = buf; + *x = 0; + return buf[0]; + // NOSAFETY: call void @__asan_load1 + // SAFETY-NOT: call void @__asan_load1 +} Index: clang/lib/CodeGen/BackendUtil.cpp =================================================================== --- clang/lib/CodeGen/BackendUtil.cpp +++ clang/lib/CodeGen/BackendUtil.cpp @@ -1187,9 +1187,7 @@ MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>()); MPM.addPass(ModuleAddressSanitizerPass( CompileKernel, Recover, ModuleUseAfterScope, UseOdrIndicator, - DestructorKind)); - MPM.addPass(createModuleToFunctionPassAdaptor(AddressSanitizerPass( - {CompileKernel, Recover, UseAfterScope, UseAfterReturn}))); + DestructorKind, UseAfterScope, UseAfterReturn)); } }; ASanPass(SanitizerKind::Address, false);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits