llvm.org GIT mirror llvm / 52eb699
[tsan] treat vtable pointer updates in a special way (requires tbaa); fix a bug (forgot to return true after instrumenting); make sure the tsan tests are run git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153448 91177308-0d34-0410-b5e6-96231b3b80d8 Kostya Serebryany 7 years ago
3 changed file(s) with 39 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
2626 #include "llvm/ADT/StringExtras.h"
2727 #include "llvm/Intrinsics.h"
2828 #include "llvm/Function.h"
29 #include "llvm/LLVMContext.h"
30 #include "llvm/Metadata.h"
2931 #include "llvm/Module.h"
3032 #include "llvm/Support/CommandLine.h"
3133 #include "llvm/Support/Debug.h"
3234 #include "llvm/Support/IRBuilder.h"
3335 #include "llvm/Support/MathExtras.h"
36 #include "llvm/Support/raw_ostream.h"
3437 #include "llvm/Target/TargetData.h"
3538 #include "llvm/Transforms/Instrumentation.h"
3639 #include "llvm/Transforms/Utils/ModuleUtils.h"
6063 static const size_t kNumberOfAccessSizes = 5;
6164 Value *TsanRead[kNumberOfAccessSizes];
6265 Value *TsanWrite[kNumberOfAccessSizes];
66 Value *TsanVptrUpdate;
6367 };
6468 } // namespace
6569
104108 TsanWrite[i] = M.getOrInsertFunction(WriteName, IRB.getVoidTy(),
105109 IRB.getInt8PtrTy(), NULL);
106110 }
111 TsanVptrUpdate = M.getOrInsertFunction("__tsan_vptr_update", IRB.getVoidTy(),
112 IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
113 NULL);
107114 return true;
108115 }
109116
150157 IRBuilder<> IRBRet(RetVec[i]);
151158 IRBRet.CreateCall(TsanFuncExit);
152159 }
160 Res = true;
153161 }
154162 return Res;
163 }
164
165 static bool isVtableAccess(Instruction *I) {
166 if (MDNode *Tag = I->getMetadata(LLVMContext::MD_tbaa)) {
167 if (Tag->getNumOperands() < 1) return false;
168 if (MDString *Tag1 = dyn_cast(Tag->getOperand(0))) {
169 if (Tag1->getString() == "vtable pointer") return true;
170 }
171 }
172 return false;
155173 }
156174
157175 bool ThreadSanitizer::instrumentLoadOrStore(Instruction *I) {
169187 // Ignore all unusual sizes.
170188 return false;
171189 }
190 if (IsWrite && isVtableAccess(I)) {
191 Value *StoredValue = cast(I)->getValueOperand();
192 IRB.CreateCall2(TsanVptrUpdate,
193 IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()),
194 IRB.CreatePointerCast(StoredValue, IRB.getInt8PtrTy()));
195 return true;
196 }
172197 size_t Idx = CountTrailingZeros_32(TypeSize / 8);
173198 assert(Idx < kNumberOfAccessSizes);
174199 Value *OnAccessFunc = IsWrite ? TsanWrite[Idx] : TsanRead[Idx];
0 config.suffixes = ['.ll', '.c', '.cpp']
0 ; RUN: opt < %s -tsan -S | FileCheck %s
1 ; Check that vtable pointer updates are treated in a special way.
2 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
3
4 define void @Foo(i8** nocapture %a, i8* %b) nounwind uwtable {
5 entry:
6 ; CHECK: call void @__tsan_vptr_update
7 store i8* %b, i8** %a, align 8, !tbaa !0
8 ret void
9 }
10 !0 = metadata !{metadata !"vtable pointer", metadata !1}
11 !1 = metadata !{metadata !"Simple C/C++ TBAA", null}
12