summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
diff options
context:
space:
mode:
authorMarcin Koscielnicki <koriakin@0x04.net>2016-05-09 20:57:36 +0000
committerMarcin Koscielnicki <koriakin@0x04.net>2016-05-09 20:57:36 +0000
commit60b3cbe0953c6f8662e39d1d8aab7a824ad7b721 (patch)
tree783043d6f1fff094ec2978d403e5a44eb6627ef8 /llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
parente36561855cea5f8946f5462afee12681841cedc7 (diff)
downloadbcm5719-llvm-60b3cbe0953c6f8662e39d1d8aab7a824ad7b721.tar.gz
bcm5719-llvm-60b3cbe0953c6f8662e39d1d8aab7a824ad7b721.zip
[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 llvm-svn: 268967
Diffstat (limited to 'llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp')
-rw-r--r--llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 96e94a76c91..3a544a28825 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -3131,13 +3131,13 @@ struct VarArgMIPS64Helper : public VarArgHelper {
/// \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 VarArgHelper {
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 VarArgHelper {
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 =
OpenPOWER on IntegriCloud