llvm.org GIT mirror llvm / aa5880d
Move `checkInterfaceFunction` to ModuleUtils Summary: Instead of making a local copy of `checkInterfaceFunction` for each sanitizer, move the function in a common place. Reviewers: kcc, samsonov Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D8775 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234220 91177308-0d34-0410-b5e6-96231b3b80d8 Ismail Pazarbasi 4 years ago
5 changed file(s) with 84 addition(s) and 91 deletion(s). Raw diff Collapse all Expand all
1919 class Function;
2020 class GlobalValue;
2121 class GlobalVariable;
22 class Constant;
2223 template class SmallPtrSetImpl;
2324
2425 /// Append F to the list of global ctors of module M with the given Priority.
3536 GlobalVariable *collectUsedGlobalVariables(Module &M,
3637 SmallPtrSetImpl &Set,
3738 bool CompilerUsed);
39
40 // Validate the result of Module::getOrInsertFunction called for an interface
41 // function of given sanitizer. If the instrumented module defines a function
42 // with the same name, their prototypes must match, otherwise
43 // getOrInsertFunction returns a bitcast.
44 Function *checkSanitizerInterfaceFunction(Constant *FuncOrBitcast);
3845 } // End llvm namespace
3946
4047 #endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
967967 UseCalls, Exp);
968968 }
969969
970 // Validate the result of Module::getOrInsertFunction called for an interface
971 // function of AddressSanitizer. If the instrumented module defines a function
972 // with the same name, their prototypes must match, otherwise
973 // getOrInsertFunction returns a bitcast.
974 static Function *checkInterfaceFunction(Constant *FuncOrBitcast) {
975 if (isa(FuncOrBitcast)) return cast(FuncOrBitcast);
976 FuncOrBitcast->dump();
977 report_fatal_error(
978 "trying to redefine an AddressSanitizer "
979 "interface function");
980 }
981
982970 Instruction *AddressSanitizer::generateCrashCode(Instruction *InsertBefore,
983971 Value *Addr, bool IsWrite,
984972 size_t AccessSizeIndex,
12271215 void AddressSanitizerModule::initializeCallbacks(Module &M) {
12281216 IRBuilder<> IRB(*C);
12291217 // Declare our poisoning and unpoisoning functions.
1230 AsanPoisonGlobals = checkInterfaceFunction(M.getOrInsertFunction(
1218 AsanPoisonGlobals = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
12311219 kAsanPoisonGlobalsName, IRB.getVoidTy(), IntptrTy, nullptr));
12321220 AsanPoisonGlobals->setLinkage(Function::ExternalLinkage);
1233 AsanUnpoisonGlobals = checkInterfaceFunction(M.getOrInsertFunction(
1221 AsanUnpoisonGlobals = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
12341222 kAsanUnpoisonGlobalsName, IRB.getVoidTy(), nullptr));
12351223 AsanUnpoisonGlobals->setLinkage(Function::ExternalLinkage);
12361224 // Declare functions that register/unregister globals.
1237 AsanRegisterGlobals = checkInterfaceFunction(M.getOrInsertFunction(
1225 AsanRegisterGlobals = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
12381226 kAsanRegisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr));
12391227 AsanRegisterGlobals->setLinkage(Function::ExternalLinkage);
1240 AsanUnregisterGlobals = checkInterfaceFunction(
1228 AsanUnregisterGlobals = checkSanitizerInterfaceFunction(
12411229 M.getOrInsertFunction(kAsanUnregisterGlobalsName, IRB.getVoidTy(),
12421230 IntptrTy, IntptrTy, nullptr));
12431231 AsanUnregisterGlobals->setLinkage(Function::ExternalLinkage);
14071395 const std::string ExpStr = Exp ? "exp_" : "";
14081396 const Type *ExpType = Exp ? Type::getInt32Ty(*C) : nullptr;
14091397 AsanErrorCallbackSized[AccessIsWrite][Exp] =
1410 checkInterfaceFunction(M.getOrInsertFunction(
1398 checkSanitizerInterfaceFunction(M.getOrInsertFunction(
14111399 kAsanReportErrorTemplate + ExpStr + TypeStr + "_n",
14121400 IRB.getVoidTy(), IntptrTy, IntptrTy, ExpType, nullptr));
14131401 AsanMemoryAccessCallbackSized[AccessIsWrite][Exp] =
1414 checkInterfaceFunction(M.getOrInsertFunction(
1402 checkSanitizerInterfaceFunction(M.getOrInsertFunction(
14151403 ClMemoryAccessCallbackPrefix + ExpStr + TypeStr + "N",
14161404 IRB.getVoidTy(), IntptrTy, IntptrTy, ExpType, nullptr));
14171405 for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
14181406 AccessSizeIndex++) {
14191407 const std::string Suffix = TypeStr + itostr(1 << AccessSizeIndex);
14201408 AsanErrorCallback[AccessIsWrite][Exp][AccessSizeIndex] =
1421 checkInterfaceFunction(M.getOrInsertFunction(
1409 checkSanitizerInterfaceFunction(M.getOrInsertFunction(
14221410 kAsanReportErrorTemplate + ExpStr + Suffix, IRB.getVoidTy(),
14231411 IntptrTy, ExpType, nullptr));
14241412 AsanMemoryAccessCallback[AccessIsWrite][Exp][AccessSizeIndex] =
1425 checkInterfaceFunction(M.getOrInsertFunction(
1413 checkSanitizerInterfaceFunction(M.getOrInsertFunction(
14261414 ClMemoryAccessCallbackPrefix + ExpStr + Suffix, IRB.getVoidTy(),
14271415 IntptrTy, ExpType, nullptr));
14281416 }
14291417 }
14301418 }
14311419
1432 AsanMemmove = checkInterfaceFunction(M.getOrInsertFunction(
1420 AsanMemmove = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
14331421 ClMemoryAccessCallbackPrefix + "memmove", IRB.getInt8PtrTy(),
14341422 IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy, nullptr));
1435 AsanMemcpy = checkInterfaceFunction(M.getOrInsertFunction(
1423 AsanMemcpy = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
14361424 ClMemoryAccessCallbackPrefix + "memcpy", IRB.getInt8PtrTy(),
14371425 IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy, nullptr));
1438 AsanMemset = checkInterfaceFunction(M.getOrInsertFunction(
1426 AsanMemset = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
14391427 ClMemoryAccessCallbackPrefix + "memset", IRB.getInt8PtrTy(),
14401428 IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy, nullptr));
14411429
1442 AsanHandleNoReturnFunc = checkInterfaceFunction(
1430 AsanHandleNoReturnFunc = checkSanitizerInterfaceFunction(
14431431 M.getOrInsertFunction(kAsanHandleNoReturnName, IRB.getVoidTy(), nullptr));
14441432
1445 AsanPtrCmpFunction = checkInterfaceFunction(M.getOrInsertFunction(
1433 AsanPtrCmpFunction = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
14461434 kAsanPtrCmp, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr));
1447 AsanPtrSubFunction = checkInterfaceFunction(M.getOrInsertFunction(
1435 AsanPtrSubFunction = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
14481436 kAsanPtrSub, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr));
14491437 // We insert an empty inline asm after __asan_report* to avoid callback merge.
14501438 EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false),
14691457 BasicBlock *AsanCtorBB = BasicBlock::Create(*C, "", AsanCtorFunction);
14701458 // call __asan_init in the module ctor.
14711459 IRBuilder<> IRB(ReturnInst::Create(*C, AsanCtorBB));
1472 AsanInitFunction = checkInterfaceFunction(
1460 AsanInitFunction = checkSanitizerInterfaceFunction(
14731461 M.getOrInsertFunction(kAsanInitName, IRB.getVoidTy(), nullptr));
14741462 AsanInitFunction->setLinkage(Function::ExternalLinkage);
14751463 IRB.CreateCall(AsanInitFunction);
16211609 IRBuilder<> IRB(*C);
16221610 for (int i = 0; i <= kMaxAsanStackMallocSizeClass; i++) {
16231611 std::string Suffix = itostr(i);
1624 AsanStackMallocFunc[i] = checkInterfaceFunction(M.getOrInsertFunction(
1625 kAsanStackMallocNameTemplate + Suffix, IntptrTy, IntptrTy, nullptr));
1626 AsanStackFreeFunc[i] = checkInterfaceFunction(
1612 AsanStackMallocFunc[i] = checkSanitizerInterfaceFunction(
1613 M.getOrInsertFunction(kAsanStackMallocNameTemplate + Suffix, IntptrTy,
1614 IntptrTy, nullptr));
1615 AsanStackFreeFunc[i] = checkSanitizerInterfaceFunction(
16271616 M.getOrInsertFunction(kAsanStackFreeNameTemplate + Suffix,
16281617 IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr));
16291618 }
1630 AsanPoisonStackMemoryFunc = checkInterfaceFunction(
1619 AsanPoisonStackMemoryFunc = checkSanitizerInterfaceFunction(
16311620 M.getOrInsertFunction(kAsanPoisonStackMemoryName, IRB.getVoidTy(),
16321621 IntptrTy, IntptrTy, nullptr));
1633 AsanUnpoisonStackMemoryFunc = checkInterfaceFunction(
1622 AsanUnpoisonStackMemoryFunc = checkSanitizerInterfaceFunction(
16341623 M.getOrInsertFunction(kAsanUnpoisonStackMemoryName, IRB.getVoidTy(),
16351624 IntptrTy, IntptrTy, nullptr));
16361625 }
139139
140140 } // namespace
141141
142 static Function *checkInterfaceFunction(Constant *FuncOrBitcast) {
143 if (Function *F = dyn_cast(FuncOrBitcast))
144 return F;
145 std::string Err;
146 raw_string_ostream Stream(Err);
147 Stream << "SanitizerCoverage interface function redefined: "
148 << *FuncOrBitcast;
149 report_fatal_error(Err);
150 }
151
152142 bool SanitizerCoverageModule::runOnModule(Module &M) {
153143 if (!CoverageLevel) return false;
154144 C = &(M.getContext());
166156 ReturnInst::Create(*C, BasicBlock::Create(*C, "", CtorFunc));
167157 appendToGlobalCtors(M, CtorFunc, kSanCtorAndDtorPriority);
168158
169 SanCovFunction = checkInterfaceFunction(
159 SanCovFunction = checkSanitizerInterfaceFunction(
170160 M.getOrInsertFunction(kSanCovName, VoidTy, Int32PtrTy, nullptr));
171 SanCovWithCheckFunction = checkInterfaceFunction(
161 SanCovWithCheckFunction = checkSanitizerInterfaceFunction(
172162 M.getOrInsertFunction(kSanCovWithCheckName, VoidTy, Int32PtrTy, nullptr));
173 SanCovIndirCallFunction = checkInterfaceFunction(M.getOrInsertFunction(
174 kSanCovIndirCallName, VoidTy, IntptrTy, IntptrTy, nullptr));
175 SanCovTraceCmpFunction = checkInterfaceFunction(M.getOrInsertFunction(
176 kSanCovTraceCmp, VoidTy, Int64Ty, Int64Ty, Int64Ty, nullptr));
177
178 SanCovModuleInit = checkInterfaceFunction(M.getOrInsertFunction(
163 SanCovIndirCallFunction =
164 checkSanitizerInterfaceFunction(M.getOrInsertFunction(
165 kSanCovIndirCallName, VoidTy, IntptrTy, IntptrTy, nullptr));
166 SanCovTraceCmpFunction =
167 checkSanitizerInterfaceFunction(M.getOrInsertFunction(
168 kSanCovTraceCmp, VoidTy, Int64Ty, Int64Ty, Int64Ty, nullptr));
169
170 SanCovModuleInit = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
179171 kSanCovModuleInitName, Type::getVoidTy(*C), Int32PtrTy, IntptrTy,
180172 Int8PtrTy, Int8PtrTy, nullptr));
181173 SanCovModuleInit->setLinkage(Function::ExternalLinkage);
185177 /*hasSideEffects=*/true);
186178
187179 if (ClExperimentalTracing) {
188 SanCovTraceEnter = checkInterfaceFunction(
180 SanCovTraceEnter = checkSanitizerInterfaceFunction(
189181 M.getOrInsertFunction(kSanCovTraceEnter, VoidTy, Int32PtrTy, nullptr));
190 SanCovTraceBB = checkInterfaceFunction(
182 SanCovTraceBB = checkSanitizerInterfaceFunction(
191183 M.getOrInsertFunction(kSanCovTraceBB, VoidTy, Int32PtrTy, nullptr));
192184 }
193185
128128 return new ThreadSanitizer();
129129 }
130130
131 static Function *checkInterfaceFunction(Constant *FuncOrBitcast) {
132 if (Function *F = dyn_cast(FuncOrBitcast))
133 return F;
134 FuncOrBitcast->dump();
135 report_fatal_error("ThreadSanitizer interface function redefined");
136 }
137
138131 void ThreadSanitizer::initializeCallbacks(Module &M) {
139132 IRBuilder<> IRB(M.getContext());
140133 // Initialize the callbacks.
141 TsanFuncEntry = checkInterfaceFunction(M.getOrInsertFunction(
134 TsanFuncEntry = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
142135 "__tsan_func_entry", IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
143 TsanFuncExit = checkInterfaceFunction(M.getOrInsertFunction(
144 "__tsan_func_exit", IRB.getVoidTy(), nullptr));
136 TsanFuncExit = checkSanitizerInterfaceFunction(
137 M.getOrInsertFunction("__tsan_func_exit", IRB.getVoidTy(), nullptr));
145138 OrdTy = IRB.getInt32Ty();
146139 for (size_t i = 0; i < kNumberOfAccessSizes; ++i) {
147140 const size_t ByteSize = 1 << i;
148141 const size_t BitSize = ByteSize * 8;
149142 SmallString<32> ReadName("__tsan_read" + itostr(ByteSize));
150 TsanRead[i] = checkInterfaceFunction(M.getOrInsertFunction(
143 TsanRead[i] = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
151144 ReadName, IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
152145
153146 SmallString<32> WriteName("__tsan_write" + itostr(ByteSize));
154 TsanWrite[i] = checkInterfaceFunction(M.getOrInsertFunction(
147 TsanWrite[i] = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
155148 WriteName, IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
156149
157150 SmallString<64> UnalignedReadName("__tsan_unaligned_read" +
158151 itostr(ByteSize));
159 TsanUnalignedRead[i] = checkInterfaceFunction(M.getOrInsertFunction(
160 UnalignedReadName, IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
152 TsanUnalignedRead[i] =
153 checkSanitizerInterfaceFunction(M.getOrInsertFunction(
154 UnalignedReadName, IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
161155
162156 SmallString<64> UnalignedWriteName("__tsan_unaligned_write" +
163157 itostr(ByteSize));
164 TsanUnalignedWrite[i] = checkInterfaceFunction(M.getOrInsertFunction(
165 UnalignedWriteName, IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
158 TsanUnalignedWrite[i] =
159 checkSanitizerInterfaceFunction(M.getOrInsertFunction(
160 UnalignedWriteName, IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
166161
167162 Type *Ty = Type::getIntNTy(M.getContext(), BitSize);
168163 Type *PtrTy = Ty->getPointerTo();
169164 SmallString<32> AtomicLoadName("__tsan_atomic" + itostr(BitSize) +
170165 "_load");
171 TsanAtomicLoad[i] = checkInterfaceFunction(M.getOrInsertFunction(
172 AtomicLoadName, Ty, PtrTy, OrdTy, nullptr));
166 TsanAtomicLoad[i] = checkSanitizerInterfaceFunction(
167 M.getOrInsertFunction(AtomicLoadName, Ty, PtrTy, OrdTy, nullptr));
173168
174169 SmallString<32> AtomicStoreName("__tsan_atomic" + itostr(BitSize) +
175170 "_store");
176 TsanAtomicStore[i] = checkInterfaceFunction(M.getOrInsertFunction(
177 AtomicStoreName, IRB.getVoidTy(), PtrTy, Ty, OrdTy,
178 nullptr));
171 TsanAtomicStore[i] = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
172 AtomicStoreName, IRB.getVoidTy(), PtrTy, Ty, OrdTy, nullptr));
179173
180174 for (int op = AtomicRMWInst::FIRST_BINOP;
181175 op <= AtomicRMWInst::LAST_BINOP; ++op) {
198192 else
199193 continue;
200194 SmallString<32> RMWName("__tsan_atomic" + itostr(BitSize) + NamePart);
201 TsanAtomicRMW[op][i] = checkInterfaceFunction(M.getOrInsertFunction(
202 RMWName, Ty, PtrTy, Ty, OrdTy, nullptr));
195 TsanAtomicRMW[op][i] = checkSanitizerInterfaceFunction(
196 M.getOrInsertFunction(RMWName, Ty, PtrTy, Ty, OrdTy, nullptr));
203197 }
204198
205199 SmallString<32> AtomicCASName("__tsan_atomic" + itostr(BitSize) +
206200 "_compare_exchange_val");
207 TsanAtomicCAS[i] = checkInterfaceFunction(M.getOrInsertFunction(
201 TsanAtomicCAS[i] = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
208202 AtomicCASName, Ty, PtrTy, Ty, Ty, OrdTy, OrdTy, nullptr));
209203 }
210 TsanVptrUpdate = checkInterfaceFunction(M.getOrInsertFunction(
211 "__tsan_vptr_update", IRB.getVoidTy(), IRB.getInt8PtrTy(),
212 IRB.getInt8PtrTy(), nullptr));
213 TsanVptrLoad = checkInterfaceFunction(M.getOrInsertFunction(
204 TsanVptrUpdate = checkSanitizerInterfaceFunction(
205 M.getOrInsertFunction("__tsan_vptr_update", IRB.getVoidTy(),
206 IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), nullptr));
207 TsanVptrLoad = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
214208 "__tsan_vptr_read", IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
215 TsanAtomicThreadFence = checkInterfaceFunction(M.getOrInsertFunction(
209 TsanAtomicThreadFence = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
216210 "__tsan_atomic_thread_fence", IRB.getVoidTy(), OrdTy, nullptr));
217 TsanAtomicSignalFence = checkInterfaceFunction(M.getOrInsertFunction(
211 TsanAtomicSignalFence = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
218212 "__tsan_atomic_signal_fence", IRB.getVoidTy(), OrdTy, nullptr));
219213
220 MemmoveFn = checkInterfaceFunction(M.getOrInsertFunction(
221 "memmove", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
222 IRB.getInt8PtrTy(), IntptrTy, nullptr));
223 MemcpyFn = checkInterfaceFunction(M.getOrInsertFunction(
224 "memcpy", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
225 IntptrTy, nullptr));
226 MemsetFn = checkInterfaceFunction(M.getOrInsertFunction(
227 "memset", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt32Ty(),
228 IntptrTy, nullptr));
214 MemmoveFn = checkSanitizerInterfaceFunction(
215 M.getOrInsertFunction("memmove", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
216 IRB.getInt8PtrTy(), IntptrTy, nullptr));
217 MemcpyFn = checkSanitizerInterfaceFunction(
218 M.getOrInsertFunction("memcpy", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
219 IRB.getInt8PtrTy(), IntptrTy, nullptr));
220 MemsetFn = checkSanitizerInterfaceFunction(
221 M.getOrInsertFunction("memset", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
222 IRB.getInt32Ty(), IntptrTy, nullptr));
229223 }
230224
231225 bool ThreadSanitizer::doInitialization(Module &M) {
1616 #include "llvm/IR/Function.h"
1717 #include "llvm/IR/IRBuilder.h"
1818 #include "llvm/IR/Module.h"
19 #include "llvm/Support/raw_ostream.h"
1920
2021 using namespace llvm;
2122
9293 }
9394 return GV;
9495 }
96
97 Function *llvm::checkSanitizerInterfaceFunction(Constant *FuncOrBitcast) {
98 if (isa(FuncOrBitcast))
99 return cast(FuncOrBitcast);
100 FuncOrBitcast->dump();
101 std::string Err;
102 raw_string_ostream Stream(Err);
103 Stream << "Sanitizer interface function redefined: " << *FuncOrBitcast;
104 report_fatal_error(Err);
105 }