Skip to content

Commit cb1f1aa

Browse files
[dfsan] Add origin address calculation
This is a part of https://reviews.llvm.org/D95835. Reviewed-by: morehouse Differential Revision: https://reviews.llvm.org/D97065
1 parent 82c4701 commit cb1f1aa

File tree

1 file changed

+46
-10
lines changed

1 file changed

+46
-10
lines changed

llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@
2626
/// | |
2727
/// | unused |
2828
/// | |
29-
/// +--------------------+ 0x200200000000 (kUnusedAddr)
29+
/// +--------------------+ 0x300200000000 (kUnusedAddr)
3030
/// | union table |
31-
/// +--------------------+ 0x200000000000 (kUnionTableAddr)
31+
/// +--------------------+ 0x300000000000 (kUnionTableAddr)
32+
/// | origin |
33+
/// +--------------------+ 0x200000008000 (kOriginAddr)
3234
/// | shadow memory |
3335
/// +--------------------+ 0x000000010000 (kShadowAddr)
3436
/// | reserved by kernel |
@@ -109,6 +111,8 @@ using namespace llvm;
109111
// This must be consistent with ShadowWidthBits.
110112
static const Align kShadowTLSAlignment = Align(2);
111113

114+
static const Align kMinOriginAlignment = Align(4);
115+
112116
// The size of TLS variables. These constants must be kept in sync with the ones
113117
// in dfsan.cpp.
114118
static const unsigned kArgTLSSize = 800;
@@ -377,6 +381,7 @@ class DataFlowSanitizer {
377381
Type *Int8Ptr;
378382
IntegerType *OriginTy;
379383
PointerType *OriginPtrTy;
384+
ConstantInt *OriginBase;
380385
/// The shadow type for all primitive types and vector types.
381386
IntegerType *PrimitiveShadowTy;
382387
PointerType *PrimitiveShadowPtrTy;
@@ -426,7 +431,10 @@ class DataFlowSanitizer {
426431
AttrBuilder ReadOnlyNoneAttrs;
427432
bool DFSanRuntimeShadowMask = false;
428433

434+
Value *getShadowOffset(Value *Addr, IRBuilder<> &IRB);
429435
Value *getShadowAddress(Value *Addr, Instruction *Pos);
436+
std::pair<Value *, Value *>
437+
getShadowOriginAddress(Value *Addr, Align InstAlignment, Instruction *Pos);
430438
bool isInstrumented(const Function *F);
431439
bool isInstrumented(const GlobalAlias *GA);
432440
FunctionType *getArgsFunctionType(FunctionType *T);
@@ -868,6 +876,7 @@ bool DataFlowSanitizer::init(Module &M) {
868876
IntptrTy = DL.getIntPtrType(*Ctx);
869877
ZeroPrimitiveShadow = ConstantInt::getSigned(PrimitiveShadowTy, 0);
870878
ShadowPtrMul = ConstantInt::getSigned(IntptrTy, ShadowWidthBytes);
879+
OriginBase = ConstantInt::get(IntptrTy, 0x200000000000LL);
871880
if (IsX86_64)
872881
ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x700000000000LL);
873882
else if (IsMIPS64)
@@ -1513,20 +1522,47 @@ void DFSanFunction::setShadow(Instruction *I, Value *Shadow) {
15131522
ValShadowMap[I] = Shadow;
15141523
}
15151524

1516-
Value *DataFlowSanitizer::getShadowAddress(Value *Addr, Instruction *Pos) {
1525+
Value *DataFlowSanitizer::getShadowOffset(Value *Addr, IRBuilder<> &IRB) {
1526+
// Returns Addr & shadow_mask
15171527
assert(Addr != RetvalTLS && "Reinstrumenting?");
1518-
IRBuilder<> IRB(Pos);
15191528
Value *ShadowPtrMaskValue;
15201529
if (DFSanRuntimeShadowMask)
15211530
ShadowPtrMaskValue = IRB.CreateLoad(IntptrTy, ExternalShadowMask);
15221531
else
15231532
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);
15301566
}
15311567

15321568
Value *DFSanFunction::combineShadowsThenConvert(Type *T, Value *V1, Value *V2,

0 commit comments

Comments
 (0)