@@ -62,6 +62,12 @@ static cl::opt<bool>
6262 cl::desc (" Writes always set the type" ), cl::Hidden,
6363 cl::init(false ));
6464
65+ static cl::opt<bool > ClOutlineInstrumentation (
66+ " tysan-outline-instrumentation" ,
67+ cl::desc (" Uses function calls for all TySan instrumentation, reducing "
68+ " ELF size" ),
69+ cl::Hidden, cl::init(false ));
70+
6571STATISTIC (NumInstrumentedAccesses, " Number of instrumented accesses" );
6672
6773namespace {
@@ -109,12 +115,16 @@ struct TypeSanitizer {
109115 Regex AnonNameRegex;
110116 Type *IntptrTy;
111117 uint64_t PtrShift;
112- IntegerType *OrdTy;
118+ IntegerType *OrdTy, *U64Ty ;
113119
114120 // / Callbacks to run-time library are computed in initializeCallbacks.
115121 FunctionCallee TysanCheck;
116122 FunctionCallee TysanCtorFunction;
117123
124+ FunctionCallee TysanIntrumentMemInst;
125+ FunctionCallee TysanInstrumentWithShadowUpdate;
126+ FunctionCallee TysanSetShadowType;
127+
118128 // / Callback to set types for gloabls.
119129 Function *TysanGlobalsSetTypeFunction;
120130};
@@ -134,6 +144,8 @@ TypeSanitizer::TypeSanitizer(Module &M)
134144void TypeSanitizer::initializeCallbacks (Module &M) {
135145 IRBuilder<> IRB (M.getContext ());
136146 OrdTy = IRB.getInt32Ty ();
147+ U64Ty = IRB.getInt64Ty ();
148+ Type *BoolType = IRB.getInt1Ty ();
137149
138150 AttributeList Attr;
139151 Attr = Attr.addFnAttribute (M.getContext (), Attribute::NoUnwind);
@@ -148,6 +160,30 @@ void TypeSanitizer::initializeCallbacks(Module &M) {
148160
149161 TysanCtorFunction =
150162 M.getOrInsertFunction (kTysanModuleCtorName , Attr, IRB.getVoidTy ());
163+
164+ TysanIntrumentMemInst =
165+ M.getOrInsertFunction (" __tysan_instrument_mem_inst" , Attr, IRB.getVoidTy (),
166+ IRB.getPtrTy (), // Pointer of data to be written to
167+ IRB.getPtrTy (), // Pointer of data to write
168+ U64Ty, // Size of the data in bytes
169+ BoolType // Do we need to call memmove
170+ );
171+
172+ TysanInstrumentWithShadowUpdate =
173+ M.getOrInsertFunction (" __tysan_instrument_with_shadow_update" , Attr, IRB.getVoidTy (),
174+ IRB.getPtrTy (), // Pointer to data to be read
175+ IRB.getPtrTy (), // Pointer to type descriptor
176+ BoolType, // Do we need to type check this
177+ U64Ty, // Size of data we access in bytes
178+ OrdTy // Flags
179+ );
180+
181+ TysanSetShadowType =
182+ M.getOrInsertFunction (" __tysan_set_shadow_type" , Attr, IRB.getVoidTy (),
183+ IRB.getPtrTy (), // Pointer of data to be written to
184+ IRB.getPtrTy (), // Pointer to the new type descriptor
185+ U64Ty // Size of data we access in bytes
186+ );
151187}
152188
153189void TypeSanitizer::instrumentGlobals (Module &M) {
@@ -591,6 +627,28 @@ bool TypeSanitizer::instrumentWithShadowUpdate(
591627
592628 Value *TD = IRB.CreateBitCast (TDGV, IRB.getPtrTy ());
593629
630+ if (ClOutlineInstrumentation){
631+ if (!ForceSetType && (!ClWritesAlwaysSetType || IsRead)) {
632+ // We need to check the type here. If the type is unknown, then the read
633+ // sets the type. If the type is known, then it is checked. If the type
634+ // doesn't match, then we call the runtime (which may yet determine that
635+ // the mismatch is okay).
636+
637+ Constant *Flags =
638+ ConstantInt::get (OrdTy, (int )IsRead | (((int )IsWrite) << 1 ));
639+
640+ IRB.CreateCall (TysanInstrumentWithShadowUpdate,
641+ {Ptr, TD, SanitizeFunction ? IRB.getTrue () : IRB.getFalse (),
642+ IRB.getInt64 (AccessSize), Flags});
643+ } else if (ForceSetType || IsWrite) {
644+ // In the mode where writes always set the type, for a write (which does
645+ // not also read), we just set the type.
646+ IRB.CreateCall (TysanSetShadowType, {Ptr, TD, IRB.getInt64 (AccessSize)});
647+ }
648+
649+ return true ;
650+ }
651+
594652 Value *ShadowDataInt = convertToShadowDataInt (IRB, Ptr, IntptrTy, PtrShift,
595653 ShadowBase, AppMemMask);
596654 Type *Int8PtrPtrTy = PointerType::get (IRB.getContext (), 0 );
@@ -834,37 +892,47 @@ bool TypeSanitizer::instrumentMemInst(Value *V, Instruction *ShadowBase,
834892 }
835893 }
836894
837- if (!ShadowBase)
838- ShadowBase = getShadowBase (*F);
839- if (!AppMemMask)
840- AppMemMask = getAppMemMask (*F);
841-
842- Value *ShadowDataInt = IRB.CreateAdd (
843- IRB.CreateShl (
844- IRB.CreateAnd (IRB.CreatePtrToInt (Dest, IntptrTy), AppMemMask),
845- PtrShift),
846- ShadowBase);
847- Value *ShadowData = IRB.CreateIntToPtr (ShadowDataInt, IRB.getPtrTy ());
848-
849- if (!Src) {
850- IRB.CreateMemSet (ShadowData, IRB.getInt8 (0 ), IRB.CreateShl (Size, PtrShift),
851- Align (1ull << PtrShift));
852- return true ;
895+ if (ClOutlineInstrumentation) {
896+ if (!Src){
897+ Src = ConstantPointerNull::get (IRB.getPtrTy ());
898+ }
899+ IRB.CreateCall (TysanIntrumentMemInst, {
900+ Dest, Src, Size, NeedsMemMove ? IRB.getTrue () : IRB.getFalse ()
901+ });
853902 }
903+ else {
904+ if (!ShadowBase)
905+ ShadowBase = getShadowBase (*F);
906+ if (!AppMemMask)
907+ AppMemMask = getAppMemMask (*F);
908+
909+ Value *ShadowDataInt = IRB.CreateAdd (
910+ IRB.CreateShl (
911+ IRB.CreateAnd (IRB.CreatePtrToInt (Dest, IntptrTy), AppMemMask),
912+ PtrShift),
913+ ShadowBase);
914+ Value *ShadowData = IRB.CreateIntToPtr (ShadowDataInt, IRB.getPtrTy ());
915+
916+ if (!Src) {
917+ IRB.CreateMemSet (ShadowData, IRB.getInt8 (0 ), IRB.CreateShl (Size, PtrShift),
918+ Align (1ull << PtrShift));
919+ return true ;
920+ }
854921
855- Value *SrcShadowDataInt = IRB.CreateAdd (
856- IRB.CreateShl (
857- IRB.CreateAnd (IRB.CreatePtrToInt (Src, IntptrTy), AppMemMask),
858- PtrShift),
859- ShadowBase);
860- Value *SrcShadowData = IRB.CreateIntToPtr (SrcShadowDataInt, IRB.getPtrTy ());
922+ Value *SrcShadowDataInt = IRB.CreateAdd (
923+ IRB.CreateShl (
924+ IRB.CreateAnd (IRB.CreatePtrToInt (Src, IntptrTy), AppMemMask),
925+ PtrShift),
926+ ShadowBase);
927+ Value *SrcShadowData = IRB.CreateIntToPtr (SrcShadowDataInt, IRB.getPtrTy ());
861928
862- if (NeedsMemMove) {
863- IRB.CreateMemMove (ShadowData, Align (1ull << PtrShift), SrcShadowData,
929+ if (NeedsMemMove) {
930+ IRB.CreateMemMove (ShadowData, Align (1ull << PtrShift), SrcShadowData,
931+ Align (1ull << PtrShift), IRB.CreateShl (Size, PtrShift));
932+ } else {
933+ IRB.CreateMemCpy (ShadowData, Align (1ull << PtrShift), SrcShadowData,
864934 Align (1ull << PtrShift), IRB.CreateShl (Size, PtrShift));
865- } else {
866- IRB.CreateMemCpy (ShadowData, Align (1ull << PtrShift), SrcShadowData,
867- Align (1ull << PtrShift), IRB.CreateShl (Size, PtrShift));
935+ }
868936 }
869937
870938 return true ;
0 commit comments