Index: lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -182,7 +182,7 @@ static cl::opt ClExperimentalPoisoning( "asan-experimental-poisoning", cl::desc("Enable experimental red zones and scope poisoning"), cl::Hidden, - cl::init(false)); + cl::init(true)); // 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, Index: test/Instrumentation/AddressSanitizer/lifetime-throw.ll =================================================================== --- test/Instrumentation/AddressSanitizer/lifetime-throw.ll +++ test/Instrumentation/AddressSanitizer/lifetime-throw.ll @@ -19,8 +19,12 @@ entry: %x = alloca %struct.ABC, align 4 %0 = bitcast %struct.ABC* %x to i8* + + ; Poison memory in prologue: F1F1F1F1F8F3F3F3 + ; CHECK: store i64 -868082052615769615, i64* %{{[0-9]+}} + call void @llvm.lifetime.start(i64 4, i8* %0) - ; CHECK: call void @__asan_unpoison_stack_memory + ; CHECK: store i8 4, i8* %{{[0-9]+}} ; CHECK-NEXT: @llvm.lifetime.start %exception = call i8* @__cxa_allocate_exception(i64 4) @@ -34,11 +38,11 @@ cleanup call void @_ZN3ABCD2Ev(%struct.ABC* nonnull %x) call void @llvm.lifetime.end(i64 4, i8* %0) - ; CHECK: call void @__asan_poison_stack_memory + ; CHECK: store i8 -8, i8* %{{[0-9]+}} ; CHECK-NEXT: @llvm.lifetime.end resume { i8*, i32 } %1 - ; CHECK: call void @__asan_unpoison_stack_memory + ; CHECK: store i64 0, i64* %{{[0-9]+}} ; CHECK-NEXT: resume unreachable: @@ -69,8 +73,12 @@ %x = alloca %struct.ABC, align 4 %tmp = alloca %struct.ABC, align 4 %0 = bitcast %struct.ABC* %x to i8* + + ; Poison memory in prologue: F1F1F1F1F8F304F2 + ; CHECK: store i64 -935355671561244175, i64* %{{[0-9]+}} + call void @llvm.lifetime.start(i64 4, i8* %0) - ; CHECK: call void @__asan_unpoison_stack_memory + ; CHECK: store i8 4, i8* %{{[0-9]+}} ; CHECK-NEXT: @llvm.lifetime.start %1 = bitcast %struct.ABC* %tmp to i8* @@ -83,11 +91,11 @@ %2 = cleanuppad within none [] call void @"\01??1ABC@@QEAA@XZ"(%struct.ABC* nonnull %x) [ "funclet"(token %2) ] call void @llvm.lifetime.end(i64 4, i8* %0) - ; CHECK: call void @__asan_poison_stack_memory + ; CHECK: store i8 -8, i8* %{{[0-9]+}} ; CHECK-NEXT: @llvm.lifetime.end cleanupret from %2 unwind to caller - ; CHECK: call void @__asan_unpoison_stack_memory + ; CHECK: store i64 0, i64* %{{[0-9]+}} ; CHECK-NEXT: cleanupret unreachable: Index: test/Instrumentation/AddressSanitizer/lifetime-uar-uas.ll =================================================================== --- test/Instrumentation/AddressSanitizer/lifetime-uar-uas.ll +++ test/Instrumentation/AddressSanitizer/lifetime-uar-uas.ll @@ -16,20 +16,22 @@ %retval = alloca i32, align 4 %c = alloca i8, align 1 + ; Memory is poisoned in prologue: F1F1F1F104F3F8F2 + ; CHECK-UAS: store i64 -866676825215864335, i64* %{{[0-9]+}} + call void @llvm.lifetime.start(i64 1, i8* %c) - ; Memory is unpoisoned at llvm.lifetime.start - ; CHECK-UAS: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 1) + ; Memory is unpoisoned at llvm.lifetime.start: 01 + ; CHECK-UAS: store i8 1, i8* %{{[0-9]+}} store volatile i32 0, i32* %retval store volatile i8 0, i8* %c, align 1 call void @llvm.lifetime.end(i64 1, i8* %c) - ; Memory is poisoned at llvm.lifetime.end - ; CHECK-UAS: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 1) + ; Memory is poisoned at llvm.lifetime.end: F8 + ; CHECK-UAS: store i8 -8, i8* %{{[0-9]+}} ; Unpoison memory at function exit in UAS mode. - ; CHECK-UAS: store i64 0 - ; CHECK-UAS-NEXT: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 64) + ; CHECK-UAS: store i64 0, i64* %{{[0-9]+}} ; CHECK-UAS: ret i32 0 ret i32 0 } Index: test/Instrumentation/AddressSanitizer/lifetime.ll =================================================================== --- test/Instrumentation/AddressSanitizer/lifetime.ll +++ test/Instrumentation/AddressSanitizer/lifetime.ll @@ -9,18 +9,30 @@ declare void @llvm.lifetime.end(i64, i8* nocapture) nounwind define void @lifetime_no_size() sanitize_address { + ; CHECK-LABEL: define void @lifetime_no_size() entry: %i = alloca i32, align 4 %i.ptr = bitcast i32* %i to i8* + + ; Poison memory in prologue: F1F1F1F104F3F3F3 + ; CHECK: store i64 -868083100587789839, i64* %{{[0-9]+}} + call void @llvm.lifetime.start(i64 -1, i8* %i.ptr) + ; Check that lifetime with no size are ignored. + ; CHECK-NOT: store + ; CHECK: call void @llvm.lifetime.start + store volatile i8 0, i8* %i.ptr + ; CHECK: store volatile + call void @llvm.lifetime.end(i64 -1, i8* %i.ptr) + ; Check that lifetime with no size are ignored. + ; CHECK-NOT: store + ; CHECK: call void @llvm.lifetime.end -; Check that lifetime with no size are ignored. -; CHECK-LABEL: define void @lifetime_no_size() -; CHECK-NOT: @__asan_poison_stack_memory -; CHECK-NOT: @__asan_unpoison_stack_memory -; CHECK: ret void + ; Unpoison stack frame on exit. + ; CHECK: store i64 0, i64* %{{[0-9]+}} + ; CHECK: ret void ret void } @@ -31,39 +43,57 @@ ; Regular variable lifetime intrinsics. %i = alloca i32, align 4 %i.ptr = bitcast i32* %i to i8* + + ; Poison memory in prologue: F1F1F1F1F8F3F3F3 + ; CHECK: store i64 -868082052615769615, i64* %{{[0-9]+}} + + ; Memory is unpoisoned at llvm.lifetime.start call void @llvm.lifetime.start(i64 3, i8* %i.ptr) + ; CHECK: store i8 4, i8* %{{[0-9]+}} + ; CHECK-NEXT: llvm.lifetime.start + store volatile i8 0, i8* %i.ptr - ; Memory is unpoisoned at llvm.lifetime.start - ; CHECK: %[[VAR:[^ ]*]] = ptrtoint i32* %{{[^ ]+}} to i64 - ; CHECK-NEXT: call void @__asan_unpoison_stack_memory(i64 %[[VAR]], i64 3) + ; CHECK: store volatile + call void @llvm.lifetime.end(i64 4, i8* %i.ptr) - call void @llvm.lifetime.end(i64 2, i8* %i.ptr) + ; CHECK: store i8 -8, i8* %{{[0-9]+}} + ; CHECK-NEXT: call void @llvm.lifetime.end + ; Memory is poisoned at every call to llvm.lifetime.end - ; CHECK: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 4) - ; CHECK: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 2) + call void @llvm.lifetime.end(i64 2, i8* %i.ptr) + ; CHECK: store i8 -8, i8* %{{[0-9]+}} + ; CHECK-NEXT: call void @llvm.lifetime.end ; Lifetime intrinsics for array. %arr = alloca [10 x i32], align 16 %arr.ptr = bitcast [10 x i32]* %arr to i8* + call void @llvm.lifetime.start(i64 40, i8* %arr.ptr) - store volatile i8 0, i8* %arr.ptr ; CHECK: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 40) ; CHECK-NO-DYNAMIC-NOT: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 40) + + store volatile i8 0, i8* %arr.ptr + ; CHECK: store volatile + call void @llvm.lifetime.end(i64 40, i8* %arr.ptr) ; CHECK: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 40) ; CHECK-NO-DYNAMIC-NOT: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 40) ; One more lifetime start/end for the same variable %i. - call void @llvm.lifetime.start(i64 4, i8* %i.ptr) + call void @llvm.lifetime.start(i64 2, i8* %i.ptr) + ; CHECK: store i8 4, i8* %{{[0-9]+}} + ; CHECK-NEXT: llvm.lifetime.start + store volatile i8 0, i8* %i.ptr - ; CHECK: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 4) + ; CHECK: store volatile + call void @llvm.lifetime.end(i64 4, i8* %i.ptr) - ; CHECK: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 4) + ; CHECK: store i8 -8, i8* %{{[0-9]+}} + ; CHECK-NEXT: llvm.lifetime.end ; Memory is unpoisoned at function exit (only once). - ; CHECK: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 {{.*}}) - ; CHECK-NOT: @__asan_unpoison_stack_memory - ; CHECK: ret void + ; CHECK: store i64 0, i64* %{{[0-9]+}} + ; CHECK-NEXT: ret void ret void } @@ -74,9 +104,17 @@ entry: %i = alloca i64, align 4 %i.ptr = bitcast i64* %i to i8* + + ; Poison memory in prologue: F1F1F1F1F8F3F3F3 + ; CHECK: store i64 -868082052615769615, i64* %{{[0-9]+}} + call void @llvm.lifetime.start(i64 8, i8* %i.ptr) + ; CHECK: store i8 0, i8* %{{[0-9]+}} + ; CHECK-NEXT: llvm.lifetime.start + store volatile i8 0, i8* %i.ptr - ; CHECK: __asan_unpoison_stack_memory + ; CHECK: store volatile + br i1 %x, label %bb0, label %bb1 bb0: @@ -86,9 +124,12 @@ bb1: %i.phi = phi i8* [ %i.ptr, %entry ], [ %i.ptr2, %bb0 ] call void @llvm.lifetime.end(i64 8, i8* %i.phi) - ; CHECK: __asan_poison_stack_memory - ; CHECK: ret void + ; CHECK: store i8 -8, i8* %{{[0-9]+}} + ; CHECK-NEXT: llvm.lifetime.end + ret void + ; CHECK: store i64 0, i64* %{{[0-9]+}} + ; CHECK-NEXT: ret void } ; Check that arguments of lifetime may come from getelementptr nodes. @@ -98,20 +139,28 @@ %x = alloca [1024 x i8], align 16 %d = alloca i8*, align 8 + ; F1F1F1F1 + ; CHECK: store i32 -235802127, i32* %{{[0-9]+}} + ; F3F3F3F3F3F3F3F3 + ; CHECK: store i64 -868082074056920077, i64* %{{[0-9]+}} + ; F3F3F3F3F3F3F3F3 + ; CHECK: store i64 -868082074056920077, i64* %{{[0-9]+}} + %0 = getelementptr inbounds [1024 x i8], [1024 x i8]* %x, i64 0, i64 0 call void @llvm.lifetime.start(i64 1024, i8* %0) - ; CHECK: __asan_unpoison_stack_memory + ; CHECK: call void @__asan_set_shadow_00(i64 %{{[0-9]+}}, i64 128) + ; CHECK-NEXT: call void @llvm.lifetime.start store i8* %0, i8** %d, align 8 + ; CHECK: store i8 call void @llvm.lifetime.end(i64 1024, i8* %0) - ; CHECK: __asan_poison_stack_memory + ; CHECK: call void @__asan_set_shadow_f8(i64 %{{[0-9]+}}, i64 128) + ; CHECK-NEXT: call void @llvm.lifetime.end ret void - ; CHECK: store i32 0 - ; CHECK: store i64 0 - ; CHECK: store i64 0 - ; CHECK-NEXT: __asan_unpoison_stack_memory + ; CHECK: call void @__asan_set_shadow_00(i64 %{{[0-9]+}}, i64 148) + ; CHECK-NEXT: ret void } define void @zero_sized(i64 %a) #0 { @@ -121,12 +170,17 @@ %a.addr = alloca i64, align 8 %b = alloca [0 x i8], align 1 store i64 %a, i64* %a.addr, align 8 + %0 = bitcast [0 x i8]* %b to i8* call void @llvm.lifetime.start(i64 0, i8* %0) #2 - ; CHECK-NOT: call void @__asan_unpoison_stack_memory + ; CHECK: %{{[0-9]+}} = bitcast + ; CHECK-NEXT: call void @llvm.lifetime.start + %1 = bitcast [0 x i8]* %b to i8* call void @llvm.lifetime.end(i64 0, i8* %1) #2 - ; CHECK-NOT: call void @__asan_poison_stack_memory + ; CHECK-NEXT: %{{[0-9]+}} = bitcast + ; CHECK-NEXT: call void @llvm.lifetime.end ret void + ; CHECK-NEXT: ret void } Index: test/Instrumentation/AddressSanitizer/stack-poisoning.ll =================================================================== --- test/Instrumentation/AddressSanitizer/stack-poisoning.ll +++ test/Instrumentation/AddressSanitizer/stack-poisoning.ll @@ -28,25 +28,8 @@ ; If LocalStackBase != OrigStackBase ; CHECK-UAR: label ; Then Block: poison the entire frame. - ; CHECK-UAR: store i64 -723401728380766731 - ; CHECK-UAR: store i64 -723401728380766731 - ; CHECK-UAR: store i64 -723401728380766731 - ; CHECK-UAR: store i64 -723401728380766731 - ; CHECK-UAR: store i64 -723401728380766731 - ; CHECK-UAR: store i64 -723401728380766731 - ; CHECK-UAR: store i64 -723401728380766731 - ; CHECK-UAR: store i64 -723401728380766731 - ; CHECK-UAR: store i64 -723401728380766731 - ; CHECK-UAR: store i64 -723401728380766731 - ; CHECK-UAR: store i64 -723401728380766731 - ; CHECK-UAR: store i64 -723401728380766731 - ; CHECK-UAR: store i64 -723401728380766731 - ; CHECK-UAR: store i64 -723401728380766731 - ; CHECK-UAR: store i64 -723401728380766731 - ; CHECK-UAR: store i64 -723401728380766731 + ; CHECK-UAR: call void @__asan_set_shadow_f5(i64 %{{[0-9]+}}, i64 128) ; CHECK-UAR-NOT: store i64 - ; CHECK-UAR: store i8 0 - ; CHECK-UAR-NOT: store ; CHECK-UAR: label ; Else Block: no UAR frame. Only unpoison the redzones. ; CHECK-UAR: store i64 0