|
26 | 26 | /// | |
|
27 | 27 | /// | unused |
|
28 | 28 | /// | |
|
29 |
| -/// +--------------------+ 0x200200000000 (kUnusedAddr) |
| 29 | +/// +--------------------+ 0x300200000000 (kUnusedAddr) |
30 | 30 | /// | union table |
|
31 |
| -/// +--------------------+ 0x200000000000 (kUnionTableAddr) |
| 31 | +/// +--------------------+ 0x300000000000 (kUnionTableAddr) |
| 32 | +/// | origin | |
| 33 | +/// +--------------------+ 0x200000008000 (kOriginAddr) |
32 | 34 | /// | shadow memory |
|
33 | 35 | /// +--------------------+ 0x000000010000 (kShadowAddr)
|
34 | 36 | /// | reserved by kernel |
|
@@ -109,6 +111,8 @@ using namespace llvm;
|
109 | 111 | // This must be consistent with ShadowWidthBits.
|
110 | 112 | static const Align kShadowTLSAlignment = Align(2);
|
111 | 113 |
|
| 114 | +static const Align kMinOriginAlignment = Align(4); |
| 115 | + |
112 | 116 | // The size of TLS variables. These constants must be kept in sync with the ones
|
113 | 117 | // in dfsan.cpp.
|
114 | 118 | static const unsigned kArgTLSSize = 800;
|
@@ -377,6 +381,7 @@ class DataFlowSanitizer {
|
377 | 381 | Type *Int8Ptr;
|
378 | 382 | IntegerType *OriginTy;
|
379 | 383 | PointerType *OriginPtrTy;
|
| 384 | + ConstantInt *OriginBase; |
380 | 385 | /// The shadow type for all primitive types and vector types.
|
381 | 386 | IntegerType *PrimitiveShadowTy;
|
382 | 387 | PointerType *PrimitiveShadowPtrTy;
|
@@ -426,7 +431,10 @@ class DataFlowSanitizer {
|
426 | 431 | AttrBuilder ReadOnlyNoneAttrs;
|
427 | 432 | bool DFSanRuntimeShadowMask = false;
|
428 | 433 |
|
| 434 | + Value *getShadowOffset(Value *Addr, IRBuilder<> &IRB); |
429 | 435 | Value *getShadowAddress(Value *Addr, Instruction *Pos);
|
| 436 | + std::pair<Value *, Value *> |
| 437 | + getShadowOriginAddress(Value *Addr, Align InstAlignment, Instruction *Pos); |
430 | 438 | bool isInstrumented(const Function *F);
|
431 | 439 | bool isInstrumented(const GlobalAlias *GA);
|
432 | 440 | FunctionType *getArgsFunctionType(FunctionType *T);
|
@@ -868,6 +876,7 @@ bool DataFlowSanitizer::init(Module &M) {
|
868 | 876 | IntptrTy = DL.getIntPtrType(*Ctx);
|
869 | 877 | ZeroPrimitiveShadow = ConstantInt::getSigned(PrimitiveShadowTy, 0);
|
870 | 878 | ShadowPtrMul = ConstantInt::getSigned(IntptrTy, ShadowWidthBytes);
|
| 879 | + OriginBase = ConstantInt::get(IntptrTy, 0x200000000000LL); |
871 | 880 | if (IsX86_64)
|
872 | 881 | ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x700000000000LL);
|
873 | 882 | else if (IsMIPS64)
|
@@ -1513,20 +1522,47 @@ void DFSanFunction::setShadow(Instruction *I, Value *Shadow) {
|
1513 | 1522 | ValShadowMap[I] = Shadow;
|
1514 | 1523 | }
|
1515 | 1524 |
|
1516 |
| -Value *DataFlowSanitizer::getShadowAddress(Value *Addr, Instruction *Pos) { |
| 1525 | +Value *DataFlowSanitizer::getShadowOffset(Value *Addr, IRBuilder<> &IRB) { |
| 1526 | + // Returns Addr & shadow_mask |
1517 | 1527 | assert(Addr != RetvalTLS && "Reinstrumenting?");
|
1518 |
| - IRBuilder<> IRB(Pos); |
1519 | 1528 | Value *ShadowPtrMaskValue;
|
1520 | 1529 | if (DFSanRuntimeShadowMask)
|
1521 | 1530 | ShadowPtrMaskValue = IRB.CreateLoad(IntptrTy, ExternalShadowMask);
|
1522 | 1531 | else
|
1523 | 1532 | ShadowPtrMaskValue = ShadowPtrMask;
|
1524 |
| - return IRB.CreateIntToPtr( |
1525 |
| - IRB.CreateMul( |
1526 |
| - IRB.CreateAnd(IRB.CreatePtrToInt(Addr, IntptrTy), |
1527 |
| - IRB.CreatePtrToInt(ShadowPtrMaskValue, IntptrTy)), |
1528 |
| - ShadowPtrMul), |
1529 |
| - PrimitiveShadowPtrTy); |
| 1533 | + return IRB.CreateAnd(IRB.CreatePtrToInt(Addr, IntptrTy), |
| 1534 | + IRB.CreatePtrToInt(ShadowPtrMaskValue, IntptrTy)); |
| 1535 | +} |
| 1536 | + |
| 1537 | +std::pair<Value *, Value *> |
| 1538 | +DataFlowSanitizer::getShadowOriginAddress(Value *Addr, Align InstAlignment, |
| 1539 | + Instruction *Pos) { |
| 1540 | + // Returns ((Addr & shadow_mask) + origin_base) & ~4UL |
| 1541 | + IRBuilder<> IRB(Pos); |
| 1542 | + Value *ShadowOffset = getShadowOffset(Addr, IRB); |
| 1543 | + Value *ShadowPtr = IRB.CreateIntToPtr( |
| 1544 | + IRB.CreateMul(ShadowOffset, ShadowPtrMul), PrimitiveShadowPtrTy); |
| 1545 | + Value *OriginPtr = nullptr; |
| 1546 | + if (shouldTrackOrigins()) { |
| 1547 | + Value *OriginLong = IRB.CreateAdd(ShadowOffset, OriginBase); |
| 1548 | + const Align Alignment = llvm::assumeAligned(InstAlignment.value()); |
| 1549 | + // When alignment is >= 4, Addr must be aligned to 4, otherwise it is UB. |
| 1550 | + // So Mask is unnecessary. |
| 1551 | + if (Alignment < kMinOriginAlignment) { |
| 1552 | + uint64_t Mask = kMinOriginAlignment.value() - 1; |
| 1553 | + OriginLong = IRB.CreateAnd(OriginLong, ConstantInt::get(IntptrTy, ~Mask)); |
| 1554 | + } |
| 1555 | + OriginPtr = IRB.CreateIntToPtr(OriginLong, OriginPtrTy); |
| 1556 | + } |
| 1557 | + return {ShadowPtr, OriginPtr}; |
| 1558 | +} |
| 1559 | + |
| 1560 | +Value *DataFlowSanitizer::getShadowAddress(Value *Addr, Instruction *Pos) { |
| 1561 | + // Returns (Addr & shadow_mask) x 2 |
| 1562 | + IRBuilder<> IRB(Pos); |
| 1563 | + Value *ShadowOffset = getShadowOffset(Addr, IRB); |
| 1564 | + return IRB.CreateIntToPtr(IRB.CreateMul(ShadowOffset, ShadowPtrMul), |
| 1565 | + PrimitiveShadowPtrTy); |
1530 | 1566 | }
|
1531 | 1567 |
|
1532 | 1568 | Value *DFSanFunction::combineShadowsThenConvert(Type *T, Value *V1, Value *V2,
|
|
0 commit comments