[llvm] r268967 - [MSan] [AArch64] Fix vararg helper for >1 or non-int fixed arguments.

Marcin Koscielnicki via llvm-commits llvm-commits at lists.llvm.org
Mon May 9 13:57:37 PDT 2016


Author: koriakin
Date: Mon May  9 15:57:36 2016
New Revision: 268967

URL: http://llvm.org/viewvc/llvm-project?rev=268967&view=rev
Log:
[MSan] [AArch64] Fix vararg helper for >1 or non-int fixed arguments.

This fixes http://llvm.org/PR27646 on AArch64.

There are three issues here:

- The GR save area is 7 words in size, instead of 8.  This is not enough
  if none of the fixed arguments is passed in GRs (they're all floats or
  aggregates).
- The first argument is ignored (which counteracts the above if it's passed
  in GR).
- Like x86_64, fixed arguments landing in the overflow area are wrongly
  counted towards the overflow offset.

Differential Revision: http://reviews.llvm.org/D20023

Modified:
    llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp
    llvm/trunk/test/Instrumentation/MemorySanitizer/AArch64/vararg.ll

Modified: llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp?rev=268967&r1=268966&r2=268967&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp Mon May  9 15:57:36 2016
@@ -3131,13 +3131,13 @@ struct VarArgMIPS64Helper : public VarAr
 
 /// \brief AArch64-specific implementation of VarArgHelper.
 struct VarArgAArch64Helper : public VarArgHelper {
-  static const unsigned kAArch64GrArgSize = 56;
+  static const unsigned kAArch64GrArgSize = 64;
   static const unsigned kAArch64VrArgSize = 128;
 
   static const unsigned AArch64GrBegOffset = 0;
   static const unsigned AArch64GrEndOffset = kAArch64GrArgSize;
   // Make VR space aligned to 16 bytes.
-  static const unsigned AArch64VrBegOffset = AArch64GrEndOffset + 8;
+  static const unsigned AArch64VrBegOffset = AArch64GrEndOffset;
   static const unsigned AArch64VrEndOffset = AArch64VrBegOffset
                                              + kAArch64VrArgSize;
   static const unsigned AArch64VAEndOffset = AArch64VrEndOffset;
@@ -3182,9 +3182,11 @@ struct VarArgAArch64Helper : public VarA
     unsigned OverflowOffset = AArch64VAEndOffset;
 
     const DataLayout &DL = F.getParent()->getDataLayout();
-    for (CallSite::arg_iterator ArgIt = CS.arg_begin() + 1, End = CS.arg_end();
+    for (CallSite::arg_iterator ArgIt = CS.arg_begin(), End = CS.arg_end();
          ArgIt != End; ++ArgIt) {
       Value *A = *ArgIt;
+      unsigned ArgNo = CS.getArgumentNo(ArgIt);
+      bool IsFixed = ArgNo < CS.getFunctionType()->getNumParams();
       ArgKind AK = classifyArgument(A);
       if (AK == AK_GeneralPurpose && GrOffset >= AArch64GrEndOffset)
         AK = AK_Memory;
@@ -3201,11 +3203,19 @@ struct VarArgAArch64Helper : public VarA
           VrOffset += 16;
           break;
         case AK_Memory:
+          // Don't count fixed arguments in the overflow area - va_start will
+          // skip right over them.
+          if (IsFixed)
+            continue;
           uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
           Base = getShadowPtrForVAArgument(A->getType(), IRB, OverflowOffset);
           OverflowOffset += alignTo(ArgSize, 8);
           break;
       }
+      // Count Gp/Vr fixed arguments to their respective offsets, but don't
+      // bother to actually store a shadow.
+      if (IsFixed)
+        continue;
       IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
     }
     Constant *OverflowSize =

Modified: llvm/trunk/test/Instrumentation/MemorySanitizer/AArch64/vararg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/MemorySanitizer/AArch64/vararg.ll?rev=268967&r1=268966&r2=268967&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/MemorySanitizer/AArch64/vararg.ll (original)
+++ llvm/trunk/test/Instrumentation/MemorySanitizer/AArch64/vararg.ll Mon May  9 15:57:36 2016
@@ -16,8 +16,8 @@ define i32 @foo(i32 %guard, ...) {
 }
 
 ; First check if the variadic shadow values are saved in stack with correct
-; size (192 is total of general purpose registers size, 56, rounded to 16
-; plus total of floating-point registers size, 128).
+; size (192 is total of general purpose registers size, 64, plus total of
+; floating-point registers size, 128).
 
 ; CHECK-LABEL: @foo
 ; CHECK: [[A:%.*]] = load {{.*}} @__msan_va_arg_overflow_size_tls
@@ -31,7 +31,7 @@ define i32 @foo(i32 %guard, ...) {
 ; offset in the __msan_va_arg_tls based on va_list:__gp_off, and finally
 ; issue the memcpy.
 ; CHECK: [[GRP:%.*]] = getelementptr inbounds i8, i8* {{%.*}}, i64 {{%.*}}
-; CHECK: [[GRSIZE:%.*]] = sub i64 56, {{%.*}}
+; CHECK: [[GRSIZE:%.*]] = sub i64 64, {{%.*}}
 ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{%.*}}, i8* [[GRP]], i64 [[GRSIZE]], i32 8, i1 false)
 
 ; Propagate the VR shadow values on for the va_list::__vr_top, adjust the 
@@ -59,17 +59,18 @@ define i32 @bar() {
 }
 
 ; Save the incoming shadow value from the arguments in the __msan_va_arg_tls
-; array.  General purpose registers are saved at positions from 0 to 56, Floating
+; array.  General purpose registers are saved at positions from 0 to 64, Floating
 ; point and SIMD are saved from 64 to 192, and the remaining from 192.
 ; CHECK-LABEL: @bar
 ; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 8
+; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 16
 ; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 64
 ; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 80
-; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 16
 ; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 24
-; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 96
 ; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 32
+; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 96
 ; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 40
 ; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 48
+; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 56
 ; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 192
 ; CHECK: store {{.*}} 8, {{.*}} @__msan_va_arg_overflow_size_tls




More information about the llvm-commits mailing list