Index: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -54,6 +54,8 @@ #include "llvm/Transforms/Utils/ModuleUtils.h" #include "llvm/Transforms/Utils/PromoteMemToReg.h" #include +#include +#include #include #include @@ -111,6 +113,7 @@ static const char *const kAsanGenPrefix = "__asan_gen_"; static const char *const kODRGenPrefix = "__odr_asan_gen_"; static const char *const kSanCovGenPrefix = "__sancov_gen_"; +static const char *const kAsanSetShadowPrefix = "__asan_set_shadow_"; static const char *const kAsanPoisonStackMemoryName = "__asan_poison_stack_memory"; static const char *const kAsanUnpoisonStackMemoryName = @@ -170,6 +173,10 @@ static cl::opt ClUseAfterScope("asan-use-after-scope", cl::desc("Check stack-use-after-scope"), cl::Hidden, cl::init(false)); +static cl::opt ClExperimentalPoisoning( + "asan-experimental-poisoning", + cl::desc("Enable experimental red zones and scope poisoning"), cl::Hidden, + cl::init(false)); // This flag may need to be replaced with -f[no]asan-globals. static cl::opt ClGlobals("asan-globals", cl::desc("Handle global objects"), cl::Hidden, @@ -613,6 +620,7 @@ Function *AsanStackMallocFunc[kMaxAsanStackMallocSizeClass + 1], *AsanStackFreeFunc[kMaxAsanStackMallocSizeClass + 1]; + Function *AsanSetShadowFunc[0x100] = {}; Function *AsanPoisonStackMemoryFunc, *AsanUnpoisonStackMemoryFunc; Function *AsanAllocaPoisonFunc, *AsanAllocasUnpoisonFunc; @@ -1924,6 +1932,17 @@ IntptrTy, IntptrTy, nullptr)); } + if (ClExperimentalPoisoning) { + for (size_t Val : {0x00, 0xf1, 0xf2, 0xf3, 0xf5, 0xf8}) { + std::ostringstream Name; + Name << kAsanSetShadowPrefix; + Name << std::setw(2) << std::setfill('0') << std::hex << Val; + AsanSetShadowFunc[Val] = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + Name.str(), IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); + } + } + AsanAllocaPoisonFunc = checkSanitizerInterfaceFunction(M.getOrInsertFunction( kAsanAllocaPoison, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); AsanAllocasUnpoisonFunc = Index: llvm/trunk/test/Instrumentation/AddressSanitizer/stack-poisoning-experimental.ll =================================================================== --- llvm/trunk/test/Instrumentation/AddressSanitizer/stack-poisoning-experimental.ll +++ llvm/trunk/test/Instrumentation/AddressSanitizer/stack-poisoning-experimental.ll @@ -0,0 +1,24 @@ +; RUN: opt < %s -asan -asan-module -asan-experimental-poisoning -S | FileCheck %s +; RUN: opt < %s -asan -asan-module -S | FileCheck --check-prefix=CHECK-OFF %s + +target datalayout = "e-i64:64-f80:128-s:64-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare void @Foo(i8*) + +define void @Bar() uwtable sanitize_address { +entry: + %x = alloca [20 x i8], align 16 + %arraydecay = getelementptr inbounds [20 x i8], [20 x i8]* %x, i64 0, i64 0 + call void @Foo(i8* %arraydecay) + ret void +} + +; CHECK: declare void @__asan_set_shadow_00(i64, i64) +; CHECK: declare void @__asan_set_shadow_f1(i64, i64) +; CHECK: declare void @__asan_set_shadow_f2(i64, i64) +; CHECK: declare void @__asan_set_shadow_f3(i64, i64) +; CHECK: declare void @__asan_set_shadow_f5(i64, i64) +; CHECK: declare void @__asan_set_shadow_f8(i64, i64) + +; CHECK-OFF-NOT: declare void @__asan_set_shadow_