From 740a00491b012ebf5fbb5c63eac5d070e3e55c00 Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Mon, 24 Feb 2014 13:40:24 +0000 Subject: [PATCH] [asan] simplify the code that compute the shadow offset; get rid of two internal flags that allowed to override it. The tests pass, but still this change might break asan on some platform not covered by tests. If you see this, please submit a fix with a test. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202033 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Instrumentation/AddressSanitizer.cpp | 72 +++++++------------ 1 file changed, 26 insertions(+), 46 deletions(-) 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;