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.  | 

