1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

[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.

llvm-svn: 189104
This commit is contained in:
Evgeniy Stepanov 2013-08-23 12:11:00 +00:00
parent 9ebd1c7d68
commit 47f9a57504
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 *OverflowArgAreaShadowPtr =
MSV.getShadowPtr(OverflowArgAreaPtr, IRB.getInt8Ty(), IRB);
Value *SrcPtr =
getShadowPtrForVAArgument(VAArgTLSCopy, IRB, AMD64FpEndOffset);
Value *SrcPtr = IRB.CreateConstGEP1_32(VAArgTLSCopy, AMD64FpEndOffset);
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
; 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.
; Check that MemorySanitizer does not add a check of the value being stored.