Index: lib/Transforms/Instrumentation/DataFlowSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -72,15 +72,10 @@ using namespace llvm; -// VMA size definition for architecture that support multiple sizes. -// AArch64 has 3 VMA sizes: 39, 42 and 48. -#ifndef SANITIZER_AARCH64_VMA -# define SANITIZER_AARCH64_VMA 39 -#else -# if SANITIZER_AARCH64_VMA != 39 && SANITIZER_AARCH64_VMA != 42 -# error "invalid SANITIZER_AARCH64_VMA size" -# endif -#endif +// External symbol to be used when generating the shadow address for +// architectures with multiple VMAs. Instead of using a constant integer +// the runtime will set the external mask based on the VMA range. +static const char *const kDFSanExternShadoPtrMask = "__dfsan_shadow_ptr_mask"; // The -dfsan-preserve-alignment flag controls whether this pass assumes that // alignment requirements provided by the input IR are correct. For example, @@ -134,6 +129,15 @@ "load or return with a nonzero label"), cl::Hidden); +// Controls whether the instrumentation will use constant application mask +// mask or read its value from a external variable to generate the shadow +// address. +static cl::opt ClRuntimeShadowMaskValue( + "dfsan-runtime-shadow-mask-value", + cl::desc("Use an external shadow mask value provided by the runtime " + "library."), + cl::Hidden, cl::init(false)); + namespace { StringRef GetGlobalTypeString(const GlobalValue &G) { @@ -232,6 +236,7 @@ IntegerType *ShadowTy; PointerType *ShadowPtrTy; IntegerType *IntptrTy; + IntegerType *IntTy; ConstantInt *ZeroShadow; ConstantInt *ShadowPtrMask; ConstantInt *ShadowPtrMul; @@ -439,18 +444,16 @@ ShadowTy = IntegerType::get(*Ctx, ShadowWidth); ShadowPtrTy = PointerType::getUnqual(ShadowTy); IntptrTy = DL.getIntPtrType(*Ctx); + IntTy = IntegerType::get(*Ctx, IntptrTy->getBitWidth()); ZeroShadow = ConstantInt::getSigned(ShadowTy, 0); ShadowPtrMul = ConstantInt::getSigned(IntptrTy, ShadowWidth / 8); if (IsX86_64) ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x700000000000LL); else if (IsMIPS64) ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0xF000000000LL); + // AArch64 supports multiple VMAs and the shadow mask is set at runtime. else if (IsAArch64) -#if SANITIZER_AARCH64_VMA == 39 - ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x7800000000LL); -#else - ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x3c000000000LL); -#endif + ClRuntimeShadowMaskValue = true; else report_fatal_error("unsupported triple"); @@ -938,9 +941,18 @@ Value *DataFlowSanitizer::getShadowAddress(Value *Addr, Instruction *Pos) { assert(Addr != RetvalTLS && "Reinstrumenting?"); IRBuilder<> IRB(Pos); + Value *ShadowPtrMaskValue; + if (ClRuntimeShadowMaskValue) { + Value *ExternalShadowMask = + Mod->getOrInsertGlobal(kDFSanExternShadoPtrMask, IntTy); + ShadowPtrMaskValue = IRB.CreateLoad(IntTy, ExternalShadowMask); + } else { + ShadowPtrMaskValue = ShadowPtrMask; + } return IRB.CreateIntToPtr( IRB.CreateMul( - IRB.CreateAnd(IRB.CreatePtrToInt(Addr, IntptrTy), ShadowPtrMask), + IRB.CreateAnd(IRB.CreatePtrToInt(Addr, IntptrTy), + ShadowPtrMaskValue), ShadowPtrMul), ShadowPtrTy); }