[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
This commit is contained in:
Evgeniy Stepanov 2013-08-23 12:11:00 +00:00
parent a0b2d332c1
commit 7c7b8e57f8
2 changed files with 26 additions and 2 deletions

View File

@ -1970,8 +1970,7 @@ struct VarArgAMD64Helper : public VarArgHelper {
Value *OverflowArgAreaPtr = IRB.CreateLoad(OverflowArgAreaPtrPtr); Value *OverflowArgAreaPtr = IRB.CreateLoad(OverflowArgAreaPtrPtr);
Value *OverflowArgAreaShadowPtr = Value *OverflowArgAreaShadowPtr =
MSV.getShadowPtr(OverflowArgAreaPtr, IRB.getInt8Ty(), IRB); MSV.getShadowPtr(OverflowArgAreaPtr, IRB.getInt8Ty(), IRB);
Value *SrcPtr = Value *SrcPtr = IRB.CreateConstGEP1_32(VAArgTLSCopy, AMD64FpEndOffset);
getShadowPtrForVAArgument(VAArgTLSCopy, IRB, AMD64FpEndOffset);
IRB.CreateMemCpy(OverflowArgAreaShadowPtr, SrcPtr, VAArgOverflowSize, 16); IRB.CreateMemCpy(OverflowArgAreaShadowPtr, SrcPtr, VAArgOverflowSize, 16);
} }
} }

View File

@ -597,6 +597,31 @@ define void @VACopy(i8* %p1, i8* %p2) nounwind uwtable sanitize_memory {
; CHECK: ret void ; CHECK: ret void
; Test that va_start instrumentation does not use va_arg_tls*.
; It should work with a local stack copy instead.
%struct.__va_list_tag = type { i32, i32, i8*, i8* }
declare void @llvm.va_start(i8*) nounwind
; Function Attrs: nounwind uwtable
define void @VAStart(i32 %x, ...) {
entry:
%x.addr = alloca i32, align 4
%va = alloca [1 x %struct.__va_list_tag], align 16
store i32 %x, i32* %x.addr, align 4
%arraydecay = getelementptr inbounds [1 x %struct.__va_list_tag]* %va, i32 0, i32 0
%arraydecay1 = bitcast %struct.__va_list_tag* %arraydecay to i8*
call void @llvm.va_start(i8* %arraydecay1)
ret void
}
; CHECK: @VAStart
; CHECK: call void @llvm.va_start
; CHECK-NOT: @__msan_va_arg_tls
; CHECK-NOT: @__msan_va_arg_overflow_size_tls
; CHECK: ret void
; Test handling of volatile stores. ; Test handling of volatile stores.
; Check that MemorySanitizer does not add a check of the value being stored. ; Check that MemorySanitizer does not add a check of the value being stored.