[llvm-branch-commits] [llvm] a28db8b - [dfsan] Add empty APIs for field-level shadow
Jianzhou Zhao via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Dec 4 13:47:30 PST 2020
Author: Jianzhou Zhao
Date: 2020-12-04T21:42:07Z
New Revision: a28db8b27a232cffcb77d0f902d76ee07cd54c05
URL: https://github.com/llvm/llvm-project/commit/a28db8b27a232cffcb77d0f902d76ee07cd54c05
DIFF: https://github.com/llvm/llvm-project/commit/a28db8b27a232cffcb77d0f902d76ee07cd54c05.diff
LOG: [dfsan] Add empty APIs for field-level shadow
This is a child diff of D92261.
This diff adds APIs that return shadow type/value/zero from origin
objects. For the time being these APIs simply returns primitive
shadow type/value/zero. The following diff will be implementing the
conversion.
As D92261 explains, some cases still use primitive shadow during
the incremential changes. The cases include
1) alloca/load/store
2) custom function IO
3) vectors
At the cases this diff does not use the new APIs, but uses primitive
shadow objects explicitly.
Reviewed-by: morehouse
Differential Revision: https://reviews.llvm.org/D92629
Added:
Modified:
llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index fc784e72797c..87cf67705324 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -419,6 +419,17 @@ class DataFlowSanitizer {
bool init(Module &M);
+ /// Returns a zero constant with the shadow type of V's type. Until we support
+ /// field/index level shadow values, the following methods always return
+ /// primitive types, values or zero constants.
+ Constant *getZeroShadow(Value *V);
+ /// Checks if V is a zero shadow.
+ bool isZeroShadow(Value *V);
+ /// Returns the shadow type of OrigTy.
+ Type *getShadowTy(Type *OrigTy);
+ /// Returns the shadow type of of V's type.
+ Type *getShadowTy(Value *V);
+
public:
DataFlowSanitizer(const std::vector<std::string> &ABIListFiles);
@@ -458,10 +469,10 @@ struct DFSanFunction {
/// Computes the shadow address for a given function argument.
///
/// Shadow = ArgTLS+ArgOffset.
- Value *getArgTLS(unsigned ArgOffset, IRBuilder<> &IRB);
+ Value *getArgTLS(Type *T, unsigned ArgOffset, IRBuilder<> &IRB);
/// Computes the shadow address for a retval.
- Value *getRetvalTLS(IRBuilder<> &IRB);
+ Value *getRetvalTLS(Type *T, IRBuilder<> &IRB);
Value *getShadow(Value *V);
void setShadow(Instruction *I, Value *Shadow);
@@ -580,6 +591,20 @@ TransformedFunction DataFlowSanitizer::getCustomFunctionType(FunctionType *T) {
ArgumentIndexMapping);
}
+bool DataFlowSanitizer::isZeroShadow(Value *V) {
+ return ZeroPrimitiveShadow == V;
+}
+
+Constant *DataFlowSanitizer::getZeroShadow(Value *V) {
+ return ZeroPrimitiveShadow;
+}
+
+Type *DataFlowSanitizer::getShadowTy(Type *OrigTy) { return PrimitiveShadowTy; }
+
+Type *DataFlowSanitizer::getShadowTy(Value *V) {
+ return getShadowTy(V->getType());
+}
+
bool DataFlowSanitizer::init(Module &M) {
Triple TargetTriple(M.getTargetTriple());
bool IsX86_64 = TargetTriple.getArch() == Triple::x86_64;
@@ -1075,17 +1100,17 @@ bool DataFlowSanitizer::runImpl(Module &M) {
M.global_size() != InitialGlobalSize || M.size() != InitialModuleSize;
}
-Value *DFSanFunction::getArgTLS(unsigned ArgOffset, IRBuilder<> &IRB) {
+Value *DFSanFunction::getArgTLS(Type *T, unsigned ArgOffset, IRBuilder<> &IRB) {
Value *Base = IRB.CreatePointerCast(DFS.ArgTLS, DFS.IntptrTy);
if (ArgOffset)
Base = IRB.CreateAdd(Base, ConstantInt::get(DFS.IntptrTy, ArgOffset));
- return IRB.CreateIntToPtr(Base, PointerType::get(DFS.PrimitiveShadowTy, 0),
+ return IRB.CreateIntToPtr(Base, PointerType::get(DFS.getShadowTy(T), 0),
"_dfsarg");
}
-Value *DFSanFunction::getRetvalTLS(IRBuilder<> &IRB) {
+Value *DFSanFunction::getRetvalTLS(Type *T, IRBuilder<> &IRB) {
return IRB.CreatePointerCast(
- DFS.RetvalTLS, PointerType::get(DFS.PrimitiveShadowTy, 0), "_dfsret");
+ DFS.RetvalTLS, PointerType::get(DFS.getShadowTy(T), 0), "_dfsret");
}
Value *DFSanFunction::getShadowForTLSArgument(Argument *A) {
@@ -1098,7 +1123,7 @@ Value *DFSanFunction::getShadowForTLSArgument(Argument *A) {
continue;
}
- unsigned Size = DL.getTypeAllocSize(DFS.PrimitiveShadowTy);
+ unsigned Size = DL.getTypeAllocSize(DFS.getShadowTy(&FArg));
if (A != &FArg) {
ArgOffset += alignTo(Size, kShadowTLSAlignment);
if (ArgOffset > kArgTLSSize)
@@ -1111,22 +1136,22 @@ Value *DFSanFunction::getShadowForTLSArgument(Argument *A) {
Instruction *ArgTLSPos = &*F->getEntryBlock().begin();
IRBuilder<> IRB(ArgTLSPos);
- Value *ArgShadowPtr = getArgTLS(ArgOffset, IRB);
- return IRB.CreateAlignedLoad(DFS.PrimitiveShadowTy, ArgShadowPtr,
+ Value *ArgShadowPtr = getArgTLS(FArg.getType(), ArgOffset, IRB);
+ return IRB.CreateAlignedLoad(DFS.getShadowTy(&FArg), ArgShadowPtr,
kShadowTLSAlignment);
}
- return DFS.ZeroPrimitiveShadow;
+ return DFS.getZeroShadow(A);
}
Value *DFSanFunction::getShadow(Value *V) {
if (!isa<Argument>(V) && !isa<Instruction>(V))
- return DFS.ZeroPrimitiveShadow;
+ return DFS.getZeroShadow(V);
Value *&Shadow = ValShadowMap[V];
if (!Shadow) {
if (Argument *A = dyn_cast<Argument>(V)) {
if (IsNativeABI)
- return DFS.ZeroPrimitiveShadow;
+ return DFS.getZeroShadow(V);
switch (IA) {
case DataFlowSanitizer::IA_TLS: {
Shadow = getShadowForTLSArgument(A);
@@ -1144,7 +1169,7 @@ Value *DFSanFunction::getShadow(Value *V) {
}
NonZeroChecks.push_back(Shadow);
} else {
- Shadow = DFS.ZeroPrimitiveShadow;
+ Shadow = DFS.getZeroShadow(V);
}
}
return Shadow;
@@ -1175,9 +1200,9 @@ Value *DataFlowSanitizer::getShadowAddress(Value *Addr, Instruction *Pos) {
// Generates IR to compute the union of the two given shadows, inserting it
// before Pos. Returns the computed union Value.
Value *DFSanFunction::combineShadows(Value *V1, Value *V2, Instruction *Pos) {
- if (V1 == DFS.ZeroPrimitiveShadow)
+ if (DFS.isZeroShadow(V1))
return V2;
- if (V2 == DFS.ZeroPrimitiveShadow)
+ if (DFS.isZeroShadow(V2))
return V1;
if (V1 == V2)
return V1;
@@ -1261,7 +1286,7 @@ Value *DFSanFunction::combineShadows(Value *V1, Value *V2, Instruction *Pos) {
// the computed union Value.
Value *DFSanFunction::combineOperandShadows(Instruction *Inst) {
if (Inst->getNumOperands() == 0)
- return DFS.ZeroPrimitiveShadow;
+ return DFS.getZeroShadow(Inst);
Value *Shadow = getShadow(Inst->getOperand(0));
for (unsigned i = 1, n = Inst->getNumOperands(); i != n; ++i) {
@@ -1426,7 +1451,7 @@ void DFSanVisitor::visitLoadInst(LoadInst &LI) {
auto &DL = LI.getModule()->getDataLayout();
uint64_t Size = DL.getTypeStoreSize(LI.getType());
if (Size == 0) {
- DFSF.setShadow(&LI, DFSF.DFS.ZeroPrimitiveShadow);
+ DFSF.setShadow(&LI, DFSF.DFS.getZeroShadow(&LI));
return;
}
@@ -1437,7 +1462,7 @@ void DFSanVisitor::visitLoadInst(LoadInst &LI) {
Value *PtrShadow = DFSF.getShadow(LI.getPointerOperand());
Shadow = DFSF.combineShadows(Shadow, PtrShadow, &LI);
}
- if (Shadow != DFSF.DFS.ZeroPrimitiveShadow)
+ if (!DFSF.DFS.isZeroShadow(Shadow))
DFSF.NonZeroChecks.push_back(Shadow);
DFSF.setShadow(&LI, Shadow);
@@ -1462,7 +1487,7 @@ void DFSanFunction::storeShadow(Value *Addr, uint64_t Size, Align Alignment,
const Align ShadowAlign(Alignment.value() * DFS.ShadowWidthBytes);
IRBuilder<> IRB(Pos);
Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
- if (Shadow == DFS.ZeroPrimitiveShadow) {
+ if (DFS.isZeroShadow(Shadow)) {
IntegerType *ShadowTy =
IntegerType::get(*DFS.Ctx, Size * DFS.ShadowWidthBits);
Value *ExtZeroShadow = ConstantInt::get(ShadowTy, 0);
@@ -1648,12 +1673,14 @@ void DFSanVisitor::visitReturnInst(ReturnInst &RI) {
case DataFlowSanitizer::IA_TLS: {
Value *S = DFSF.getShadow(RI.getReturnValue());
IRBuilder<> IRB(&RI);
+ Type *RT = DFSF.F->getFunctionType()->getReturnType();
unsigned Size =
- getDataLayout().getTypeAllocSize(DFSF.DFS.PrimitiveShadowTy);
+ getDataLayout().getTypeAllocSize(DFSF.DFS.getShadowTy(RT));
if (Size <= kRetvalTLSSize) {
// If the size overflows, stores nothing. At callsite, oversized return
// shadows are set to zero.
- IRB.CreateAlignedStore(S, DFSF.getRetvalTLS(IRB), kShadowTLSAlignment);
+ IRB.CreateAlignedStore(S, DFSF.getRetvalTLS(RT, IRB),
+ kShadowTLSAlignment);
}
break;
}
@@ -1694,11 +1721,11 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
CB.setCalledFunction(F);
IRB.CreateCall(DFSF.DFS.DFSanUnimplementedFn,
IRB.CreateGlobalStringPtr(F->getName()));
- DFSF.setShadow(&CB, DFSF.DFS.ZeroPrimitiveShadow);
+ DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
return;
case DataFlowSanitizer::WK_Discard:
CB.setCalledFunction(F);
- DFSF.setShadow(&CB, DFSF.DFS.ZeroPrimitiveShadow);
+ DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
return;
case DataFlowSanitizer::WK_Functional:
CB.setCalledFunction(F);
@@ -1787,7 +1814,7 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
// Update the parameter attributes of the custom call instruction to
// zero extend the shadow parameters. This is required for targets
- // which consider ShadowTy an illegal type.
+ // which consider PrimitiveShadowTy an illegal type.
for (unsigned n = 0; n < FT->getNumParams(); n++) {
const unsigned ArgNo = ShadowArgStart + n;
if (CustomCI->getArgOperand(ArgNo)->getType() ==
@@ -1814,14 +1841,16 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
unsigned ArgOffset = 0;
const DataLayout &DL = getDataLayout();
for (unsigned I = 0, N = FT->getNumParams(); I != N; ++I) {
- unsigned Size = DL.getTypeAllocSize(DFSF.DFS.PrimitiveShadowTy);
+ unsigned Size =
+ DL.getTypeAllocSize(DFSF.DFS.getShadowTy(FT->getParamType(I)));
// Stop storing if arguments' size overflows. Inside a function, arguments
// after overflow have zero shadow values.
if (ArgOffset + Size > kArgTLSSize)
break;
- IRB.CreateAlignedStore(DFSF.getShadow(CB.getArgOperand(I)),
- DFSF.getArgTLS(ArgOffset, IRB),
- kShadowTLSAlignment);
+ IRB.CreateAlignedStore(
+ DFSF.getShadow(CB.getArgOperand(I)),
+ DFSF.getArgTLS(FT->getParamType(I), ArgOffset, IRB),
+ kShadowTLSAlignment);
ArgOffset += alignTo(Size, kShadowTLSAlignment);
}
}
@@ -1844,13 +1873,13 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) {
IRBuilder<> NextIRB(Next);
const DataLayout &DL = getDataLayout();
- unsigned Size = DL.getTypeAllocSize(DFSF.DFS.PrimitiveShadowTy);
+ unsigned Size = DL.getTypeAllocSize(DFSF.DFS.getShadowTy(&CB));
if (Size > kRetvalTLSSize) {
// Set overflowed return shadow to be zero.
- DFSF.setShadow(&CB, DFSF.DFS.ZeroPrimitiveShadow);
+ DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
} else {
LoadInst *LI = NextIRB.CreateAlignedLoad(
- DFSF.DFS.PrimitiveShadowTy, DFSF.getRetvalTLS(NextIRB),
+ DFSF.DFS.getShadowTy(&CB), DFSF.getRetvalTLS(CB.getType(), NextIRB),
kShadowTLSAlignment, "_dfsret");
DFSF.SkipInsts.insert(LI);
DFSF.setShadow(&CB, LI);
@@ -1919,11 +1948,12 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
}
void DFSanVisitor::visitPHINode(PHINode &PN) {
- PHINode *ShadowPN = PHINode::Create(DFSF.DFS.PrimitiveShadowTy,
- PN.getNumIncomingValues(), "", &PN);
+ Type *ShadowTy = DFSF.DFS.getShadowTy(&PN);
+ PHINode *ShadowPN =
+ PHINode::Create(ShadowTy, PN.getNumIncomingValues(), "", &PN);
// Give the shadow phi node valid predecessors to fool SplitEdge into working.
- Value *UndefShadow = UndefValue::get(DFSF.DFS.PrimitiveShadowTy);
+ Value *UndefShadow = UndefValue::get(ShadowTy);
for (PHINode::block_iterator i = PN.block_begin(), e = PN.block_end(); i != e;
++i) {
ShadowPN->addIncoming(UndefShadow, *i);
More information about the llvm-branch-commits
mailing list