@@ -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) {
@@ -593,6 +629,28 @@ bool TypeSanitizer::instrumentWithShadowUpdate(
593629
594630 Value *TD = IRB.CreateBitCast (TDGV, IRB.getPtrTy ());
595631
632+ if (ClOutlineInstrumentation){
633+ if (!ForceSetType && (!ClWritesAlwaysSetType || IsRead)) {
634+ // We need to check the type here. If the type is unknown, then the read
635+ // sets the type. If the type is known, then it is checked. If the type
636+ // doesn't match, then we call the runtime (which may yet determine that
637+ // the mismatch is okay).
638+
639+ Constant *Flags =
640+ ConstantInt::get (OrdTy, (int )IsRead | (((int )IsWrite) << 1 ));
641+
642+ IRB.CreateCall (TysanInstrumentWithShadowUpdate,
643+ {Ptr, TD, SanitizeFunction ? IRB.getTrue () : IRB.getFalse (),
644+ IRB.getInt64 (AccessSize), Flags});
645+ } else if (ForceSetType || IsWrite) {
646+ // In the mode where writes always set the type, for a write (which does
647+ // not also read), we just set the type.
648+ IRB.CreateCall (TysanSetShadowType, {Ptr, TD, IRB.getInt64 (AccessSize)});
649+ }
650+
651+ return true ;
652+ }
653+
596654 Value *ShadowDataInt = convertToShadowDataInt (IRB, Ptr, IntptrTy, PtrShift,
597655 ShadowBase, AppMemMask);
598656 Type *Int8PtrPtrTy = PointerType::get (IRB.getPtrTy (), 0 );
@@ -840,37 +898,47 @@ bool TypeSanitizer::instrumentMemInst(Value *V, Instruction *ShadowBase,
840898 }
841899 }
842900
843- if (!ShadowBase)
844- ShadowBase = getShadowBase (*F);
845- if (!AppMemMask)
846- AppMemMask = getAppMemMask (*F);
847-
848- Value *ShadowDataInt = IRB.CreateAdd (
849- IRB.CreateShl (
850- IRB.CreateAnd (IRB.CreatePtrToInt (Dest, IntptrTy), AppMemMask),
851- PtrShift),
852- ShadowBase);
853- Value *ShadowData = IRB.CreateIntToPtr (ShadowDataInt, IRB.getPtrTy ());
854-
855- if (!Src) {
856- IRB.CreateMemSet (ShadowData, IRB.getInt8 (0 ), IRB.CreateShl (Size, PtrShift),
857- Align (1ull << PtrShift));
858- return true ;
901+ if (ClOutlineInstrumentation) {
902+ if (!Src){
903+ Src = ConstantPointerNull::get (IRB.getPtrTy ());
904+ }
905+ IRB.CreateCall (TysanIntrumentMemInst, {
906+ Dest, Src, Size, NeedsMemMove ? IRB.getTrue () : IRB.getFalse ()
907+ });
859908 }
909+ else {
910+ if (!ShadowBase)
911+ ShadowBase = getShadowBase (*F);
912+ if (!AppMemMask)
913+ AppMemMask = getAppMemMask (*F);
914+
915+ Value *ShadowDataInt = IRB.CreateAdd (
916+ IRB.CreateShl (
917+ IRB.CreateAnd (IRB.CreatePtrToInt (Dest, IntptrTy), AppMemMask),
918+ PtrShift),
919+ ShadowBase);
920+ Value *ShadowData = IRB.CreateIntToPtr (ShadowDataInt, IRB.getPtrTy ());
921+
922+ if (!Src) {
923+ IRB.CreateMemSet (ShadowData, IRB.getInt8 (0 ), IRB.CreateShl (Size, PtrShift),
924+ Align (1ull << PtrShift));
925+ return true ;
926+ }
860927
861- Value *SrcShadowDataInt = IRB.CreateAdd (
862- IRB.CreateShl (
863- IRB.CreateAnd (IRB.CreatePtrToInt (Src, IntptrTy), AppMemMask),
864- PtrShift),
865- ShadowBase);
866- Value *SrcShadowData = IRB.CreateIntToPtr (SrcShadowDataInt, IRB.getPtrTy ());
928+ Value *SrcShadowDataInt = IRB.CreateAdd (
929+ IRB.CreateShl (
930+ IRB.CreateAnd (IRB.CreatePtrToInt (Src, IntptrTy), AppMemMask),
931+ PtrShift),
932+ ShadowBase);
933+ Value *SrcShadowData = IRB.CreateIntToPtr (SrcShadowDataInt, IRB.getPtrTy ());
867934
868- if (NeedsMemMove) {
869- IRB.CreateMemMove (ShadowData, Align (1ull << PtrShift), SrcShadowData,
935+ if (NeedsMemMove) {
936+ IRB.CreateMemMove (ShadowData, Align (1ull << PtrShift), SrcShadowData,
937+ Align (1ull << PtrShift), IRB.CreateShl (Size, PtrShift));
938+ } else {
939+ IRB.CreateMemCpy (ShadowData, Align (1ull << PtrShift), SrcShadowData,
870940 Align (1ull << PtrShift), IRB.CreateShl (Size, PtrShift));
871- } else {
872- IRB.CreateMemCpy (ShadowData, Align (1ull << PtrShift), SrcShadowData,
873- Align (1ull << PtrShift), IRB.CreateShl (Size, PtrShift));
941+ }
874942 }
875943
876944 return true ;
0 commit comments