Created
August 31, 2018 12:50
-
-
Save ramosian-glider/af6132c619db37e5650115aa284eb849 to your computer and use it in GitHub Desktop.
lib/Transforms/Instrumentation/InitializeStack.cpp v.1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//===- AllocaZeroInitializer.cpp - detector of uninitialized reads -------===// | |
// | |
// The LLVM Compiler Infrastructure | |
// | |
// This file is distributed under the University of Illinois Open Source | |
// License. See LICENSE.TXT for details. | |
// | |
//===----------------------------------------------------------------------===// | |
// | |
/// \file | |
/// This file is a part of AllocaZeroInitializer, an address sanity checker | |
/// based on tagged addressing. | |
//===----------------------------------------------------------------------===// | |
#include "llvm/ADT/SmallVector.h" | |
#include "llvm/ADT/StringExtras.h" | |
#include "llvm/ADT/StringRef.h" | |
#include "llvm/ADT/Triple.h" | |
#include "llvm/IR/Attributes.h" | |
#include "llvm/IR/BasicBlock.h" | |
#include "llvm/IR/Constant.h" | |
#include "llvm/IR/Constants.h" | |
#include "llvm/IR/DataLayout.h" | |
#include "llvm/IR/DerivedTypes.h" | |
#include "llvm/IR/Function.h" | |
#include "llvm/IR/IRBuilder.h" | |
#include "llvm/IR/InlineAsm.h" | |
#include "llvm/IR/InstVisitor.h" | |
#include "llvm/IR/Instruction.h" | |
#include "llvm/IR/Instructions.h" | |
#include "llvm/IR/IntrinsicInst.h" | |
#include "llvm/IR/Intrinsics.h" | |
#include "llvm/IR/LLVMContext.h" | |
#include "llvm/IR/MDBuilder.h" | |
#include "llvm/IR/Module.h" | |
#include "llvm/IR/Type.h" | |
#include "llvm/IR/Value.h" | |
#include "llvm/Pass.h" | |
#include "llvm/Support/Casting.h" | |
#include "llvm/Support/CommandLine.h" | |
#include "llvm/Support/Debug.h" | |
#include "llvm/Support/raw_ostream.h" | |
#include "llvm/Transforms/Instrumentation.h" | |
#include "llvm/Transforms/Utils/BasicBlockUtils.h" | |
#include "llvm/Transforms/Utils/ModuleUtils.h" | |
#include "llvm/Transforms/Utils/PromoteMemToReg.h" | |
using namespace llvm; | |
#define DEBUG_TYPE "alloca-zero-init" | |
static cl::opt<bool> | |
ClZeroInitAllocas("zero-init-allocas", | |
cl::desc("zero-initialize allocas"), | |
cl::Hidden, cl::init(false)); | |
namespace { | |
class AllocaZeroInitializer : public FunctionPass { | |
public: | |
// Pass identification, replacement for typeid. | |
static char ID; | |
explicit AllocaZeroInitializer() : FunctionPass(ID) { } | |
StringRef getPassName() const override { return "AllocaZeroInitializer"; } | |
bool runOnFunction(Function &F) override; | |
}; | |
} // end anonymous namespace | |
char AllocaZeroInitializer::ID = 0; | |
INITIALIZE_PASS_BEGIN( | |
AllocaZeroInitializer, "alloca-zero-init", | |
"AllocaZeroInitializer: zero-initialize allocas.", false, | |
false) | |
INITIALIZE_PASS_END( | |
AllocaZeroInitializer, "alloca-zero-init", | |
"AllocaZeroInitializer: zero-initialize allocas.", false, | |
false) | |
FunctionPass *llvm::createAllocaZeroInitializerPass() { | |
return new AllocaZeroInitializer(); | |
} | |
static uint64_t getAllocaSizeInBytes(const AllocaInst &AI) { | |
uint64_t ArraySize = 1; | |
if (AI.isArrayAllocation()) { | |
const ConstantInt *CI = dyn_cast<ConstantInt>(AI.getArraySize()); | |
assert(CI && "non-constant array size"); | |
ArraySize = CI->getZExtValue(); | |
} | |
Type *Ty = AI.getAllocatedType(); | |
uint64_t SizeInBytes = AI.getModule()->getDataLayout().getTypeAllocSize(Ty); | |
return SizeInBytes * ArraySize; | |
} | |
bool AllocaZeroInitializer::runOnFunction(Function &F) { | |
if (!ClZeroInitAllocas) | |
return false; | |
/// if (!F.hasFnAttribute(Attribute::ZeroInitializeAllocas)) | |
/// return false; | |
LLVM_DEBUG(dbgs() << "Function: " << F.getName() << "\n"); | |
///errs() << F.getName() << "\n"; | |
///errs() << F << "\n"; | |
bool Changed = false; | |
const DataLayout &DL = F.getParent()->getDataLayout(); | |
SmallVector<AllocaInst*, 8> AllocasToInstrument; | |
for (auto &BB : F) { | |
for (auto &Inst : BB) { | |
if (AllocaInst *AI = dyn_cast<AllocaInst>(&Inst)) { | |
AllocasToInstrument.push_back(AI); | |
continue; | |
} | |
} | |
Instruction *InsertPt = &*F.getEntryBlock().begin(); | |
IRBuilder<> IRB(InsertPt); | |
for (auto *AI : AllocasToInstrument) { | |
IRB.SetInsertPoint(AI->getNextNode()); | |
Value *APtr = IRB.CreatePointerCast(AI, IRB.getInt8PtrTy()); | |
if (AI->isStaticAlloca()) { | |
int Size = getAllocaSizeInBytes(*AI); | |
IRB.CreateMemSet(APtr, ConstantInt::get(IRB.getInt8Ty(), 0), Size, AI->getAlignment()); | |
} else { | |
Value *ArraySize = AI->getArraySize(); | |
Type *Ty = AI->getAllocatedType(); | |
Value *TySize = ConstantInt::get(IRB.getIntPtrTy(DL), DL.getTypeAllocSize(Ty)); | |
Value *Size = IRB.CreateMul(ArraySize, TySize); | |
IRB.CreateMemSet(APtr, ConstantInt::get(IRB.getInt8Ty(), 0), Size, AI->getAlignment()); | |
} | |
Changed = true; | |
} | |
} | |
///errs() << "Done\n"; | |
return Changed; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment