llvm.org GIT mirror llvm / 7c7b8e5
[msan] Fix handling of va_arg overflow area on x86_64. The code was erroneously reading overflow area shadow from the TLS slot, bypassing the local copy. Reading shadow directly from TLS is wrong, because it can be overwritten by a nested vararg call, if that happens before va_start. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189104 91177308-0d34-0410-b5e6-96231b3b80d8 Evgeniy Stepanov 7 years ago
2 changed file(s) with 26 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
19691969 Value *OverflowArgAreaPtr = IRB.CreateLoad(OverflowArgAreaPtrPtr);
19701970 Value *OverflowArgAreaShadowPtr =
19711971 MSV.getShadowPtr(OverflowArgAreaPtr, IRB.getInt8Ty(), IRB);
1972 Value *SrcPtr =
1973 getShadowPtrForVAArgument(VAArgTLSCopy, IRB, AMD64FpEndOffset);
1972 Value *SrcPtr = IRB.CreateConstGEP1_32(VAArgTLSCopy, AMD64FpEndOffset);
19741973 IRB.CreateMemCpy(OverflowArgAreaShadowPtr, SrcPtr, VAArgOverflowSize, 16);
19751974 }
19761975 }
596596 ; CHECK: ret void
597597
598598
599 ; Test that va_start instrumentation does not use va_arg_tls*.
600 ; It should work with a local stack copy instead.
601
602 %struct.__va_list_tag = type { i32, i32, i8*, i8* }
603 declare void @llvm.va_start(i8*) nounwind
604
605 ; Function Attrs: nounwind uwtable
606 define void @VAStart(i32 %x, ...) {
607 entry:
608 %x.addr = alloca i32, align 4
609 %va = alloca [1 x %struct.__va_list_tag], align 16
610 store i32 %x, i32* %x.addr, align 4
611 %arraydecay = getelementptr inbounds [1 x %struct.__va_list_tag]* %va, i32 0, i32 0
612 %arraydecay1 = bitcast %struct.__va_list_tag* %arraydecay to i8*
613 call void @llvm.va_start(i8* %arraydecay1)
614 ret void
615 }
616
617 ; CHECK: @VAStart
618 ; CHECK: call void @llvm.va_start
619 ; CHECK-NOT: @__msan_va_arg_tls
620 ; CHECK-NOT: @__msan_va_arg_overflow_size_tls
621 ; CHECK: ret void
622
623
599624 ; Test handling of volatile stores.
600625 ; Check that MemorySanitizer does not add a check of the value being stored.
601626