Skip to content

Instantly share code, notes, and snippets.

@ramosian-glider
Created August 31, 2018 12:50
Show Gist options
  • Save ramosian-glider/af6132c619db37e5650115aa284eb849 to your computer and use it in GitHub Desktop.
Save ramosian-glider/af6132c619db37e5650115aa284eb849 to your computer and use it in GitHub Desktop.
lib/Transforms/Instrumentation/InitializeStack.cpp v.1
//===- 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