@@ -5342,84 +5342,6 @@ struct VarArgAMD64Helper : public VarArgHelperBase {
5342
5342
}
5343
5343
};
5344
5344
5345
- // / MIPS-specific implementation of VarArgHelper.
5346
- // / NOTE: This is also used for LoongArch64.
5347
- struct VarArgGenericHelper : public VarArgHelperBase {
5348
- AllocaInst *VAArgTLSCopy = nullptr ;
5349
- Value *VAArgSize = nullptr ;
5350
-
5351
- VarArgGenericHelper (Function &F, MemorySanitizer &MS,
5352
- MemorySanitizerVisitor &MSV, const unsigned VAListTagSize)
5353
- : VarArgHelperBase(F, MS, MSV, VAListTagSize) {}
5354
-
5355
- void visitCallBase (CallBase &CB, IRBuilder<> &IRB) override {
5356
- unsigned VAArgOffset = 0 ;
5357
- const DataLayout &DL = F.getDataLayout ();
5358
- for (Value *A :
5359
- llvm::drop_begin (CB.args (), CB.getFunctionType ()->getNumParams ())) {
5360
- uint64_t ArgSize = DL.getTypeAllocSize (A->getType ());
5361
- if (DL.isBigEndian ()) {
5362
- // Adjusting the shadow for argument with size < 8 to match the
5363
- // placement of bits in big endian system
5364
- if (ArgSize < 8 )
5365
- VAArgOffset += (8 - ArgSize);
5366
- }
5367
- Value *Base = getShadowPtrForVAArgument (IRB, VAArgOffset, ArgSize);
5368
- VAArgOffset += ArgSize;
5369
- VAArgOffset = alignTo (VAArgOffset, 8 );
5370
- if (!Base)
5371
- continue ;
5372
- IRB.CreateAlignedStore (MSV.getShadow (A), Base, kShadowTLSAlignment );
5373
- }
5374
-
5375
- Constant *TotalVAArgSize = ConstantInt::get (IRB.getInt64Ty (), VAArgOffset);
5376
- // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
5377
- // a new class member i.e. it is the total size of all VarArgs.
5378
- IRB.CreateStore (TotalVAArgSize, MS.VAArgOverflowSizeTLS );
5379
- }
5380
-
5381
- void finalizeInstrumentation () override {
5382
- assert (!VAArgSize && !VAArgTLSCopy &&
5383
- " finalizeInstrumentation called twice" );
5384
- IRBuilder<> IRB (MSV.FnPrologueEnd );
5385
- VAArgSize = IRB.CreateLoad (IRB.getInt64Ty (), MS.VAArgOverflowSizeTLS );
5386
- Value *CopySize =
5387
- IRB.CreateAdd (ConstantInt::get (MS.IntptrTy , 0 ), VAArgSize);
5388
-
5389
- if (!VAStartInstrumentationList.empty ()) {
5390
- // If there is a va_start in this function, make a backup copy of
5391
- // va_arg_tls somewhere in the function entry block.
5392
- VAArgTLSCopy = IRB.CreateAlloca (Type::getInt8Ty (*MS.C ), CopySize);
5393
- VAArgTLSCopy->setAlignment (kShadowTLSAlignment );
5394
- IRB.CreateMemSet (VAArgTLSCopy, Constant::getNullValue (IRB.getInt8Ty ()),
5395
- CopySize, kShadowTLSAlignment , false );
5396
-
5397
- Value *SrcSize = IRB.CreateBinaryIntrinsic (
5398
- Intrinsic::umin, CopySize,
5399
- ConstantInt::get (MS.IntptrTy , kParamTLSSize ));
5400
- IRB.CreateMemCpy (VAArgTLSCopy, kShadowTLSAlignment , MS.VAArgTLS ,
5401
- kShadowTLSAlignment , SrcSize);
5402
- }
5403
-
5404
- // Instrument va_start.
5405
- // Copy va_list shadow from the backup copy of the TLS contents.
5406
- for (CallInst *OrigInst : VAStartInstrumentationList) {
5407
- NextNodeIRBuilder IRB (OrigInst);
5408
- Value *VAListTag = OrigInst->getArgOperand (0 );
5409
- Value *RegSaveAreaPtrPtr = IRB.CreateIntToPtr (
5410
- IRB.CreatePtrToInt (VAListTag, MS.IntptrTy ), MS.PtrTy );
5411
- Value *RegSaveAreaPtr = IRB.CreateLoad (MS.PtrTy , RegSaveAreaPtrPtr);
5412
- Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
5413
- const Align Alignment = Align (8 );
5414
- std::tie (RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
5415
- MSV.getShadowOriginPtr (RegSaveAreaPtr, IRB, IRB.getInt8Ty (),
5416
- Alignment, /* isStore*/ true );
5417
- IRB.CreateMemCpy (RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
5418
- CopySize);
5419
- }
5420
- }
5421
- };
5422
-
5423
5345
// / AArch64-specific implementation of VarArgHelper.
5424
5346
struct VarArgAArch64Helper : public VarArgHelperBase {
5425
5347
static const unsigned kAArch64GrArgSize = 64 ;
@@ -6082,6 +6004,84 @@ struct VarArgSystemZHelper : public VarArgHelperBase {
6082
6004
}
6083
6005
};
6084
6006
6007
+ // / MIPS-specific implementation of VarArgHelper.
6008
+ // / NOTE: This is also used for LoongArch64.
6009
+ struct VarArgGenericHelper : public VarArgHelperBase {
6010
+ AllocaInst *VAArgTLSCopy = nullptr ;
6011
+ Value *VAArgSize = nullptr ;
6012
+
6013
+ VarArgGenericHelper (Function &F, MemorySanitizer &MS,
6014
+ MemorySanitizerVisitor &MSV, const unsigned VAListTagSize)
6015
+ : VarArgHelperBase(F, MS, MSV, VAListTagSize) {}
6016
+
6017
+ void visitCallBase (CallBase &CB, IRBuilder<> &IRB) override {
6018
+ unsigned VAArgOffset = 0 ;
6019
+ const DataLayout &DL = F.getDataLayout ();
6020
+ for (Value *A :
6021
+ llvm::drop_begin (CB.args (), CB.getFunctionType ()->getNumParams ())) {
6022
+ uint64_t ArgSize = DL.getTypeAllocSize (A->getType ());
6023
+ if (DL.isBigEndian ()) {
6024
+ // Adjusting the shadow for argument with size < 8 to match the
6025
+ // placement of bits in big endian system
6026
+ if (ArgSize < 8 )
6027
+ VAArgOffset += (8 - ArgSize);
6028
+ }
6029
+ Value *Base = getShadowPtrForVAArgument (IRB, VAArgOffset, ArgSize);
6030
+ VAArgOffset += ArgSize;
6031
+ VAArgOffset = alignTo (VAArgOffset, 8 );
6032
+ if (!Base)
6033
+ continue ;
6034
+ IRB.CreateAlignedStore (MSV.getShadow (A), Base, kShadowTLSAlignment );
6035
+ }
6036
+
6037
+ Constant *TotalVAArgSize = ConstantInt::get (IRB.getInt64Ty (), VAArgOffset);
6038
+ // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
6039
+ // a new class member i.e. it is the total size of all VarArgs.
6040
+ IRB.CreateStore (TotalVAArgSize, MS.VAArgOverflowSizeTLS );
6041
+ }
6042
+
6043
+ void finalizeInstrumentation () override {
6044
+ assert (!VAArgSize && !VAArgTLSCopy &&
6045
+ " finalizeInstrumentation called twice" );
6046
+ IRBuilder<> IRB (MSV.FnPrologueEnd );
6047
+ VAArgSize = IRB.CreateLoad (IRB.getInt64Ty (), MS.VAArgOverflowSizeTLS );
6048
+ Value *CopySize =
6049
+ IRB.CreateAdd (ConstantInt::get (MS.IntptrTy , 0 ), VAArgSize);
6050
+
6051
+ if (!VAStartInstrumentationList.empty ()) {
6052
+ // If there is a va_start in this function, make a backup copy of
6053
+ // va_arg_tls somewhere in the function entry block.
6054
+ VAArgTLSCopy = IRB.CreateAlloca (Type::getInt8Ty (*MS.C ), CopySize);
6055
+ VAArgTLSCopy->setAlignment (kShadowTLSAlignment );
6056
+ IRB.CreateMemSet (VAArgTLSCopy, Constant::getNullValue (IRB.getInt8Ty ()),
6057
+ CopySize, kShadowTLSAlignment , false );
6058
+
6059
+ Value *SrcSize = IRB.CreateBinaryIntrinsic (
6060
+ Intrinsic::umin, CopySize,
6061
+ ConstantInt::get (MS.IntptrTy , kParamTLSSize ));
6062
+ IRB.CreateMemCpy (VAArgTLSCopy, kShadowTLSAlignment , MS.VAArgTLS ,
6063
+ kShadowTLSAlignment , SrcSize);
6064
+ }
6065
+
6066
+ // Instrument va_start.
6067
+ // Copy va_list shadow from the backup copy of the TLS contents.
6068
+ for (CallInst *OrigInst : VAStartInstrumentationList) {
6069
+ NextNodeIRBuilder IRB (OrigInst);
6070
+ Value *VAListTag = OrigInst->getArgOperand (0 );
6071
+ Value *RegSaveAreaPtrPtr = IRB.CreateIntToPtr (
6072
+ IRB.CreatePtrToInt (VAListTag, MS.IntptrTy ), MS.PtrTy );
6073
+ Value *RegSaveAreaPtr = IRB.CreateLoad (MS.PtrTy , RegSaveAreaPtrPtr);
6074
+ Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
6075
+ const Align Alignment = Align (8 );
6076
+ std::tie (RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
6077
+ MSV.getShadowOriginPtr (RegSaveAreaPtr, IRB, IRB.getInt8Ty (),
6078
+ Alignment, /* isStore*/ true );
6079
+ IRB.CreateMemCpy (RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
6080
+ CopySize);
6081
+ }
6082
+ }
6083
+ };
6084
+
6085
6085
// Loongarch64 is not a MIPS, but the current vargs calling convention matches
6086
6086
// the MIPS.
6087
6087
using VarArgMIPSHelper = VarArgGenericHelper;
0 commit comments