/// uninitialized reads.
class MemorySanitizer : public FunctionPass {
public:
- MemorySanitizer() : FunctionPass(ID), TD(0), WarningFn(0) { }
+ MemorySanitizer(bool TrackOrigins = false)
+ : FunctionPass(ID),
+ TrackOrigins(TrackOrigins || ClTrackOrigins),
+ TD(0),
+ WarningFn(0) { }
const char *getPassName() const { return "MemorySanitizer"; }
bool runOnFunction(Function &F);
bool doInitialization(Module &M);
private:
void initializeCallbacks(Module &M);
+ /// \brief Track origins (allocation points) of uninitialized values.
+ bool TrackOrigins;
+
DataLayout *TD;
LLVMContext *C;
Type *IntptrTy;
"MemorySanitizer: detects uninitialized reads.",
false, false)
-FunctionPass *llvm::createMemorySanitizerPass() {
- return new MemorySanitizer();
+FunctionPass *llvm::createMemorySanitizerPass(bool TrackOrigins) {
+ return new MemorySanitizer(TrackOrigins);
}
/// \brief Create a non-const global initialized with the given string.
"__msan_init", IRB.getVoidTy(), NULL)), 0);
new GlobalVariable(M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
- IRB.getInt32(ClTrackOrigins), "__msan_track_origins");
+ IRB.getInt32(TrackOrigins), "__msan_track_origins");
return true;
}
if (ClCheckAccessAddress)
insertCheck(Addr, &I);
- if (ClTrackOrigins) {
+ if (MS.TrackOrigins) {
if (ClStoreCleanOrigin || isa<StructType>(Shadow->getType())) {
IRB.CreateStore(getOrigin(Val), getOriginPtr(Addr, IRB));
} else {
MS.ColdCallWeights);
IRB.SetInsertPoint(CheckTerm);
- if (ClTrackOrigins) {
+ if (MS.TrackOrigins) {
Instruction *Origin = InstrumentationList[i].Origin;
IRB.CreateStore(Origin ? (Value*)Origin : (Value*)IRB.getInt32(0),
MS.OriginTLS);
for (size_t i = 0, n = ShadowPHINodes.size(); i < n; i++) {
PHINode *PN = ShadowPHINodes[i];
PHINode *PNS = cast<PHINode>(getShadow(PN));
- PHINode *PNO = ClTrackOrigins ? cast<PHINode>(getOrigin(PN)) : 0;
+ PHINode *PNO = MS.TrackOrigins ? cast<PHINode>(getOrigin(PN)) : 0;
size_t NumValues = PN->getNumIncomingValues();
for (size_t v = 0; v < NumValues; v++) {
PNS->addIncoming(getShadow(PN, v), PN->getIncomingBlock(v));
/// \brief Compute the origin address for a given function argument.
Value *getOriginPtrForArgument(Value *A, IRBuilder<> &IRB,
int ArgOffset) {
- if (!ClTrackOrigins) return 0;
+ if (!MS.TrackOrigins) return 0;
Value *Base = IRB.CreatePointerCast(MS.ParamOriginTLS, MS.IntptrTy);
Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
return IRB.CreateIntToPtr(Base, PointerType::get(MS.OriginTy, 0),
/// \brief Set Origin to be the origin value for V.
void setOrigin(Value *V, Value *Origin) {
- if (!ClTrackOrigins) return;
+ if (!MS.TrackOrigins) return;
assert(!OriginMap.count(V) && "Values may only have one origin");
DEBUG(dbgs() << "ORIGIN: " << *V << " ==> " << *Origin << "\n");
OriginMap[V] = Origin;
}
DEBUG(dbgs() << " ARG: " << *AI << " ==> " <<
**ShadowPtr << "\n");
- if (ClTrackOrigins) {
+ if (MS.TrackOrigins) {
Value* OriginPtr = getOriginPtrForArgument(AI, EntryIRB, ArgOffset);
setOrigin(A, EntryIRB.CreateLoad(OriginPtr));
}
/// \brief Get the origin for a value.
Value *getOrigin(Value *V) {
- if (!ClTrackOrigins) return 0;
+ if (!MS.TrackOrigins) return 0;
if (isa<Instruction>(V) || isa<Argument>(V)) {
Value *Origin = OriginMap[V];
if (!Origin) {
if (ClCheckAccessAddress)
insertCheck(I.getPointerOperand(), &I);
- if (ClTrackOrigins)
+ if (MS.TrackOrigins)
setOrigin(&I, IRB.CreateLoad(getOriginPtr(Addr, IRB)));
}
}
}
- if (ClTrackOrigins) {
+ if (MSV->MS.TrackOrigins) {
assert(OpOrigin);
if (!Origin) {
Origin = OpOrigin;
/// \brief Add an application value to the mix.
Combiner &Add(Value *V) {
Value *OpShadow = MSV->getShadow(V);
- Value *OpOrigin = ClTrackOrigins ? MSV->getOrigin(V) : 0;
+ Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(V) : 0;
return Add(OpShadow, OpOrigin);
}
Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(I));
MSV->setShadow(I, Shadow);
}
- if (ClTrackOrigins) {
+ if (MSV->MS.TrackOrigins) {
assert(Origin);
MSV->setOrigin(I, Origin);
}
/// \brief Propagate origin for arbitrary operation.
void setOriginForNaryOp(Instruction &I) {
- if (!ClTrackOrigins) return;
+ if (!MS.TrackOrigins) return;
IRBuilder<> IRB(&I);
OriginCombiner OC(this, IRB);
for (Instruction::op_iterator OI = I.op_begin(); OI != I.op_end(); ++OI)
// FIXME: use ClStoreCleanOrigin
// FIXME: factor out common code from materializeStores
- if (ClTrackOrigins)
+ if (MS.TrackOrigins)
IRB.CreateStore(getOrigin(&I, 1), getOriginPtr(Addr, IRB));
return true;
}
if (ClCheckAccessAddress)
insertCheck(Addr, &I);
- if (ClTrackOrigins)
+ if (MS.TrackOrigins)
setOrigin(&I, IRB.CreateLoad(getOriginPtr(Addr, IRB)));
return true;
}
Store = IRB.CreateAlignedStore(ArgShadow, ArgShadowBase,
kShadowTLSAlignment);
}
- if (ClTrackOrigins)
+ if (MS.TrackOrigins)
IRB.CreateStore(getOrigin(A),
getOriginPtrForArgument(A, IRB, ArgOffset));
assert(Size != 0 && Store != 0);
IRBAfter.CreateAlignedLoad(getShadowPtrForRetval(&I, IRBAfter),
kShadowTLSAlignment, "_msret");
setShadow(&I, RetvalShadow);
- if (ClTrackOrigins)
+ if (MS.TrackOrigins)
setOrigin(&I, IRBAfter.CreateLoad(getOriginPtrForRetval(IRBAfter)));
}
Value *ShadowPtr = getShadowPtrForRetval(RetVal, IRB);
DEBUG(dbgs() << "Return: " << *Shadow << "\n" << *ShadowPtr << "\n");
IRB.CreateAlignedStore(Shadow, ShadowPtr, kShadowTLSAlignment);
- if (ClTrackOrigins)
+ if (MS.TrackOrigins)
IRB.CreateStore(getOrigin(RetVal), getOriginPtrForRetval(IRB));
}
}
ShadowPHINodes.push_back(&I);
setShadow(&I, IRB.CreatePHI(getShadowTy(&I), I.getNumIncomingValues(),
"_msphi_s"));
- if (ClTrackOrigins)
+ if (MS.TrackOrigins)
setOrigin(&I, IRB.CreatePHI(MS.OriginTy, I.getNumIncomingValues(),
"_msphi_o"));
}
Size, I.getAlignment());
}
- if (ClTrackOrigins) {
+ if (MS.TrackOrigins) {
setOrigin(&I, getCleanOrigin());
SmallString<2048> StackDescriptionStorage;
raw_svector_ostream StackDescription(StackDescriptionStorage);
setShadow(&I, IRB.CreateSelect(I.getCondition(),
getShadow(I.getTrueValue()), getShadow(I.getFalseValue()),
"_msprop"));
- if (ClTrackOrigins)
+ if (MS.TrackOrigins)
setOrigin(&I, IRB.CreateSelect(I.getCondition(),
getOrigin(I.getTrueValue()), getOrigin(I.getFalseValue())));
}