diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp index 63391b373c5..83ae3d516f8 100644 --- a/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp @@ -158,8 +158,9 @@ private: bool shouldIgnoreStructType(StructType *StructTy); void createStructCounterName( StructType *StructTy, SmallString<MaxStructCounterNameSize> &NameStr); - GlobalVariable *createCacheFragInfoGV(Module &M, Constant *UnitName); - Constant *createEsanInitToolInfoArg(Module &M); + GlobalVariable *createCacheFragInfoGV(Module &M, const DataLayout &DL, + Constant *UnitName); + Constant *createEsanInitToolInfoArg(Module &M, const DataLayout &DL); void createDestructor(Module &M, Constant *ToolInfoArg); bool runOnFunction(Function &F, Module &M); bool instrumentLoadOrStore(Instruction *I, const DataLayout &DL); @@ -287,24 +288,28 @@ void EfficiencySanitizer::createStructCounterName( // Create the global variable for the cache-fragmentation tool. GlobalVariable *EfficiencySanitizer::createCacheFragInfoGV( - Module &M, Constant *UnitName) { + Module &M, const DataLayout &DL, Constant *UnitName) { assert(Options.ToolType == EfficiencySanitizerOptions::ESAN_CacheFrag); auto *Int8PtrTy = Type::getInt8PtrTy(*Ctx); auto *Int8PtrPtrTy = Int8PtrTy->getPointerTo(); auto *Int32Ty = Type::getInt32Ty(*Ctx); + auto *Int32PtrTy = Type::getInt32PtrTy(*Ctx); auto *Int64Ty = Type::getInt64Ty(*Ctx); auto *Int64PtrTy = Type::getInt64PtrTy(*Ctx); // This structure should be kept consistent with the StructInfo struct // in the runtime library. // struct StructInfo { // const char *StructName; + // u32 Size; // u32 NumFields; + // u32 *FieldOffsets; // u64 *FieldCounters; // const char **FieldTypeNames; // }; auto *StructInfoTy = - StructType::get(Int8PtrTy, Int32Ty, Int64PtrTy, Int8PtrPtrTy, nullptr); + StructType::get(Int8PtrTy, Int32Ty, Int32Ty, Int32PtrTy, Int64PtrTy, + Int8PtrPtrTy, nullptr); auto *StructInfoPtrTy = StructInfoTy->getPointerTo(); // This structure should be kept consistent with the CacheFragInfo struct // in the runtime library. @@ -347,13 +352,21 @@ GlobalVariable *EfficiencySanitizer::createCacheFragInfoGV( // Remember the counter variable for each struct type. StructTyMap.insert(std::pair<Type *, GlobalVariable *>(StructTy, Counters)); + // We pass the field type name array and offset array to the runtime for + // better reporting. // FieldTypeNames. - // We pass the field type name array to the runtime for better reporting. auto *TypeNameArrayTy = ArrayType::get(Int8PtrTy, StructTy->getNumElements()); - GlobalVariable *TypeName = + GlobalVariable *TypeNames = new GlobalVariable(M, TypeNameArrayTy, true, GlobalVariable::InternalLinkage, nullptr); SmallVector<Constant *, 16> TypeNameVec; + // FieldOffsets. + const StructLayout *SL = DL.getStructLayout(StructTy); + auto *OffsetArrayTy = ArrayType::get(Int32Ty, StructTy->getNumElements()); + GlobalVariable *Offsets = + new GlobalVariable(M, OffsetArrayTy, true, + GlobalVariable::InternalLinkage, nullptr); + SmallVector<Constant *, 16> OffsetVec; for (unsigned i = 0; i < StructTy->getNumElements(); ++i) { Type *Ty = StructTy->getElementType(i); std::string Str; @@ -363,16 +376,20 @@ GlobalVariable *EfficiencySanitizer::createCacheFragInfoGV( ConstantExpr::getPointerCast( createPrivateGlobalForString(M, StrOS.str(), true), Int8PtrTy)); + OffsetVec.push_back(ConstantInt::get(Int32Ty, SL->getElementOffset(i))); } - TypeName->setInitializer(ConstantArray::get(TypeNameArrayTy, TypeNameVec)); + TypeNames->setInitializer(ConstantArray::get(TypeNameArrayTy, TypeNameVec)); + Offsets->setInitializer(ConstantArray::get(OffsetArrayTy, OffsetVec)); Initializers.push_back( ConstantStruct::get( StructInfoTy, ConstantExpr::getPointerCast(StructCounterName, Int8PtrTy), + ConstantInt::get(Int32Ty, SL->getSizeInBytes()), ConstantInt::get(Int32Ty, StructTy->getNumElements()), + ConstantExpr::getPointerCast(Offsets, Int32PtrTy), ConstantExpr::getPointerCast(Counters, Int64PtrTy), - ConstantExpr::getPointerCast(TypeName, Int8PtrPtrTy), + ConstantExpr::getPointerCast(TypeNames, Int8PtrPtrTy), nullptr)); } // Structs. @@ -399,7 +416,8 @@ GlobalVariable *EfficiencySanitizer::createCacheFragInfoGV( } // Create the tool-specific argument passed to EsanInit and EsanExit. -Constant *EfficiencySanitizer::createEsanInitToolInfoArg(Module &M) { +Constant *EfficiencySanitizer::createEsanInitToolInfoArg(Module &M, + const DataLayout &DL) { // This structure contains tool-specific information about each compilation // unit (module) and is passed to the runtime library. GlobalVariable *ToolInfoGV = nullptr; @@ -412,7 +430,7 @@ Constant *EfficiencySanitizer::createEsanInitToolInfoArg(Module &M) { // Create the tool-specific variable. if (Options.ToolType == EfficiencySanitizerOptions::ESAN_CacheFrag) - ToolInfoGV = createCacheFragInfoGV(M, UnitName); + ToolInfoGV = createCacheFragInfoGV(M, DL, UnitName); if (ToolInfoGV != nullptr) return ConstantExpr::getPointerCast(ToolInfoGV, Int8PtrTy); @@ -445,7 +463,7 @@ bool EfficiencySanitizer::initOnModule(Module &M) { PointerType *Int8PtrTy = Type::getInt8PtrTy(*Ctx); IntptrTy = DL.getIntPtrType(M.getContext()); // Create the variable passed to EsanInit and EsanExit. - Constant *ToolInfoArg = createEsanInitToolInfoArg(M); + Constant *ToolInfoArg = createEsanInitToolInfoArg(M, DL); // Constructor // We specify the tool type both in the EsanWhichToolName global // and as an arg to the init routine as a sanity check. |