@@ -5342,84 +5342,6 @@ struct VarArgAMD64Helper : public VarArgHelperBase {
53425342 }
53435343};
53445344
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-
54235345// / AArch64-specific implementation of VarArgHelper.
54245346struct VarArgAArch64Helper : public VarArgHelperBase {
54255347 static const unsigned kAArch64GrArgSize = 64 ;
@@ -6082,6 +6004,84 @@ struct VarArgSystemZHelper : public VarArgHelperBase {
60826004 }
60836005};
60846006
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+
60856085// Loongarch64 is not a MIPS, but the current vargs calling convention matches
60866086// the MIPS.
60876087using VarArgMIPSHelper = VarArgGenericHelper;
0 commit comments