@@ -419,6 +419,17 @@ class DataFlowSanitizer {
419
419
420
420
bool init (Module &M);
421
421
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
+
422
433
public:
423
434
DataFlowSanitizer (const std::vector<std::string> &ABIListFiles);
424
435
@@ -458,10 +469,10 @@ struct DFSanFunction {
458
469
// / Computes the shadow address for a given function argument.
459
470
// /
460
471
// / Shadow = ArgTLS+ArgOffset.
461
- Value *getArgTLS (unsigned ArgOffset, IRBuilder<> &IRB);
472
+ Value *getArgTLS (Type *T, unsigned ArgOffset, IRBuilder<> &IRB);
462
473
463
474
// / Computes the shadow address for a retval.
464
- Value *getRetvalTLS (IRBuilder<> &IRB);
475
+ Value *getRetvalTLS (Type *T, IRBuilder<> &IRB);
465
476
466
477
Value *getShadow (Value *V);
467
478
void setShadow (Instruction *I, Value *Shadow);
@@ -580,6 +591,20 @@ TransformedFunction DataFlowSanitizer::getCustomFunctionType(FunctionType *T) {
580
591
ArgumentIndexMapping);
581
592
}
582
593
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
+
583
608
bool DataFlowSanitizer::init (Module &M) {
584
609
Triple TargetTriple (M.getTargetTriple ());
585
610
bool IsX86_64 = TargetTriple.getArch () == Triple::x86_64;
@@ -1075,17 +1100,17 @@ bool DataFlowSanitizer::runImpl(Module &M) {
1075
1100
M.global_size () != InitialGlobalSize || M.size () != InitialModuleSize;
1076
1101
}
1077
1102
1078
- Value *DFSanFunction::getArgTLS (unsigned ArgOffset, IRBuilder<> &IRB) {
1103
+ Value *DFSanFunction::getArgTLS (Type *T, unsigned ArgOffset, IRBuilder<> &IRB) {
1079
1104
Value *Base = IRB.CreatePointerCast (DFS.ArgTLS , DFS.IntptrTy );
1080
1105
if (ArgOffset)
1081
1106
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 ),
1083
1108
" _dfsarg" );
1084
1109
}
1085
1110
1086
- Value *DFSanFunction::getRetvalTLS (IRBuilder<> &IRB) {
1111
+ Value *DFSanFunction::getRetvalTLS (Type *T, IRBuilder<> &IRB) {
1087
1112
return IRB.CreatePointerCast (
1088
- DFS.RetvalTLS , PointerType::get (DFS.PrimitiveShadowTy , 0 ), " _dfsret" );
1113
+ DFS.RetvalTLS , PointerType::get (DFS.getShadowTy (T) , 0 ), " _dfsret" );
1089
1114
}
1090
1115
1091
1116
Value *DFSanFunction::getShadowForTLSArgument (Argument *A) {
@@ -1098,7 +1123,7 @@ Value *DFSanFunction::getShadowForTLSArgument(Argument *A) {
1098
1123
continue ;
1099
1124
}
1100
1125
1101
- unsigned Size = DL.getTypeAllocSize (DFS.PrimitiveShadowTy );
1126
+ unsigned Size = DL.getTypeAllocSize (DFS.getShadowTy (&FArg) );
1102
1127
if (A != &FArg) {
1103
1128
ArgOffset += alignTo (Size, kShadowTLSAlignment );
1104
1129
if (ArgOffset > kArgTLSSize )
@@ -1111,22 +1136,22 @@ Value *DFSanFunction::getShadowForTLSArgument(Argument *A) {
1111
1136
1112
1137
Instruction *ArgTLSPos = &*F->getEntryBlock ().begin ();
1113
1138
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,
1116
1141
kShadowTLSAlignment );
1117
1142
}
1118
1143
1119
- return DFS.ZeroPrimitiveShadow ;
1144
+ return DFS.getZeroShadow (A) ;
1120
1145
}
1121
1146
1122
1147
Value *DFSanFunction::getShadow (Value *V) {
1123
1148
if (!isa<Argument>(V) && !isa<Instruction>(V))
1124
- return DFS.ZeroPrimitiveShadow ;
1149
+ return DFS.getZeroShadow (V) ;
1125
1150
Value *&Shadow = ValShadowMap[V];
1126
1151
if (!Shadow) {
1127
1152
if (Argument *A = dyn_cast<Argument>(V)) {
1128
1153
if (IsNativeABI)
1129
- return DFS.ZeroPrimitiveShadow ;
1154
+ return DFS.getZeroShadow (V) ;
1130
1155
switch (IA) {
1131
1156
case DataFlowSanitizer::IA_TLS: {
1132
1157
Shadow = getShadowForTLSArgument (A);
@@ -1144,7 +1169,7 @@ Value *DFSanFunction::getShadow(Value *V) {
1144
1169
}
1145
1170
NonZeroChecks.push_back (Shadow);
1146
1171
} else {
1147
- Shadow = DFS.ZeroPrimitiveShadow ;
1172
+ Shadow = DFS.getZeroShadow (V) ;
1148
1173
}
1149
1174
}
1150
1175
return Shadow;
@@ -1175,9 +1200,9 @@ Value *DataFlowSanitizer::getShadowAddress(Value *Addr, Instruction *Pos) {
1175
1200
// Generates IR to compute the union of the two given shadows, inserting it
1176
1201
// before Pos. Returns the computed union Value.
1177
1202
Value *DFSanFunction::combineShadows (Value *V1, Value *V2, Instruction *Pos) {
1178
- if (V1 == DFS.ZeroPrimitiveShadow )
1203
+ if (DFS.isZeroShadow (V1) )
1179
1204
return V2;
1180
- if (V2 == DFS.ZeroPrimitiveShadow )
1205
+ if (DFS.isZeroShadow (V2) )
1181
1206
return V1;
1182
1207
if (V1 == V2)
1183
1208
return V1;
@@ -1261,7 +1286,7 @@ Value *DFSanFunction::combineShadows(Value *V1, Value *V2, Instruction *Pos) {
1261
1286
// the computed union Value.
1262
1287
Value *DFSanFunction::combineOperandShadows (Instruction *Inst) {
1263
1288
if (Inst->getNumOperands () == 0 )
1264
- return DFS.ZeroPrimitiveShadow ;
1289
+ return DFS.getZeroShadow (Inst) ;
1265
1290
1266
1291
Value *Shadow = getShadow (Inst->getOperand (0 ));
1267
1292
for (unsigned i = 1 , n = Inst->getNumOperands (); i != n; ++i) {
@@ -1426,7 +1451,7 @@ void DFSanVisitor::visitLoadInst(LoadInst &LI) {
1426
1451
auto &DL = LI.getModule ()->getDataLayout ();
1427
1452
uint64_t Size = DL.getTypeStoreSize (LI.getType ());
1428
1453
if (Size == 0 ) {
1429
- DFSF.setShadow (&LI, DFSF.DFS .ZeroPrimitiveShadow );
1454
+ DFSF.setShadow (&LI, DFSF.DFS .getZeroShadow (&LI) );
1430
1455
return ;
1431
1456
}
1432
1457
@@ -1437,7 +1462,7 @@ void DFSanVisitor::visitLoadInst(LoadInst &LI) {
1437
1462
Value *PtrShadow = DFSF.getShadow (LI.getPointerOperand ());
1438
1463
Shadow = DFSF.combineShadows (Shadow, PtrShadow, &LI);
1439
1464
}
1440
- if (Shadow != DFSF.DFS .ZeroPrimitiveShadow )
1465
+ if (! DFSF.DFS .isZeroShadow (Shadow) )
1441
1466
DFSF.NonZeroChecks .push_back (Shadow);
1442
1467
1443
1468
DFSF.setShadow (&LI, Shadow);
@@ -1462,7 +1487,7 @@ void DFSanFunction::storeShadow(Value *Addr, uint64_t Size, Align Alignment,
1462
1487
const Align ShadowAlign (Alignment.value () * DFS.ShadowWidthBytes );
1463
1488
IRBuilder<> IRB (Pos);
1464
1489
Value *ShadowAddr = DFS.getShadowAddress (Addr, Pos);
1465
- if (Shadow == DFS.ZeroPrimitiveShadow ) {
1490
+ if (DFS.isZeroShadow (Shadow) ) {
1466
1491
IntegerType *ShadowTy =
1467
1492
IntegerType::get (*DFS.Ctx , Size * DFS.ShadowWidthBits );
1468
1493
Value *ExtZeroShadow = ConstantInt::get (ShadowTy, 0 );
@@ -1648,12 +1673,14 @@ void DFSanVisitor::visitReturnInst(ReturnInst &RI) {
1648
1673
case DataFlowSanitizer::IA_TLS: {
1649
1674
Value *S = DFSF.getShadow (RI.getReturnValue ());
1650
1675
IRBuilder<> IRB (&RI);
1676
+ Type *RT = DFSF.F ->getFunctionType ()->getReturnType ();
1651
1677
unsigned Size =
1652
- getDataLayout ().getTypeAllocSize (DFSF.DFS .PrimitiveShadowTy );
1678
+ getDataLayout ().getTypeAllocSize (DFSF.DFS .getShadowTy (RT) );
1653
1679
if (Size <= kRetvalTLSSize ) {
1654
1680
// If the size overflows, stores nothing. At callsite, oversized return
1655
1681
// shadows are set to zero.
1656
- IRB.CreateAlignedStore (S, DFSF.getRetvalTLS (IRB), kShadowTLSAlignment );
1682
+ IRB.CreateAlignedStore (S, DFSF.getRetvalTLS (RT, IRB),
1683
+ kShadowTLSAlignment );
1657
1684
}
1658
1685
break ;
1659
1686
}
@@ -1694,11 +1721,11 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
1694
1721
CB.setCalledFunction (F);
1695
1722
IRB.CreateCall (DFSF.DFS .DFSanUnimplementedFn ,
1696
1723
IRB.CreateGlobalStringPtr (F->getName ()));
1697
- DFSF.setShadow (&CB, DFSF.DFS .ZeroPrimitiveShadow );
1724
+ DFSF.setShadow (&CB, DFSF.DFS .getZeroShadow (&CB) );
1698
1725
return ;
1699
1726
case DataFlowSanitizer::WK_Discard:
1700
1727
CB.setCalledFunction (F);
1701
- DFSF.setShadow (&CB, DFSF.DFS .ZeroPrimitiveShadow );
1728
+ DFSF.setShadow (&CB, DFSF.DFS .getZeroShadow (&CB) );
1702
1729
return ;
1703
1730
case DataFlowSanitizer::WK_Functional:
1704
1731
CB.setCalledFunction (F);
@@ -1787,7 +1814,7 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
1787
1814
1788
1815
// Update the parameter attributes of the custom call instruction to
1789
1816
// zero extend the shadow parameters. This is required for targets
1790
- // which consider ShadowTy an illegal type.
1817
+ // which consider PrimitiveShadowTy an illegal type.
1791
1818
for (unsigned n = 0 ; n < FT->getNumParams (); n++) {
1792
1819
const unsigned ArgNo = ShadowArgStart + n;
1793
1820
if (CustomCI->getArgOperand (ArgNo)->getType () ==
@@ -1814,14 +1841,16 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
1814
1841
unsigned ArgOffset = 0 ;
1815
1842
const DataLayout &DL = getDataLayout ();
1816
1843
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)));
1818
1846
// Stop storing if arguments' size overflows. Inside a function, arguments
1819
1847
// after overflow have zero shadow values.
1820
1848
if (ArgOffset + Size > kArgTLSSize )
1821
1849
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 );
1825
1854
ArgOffset += alignTo (Size, kShadowTLSAlignment );
1826
1855
}
1827
1856
}
@@ -1844,13 +1873,13 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
1844
1873
if (DFSF.DFS .getInstrumentedABI () == DataFlowSanitizer::IA_TLS) {
1845
1874
IRBuilder<> NextIRB (Next);
1846
1875
const DataLayout &DL = getDataLayout ();
1847
- unsigned Size = DL.getTypeAllocSize (DFSF.DFS .PrimitiveShadowTy );
1876
+ unsigned Size = DL.getTypeAllocSize (DFSF.DFS .getShadowTy (&CB) );
1848
1877
if (Size > kRetvalTLSSize ) {
1849
1878
// Set overflowed return shadow to be zero.
1850
- DFSF.setShadow (&CB, DFSF.DFS .ZeroPrimitiveShadow );
1879
+ DFSF.setShadow (&CB, DFSF.DFS .getZeroShadow (&CB) );
1851
1880
} else {
1852
1881
LoadInst *LI = NextIRB.CreateAlignedLoad (
1853
- DFSF.DFS .PrimitiveShadowTy , DFSF.getRetvalTLS (NextIRB),
1882
+ DFSF.DFS .getShadowTy (&CB) , DFSF.getRetvalTLS (CB. getType (), NextIRB),
1854
1883
kShadowTLSAlignment , " _dfsret" );
1855
1884
DFSF.SkipInsts .insert (LI);
1856
1885
DFSF.setShadow (&CB, LI);
@@ -1919,11 +1948,12 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
1919
1948
}
1920
1949
1921
1950
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);
1924
1954
1925
1955
// 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 );
1927
1957
for (PHINode::block_iterator i = PN.block_begin (), e = PN.block_end (); i != e;
1928
1958
++i) {
1929
1959
ShadowPN->addIncoming (UndefShadow, *i);
0 commit comments