diff --git a/compiler-rt/lib/asan/CMakeLists.txt b/compiler-rt/lib/asan/CMakeLists.txt index da82e485b581..78872cd9f6be 100644 --- a/compiler-rt/lib/asan/CMakeLists.txt +++ b/compiler-rt/lib/asan/CMakeLists.txt @@ -21,7 +21,6 @@ set(ASAN_SOURCES asan_memory_profile.cc asan_poisoning.cc asan_posix.cc - asan_premap_shadow.cc asan_report.cc asan_rtl.cc asan_shadow_setup.cc diff --git a/compiler-rt/lib/asan/asan_init_version.h b/compiler-rt/lib/asan/asan_init_version.h index c49fcd740248..f48cc19cc515 100644 --- a/compiler-rt/lib/asan/asan_init_version.h +++ b/compiler-rt/lib/asan/asan_init_version.h @@ -15,8 +15,6 @@ #ifndef ASAN_INIT_VERSION_H #define ASAN_INIT_VERSION_H -#include "sanitizer_common/sanitizer_platform.h" - extern "C" { // Every time the ASan ABI changes we also change the version number in the // __asan_init function name. Objects built with incompatible ASan ABI @@ -34,12 +32,7 @@ extern "C" { // v6=>v7: added 'odr_indicator' to __asan_global // v7=>v8: added '__asan_(un)register_image_globals' functions for dead // stripping support on Mach-O platforms -#if SANITIZER_WORDSIZE == 32 && SANITIZER_ANDROID - // v8=>v9: 32-bit Android switched to dynamic shadow - #define __asan_version_mismatch_check __asan_version_mismatch_check_v9 -#else #define __asan_version_mismatch_check __asan_version_mismatch_check_v8 -#endif } #endif // ASAN_INIT_VERSION_H diff --git a/compiler-rt/lib/asan/asan_linux.cc b/compiler-rt/lib/asan/asan_linux.cc index 8ce4b96c26ed..a949a9888e20 100644 --- a/compiler-rt/lib/asan/asan_linux.cc +++ b/compiler-rt/lib/asan/asan_linux.cc @@ -17,7 +17,6 @@ #include "asan_interceptors.h" #include "asan_internal.h" -#include "asan_premap_shadow.h" #include "asan_thread.h" #include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_freebsd.h" @@ -82,41 +81,9 @@ void *AsanDoesNotSupportStaticLinkage() { return &_DYNAMIC; // defined in link.h } -#if ASAN_PREMAP_SHADOW -uptr FindPremappedShadowStart() { - uptr granularity = GetMmapGranularity(); - uptr shadow_start = reinterpret_cast(&__asan_shadow); - uptr shadow_size = PremapShadowSize(); - UnmapOrDie((void *)(shadow_start - granularity), shadow_size + granularity); - // MmapNoAccess does not touch TotalMmap, but UnmapOrDie decreases it. - // Compensate. - IncreaseTotalMmap(shadow_size + granularity); - return shadow_start; -} -#endif - uptr FindDynamicShadowStart() { -#if ASAN_PREMAP_SHADOW - if (!PremapShadowFailed()) - return FindPremappedShadowStart(); -#endif - - uptr granularity = GetMmapGranularity(); - uptr alignment = granularity * 8; - uptr left_padding = granularity; - uptr shadow_size = kHighShadowEnd + left_padding; - uptr map_size = shadow_size + alignment; - - uptr map_start = (uptr)MmapNoAccess(map_size); - CHECK_NE(map_start, ~(uptr)0); - - uptr shadow_start = RoundUpTo(map_start, alignment); - UnmapOrDie((void *)map_start, map_size); - // MmapNoAccess does not touch TotalMmap, but UnmapOrDie decreases it. - // Compensate. - IncreaseTotalMmap(map_size); - - return shadow_start; + UNREACHABLE("FindDynamicShadowStart is not available"); + return 0; } void AsanApplyToGlobals(globals_op_fptr op, const void *needle) { diff --git a/compiler-rt/lib/asan/asan_mapping.h b/compiler-rt/lib/asan/asan_mapping.h index c51c960c5ab3..acdaa60b9c59 100644 --- a/compiler-rt/lib/asan/asan_mapping.h +++ b/compiler-rt/lib/asan/asan_mapping.h @@ -161,7 +161,7 @@ static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000 # define SHADOW_OFFSET (0) #elif SANITIZER_WORDSIZE == 32 # if SANITIZER_ANDROID -# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address +# define SHADOW_OFFSET (0) # elif defined(__mips__) # define SHADOW_OFFSET kMIPS32_ShadowOffset32 # elif SANITIZER_FREEBSD @@ -205,12 +205,6 @@ static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000 # endif #endif -#if SANITIZER_ANDROID && defined(__arm__) -# define ASAN_PREMAP_SHADOW 1 -#else -# define ASAN_PREMAP_SHADOW 0 -#endif - #define SHADOW_GRANULARITY (1ULL << SHADOW_SCALE) #define MEM_TO_SHADOW(mem) (((mem) >> SHADOW_SCALE) + (SHADOW_OFFSET)) diff --git a/compiler-rt/lib/asan/asan_premap_shadow.cc b/compiler-rt/lib/asan/asan_premap_shadow.cc deleted file mode 100644 index 2d20c3b8ca01..000000000000 --- a/compiler-rt/lib/asan/asan_premap_shadow.cc +++ /dev/null @@ -1,78 +0,0 @@ -//===-- asan_premap_shadow.cc ---------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file is a part of AddressSanitizer, an address sanity checker. -// -// Reserve shadow memory with an ifunc resolver. -//===----------------------------------------------------------------------===// - -#include "asan_mapping.h" - -#if ASAN_PREMAP_SHADOW - -#include "asan_premap_shadow.h" -#include "sanitizer_common/sanitizer_posix.h" - -namespace __asan { - -// The code in this file needs to run in an unrelocated binary. It may not -// access any external symbol, including its own non-hidden globals. - -// Conservative upper limit. -uptr PremapShadowSize() { - return GetMaxVirtualAddress() >> SHADOW_SCALE; -} - -// Returns an address aligned to 8 pages, such that one page on the left and -// PremapShadowSize() bytes on the right of it are mapped r/o. -uptr PremapShadow() { - uptr granularity = GetMmapGranularity(); - uptr alignment = granularity * 8; - uptr left_padding = granularity; - uptr shadow_size = PremapShadowSize(); - uptr map_size = shadow_size + left_padding + alignment; - - uptr map_start = (uptr)MmapNoAccess(map_size); - CHECK_NE(map_start, ~(uptr)0); - - uptr shadow_start = RoundUpTo(map_start + left_padding, alignment); - uptr shadow_end = shadow_start + shadow_size; - internal_munmap(reinterpret_cast(map_start), - shadow_start - left_padding - map_start); - internal_munmap(reinterpret_cast(shadow_end), - map_start + map_size - shadow_end); - return shadow_start; -} - -bool PremapShadowFailed() { - uptr shadow = reinterpret_cast(&__asan_shadow); - uptr resolver = reinterpret_cast(&__asan_premap_shadow); - // shadow == resolver is how Android KitKat and older handles ifunc. - // shadow == 0 just in case. - if (shadow == 0 || shadow == resolver) - return true; - return false; -} -} // namespace __asan - -extern "C" { -decltype(__asan_shadow)* __asan_premap_shadow() { - // The resolver may be called multiple times. Map the shadow just once. - static uptr premapped_shadow = 0; - if (!premapped_shadow) premapped_shadow = __asan::PremapShadow(); - return reinterpret_cast(premapped_shadow); -} - -// __asan_shadow is a "function" that has the same address as the first byte of -// the shadow mapping. -INTERFACE_ATTRIBUTE __attribute__((ifunc("__asan_premap_shadow"))) void -__asan_shadow(); -} - -#endif // ASAN_PREMAP_SHADOW diff --git a/compiler-rt/lib/asan/asan_premap_shadow.h b/compiler-rt/lib/asan/asan_premap_shadow.h deleted file mode 100644 index 41acbdbbb69f..000000000000 --- a/compiler-rt/lib/asan/asan_premap_shadow.h +++ /dev/null @@ -1,30 +0,0 @@ -//===-- asan_mapping.h ------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file is a part of AddressSanitizer, an address sanity checker. -// -// Premap shadow range with an ifunc resolver. -//===----------------------------------------------------------------------===// - - -#ifndef ASAN_PREMAP_SHADOW_H -#define ASAN_PREMAP_SHADOW_H - -#if ASAN_PREMAP_SHADOW -namespace __asan { -// Conservative upper limit. -uptr PremapShadowSize(); -bool PremapShadowFailed(); -} -#endif - -extern "C" INTERFACE_ATTRIBUTE void __asan_shadow(); -extern "C" decltype(__asan_shadow)* __asan_premap_shadow(); - -#endif // ASAN_PREMAP_SHADOW_H diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index 746ba226cd5a..9fb615f9668e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -73,7 +73,6 @@ INLINE uptr GetPageSizeCached() { return PageSizeCached; } uptr GetMmapGranularity(); -uptr GetMaxVirtualAddress(); uptr GetMaxUserVirtualAddress(); // Threads tid_t GetTid(); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cc b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cc index c130c10c2dcf..554bc458cbeb 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cc @@ -191,10 +191,6 @@ uptr GetMaxUserVirtualAddress() { return ShadowBounds.memory_limit - 1; } -uptr GetMaxVirtualAddress() { - return GetMaxUserVirtualAddress(); -} - static void *DoAnonymousMmapOrDie(uptr size, const char *mem_type, bool raw_report, bool die_for_nomem) { size = RoundUpTo(size, PAGE_SIZE); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc index 6274b248edb2..ea1e79556ab7 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc @@ -954,7 +954,7 @@ static uptr GetKernelAreaSize() { } #endif // SANITIZER_WORDSIZE == 32 -uptr GetMaxVirtualAddress() { +uptr GetMaxUserVirtualAddress() { #if SANITIZER_NETBSD && defined(__x86_64__) return 0x7f7ffffff000ULL; // (0x00007f8000000000 - PAGE_SIZE) #elif SANITIZER_WORDSIZE == 64 @@ -978,21 +978,15 @@ uptr GetMaxVirtualAddress() { # if defined(__s390__) return (1ULL << 31) - 1; // 0x7fffffff; # else - return (1ULL << 32) - 1; // 0xffffffff; + uptr res = (1ULL << 32) - 1; // 0xffffffff; + if (!common_flags()->full_address_space) + res -= GetKernelAreaSize(); + CHECK_LT(reinterpret_cast(&res), res); + return res; # endif #endif // SANITIZER_WORDSIZE } -uptr GetMaxUserVirtualAddress() { - uptr addr = GetMaxVirtualAddress(); -#if SANITIZER_WORDSIZE == 32 && !defined(__s390__) - if (!common_flags()->full_address_space) - addr -= GetKernelAreaSize(); - CHECK_LT(reinterpret_cast(&addr), addr); -#endif - return addr; -} - uptr GetPageSize() { // Android post-M sysconf(_SC_PAGESIZE) crashes if called from .preinit_array. #if SANITIZER_ANDROID diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc index 195a52c47719..284b6cfc75fe 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc @@ -864,10 +864,6 @@ uptr GetMaxUserVirtualAddress() { #endif // SANITIZER_WORDSIZE } -uptr GetMaxVirtualAddress() { - return GetMaxUserVirtualAddress(); -} - uptr FindAvailableMemoryRange(uptr shadow_size, uptr alignment, uptr left_padding, diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cc b/compiler-rt/lib/sanitizer_common/sanitizer_win.cc index 0d72b494d25d..ef69ad45e9fb 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cc @@ -70,10 +70,6 @@ uptr GetMaxUserVirtualAddress() { return (uptr)si.lpMaximumApplicationAddress; } -uptr GetMaxVirtualAddress() { - return GetMaxUserVirtualAddress(); -} - bool FileExists(const char *filename) { return ::GetFileAttributesA(filename) != INVALID_FILE_ATTRIBUTES; } diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index c707dfc0b50a..26bea031463e 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -137,8 +137,8 @@ static const char *const kAsanUnregisterElfGlobalsName = static const char *const kAsanPoisonGlobalsName = "__asan_before_dynamic_init"; static const char *const kAsanUnpoisonGlobalsName = "__asan_after_dynamic_init"; static const char *const kAsanInitName = "__asan_init"; -static const char *const kAsanVersionCheckNamePrefix = - "__asan_version_mismatch_check_v"; +static const char *const kAsanVersionCheckName = + "__asan_version_mismatch_check_v8"; static const char *const kAsanPtrCmp = "__sanitizer_ptr_cmp"; static const char *const kAsanPtrSub = "__sanitizer_ptr_sub"; static const char *const kAsanHandleNoReturnName = "__asan_handle_no_return"; @@ -208,18 +208,6 @@ static cl::opt ClForceDynamicShadow( cl::desc("Load shadow address into a local variable for each function"), cl::Hidden, cl::init(false)); -static cl::opt - ClWithIfunc("asan-with-ifunc", - cl::desc("Access dynamic shadow through an ifunc global on " - "platforms that support this"), - cl::Hidden, cl::init(true)); - -static cl::opt ClWithIfuncSuppressRemat( - "asan-with-ifunc-suppress-remat", - cl::desc("Suppress rematerialization of dynamic shadow address by passing " - "it through inline asm in prologue."), - cl::Hidden, cl::init(true)); - // This flag limits the number of instructions to be instrumented // in any given BB. Normally, this should be set to unlimited (INT_MAX), // but due to http://llvm.org/bugs/show_bug.cgi?id=12652 we temporary @@ -460,14 +448,10 @@ private: /// This struct defines the shadow mapping using the rule: /// shadow = (mem >> Scale) ADD-or-OR Offset. -/// If InGlobal is true, then -/// extern char __asan_shadow[]; -/// shadow = (mem >> Scale) + &__asan_shadow struct ShadowMapping { int Scale; uint64_t Offset; bool OrShadowOffset; - bool InGlobal; }; } // end anonymous namespace @@ -489,7 +473,6 @@ static ShadowMapping getShadowMapping(Triple &TargetTriple, int LongSize, TargetTriple.getArch() == Triple::mipsel; bool IsMIPS64 = TargetTriple.getArch() == Triple::mips64 || TargetTriple.getArch() == Triple::mips64el; - bool IsArmOrThumb = TargetTriple.isARM() || TargetTriple.isThumb(); bool IsAArch64 = TargetTriple.getArch() == Triple::aarch64; bool IsWindows = TargetTriple.isOSWindows(); bool IsFuchsia = TargetTriple.isOSFuchsia(); @@ -502,8 +485,10 @@ static ShadowMapping getShadowMapping(Triple &TargetTriple, int LongSize, } if (LongSize == 32) { + // Android is always PIE, which means that the beginning of the address + // space is always available. if (IsAndroid) - Mapping.Offset = kDynamicShadowSentinel; + Mapping.Offset = 0; else if (IsMIPS32) Mapping.Offset = kMIPS32_ShadowOffset32; else if (IsFreeBSD) @@ -567,9 +552,6 @@ static ShadowMapping getShadowMapping(Triple &TargetTriple, int LongSize, Mapping.OrShadowOffset = !IsAArch64 && !IsPPC64 && !IsSystemZ && !IsPS4CPU && !(Mapping.Offset & (Mapping.Offset - 1)) && Mapping.Offset != kDynamicShadowSentinel; - bool IsAndroidWithIfuncSupport = - IsAndroid && !TargetTriple.isAndroidVersionLT(21); - Mapping.InGlobal = ClWithIfunc && IsAndroidWithIfuncSupport && IsArmOrThumb; return Mapping; } @@ -692,7 +674,6 @@ private: DominatorTree *DT; Function *AsanHandleNoReturnFunc; Function *AsanPtrCmpFunction, *AsanPtrSubFunction; - Constant *AsanShadowGlobal; // These arrays is indexed by AccessIsWrite, Experiment and log2(AccessSize). Function *AsanErrorCallback[2][2][kNumberOfAccessSizes]; @@ -765,7 +746,6 @@ private: size_t MinRedzoneSizeForGlobal() const { return RedzoneSizeForScale(Mapping.Scale); } - int GetAsanVersion(const Module &M) const; GlobalsMetadata GlobalsMD; bool CompileKernel; @@ -998,9 +978,8 @@ struct FunctionStackPoisoner : public InstVisitor { void visitCallSite(CallSite CS) { Instruction *I = CS.getInstruction(); if (CallInst *CI = dyn_cast(I)) { - HasNonEmptyInlineAsm |= CI->isInlineAsm() && - !CI->isIdenticalTo(EmptyInlineAsm.get()) && - I != ASan.LocalDynamicShadow; + HasNonEmptyInlineAsm |= + CI->isInlineAsm() && !CI->isIdenticalTo(EmptyInlineAsm.get()); HasReturnsTwiceCall |= CI->canReturnTwice(); } } @@ -2181,16 +2160,6 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M, bool return true; } -int AddressSanitizerModule::GetAsanVersion(const Module &M) const { - int LongSize = M.getDataLayout().getPointerSizeInBits(); - bool isAndroid = Triple(M.getTargetTriple()).isAndroid(); - int Version = 8; - // 32-bit Android is one version ahead because of the switch to dynamic - // shadow. - Version += (LongSize == 32 && isAndroid); - return Version; -} - bool AddressSanitizerModule::runOnModule(Module &M) { C = &(M.getContext()); int LongSize = M.getDataLayout().getPointerSizeInBits(); @@ -2204,11 +2173,9 @@ bool AddressSanitizerModule::runOnModule(Module &M) { // Create a module constructor. A destructor is created lazily because not all // platforms, and not all modules need it. - std::string VersionCheckName = - kAsanVersionCheckNamePrefix + std::to_string(GetAsanVersion(M)); std::tie(AsanCtorFunction, std::ignore) = createSanitizerCtorAndInitFunctions( M, kAsanModuleCtorName, kAsanInitName, /*InitArgTypes=*/{}, - /*InitArgs=*/{}, VersionCheckName); + /*InitArgs=*/{}, kAsanVersionCheckName); bool CtorComdat = true; bool Changed = false; @@ -2307,9 +2274,6 @@ void AddressSanitizer::initializeCallbacks(Module &M) { EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), StringRef(""), StringRef(""), /*hasSideEffects=*/true); - if (Mapping.InGlobal) - AsanShadowGlobal = M.getOrInsertGlobal("__asan_shadow", - ArrayType::get(IRB.getInt8Ty(), 0)); } // virtual @@ -2355,25 +2319,9 @@ void AddressSanitizer::maybeInsertDynamicShadowAtFunctionEntry(Function &F) { return; IRBuilder<> IRB(&F.front().front()); - if (Mapping.InGlobal) { - if (ClWithIfuncSuppressRemat) { - // An empty inline asm with input reg == output reg. - // An opaque pointer-to-int cast, basically. - InlineAsm *Asm = InlineAsm::get( - FunctionType::get(IntptrTy, {AsanShadowGlobal->getType()}, false), - StringRef(""), StringRef("=r,0"), - /*hasSideEffects=*/false); - LocalDynamicShadow = - IRB.CreateCall(Asm, {AsanShadowGlobal}, ".asan.shadow"); - } else { - LocalDynamicShadow = - IRB.CreatePointerCast(AsanShadowGlobal, IntptrTy, ".asan.shadow"); - } - } else { - Value *GlobalDynamicAddress = F.getParent()->getOrInsertGlobal( - kAsanShadowMemoryDynamicAddress, IntptrTy); - LocalDynamicShadow = IRB.CreateLoad(GlobalDynamicAddress); - } + Value *GlobalDynamicAddress = F.getParent()->getOrInsertGlobal( + kAsanShadowMemoryDynamicAddress, IntptrTy); + LocalDynamicShadow = IRB.CreateLoad(GlobalDynamicAddress); } void AddressSanitizer::markEscapedLocalAllocas(Function &F) { diff --git a/llvm/test/Instrumentation/AddressSanitizer/with-ifunc.ll b/llvm/test/Instrumentation/AddressSanitizer/with-ifunc.ll deleted file mode 100644 index 4771a9674017..000000000000 --- a/llvm/test/Instrumentation/AddressSanitizer/with-ifunc.ll +++ /dev/null @@ -1,47 +0,0 @@ -; Test -asan-with-ifunc flag. -; -; RUN: opt -asan -asan-module -S -asan-with-ifunc=0 < %s | \ -; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-NOIFUNC -; RUN: opt -asan -asan-module -S -asan-with-ifunc=1 -asan-with-ifunc-suppress-remat=0 < %s | \ -; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-IFUNC -; RUN: opt -asan -asan-module -S -asan-with-ifunc=1 -asan-with-ifunc-suppress-remat=1 < %s | \ -; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-IFUNC-NOREMAT - -; Pre-Lollipop Android does not support ifunc. -; RUN: opt -asan -asan-module -S -asan-with-ifunc=1 -asan-with-ifunc-suppress-remat=0 -mtriple=armv7-linux-android20 < %s | \ -; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-NOIFUNC -; RUN: opt -asan -asan-module -S -asan-with-ifunc=1 -asan-with-ifunc-suppress-remat=0 -mtriple=armv7-linux-android < %s | \ -; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-NOIFUNC -; RUN: opt -asan -asan-module -S -asan-with-ifunc=1 -asan-with-ifunc-suppress-remat=0 -mtriple=armv7-linux-android21 < %s | \ -; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-IFUNC - -target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" -target triple = "armv7--linux-android22" - -; CHECK-IFUNC: @__asan_shadow = external global [0 x i8] -; CHECK-NOIFUNC: @__asan_shadow_memory_dynamic_address = external global i32 - -define i32 @test_load(i32* %a) sanitize_address { -; First instrumentation in the function must be to load the dynamic shadow -; address into a local variable. -; CHECK-LABEL: @test_load -; CHECK: entry: - -; CHECK-IFUNC-NEXT: %[[A:[^ ]*]] = ptrtoint i32* %a to i32 -; CHECK-IFUNC-NEXT: %[[B:[^ ]*]] = lshr i32 %[[A]], 3 -; CHECK-IFUNC-NEXT: %[[C:[^ ]*]] = add i32 %[[B]], ptrtoint ([0 x i8]* @__asan_shadow to i32) - -; CHECK-IFUNC-NOREMAT-NEXT: %[[S:[^ ]*]] = call i32 asm "", "=r,0"([0 x i8]* @__asan_shadow) -; CHECK-IFUNC-NOREMAT-NEXT: %[[A:[^ ]*]] = ptrtoint i32* %a to i32 -; CHECK-IFUNC-NOREMAT-NEXT: %[[B:[^ ]*]] = lshr i32 %[[A]], 3 -; CHECK-IFUNC-NOREMAT-NEXT: %[[C:[^ ]*]] = add i32 %[[B]], %[[S]] - -; CHECK-NOIFUNC-NEXT: %[[SHADOW:[^ ]*]] = load i32, i32* @__asan_shadow_memory_dynamic_address -; CHECK-NOIFUNC-NEXT: %[[A:[^ ]*]] = ptrtoint i32* %a to i32 -; CHECK-NOIFUNC-NEXT: %[[B:[^ ]*]] = lshr i32 %[[A]], 3 -; CHECK-NOIFUNC-NEXT: %[[C:[^ ]*]] = add i32 %[[B]], %[[SHADOW]] - -entry: - %x = load i32, i32* %a, align 4 - ret i32 %x -}