From 885994618c5a4c4a249101dc15e1cf54a1c0e5e0 Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Fri, 20 Feb 2015 00:30:44 +0000 Subject: [PATCH] [sanitizer] when dumping the basic block trace, also dump the module names. Patch by Laszlo Szekeres llvm-svn: 229940 --- .../sanitizer_coverage_libcdep.cc | 23 +++++++++++++++---- .../Instrumentation/SanitizerCoverage.cpp | 15 +++++++++--- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc index e8f42f68a42f..49887b1e91a9 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc @@ -82,7 +82,7 @@ class CoverageData { void TraceBasicBlock(s32 *id); void InitializeGuardArray(s32 *guards); - void InitializeGuards(s32 *guards, uptr n); + void InitializeGuards(s32 *guards, uptr n, const char *module_name); void ReinitializeGuards(); uptr *data(); @@ -110,6 +110,9 @@ class CoverageData { // Vector of coverage guard arrays, protected by mu. InternalMmapVectorNoCtor guard_array_vec; + // Vector of module (compilation unit) names. + InternalMmapVectorNoCtor comp_unit_name_vec; + // Caller-Callee (cc) array, size and current index. static const uptr kCcArrayMaxSize = FIRST_32_SECOND_64(1 << 18, 1 << 24); uptr **cc_array; @@ -286,13 +289,15 @@ void CoverageData::Extend(uptr npcs) { atomic_store(&pc_array_size, size, memory_order_release); } -void CoverageData::InitializeGuards(s32 *guards, uptr n) { +void CoverageData::InitializeGuards(s32 *guards, uptr n, + const char *module_name) { // The array 'guards' has n+1 elements, we use the element zero // to store 'n'. CHECK_LT(n, 1 << 30); guards[0] = static_cast(n); InitializeGuardArray(guards); SpinMutexLock l(&mu); + comp_unit_name_vec.push_back(module_name); guard_array_vec.push_back(guards); } @@ -450,6 +455,14 @@ void CoverageData::DumpTrace() { internal_write(fd, out.data(), out.length()); internal_close(fd); + fd = CovOpenFile(false, "trace-compunits"); + if (fd < 0) return; + out.clear(); + for (uptr i = 0; i < comp_unit_name_vec.size(); i++) + out.append("%s\n", comp_unit_name_vec[i]); + internal_write(fd, out.data(), out.length()); + internal_close(fd); + fd = CovOpenFile(false, "trace-events"); if (fd < 0) return; uptr bytes_to_write = max_idx * sizeof(tr_event_array[0]); @@ -675,9 +688,9 @@ SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_init() { coverage_data.Init(); } SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump() { CovDump(); } -SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_module_init(s32 *guards, - uptr npcs) { - coverage_data.InitializeGuards(guards, npcs); +SANITIZER_INTERFACE_ATTRIBUTE void +__sanitizer_cov_module_init(s32 *guards, uptr npcs, const char *module_name) { + coverage_data.InitializeGuards(guards, npcs, module_name); if (!common_flags()->coverage_direct) return; if (SANITIZER_ANDROID && coverage_enabled) { // dlopen/dlclose interceptors do not work on Android, so we rely on diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp index 798cd55f87e7..8c56e8709e2e 100644 --- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -137,6 +137,7 @@ bool SanitizerCoverageModule::runOnModule(Module &M) { IntptrTy = Type::getIntNTy(*C, DLP->getDataLayout().getPointerSizeInBits()); Type *VoidTy = Type::getVoidTy(*C); IRBuilder<> IRB(*C); + Type *Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty()); Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty()); Function *CtorFunc = @@ -153,7 +154,7 @@ bool SanitizerCoverageModule::runOnModule(Module &M) { kSanCovIndirCallName, VoidTy, IntptrTy, IntptrTy, nullptr)); SanCovModuleInit = checkInterfaceFunction( M.getOrInsertFunction(kSanCovModuleInitName, Type::getVoidTy(*C), - Int32PtrTy, IntptrTy, nullptr)); + Int32PtrTy, IntptrTy, Int8PtrTy, nullptr)); SanCovModuleInit->setLinkage(Function::ExternalLinkage); // We insert an empty inline asm after cov callbacks to avoid callback merge. EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), @@ -190,11 +191,19 @@ bool SanitizerCoverageModule::runOnModule(Module &M) { IRB.CreatePointerCast(RealGuardArray, Int32PtrTy)); GuardArray->eraseFromParent(); + // Create variable for module (compilation unit) name + Constant *ModNameStrConst = + ConstantDataArray::getString(M.getContext(), M.getName(), true); + GlobalVariable *ModuleName = + new GlobalVariable(M, ModNameStrConst->getType(), true, + GlobalValue::PrivateLinkage, ModNameStrConst); + // Call __sanitizer_cov_module_init IRB.SetInsertPoint(CtorFunc->getEntryBlock().getTerminator()); - IRB.CreateCall2(SanCovModuleInit, + IRB.CreateCall3(SanCovModuleInit, IRB.CreatePointerCast(RealGuardArray, Int32PtrTy), - ConstantInt::get(IntptrTy, SanCovFunction->getNumUses())); + ConstantInt::get(IntptrTy, SanCovFunction->getNumUses()), + IRB.CreatePointerCast(ModuleName, Int8PtrTy)); return true; }