diff --git a/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/lib/Transforms/Instrumentation/AddressSanitizer.cpp index a980fb1dc3f..1e2f4b7e5cb 100644 --- a/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -57,7 +57,7 @@ using namespace llvm; static const uint64_t kDefaultShadowScale = 3; static const uint64_t kDefaultShadowOffset32 = 1ULL << 29; static const uint64_t kDefaultShadowOffset64 = 1ULL << 44; -static const uint64_t kDefaultShort64bitShadowOffset = 0x7FFF8000; // < 2G. +static const uint64_t kSmallX86_64ShadowOffset = 0x7FFF8000; // < 2G. static const uint64_t kPPC64_ShadowOffset64 = 1ULL << 41; static const uint64_t kMIPS32_ShadowOffset32 = 0x0aaa8000; static const uint64_t kFreeBSD_ShadowOffset32 = 1ULL << 30; @@ -82,8 +82,6 @@ static const char *const kAsanUnpoisonGlobalsName = "__asan_after_dynamic_init"; static const char *const kAsanInitName = "__asan_init_v3"; static const char *const kAsanCovName = "__sanitizer_cov"; static const char *const kAsanHandleNoReturnName = "__asan_handle_no_return"; -static const char *const kAsanMappingOffsetName = "__asan_mapping_offset"; -static const char *const kAsanMappingScaleName = "__asan_mapping_scale"; static const int kMaxAsanStackMallocSizeClass = 10; static const char *const kAsanStackMallocNameTemplate = "__asan_stack_malloc_"; static const char *const kAsanStackFreeNameTemplate = "__asan_stack_free_"; @@ -165,11 +163,6 @@ static cl::opt ClKeepUninstrumented("asan-keep-uninstrumented-functions", // Shadow = (Mem >> scale) + (1 << offset_log) static cl::opt ClMappingScale("asan-mapping-scale", cl::desc("scale of asan shadow mapping"), cl::Hidden, cl::init(0)); -static cl::opt ClMappingOffsetLog("asan-mapping-offset-log", - cl::desc("offset of asan shadow mapping"), cl::Hidden, cl::init(-1)); -static cl::opt ClShort64BitOffset("asan-short-64bit-mapping-offset", - cl::desc("Use short immediate constant as the mapping offset for 64bit"), - cl::Hidden, cl::init(true)); // Optimization flags. Not user visible, used mostly for testing // and benchmarking the tool. @@ -241,8 +234,9 @@ struct ShadowMapping { static ShadowMapping getShadowMapping(const Module &M, int LongSize) { llvm::Triple TargetTriple(M.getTargetTriple()); bool IsAndroid = TargetTriple.getEnvironment() == llvm::Triple::Android; - bool IsMacOSX = TargetTriple.getOS() == llvm::Triple::MacOSX; + // bool IsMacOSX = TargetTriple.getOS() == llvm::Triple::MacOSX; bool IsFreeBSD = TargetTriple.getOS() == llvm::Triple::FreeBSD; + bool IsLinux = TargetTriple.getOS() == llvm::Triple::Linux; bool IsPPC64 = TargetTriple.getArch() == llvm::Triple::ppc64 || TargetTriple.getArch() == llvm::Triple::ppc64le; bool IsX86_64 = TargetTriple.getArch() == llvm::Triple::x86_64; @@ -251,24 +245,24 @@ static ShadowMapping getShadowMapping(const Module &M, int LongSize) { ShadowMapping Mapping; - // OR-ing shadow offset if more efficient (at least on x86), - // but on ppc64 we have to use add since the shadow offset is not necessary - // 1/8-th of the address space. - Mapping.OrShadowOffset = !IsPPC64 && !ClShort64BitOffset; - - Mapping.Offset = IsAndroid ? 0 : - (LongSize == 32 ? - (IsMIPS32 ? kMIPS32_ShadowOffset32 : - (IsFreeBSD ? kFreeBSD_ShadowOffset32 : kDefaultShadowOffset32)) : - IsPPC64 ? kPPC64_ShadowOffset64 : kDefaultShadowOffset64); - if (!IsAndroid && ClShort64BitOffset && IsX86_64 && !IsMacOSX) { - assert(LongSize == 64); - Mapping.Offset = (IsFreeBSD ? - kFreeBSD_ShadowOffset64 : kDefaultShort64bitShadowOffset); - } - if (!IsAndroid && ClMappingOffsetLog >= 0) { - // Zero offset log is the special case. - Mapping.Offset = (ClMappingOffsetLog == 0) ? 0 : 1ULL << ClMappingOffsetLog; + if (LongSize == 32) { + if (IsAndroid) + Mapping.Offset = 0; + else if (IsMIPS32) + Mapping.Offset = kMIPS32_ShadowOffset32; + else if (IsFreeBSD) + Mapping.Offset = kFreeBSD_ShadowOffset32; + else + Mapping.Offset = kDefaultShadowOffset32; + } else { // LongSize == 64 + if (IsPPC64) + Mapping.Offset = kPPC64_ShadowOffset64; + else if (IsFreeBSD) + Mapping.Offset = kFreeBSD_ShadowOffset64; + else if (IsLinux && IsX86_64) + Mapping.Offset = kSmallX86_64ShadowOffset; + else + Mapping.Offset = kDefaultShadowOffset64; } Mapping.Scale = kDefaultShadowScale; @@ -276,6 +270,11 @@ static ShadowMapping getShadowMapping(const Module &M, int LongSize) { Mapping.Scale = ClMappingScale; } + // OR-ing shadow offset if more efficient (at least on x86) if the offset + // is a power of two, but on ppc64 we have to use add since the shadow + // offset is not necessary 1/8-th of the address space. + Mapping.OrShadowOffset = !IsPPC64 && !(Mapping.Offset & (Mapping.Offset - 1)); + return Mapping; } @@ -316,7 +315,6 @@ struct AddressSanitizer : public FunctionPass { Value *memToShadow(Value *Shadow, IRBuilder<> &IRB); bool runOnFunction(Function &F); bool maybeInsertAsanInitAtFunctionEntry(Function &F); - void emitShadowMapping(Module &M, IRBuilder<> &IRB) const; virtual bool doInitialization(Module &M); static char ID; // Pass identification, replacement for typeid @@ -1085,23 +1083,6 @@ void AddressSanitizer::initializeCallbacks(Module &M) { /*hasSideEffects=*/true); } -void AddressSanitizer::emitShadowMapping(Module &M, IRBuilder<> &IRB) const { - // Tell the values of mapping offset and scale to the run-time. - GlobalValue *asan_mapping_offset = - new GlobalVariable(M, IntptrTy, true, GlobalValue::LinkOnceODRLinkage, - ConstantInt::get(IntptrTy, Mapping.Offset), - kAsanMappingOffsetName); - // Read the global, otherwise it may be optimized away. - IRB.CreateLoad(asan_mapping_offset, true); - - GlobalValue *asan_mapping_scale = - new GlobalVariable(M, IntptrTy, true, GlobalValue::LinkOnceODRLinkage, - ConstantInt::get(IntptrTy, Mapping.Scale), - kAsanMappingScaleName); - // Read the global, otherwise it may be optimized away. - IRB.CreateLoad(asan_mapping_scale, true); -} - // virtual bool AddressSanitizer::doInitialization(Module &M) { // Initialize the private fields. No one has accessed them before. @@ -1128,7 +1109,6 @@ bool AddressSanitizer::doInitialization(Module &M) { IRB.CreateCall(AsanInitFunction); Mapping = getShadowMapping(M, LongSize); - emitShadowMapping(M, IRB); appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndCtorPriority); return true;