@@ -80,8 +80,8 @@ struct TypeSanitizer {
80
80
81
81
void initializeCallbacks (Module &M);
82
82
83
- Value *getShadowBase (Function &F);
84
- Value *getAppMemMask (Function &F);
83
+ Instruction *getShadowBase (Function &F);
84
+ Instruction *getAppMemMask (Function &F);
85
85
86
86
bool instrumentWithShadowUpdate (IRBuilder<> &IRB, const MDNode *TBAAMD,
87
87
Value *Ptr, uint64_t AccessSize, bool IsRead,
@@ -93,8 +93,8 @@ struct TypeSanitizer {
93
93
94
94
// / Memory-related intrinsics/instructions reset the type of the destination
95
95
// / memory (including allocas and byval arguments).
96
- bool instrumentMemInst (Value *I, Value *& ShadowBase, Value *&AppMemMask ,
97
- const DataLayout &DL);
96
+ bool instrumentMemInst (Value *I, Instruction * ShadowBase,
97
+ Instruction *AppMemMask, const DataLayout &DL);
98
98
99
99
std::string getAnonymousStructIdentifier (const MDNode *MD,
100
100
TypeNameMapTy &TypeNames);
@@ -450,14 +450,14 @@ bool TypeSanitizer::generateTypeDescriptor(
450
450
return true ;
451
451
}
452
452
453
- Value *TypeSanitizer::getShadowBase (Function &F) {
453
+ Instruction *TypeSanitizer::getShadowBase (Function &F) {
454
454
IRBuilder<> IRB (&F.front ().front ());
455
455
Constant *GlobalShadowAddress =
456
456
F.getParent ()->getOrInsertGlobal (kTysanShadowMemoryAddress , IntptrTy);
457
457
return IRB.CreateLoad (IntptrTy, GlobalShadowAddress, " shadow.base" );
458
458
}
459
459
460
- Value *TypeSanitizer::getAppMemMask (Function &F) {
460
+ Instruction *TypeSanitizer::getAppMemMask (Function &F) {
461
461
IRBuilder<> IRB (&F.front ().front ());
462
462
Value *GlobalAppMemMask =
463
463
F.getParent ()->getOrInsertGlobal (kTysanAppMemMask , IntptrTy);
@@ -548,8 +548,8 @@ bool TypeSanitizer::run(Function &F, const TargetLibraryInfo &TLI) {
548
548
bool SanitizeFunction = F.hasFnAttribute (Attribute::SanitizeType);
549
549
bool NeedsInstrumentation =
550
550
MemTypeResetInsts.empty () && MemoryAccesses.empty ();
551
- Value *ShadowBase = NeedsInstrumentation ? nullptr : getShadowBase (F);
552
- Value *AppMemMask = NeedsInstrumentation ? nullptr : getAppMemMask (F);
551
+ Instruction *ShadowBase = NeedsInstrumentation ? nullptr : getShadowBase (F);
552
+ Instruction *AppMemMask = NeedsInstrumentation ? nullptr : getAppMemMask (F);
553
553
for (const auto &[I, MLoc] : MemoryAccesses) {
554
554
IRBuilder<> IRB (I);
555
555
assert (MLoc.Size .isPrecise ());
@@ -569,7 +569,7 @@ bool TypeSanitizer::run(Function &F, const TargetLibraryInfo &TLI) {
569
569
return Res;
570
570
}
571
571
572
- static Value *ConvertToShadowDataInt (IRBuilder<> &IRB, Value *Ptr,
572
+ static Value *convertToShadowDataInt (IRBuilder<> &IRB, Value *Ptr,
573
573
Type *IntptrTy, uint64_t PtrShift,
574
574
Value *ShadowBase, Value *AppMemMask) {
575
575
return IRB.CreateAdd (
@@ -593,7 +593,7 @@ bool TypeSanitizer::instrumentWithShadowUpdate(
593
593
594
594
Value *TD = IRB.CreateBitCast (TDGV, IRB.getPtrTy ());
595
595
596
- Value *ShadowDataInt = ConvertToShadowDataInt (IRB, Ptr, IntptrTy, PtrShift,
596
+ Value *ShadowDataInt = convertToShadowDataInt (IRB, Ptr, IntptrTy, PtrShift,
597
597
ShadowBase, AppMemMask);
598
598
Type *Int8PtrPtrTy = PointerType::get (IRB.getPtrTy (), 0 );
599
599
Value *ShadowData =
@@ -620,105 +620,155 @@ bool TypeSanitizer::instrumentWithShadowUpdate(
620
620
}
621
621
};
622
622
623
- if (!ForceSetType && (!ClWritesAlwaysSetType || IsRead)) {
624
- // We need to check the type here. If the type is unknown, then the read
625
- // sets the type. If the type is known, then it is checked. If the type
626
- // doesn't match, then we call the runtime (which may yet determine that
627
- // the mismatch is okay).
628
- LLVMContext &C = IRB.getContext ();
629
- MDNode *UnlikelyBW = MDBuilder (C).createBranchWeights (1 , 100000 );
623
+ if (ForceSetType || (ClWritesAlwaysSetType && IsWrite)) {
624
+ // In the mode where writes always set the type, for a write (which does
625
+ // not also read), we just set the type.
626
+ SetType ();
627
+ return true ;
628
+ }
630
629
631
- Constant *Flags =
632
- ConstantInt::get (OrdTy, (int )IsRead | (((int )IsWrite) << 1 ));
630
+ assert ((!ClWritesAlwaysSetType || IsRead) &&
631
+ " should have handled case above" );
632
+ LLVMContext &C = IRB.getContext ();
633
+ MDNode *UnlikelyBW = MDBuilder (C).createBranchWeights (1 , 100000 );
633
634
635
+ if (!SanitizeFunction) {
636
+ // If we're not sanitizing this function, then we only care whether we
637
+ // need to *set* the type.
634
638
Value *LoadedTD = IRB.CreateLoad (IRB.getPtrTy (), ShadowData, " shadow.desc" );
635
- if (SanitizeFunction) {
636
- Value *BadTDCmp = IRB.CreateICmpNE (LoadedTD, TD, " bad.desc" );
637
- Instruction *BadTDTerm, *GoodTDTerm;
638
- SplitBlockAndInsertIfThenElse (BadTDCmp, &*IRB.GetInsertPoint (),
639
- &BadTDTerm, &GoodTDTerm, UnlikelyBW);
640
- IRB.SetInsertPoint (BadTDTerm);
641
-
642
- // We now know that the types did not match (we're on the slow path). If
643
- // the type is unknown, then set it.
644
- Value *NullTDCmp = IRB.CreateIsNull (LoadedTD);
645
- Instruction *NullTDTerm, *MismatchTerm;
646
- SplitBlockAndInsertIfThenElse (NullTDCmp, &*IRB.GetInsertPoint (),
647
- &NullTDTerm, &MismatchTerm);
648
-
649
- // If the type is unknown, then set the type.
650
- IRB.SetInsertPoint (NullTDTerm);
651
-
652
- // We're about to set the type. Make sure that all bytes in the value are
653
- // also of unknown type.
654
- Value *Size = ConstantInt::get (OrdTy, AccessSize);
655
- Value *NotAllUnkTD = IRB.getFalse ();
656
- for (uint64_t i = 1 ; i < AccessSize; ++i) {
657
- Value *UnkShadowData = IRB.CreateIntToPtr (
658
- IRB.CreateAdd (ShadowDataInt,
659
- ConstantInt::get (IntptrTy, i << PtrShift)),
660
- Int8PtrPtrTy);
661
- Value *ILdTD = IRB.CreateLoad (IRB.getPtrTy (), UnkShadowData);
662
- NotAllUnkTD = IRB.CreateOr (NotAllUnkTD, IRB.CreateIsNotNull (ILdTD));
663
- }
664
-
665
- Instruction *BeforeSetType = &*IRB.GetInsertPoint ();
666
- Instruction *BadUTDTerm = SplitBlockAndInsertIfThen (
667
- NotAllUnkTD, BeforeSetType, false , UnlikelyBW);
668
- IRB.SetInsertPoint (BadUTDTerm);
669
- IRB.CreateCall (TysanCheck, {IRB.CreateBitCast (Ptr, IRB.getPtrTy ()), Size,
670
- (Value *)TD, (Value *)Flags});
671
-
672
- IRB.SetInsertPoint (BeforeSetType);
673
- SetType ();
674
-
675
- // We have a non-trivial mismatch. Call the runtime.
676
- IRB.SetInsertPoint (MismatchTerm);
677
- IRB.CreateCall (TysanCheck, {IRB.CreateBitCast (Ptr, IRB.getPtrTy ()), Size,
678
- (Value *)TD, (Value *)Flags});
679
-
680
- // We appear to have the right type. Make sure that all other bytes in
681
- // the type are still marked as interior bytes. If not, call the runtime.
682
- IRB.SetInsertPoint (GoodTDTerm);
683
- Value *NotAllBadTD = IRB.getFalse ();
684
- for (uint64_t i = 1 ; i < AccessSize; ++i) {
685
- Value *BadShadowData = IRB.CreateIntToPtr (
686
- IRB.CreateAdd (ShadowDataInt,
687
- ConstantInt::get (IntptrTy, i << PtrShift)),
688
- Int8PtrPtrTy);
689
- Value *ILdTD = IRB.CreatePtrToInt (
690
- IRB.CreateLoad (IRB.getPtrTy (), BadShadowData), IntptrTy);
691
- NotAllBadTD = IRB.CreateOr (
692
- NotAllBadTD,
693
- IRB.CreateICmpSGE (ILdTD, ConstantInt::get (IntptrTy, 0 )));
694
- }
695
-
696
- Instruction *BadITDTerm = SplitBlockAndInsertIfThen (
697
- NotAllBadTD, &*IRB.GetInsertPoint (), false , UnlikelyBW);
698
- IRB.SetInsertPoint (BadITDTerm);
699
- IRB.CreateCall (TysanCheck, {IRB.CreateBitCast (Ptr, IRB.getPtrTy ()), Size,
700
- (Value *)TD, (Value *)Flags});
701
- } else {
702
- // If we're not sanitizing this function, then we only care whether we
703
- // need to *set* the type.
704
- Value *NullTDCmp = IRB.CreateIsNull (LoadedTD, " desc.set" );
705
- Instruction *NullTDTerm = SplitBlockAndInsertIfThen (
706
- NullTDCmp, &*IRB.GetInsertPoint (), false , UnlikelyBW);
707
- IRB.SetInsertPoint (NullTDTerm);
708
- NullTDTerm->getParent ()->setName (" set.type" );
709
- SetType ();
710
- }
711
- } else if (ForceSetType || IsWrite) {
712
- // In the mode where writes always set the type, for a write (which does
713
- // not also read), we just set the type.
639
+ Value *NullTDCmp = IRB.CreateIsNull (LoadedTD, " desc.set" );
640
+ Instruction *NullTDTerm = SplitBlockAndInsertIfThen (
641
+ NullTDCmp, &*IRB.GetInsertPoint (), false , UnlikelyBW);
642
+ IRB.SetInsertPoint (NullTDTerm);
643
+ NullTDTerm->getParent ()->setName (" set.type" );
714
644
SetType ();
645
+ return true ;
646
+ }
647
+ // We need to check the type here. If the type is unknown, then the read
648
+ // sets the type. If the type is known, then it is checked. If the type
649
+ // doesn't match, then we call the runtime (which may yet determine that
650
+ // the mismatch is okay).
651
+ //
652
+ // The checks generated below have the following strucutre.
653
+ //
654
+ // ; First we load the descriptor for the load from shadow memory and
655
+ // ; compare it against the type descriptor for the current access type.
656
+ // %shadow.desc = load ptr %shadow.data
657
+ // %bad.desc = icmp ne %shadow.desc, %td
658
+ // br %bad.desc, %bad.bb, %good.bb
659
+ //
660
+ // bad.bb:
661
+ // %shadow.desc.null = icmp eq %shadow.desc, null
662
+ // br %shadow.desc.null, %null.td.bb, %good.td.bb
663
+ //
664
+ // null.td.bb:
665
+ // ; The typ is unknown, set it if all bytes in the value are also unknown.
666
+ // ; To check, we load the shadow data for all bytes of the access. For the
667
+ // ; pseudo code below, assume an access of size 1.
668
+ // %shadow.data.int = add %shadow.data.int, 0
669
+ // %l = load (inttoptr %shadow.data.int)
670
+ // %is.not.null = icmp ne %l, null
671
+ // %not.all.unknown = %is.not.null
672
+ // br %no.all.unknown, before.set.type.bb
673
+ //
674
+ // before.set.type.bb:
675
+ // ; Call runtime to check mismatch.
676
+ // call void @__tysan_check()
677
+ // br %set.type.bb
678
+ //
679
+ // set.type.bb:
680
+ // ; Now fill the remainder of the shadow memory corresponding to the
681
+ // ; remainder of the the bytes of the type with a bad type descriptor.
682
+ // store %TD, %shadow.data
683
+ // br %continue.bb
684
+ //
685
+ // good.td.bb::
686
+ // ; We have a non-trivial mismatch. Call the runtime.
687
+ // call void @__tysan_check()
688
+ // br %continue.bb
689
+ //
690
+ // good.bb:
691
+ // ; We appear to have the right type. Make sure that all other bytes in
692
+ // ; the type are still marked as interior bytes. If not, call the runtime.
693
+ // %shadow.data.int = add %shadow.data.int, 0
694
+ // %l = load (inttoptr %shadow.data.int)
695
+ // %not.all.interior = icmp sge %l, 0
696
+ // br %not.all.interior, label %check.rt.bb, label %continue.bb
697
+ //
698
+ // check.rt.bb:
699
+ // call void @__tysan_check()
700
+ // br %continue.bb
701
+
702
+ Constant *Flags = ConstantInt::get (OrdTy, int (IsRead) | (int (IsWrite) << 1 ));
703
+
704
+ Value *LoadedTD = IRB.CreateLoad (IRB.getPtrTy (), ShadowData, " shadow.desc" );
705
+ Value *BadTDCmp = IRB.CreateICmpNE (LoadedTD, TD, " bad.desc" );
706
+ Instruction *BadTDTerm, *GoodTDTerm;
707
+ SplitBlockAndInsertIfThenElse (BadTDCmp, &*IRB.GetInsertPoint (), &BadTDTerm,
708
+ &GoodTDTerm, UnlikelyBW);
709
+ IRB.SetInsertPoint (BadTDTerm);
710
+
711
+ // We now know that the types did not match (we're on the slow path). If
712
+ // the type is unknown, then set it.
713
+ Value *NullTDCmp = IRB.CreateIsNull (LoadedTD);
714
+ Instruction *NullTDTerm, *MismatchTerm;
715
+ SplitBlockAndInsertIfThenElse (NullTDCmp, &*IRB.GetInsertPoint (), &NullTDTerm,
716
+ &MismatchTerm);
717
+
718
+ // If the type is unknown, then set the type.
719
+ IRB.SetInsertPoint (NullTDTerm);
720
+
721
+ // We're about to set the type. Make sure that all bytes in the value are
722
+ // also of unknown type.
723
+ Value *Size = ConstantInt::get (OrdTy, AccessSize);
724
+ Value *NotAllUnkTD = IRB.getFalse ();
725
+ for (uint64_t i = 1 ; i < AccessSize; ++i) {
726
+ Value *UnkShadowData = IRB.CreateIntToPtr (
727
+ IRB.CreateAdd (ShadowDataInt, ConstantInt::get (IntptrTy, i << PtrShift)),
728
+ Int8PtrPtrTy);
729
+ Value *ILdTD = IRB.CreateLoad (IRB.getPtrTy (), UnkShadowData);
730
+ NotAllUnkTD = IRB.CreateOr (NotAllUnkTD, IRB.CreateIsNotNull (ILdTD));
715
731
}
716
732
733
+ Instruction *BeforeSetType = &*IRB.GetInsertPoint ();
734
+ Instruction *BadUTDTerm =
735
+ SplitBlockAndInsertIfThen (NotAllUnkTD, BeforeSetType, false , UnlikelyBW);
736
+ IRB.SetInsertPoint (BadUTDTerm);
737
+ IRB.CreateCall (TysanCheck, {IRB.CreateBitCast (Ptr, IRB.getPtrTy ()), Size,
738
+ (Value *)TD, (Value *)Flags});
739
+
740
+ IRB.SetInsertPoint (BeforeSetType);
741
+ SetType ();
742
+
743
+ // We have a non-trivial mismatch. Call the runtime.
744
+ IRB.SetInsertPoint (MismatchTerm);
745
+ IRB.CreateCall (TysanCheck, {IRB.CreateBitCast (Ptr, IRB.getPtrTy ()), Size,
746
+ (Value *)TD, (Value *)Flags});
747
+
748
+ // We appear to have the right type. Make sure that all other bytes in
749
+ // the type are still marked as interior bytes. If not, call the runtime.
750
+ IRB.SetInsertPoint (GoodTDTerm);
751
+ Value *NotAllBadTD = IRB.getFalse ();
752
+ for (uint64_t i = 1 ; i < AccessSize; ++i) {
753
+ Value *BadShadowData = IRB.CreateIntToPtr (
754
+ IRB.CreateAdd (ShadowDataInt, ConstantInt::get (IntptrTy, i << PtrShift)),
755
+ Int8PtrPtrTy);
756
+ Value *ILdTD = IRB.CreatePtrToInt (
757
+ IRB.CreateLoad (IRB.getPtrTy (), BadShadowData), IntptrTy);
758
+ NotAllBadTD = IRB.CreateOr (
759
+ NotAllBadTD, IRB.CreateICmpSGE (ILdTD, ConstantInt::get (IntptrTy, 0 )));
760
+ }
761
+
762
+ Instruction *BadITDTerm = SplitBlockAndInsertIfThen (
763
+ NotAllBadTD, &*IRB.GetInsertPoint (), false , UnlikelyBW);
764
+ IRB.SetInsertPoint (BadITDTerm);
765
+ IRB.CreateCall (TysanCheck, {IRB.CreateBitCast (Ptr, IRB.getPtrTy ()), Size,
766
+ (Value *)TD, (Value *)Flags});
717
767
return true ;
718
768
}
719
769
720
- bool TypeSanitizer::instrumentMemInst (Value *V, Value *& ShadowBase,
721
- Value *& AppMemMask,
770
+ bool TypeSanitizer::instrumentMemInst (Value *V, Instruction * ShadowBase,
771
+ Instruction * AppMemMask,
722
772
const DataLayout &DL) {
723
773
BasicBlock::iterator IP;
724
774
BasicBlock *BB;
@@ -734,14 +784,11 @@ bool TypeSanitizer::instrumentMemInst(Value *V, Value *&ShadowBase,
734
784
BB = &F->getEntryBlock ();
735
785
IP = BB->getFirstInsertionPt ();
736
786
737
- if (auto *I = cast_or_null<Instruction>(ShadowBase)) {
738
- if (IP->comesBefore (I))
739
- IP = I->getNextNode ()->getIterator ();
740
- }
741
- if (auto *I = cast_or_null<Instruction>(AppMemMask)) {
742
- if (IP->comesBefore (I))
743
- IP = I->getNextNode ()->getIterator ();
744
- }
787
+ // Find the next insert point after both ShadowBase and AppMemMask.
788
+ if (IP->comesBefore (ShadowBase))
789
+ IP = ShadowBase->getNextNode ()->getIterator ();
790
+ if (IP->comesBefore (AppMemMask))
791
+ IP = AppMemMask->getNextNode ()->getIterator ();
745
792
}
746
793
747
794
Value *Dest, *Size, *Src = nullptr ;
0 commit comments