Skip to content

Commit a28db8b

Browse files
[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
1 parent d764ad7 commit a28db8b

File tree

1 file changed

+64
-34
lines changed

1 file changed

+64
-34
lines changed

llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp

Lines changed: 64 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,17 @@ class DataFlowSanitizer {
419419

420420
bool init(Module &M);
421421

422+
/// Returns a zero constant with the shadow type of V's type. Until we support
423+
/// field/index level shadow values, the following methods always return
424+
/// primitive types, values or zero constants.
425+
Constant *getZeroShadow(Value *V);
426+
/// Checks if V is a zero shadow.
427+
bool isZeroShadow(Value *V);
428+
/// Returns the shadow type of OrigTy.
429+
Type *getShadowTy(Type *OrigTy);
430+
/// Returns the shadow type of of V's type.
431+
Type *getShadowTy(Value *V);
432+
422433
public:
423434
DataFlowSanitizer(const std::vector<std::string> &ABIListFiles);
424435

@@ -458,10 +469,10 @@ struct DFSanFunction {
458469
/// Computes the shadow address for a given function argument.
459470
///
460471
/// Shadow = ArgTLS+ArgOffset.
461-
Value *getArgTLS(unsigned ArgOffset, IRBuilder<> &IRB);
472+
Value *getArgTLS(Type *T, unsigned ArgOffset, IRBuilder<> &IRB);
462473

463474
/// Computes the shadow address for a retval.
464-
Value *getRetvalTLS(IRBuilder<> &IRB);
475+
Value *getRetvalTLS(Type *T, IRBuilder<> &IRB);
465476

466477
Value *getShadow(Value *V);
467478
void setShadow(Instruction *I, Value *Shadow);
@@ -580,6 +591,20 @@ TransformedFunction DataFlowSanitizer::getCustomFunctionType(FunctionType *T) {
580591
ArgumentIndexMapping);
581592
}
582593

594+
bool DataFlowSanitizer::isZeroShadow(Value *V) {
595+
return ZeroPrimitiveShadow == V;
596+
}
597+
598+
Constant *DataFlowSanitizer::getZeroShadow(Value *V) {
599+
return ZeroPrimitiveShadow;
600+
}
601+
602+
Type *DataFlowSanitizer::getShadowTy(Type *OrigTy) { return PrimitiveShadowTy; }
603+
604+
Type *DataFlowSanitizer::getShadowTy(Value *V) {
605+
return getShadowTy(V->getType());
606+
}
607+
583608
bool DataFlowSanitizer::init(Module &M) {
584609
Triple TargetTriple(M.getTargetTriple());
585610
bool IsX86_64 = TargetTriple.getArch() == Triple::x86_64;
@@ -1075,17 +1100,17 @@ bool DataFlowSanitizer::runImpl(Module &M) {
10751100
M.global_size() != InitialGlobalSize || M.size() != InitialModuleSize;
10761101
}
10771102

1078-
Value *DFSanFunction::getArgTLS(unsigned ArgOffset, IRBuilder<> &IRB) {
1103+
Value *DFSanFunction::getArgTLS(Type *T, unsigned ArgOffset, IRBuilder<> &IRB) {
10791104
Value *Base = IRB.CreatePointerCast(DFS.ArgTLS, DFS.IntptrTy);
10801105
if (ArgOffset)
10811106
Base = IRB.CreateAdd(Base, ConstantInt::get(DFS.IntptrTy, ArgOffset));
1082-
return IRB.CreateIntToPtr(Base, PointerType::get(DFS.PrimitiveShadowTy, 0),
1107+
return IRB.CreateIntToPtr(Base, PointerType::get(DFS.getShadowTy(T), 0),
10831108
"_dfsarg");
10841109
}
10851110

1086-
Value *DFSanFunction::getRetvalTLS(IRBuilder<> &IRB) {
1111+
Value *DFSanFunction::getRetvalTLS(Type *T, IRBuilder<> &IRB) {
10871112
return IRB.CreatePointerCast(
1088-
DFS.RetvalTLS, PointerType::get(DFS.PrimitiveShadowTy, 0), "_dfsret");
1113+
DFS.RetvalTLS, PointerType::get(DFS.getShadowTy(T), 0), "_dfsret");
10891114
}
10901115

10911116
Value *DFSanFunction::getShadowForTLSArgument(Argument *A) {
@@ -1098,7 +1123,7 @@ Value *DFSanFunction::getShadowForTLSArgument(Argument *A) {
10981123
continue;
10991124
}
11001125

1101-
unsigned Size = DL.getTypeAllocSize(DFS.PrimitiveShadowTy);
1126+
unsigned Size = DL.getTypeAllocSize(DFS.getShadowTy(&FArg));
11021127
if (A != &FArg) {
11031128
ArgOffset += alignTo(Size, kShadowTLSAlignment);
11041129
if (ArgOffset > kArgTLSSize)
@@ -1111,22 +1136,22 @@ Value *DFSanFunction::getShadowForTLSArgument(Argument *A) {
11111136

11121137
Instruction *ArgTLSPos = &*F->getEntryBlock().begin();
11131138
IRBuilder<> IRB(ArgTLSPos);
1114-
Value *ArgShadowPtr = getArgTLS(ArgOffset, IRB);
1115-
return IRB.CreateAlignedLoad(DFS.PrimitiveShadowTy, ArgShadowPtr,
1139+
Value *ArgShadowPtr = getArgTLS(FArg.getType(), ArgOffset, IRB);
1140+
return IRB.CreateAlignedLoad(DFS.getShadowTy(&FArg), ArgShadowPtr,
11161141
kShadowTLSAlignment);
11171142
}
11181143

1119-
return DFS.ZeroPrimitiveShadow;
1144+
return DFS.getZeroShadow(A);
11201145
}
11211146

11221147
Value *DFSanFunction::getShadow(Value *V) {
11231148
if (!isa<Argument>(V) && !isa<Instruction>(V))
1124-
return DFS.ZeroPrimitiveShadow;
1149+
return DFS.getZeroShadow(V);
11251150
Value *&Shadow = ValShadowMap[V];
11261151
if (!Shadow) {
11271152
if (Argument *A = dyn_cast<Argument>(V)) {
11281153
if (IsNativeABI)
1129-
return DFS.ZeroPrimitiveShadow;
1154+
return DFS.getZeroShadow(V);
11301155
switch (IA) {
11311156
case DataFlowSanitizer::IA_TLS: {
11321157
Shadow = getShadowForTLSArgument(A);
@@ -1144,7 +1169,7 @@ Value *DFSanFunction::getShadow(Value *V) {
11441169
}
11451170
NonZeroChecks.push_back(Shadow);
11461171
} else {
1147-
Shadow = DFS.ZeroPrimitiveShadow;
1172+
Shadow = DFS.getZeroShadow(V);
11481173
}
11491174
}
11501175
return Shadow;
@@ -1175,9 +1200,9 @@ Value *DataFlowSanitizer::getShadowAddress(Value *Addr, Instruction *Pos) {
11751200
// Generates IR to compute the union of the two given shadows, inserting it
11761201
// before Pos. Returns the computed union Value.
11771202
Value *DFSanFunction::combineShadows(Value *V1, Value *V2, Instruction *Pos) {
1178-
if (V1 == DFS.ZeroPrimitiveShadow)
1203+
if (DFS.isZeroShadow(V1))
11791204
return V2;
1180-
if (V2 == DFS.ZeroPrimitiveShadow)
1205+
if (DFS.isZeroShadow(V2))
11811206
return V1;
11821207
if (V1 == V2)
11831208
return V1;
@@ -1261,7 +1286,7 @@ Value *DFSanFunction::combineShadows(Value *V1, Value *V2, Instruction *Pos) {
12611286
// the computed union Value.
12621287
Value *DFSanFunction::combineOperandShadows(Instruction *Inst) {
12631288
if (Inst->getNumOperands() == 0)
1264-
return DFS.ZeroPrimitiveShadow;
1289+
return DFS.getZeroShadow(Inst);
12651290

12661291
Value *Shadow = getShadow(Inst->getOperand(0));
12671292
for (unsigned i = 1, n = Inst->getNumOperands(); i != n; ++i) {
@@ -1426,7 +1451,7 @@ void DFSanVisitor::visitLoadInst(LoadInst &LI) {
14261451
auto &DL = LI.getModule()->getDataLayout();
14271452
uint64_t Size = DL.getTypeStoreSize(LI.getType());
14281453
if (Size == 0) {
1429-
DFSF.setShadow(&LI, DFSF.DFS.ZeroPrimitiveShadow);
1454+
DFSF.setShadow(&LI, DFSF.DFS.getZeroShadow(&LI));
14301455
return;
14311456
}
14321457

@@ -1437,7 +1462,7 @@ void DFSanVisitor::visitLoadInst(LoadInst &LI) {
14371462
Value *PtrShadow = DFSF.getShadow(LI.getPointerOperand());
14381463
Shadow = DFSF.combineShadows(Shadow, PtrShadow, &LI);
14391464
}
1440-
if (Shadow != DFSF.DFS.ZeroPrimitiveShadow)
1465+
if (!DFSF.DFS.isZeroShadow(Shadow))
14411466
DFSF.NonZeroChecks.push_back(Shadow);
14421467

14431468
DFSF.setShadow(&LI, Shadow);
@@ -1462,7 +1487,7 @@ void DFSanFunction::storeShadow(Value *Addr, uint64_t Size, Align Alignment,
14621487
const Align ShadowAlign(Alignment.value() * DFS.ShadowWidthBytes);
14631488
IRBuilder<> IRB(Pos);
14641489
Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
1465-
if (Shadow == DFS.ZeroPrimitiveShadow) {
1490+
if (DFS.isZeroShadow(Shadow)) {
14661491
IntegerType *ShadowTy =
14671492
IntegerType::get(*DFS.Ctx, Size * DFS.ShadowWidthBits);
14681493
Value *ExtZeroShadow = ConstantInt::get(ShadowTy, 0);
@@ -1648,12 +1673,14 @@ void DFSanVisitor::visitReturnInst(ReturnInst &RI) {
16481673
case DataFlowSanitizer::IA_TLS: {
16491674
Value *S = DFSF.getShadow(RI.getReturnValue());
16501675
IRBuilder<> IRB(&RI);
1676+
Type *RT = DFSF.F->getFunctionType()->getReturnType();
16511677
unsigned Size =
1652-
getDataLayout().getTypeAllocSize(DFSF.DFS.PrimitiveShadowTy);
1678+
getDataLayout().getTypeAllocSize(DFSF.DFS.getShadowTy(RT));
16531679
if (Size <= kRetvalTLSSize) {
16541680
// If the size overflows, stores nothing. At callsite, oversized return
16551681
// shadows are set to zero.
1656-
IRB.CreateAlignedStore(S, DFSF.getRetvalTLS(IRB), kShadowTLSAlignment);
1682+
IRB.CreateAlignedStore(S, DFSF.getRetvalTLS(RT, IRB),
1683+
kShadowTLSAlignment);
16571684
}
16581685
break;
16591686
}
@@ -1694,11 +1721,11 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
16941721
CB.setCalledFunction(F);
16951722
IRB.CreateCall(DFSF.DFS.DFSanUnimplementedFn,
16961723
IRB.CreateGlobalStringPtr(F->getName()));
1697-
DFSF.setShadow(&CB, DFSF.DFS.ZeroPrimitiveShadow);
1724+
DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
16981725
return;
16991726
case DataFlowSanitizer::WK_Discard:
17001727
CB.setCalledFunction(F);
1701-
DFSF.setShadow(&CB, DFSF.DFS.ZeroPrimitiveShadow);
1728+
DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
17021729
return;
17031730
case DataFlowSanitizer::WK_Functional:
17041731
CB.setCalledFunction(F);
@@ -1787,7 +1814,7 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
17871814

17881815
// Update the parameter attributes of the custom call instruction to
17891816
// zero extend the shadow parameters. This is required for targets
1790-
// which consider ShadowTy an illegal type.
1817+
// which consider PrimitiveShadowTy an illegal type.
17911818
for (unsigned n = 0; n < FT->getNumParams(); n++) {
17921819
const unsigned ArgNo = ShadowArgStart + n;
17931820
if (CustomCI->getArgOperand(ArgNo)->getType() ==
@@ -1814,14 +1841,16 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
18141841
unsigned ArgOffset = 0;
18151842
const DataLayout &DL = getDataLayout();
18161843
for (unsigned I = 0, N = FT->getNumParams(); I != N; ++I) {
1817-
unsigned Size = DL.getTypeAllocSize(DFSF.DFS.PrimitiveShadowTy);
1844+
unsigned Size =
1845+
DL.getTypeAllocSize(DFSF.DFS.getShadowTy(FT->getParamType(I)));
18181846
// Stop storing if arguments' size overflows. Inside a function, arguments
18191847
// after overflow have zero shadow values.
18201848
if (ArgOffset + Size > kArgTLSSize)
18211849
break;
1822-
IRB.CreateAlignedStore(DFSF.getShadow(CB.getArgOperand(I)),
1823-
DFSF.getArgTLS(ArgOffset, IRB),
1824-
kShadowTLSAlignment);
1850+
IRB.CreateAlignedStore(
1851+
DFSF.getShadow(CB.getArgOperand(I)),
1852+
DFSF.getArgTLS(FT->getParamType(I), ArgOffset, IRB),
1853+
kShadowTLSAlignment);
18251854
ArgOffset += alignTo(Size, kShadowTLSAlignment);
18261855
}
18271856
}
@@ -1844,13 +1873,13 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
18441873
if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) {
18451874
IRBuilder<> NextIRB(Next);
18461875
const DataLayout &DL = getDataLayout();
1847-
unsigned Size = DL.getTypeAllocSize(DFSF.DFS.PrimitiveShadowTy);
1876+
unsigned Size = DL.getTypeAllocSize(DFSF.DFS.getShadowTy(&CB));
18481877
if (Size > kRetvalTLSSize) {
18491878
// Set overflowed return shadow to be zero.
1850-
DFSF.setShadow(&CB, DFSF.DFS.ZeroPrimitiveShadow);
1879+
DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
18511880
} else {
18521881
LoadInst *LI = NextIRB.CreateAlignedLoad(
1853-
DFSF.DFS.PrimitiveShadowTy, DFSF.getRetvalTLS(NextIRB),
1882+
DFSF.DFS.getShadowTy(&CB), DFSF.getRetvalTLS(CB.getType(), NextIRB),
18541883
kShadowTLSAlignment, "_dfsret");
18551884
DFSF.SkipInsts.insert(LI);
18561885
DFSF.setShadow(&CB, LI);
@@ -1919,11 +1948,12 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
19191948
}
19201949

19211950
void DFSanVisitor::visitPHINode(PHINode &PN) {
1922-
PHINode *ShadowPN = PHINode::Create(DFSF.DFS.PrimitiveShadowTy,
1923-
PN.getNumIncomingValues(), "", &PN);
1951+
Type *ShadowTy = DFSF.DFS.getShadowTy(&PN);
1952+
PHINode *ShadowPN =
1953+
PHINode::Create(ShadowTy, PN.getNumIncomingValues(), "", &PN);
19241954

19251955
// Give the shadow phi node valid predecessors to fool SplitEdge into working.
1926-
Value *UndefShadow = UndefValue::get(DFSF.DFS.PrimitiveShadowTy);
1956+
Value *UndefShadow = UndefValue::get(ShadowTy);
19271957
for (PHINode::block_iterator i = PN.block_begin(), e = PN.block_end(); i != e;
19281958
++i) {
19291959
ShadowPN->addIncoming(UndefShadow, *i);

0 commit comments

Comments
 (0)