@@ -6399,8 +6399,8 @@ struct VarArgPowerPC64Helper : public VarArgHelperBase {
6399
6399
Value *VAArgSize = nullptr ;
6400
6400
6401
6401
VarArgPowerPC64Helper (Function &F, MemorySanitizer &MS,
6402
- MemorySanitizerVisitor &MSV, unsigned VAListTagSize )
6403
- : VarArgHelperBase(F, MS, MSV, VAListTagSize) {}
6402
+ MemorySanitizerVisitor &MSV)
6403
+ : VarArgHelperBase(F, MS, MSV, /* VAListTagSize= */ 8 ) {}
6404
6404
6405
6405
void visitCallBase (CallBase &CB, IRBuilder<> &IRB) override {
6406
6406
// For PowerPC, we need to deal with alignment of stack arguments -
@@ -6414,15 +6414,10 @@ struct VarArgPowerPC64Helper : public VarArgHelperBase {
6414
6414
// Parameter save area starts at 48 bytes from frame pointer for ABIv1,
6415
6415
// and 32 bytes for ABIv2. This is usually determined by target
6416
6416
// endianness, but in theory could be overridden by function attribute.
6417
- if (TargetTriple.isPPC64 ()) {
6418
- if (TargetTriple.isPPC64ELFv2ABI ())
6419
- VAArgBase = 32 ;
6420
- else
6421
- VAArgBase = 48 ;
6422
- } else {
6423
- // Parameter save area is 8 bytes from frame pointer in PPC32
6424
- VAArgBase = 8 ;
6425
- }
6417
+ if (TargetTriple.isPPC64ELFv2ABI ())
6418
+ VAArgBase = 32 ;
6419
+ else
6420
+ VAArgBase = 48 ;
6426
6421
unsigned VAArgOffset = VAArgBase;
6427
6422
const DataLayout &DL = F.getDataLayout ();
6428
6423
for (const auto &[ArgNo, A] : llvm::enumerate (CB.args ())) {
@@ -6524,11 +6519,6 @@ struct VarArgPowerPC64Helper : public VarArgHelperBase {
6524
6519
Value *VAListTag = OrigInst->getArgOperand (0 );
6525
6520
Value *RegSaveAreaPtrPtr = IRB.CreatePtrToInt (VAListTag, MS.IntptrTy );
6526
6521
6527
- // In PPC32 va_list_tag is a struct, whereas in PPC64 it's a pointer
6528
- if (!TargetTriple.isPPC64 ()) {
6529
- RegSaveAreaPtrPtr =
6530
- IRB.CreateAdd (RegSaveAreaPtrPtr, ConstantInt::get (MS.IntptrTy , 8 ));
6531
- }
6532
6522
RegSaveAreaPtrPtr = IRB.CreateIntToPtr (RegSaveAreaPtrPtr, MS.PtrTy );
6533
6523
6534
6524
Value *RegSaveAreaPtr = IRB.CreateLoad (MS.PtrTy , RegSaveAreaPtrPtr);
@@ -6551,42 +6541,27 @@ struct VarArgPowerPC32Helper : public VarArgHelperBase {
6551
6541
Value *VAArgSize = nullptr ;
6552
6542
6553
6543
VarArgPowerPC32Helper (Function &F, MemorySanitizer &MS,
6554
- MemorySanitizerVisitor &MSV, unsigned VAListTagSize )
6555
- : VarArgHelperBase(F, MS, MSV, VAListTagSize) {}
6544
+ MemorySanitizerVisitor &MSV)
6545
+ : VarArgHelperBase(F, MS, MSV, /* VAListTagSize= */ 12 ) {}
6556
6546
6557
6547
void visitCallBase (CallBase &CB, IRBuilder<> &IRB) override {
6558
- // For PowerPC, we need to deal with alignment of stack arguments -
6559
- // they are mostly aligned to 8 bytes, but vectors and i128 arrays
6560
- // are aligned to 16 bytes, byvals can be aligned to 8 or 16 bytes,
6561
- // For that reason, we compute current offset from stack pointer (which is
6562
- // always properly aligned), and offset for the first vararg, then subtract
6563
- // them.
6564
6548
unsigned VAArgBase;
6565
6549
Triple TargetTriple (F.getParent ()->getTargetTriple ());
6566
- // Parameter save area starts at 48 bytes from frame pointer for ABIv1,
6567
- // and 32 bytes for ABIv2. This is usually determined by target
6568
- // endianness, but in theory could be overridden by function attribute.
6569
- if (TargetTriple.isPPC64 ()) {
6570
- if (TargetTriple.isPPC64ELFv2ABI ())
6571
- VAArgBase = 32 ;
6572
- else
6573
- VAArgBase = 48 ;
6574
- } else {
6575
- // Parameter save area is 8 bytes from frame pointer in PPC32
6576
- VAArgBase = 8 ;
6577
- }
6550
+ // Parameter save area is 8 bytes from frame pointer in PPC32
6551
+ VAArgBase = 8 ;
6578
6552
unsigned VAArgOffset = VAArgBase;
6579
6553
const DataLayout &DL = F.getDataLayout ();
6554
+ unsigned IntptrSize = DL.getTypeStoreSize (MS.IntptrTy );
6580
6555
for (const auto &[ArgNo, A] : llvm::enumerate (CB.args ())) {
6581
6556
bool IsFixed = ArgNo < CB.getFunctionType ()->getNumParams ();
6582
6557
bool IsByVal = CB.paramHasAttr (ArgNo, Attribute::ByVal);
6583
6558
if (IsByVal) {
6584
6559
assert (A->getType ()->isPointerTy ());
6585
6560
Type *RealTy = CB.getParamByValType (ArgNo);
6586
6561
uint64_t ArgSize = DL.getTypeAllocSize (RealTy);
6587
- Align ArgAlign = CB.getParamAlign (ArgNo).value_or (Align (8 ));
6588
- if (ArgAlign < 8 )
6589
- ArgAlign = Align (8 );
6562
+ Align ArgAlign = CB.getParamAlign (ArgNo).value_or (Align (IntptrSize ));
6563
+ if (ArgAlign < IntptrSize )
6564
+ ArgAlign = Align (IntptrSize );
6590
6565
VAArgOffset = alignTo (VAArgOffset, ArgAlign);
6591
6566
if (!IsFixed) {
6592
6567
Value *Base =
@@ -6601,41 +6576,47 @@ struct VarArgPowerPC32Helper : public VarArgHelperBase {
6601
6576
kShadowTLSAlignment , ArgSize);
6602
6577
}
6603
6578
}
6604
- VAArgOffset += alignTo (ArgSize, Align (8 ));
6579
+ VAArgOffset += alignTo (ArgSize, Align (IntptrSize ));
6605
6580
} else {
6606
6581
Value *Base;
6607
- uint64_t ArgSize = DL.getTypeAllocSize (A->getType ());
6608
- Align ArgAlign = Align (8 );
6609
- if (A->getType ()->isArrayTy ()) {
6610
- // Arrays are aligned to element size, except for long double
6611
- // arrays, which are aligned to 8 bytes.
6612
- Type *ElementTy = A->getType ()->getArrayElementType ();
6613
- if (!ElementTy->isPPC_FP128Ty ())
6614
- ArgAlign = Align (DL.getTypeAllocSize (ElementTy));
6615
- } else if (A->getType ()->isVectorTy ()) {
6616
- // Vectors are naturally aligned.
6617
- ArgAlign = Align (ArgSize);
6618
- }
6619
- if (ArgAlign < 8 )
6620
- ArgAlign = Align (8 );
6621
- VAArgOffset = alignTo (VAArgOffset, ArgAlign);
6622
- if (DL.isBigEndian ()) {
6623
- // Adjusting the shadow for argument with size < 8 to match the
6624
- // placement of bits in big endian system
6625
- if (ArgSize < 8 )
6626
- VAArgOffset += (8 - ArgSize);
6627
- }
6628
- if (!IsFixed) {
6629
- Base =
6630
- getShadowPtrForVAArgument (IRB, VAArgOffset - VAArgBase, ArgSize);
6631
- if (Base)
6632
- IRB.CreateAlignedStore (MSV.getShadow (A), Base, kShadowTLSAlignment );
6582
+ Type *ArgTy = A->getType ();
6583
+
6584
+ // On PPC 32 floating point variable arguments are stored in separate
6585
+ // area: fp_save_area = reg_save_area + 4*8. We do not copy shaodow for
6586
+ // them as they will be found when checking call arguments.
6587
+ if (!ArgTy->isFloatingPointTy ()) {
6588
+ uint64_t ArgSize = DL.getTypeAllocSize (ArgTy);
6589
+ Align ArgAlign = Align (IntptrSize);
6590
+ if (ArgTy->isArrayTy ()) {
6591
+ // Arrays are aligned to element size, except for long double
6592
+ // arrays, which are aligned to 8 bytes.
6593
+ Type *ElementTy = ArgTy->getArrayElementType ();
6594
+ if (!ElementTy->isPPC_FP128Ty ())
6595
+ ArgAlign = Align (DL.getTypeAllocSize (ElementTy));
6596
+ } else if (ArgTy->isVectorTy ()) {
6597
+ // Vectors are naturally aligned.
6598
+ ArgAlign = Align (ArgSize);
6599
+ }
6600
+ if (ArgAlign < IntptrSize)
6601
+ ArgAlign = Align (IntptrSize);
6602
+ VAArgOffset = alignTo (VAArgOffset, ArgAlign);
6603
+ if (DL.isBigEndian ()) {
6604
+ // Adjusting the shadow for argument with size < IntptrSize to match
6605
+ // the placement of bits in big endian system
6606
+ if (ArgSize < IntptrSize)
6607
+ VAArgOffset += (IntptrSize - ArgSize);
6608
+ }
6609
+ if (!IsFixed) {
6610
+ Base = getShadowPtrForVAArgument (IRB, VAArgOffset - VAArgBase,
6611
+ ArgSize);
6612
+ if (Base)
6613
+ IRB.CreateAlignedStore (MSV.getShadow (A), Base,
6614
+ kShadowTLSAlignment );
6615
+ }
6616
+ VAArgOffset += ArgSize;
6617
+ VAArgOffset = alignTo (VAArgOffset, Align (IntptrSize));
6633
6618
}
6634
- VAArgOffset += ArgSize;
6635
- VAArgOffset = alignTo (VAArgOffset, Align (8 ));
6636
6619
}
6637
- if (IsFixed)
6638
- VAArgBase = VAArgOffset;
6639
6620
}
6640
6621
6641
6622
Constant *TotalVAArgSize =
@@ -6675,24 +6656,68 @@ struct VarArgPowerPC32Helper : public VarArgHelperBase {
6675
6656
NextNodeIRBuilder IRB (OrigInst);
6676
6657
Value *VAListTag = OrigInst->getArgOperand (0 );
6677
6658
Value *RegSaveAreaPtrPtr = IRB.CreatePtrToInt (VAListTag, MS.IntptrTy );
6659
+ Value *RegSaveAreaSize = CopySize;
6678
6660
6679
- // In PPC32 va_list_tag is a struct, whereas in PPC64 it's a pointer
6680
- if (!TargetTriple.isPPC64 ()) {
6681
- RegSaveAreaPtrPtr =
6682
- IRB.CreateAdd (RegSaveAreaPtrPtr, ConstantInt::get (MS.IntptrTy , 8 ));
6683
- }
6684
- RegSaveAreaPtrPtr = IRB.CreateIntToPtr (RegSaveAreaPtrPtr, MS.PtrTy );
6661
+ // In PPC32 va_list_tag is a struct
6662
+ RegSaveAreaPtrPtr =
6663
+ IRB.CreateAdd (RegSaveAreaPtrPtr, ConstantInt::get (MS.IntptrTy , 8 ));
6664
+
6665
+ // On PPC 32 reg_save_area can only hold 32 bytes of data
6666
+ RegSaveAreaSize = IRB.CreateBinaryIntrinsic (
6667
+ Intrinsic::umin, CopySize, ConstantInt::get (MS.IntptrTy , 32 ));
6685
6668
6669
+ RegSaveAreaPtrPtr = IRB.CreateIntToPtr (RegSaveAreaPtrPtr, MS.PtrTy );
6686
6670
Value *RegSaveAreaPtr = IRB.CreateLoad (MS.PtrTy , RegSaveAreaPtrPtr);
6687
- Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
6671
+
6688
6672
const DataLayout &DL = F.getDataLayout ();
6689
6673
unsigned IntptrSize = DL.getTypeStoreSize (MS.IntptrTy );
6690
6674
const Align Alignment = Align (IntptrSize);
6691
- std::tie (RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
6692
- MSV.getShadowOriginPtr (RegSaveAreaPtr, IRB, IRB.getInt8Ty (),
6693
- Alignment, /* isStore*/ true );
6694
- IRB.CreateMemCpy (RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
6695
- CopySize);
6675
+
6676
+ { // Copy reg save area
6677
+ Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
6678
+ std::tie (RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
6679
+ MSV.getShadowOriginPtr (RegSaveAreaPtr, IRB, IRB.getInt8Ty (),
6680
+ Alignment, /* isStore*/ true );
6681
+ IRB.CreateMemCpy (RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy,
6682
+ Alignment, RegSaveAreaSize);
6683
+
6684
+ RegSaveAreaShadowPtr =
6685
+ IRB.CreatePtrToInt (RegSaveAreaShadowPtr, MS.IntptrTy );
6686
+ Value *FPSaveArea = IRB.CreateAdd (RegSaveAreaShadowPtr,
6687
+ ConstantInt::get (MS.IntptrTy , 32 ));
6688
+ FPSaveArea = IRB.CreateIntToPtr (FPSaveArea, MS.PtrTy );
6689
+ // We fill fp shadow with zeroes as uninitialized fp args should have
6690
+ // been found during call base check
6691
+ IRB.CreateMemSet (FPSaveArea, ConstantInt::getNullValue (IRB.getInt8Ty ()),
6692
+ ConstantInt::get (MS.IntptrTy , 32 ), Alignment);
6693
+ }
6694
+
6695
+ { // Copy overflow area
6696
+ // RegSaveAreaSize is min(CopySize, 32) -> no overflow can occur
6697
+ Value *OverflowAreaSize = IRB.CreateSub (CopySize, RegSaveAreaSize);
6698
+
6699
+ Value *OverflowAreaPtrPtr = IRB.CreatePtrToInt (VAListTag, MS.IntptrTy );
6700
+ OverflowAreaPtrPtr =
6701
+ IRB.CreateAdd (OverflowAreaPtrPtr, ConstantInt::get (MS.IntptrTy , 4 ));
6702
+ OverflowAreaPtrPtr = IRB.CreateIntToPtr (OverflowAreaPtrPtr, MS.PtrTy );
6703
+
6704
+ Value *OverflowAreaPtr = IRB.CreateLoad (MS.PtrTy , OverflowAreaPtrPtr);
6705
+
6706
+ Value *OverflowAreaShadowPtr, *OverflowAreaOriginPtr;
6707
+ std::tie (OverflowAreaShadowPtr, OverflowAreaOriginPtr) =
6708
+ MSV.getShadowOriginPtr (OverflowAreaPtr, IRB, IRB.getInt8Ty (),
6709
+ Alignment, /* isStore*/ true );
6710
+
6711
+ Value *OverflowVAArgTLSCopyPtr =
6712
+ IRB.CreatePtrToInt (VAArgTLSCopy, MS.IntptrTy );
6713
+ OverflowVAArgTLSCopyPtr =
6714
+ IRB.CreateAdd (OverflowVAArgTLSCopyPtr, RegSaveAreaSize);
6715
+
6716
+ OverflowVAArgTLSCopyPtr =
6717
+ IRB.CreateIntToPtr (OverflowVAArgTLSCopyPtr, MS.PtrTy );
6718
+ IRB.CreateMemCpy (OverflowAreaShadowPtr, Alignment,
6719
+ OverflowVAArgTLSCopyPtr, Alignment, OverflowAreaSize);
6720
+ }
6696
6721
}
6697
6722
}
6698
6723
};
@@ -7220,10 +7245,10 @@ static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
7220
7245
// On PowerPC32 VAListTag is a struct
7221
7246
// {char, char, i16 padding, char *, char *}
7222
7247
if (TargetTriple.isPPC32 ())
7223
- return new VarArgPowerPC32Helper (Func, Msan, Visitor, /* VAListTagSize= */ 12 );
7248
+ return new VarArgPowerPC32Helper (Func, Msan, Visitor);
7224
7249
7225
7250
if (TargetTriple.isPPC64 ())
7226
- return new VarArgPowerPC64Helper (Func, Msan, Visitor, /* VAListTagSize= */ 8 );
7251
+ return new VarArgPowerPC64Helper (Func, Msan, Visitor);
7227
7252
7228
7253
if (TargetTriple.isRISCV32 ())
7229
7254
return new VarArgRISCVHelper (Func, Msan, Visitor, /* VAListTagSize=*/ 4 );
0 commit comments