diff options
| -rw-r--r-- | llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp | 25 | ||||
| -rw-r--r-- | llvm/test/Instrumentation/HWAddressSanitizer/with-ifunc.ll | 30 | 
2 files changed, 49 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index d62598bb5d4..bc690ccd5cd 100644 --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -127,6 +127,11 @@ static cl::opt<unsigned long long> ClMappingOffset(      cl::desc("HWASan shadow mapping offset [EXPERIMENTAL]"), cl::Hidden,      cl::init(0)); +static cl::opt<bool> +    ClWithIfunc("hwasan-with-ifunc", +                cl::desc("Access dynamic shadow through an ifunc global on " +                         "platforms that support this"), +                cl::Hidden, cl::init(false));  namespace {  /// An instrumentation pass implementing detection of addressability bugs @@ -751,13 +756,21 @@ void HWAddressSanitizer::ShadowMapping::init(Triple &TargetTriple) {        IsAndroid && !TargetTriple.isAndroidVersionLT(21);    Scale = kDefaultShadowScale; +  const bool WithIfunc = ClWithIfunc.getNumOccurrences() > 0 +                             ? ClWithIfunc +                             : IsAndroidWithIfuncSupport; -  if (ClEnableKhwasan || ClInstrumentWithCalls || !IsAndroidWithIfuncSupport) +  if (ClMappingOffset.getNumOccurrences() > 0) { +    InGlobal = false; +    Offset = ClMappingOffset; +  } else if (ClEnableKhwasan || ClInstrumentWithCalls) { +    InGlobal = false;      Offset = 0; -  else +  } else if (WithIfunc) { +    InGlobal = true;      Offset = kDynamicShadowSentinel; -  if (ClMappingOffset.getNumOccurrences() > 0) -    Offset = ClMappingOffset; - -  InGlobal = IsAndroidWithIfuncSupport; +  } else { +    InGlobal = false; +    Offset = kDynamicShadowSentinel; +  }  } diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/with-ifunc.ll b/llvm/test/Instrumentation/HWAddressSanitizer/with-ifunc.ll new file mode 100644 index 00000000000..2f4abb49b29 --- /dev/null +++ b/llvm/test/Instrumentation/HWAddressSanitizer/with-ifunc.ll @@ -0,0 +1,30 @@ +; Test -hwasan-with-ifunc flag. +; +; RUN: opt -hwasan -S < %s | \ +; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-IFUNC +; RUN: opt -hwasan -S -hwasan-with-ifunc=0 < %s | \ +; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-NOIFUNC +; RUN: opt -hwasan -S -hwasan-with-ifunc=1 < %s | \ +; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-IFUNC + +target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" +target triple = "aarch64--linux-android22" + +; CHECK-IFUNC: @__hwasan_shadow = external global [0 x i8] +; CHECK-NOIFUNC: @__hwasan_shadow_memory_dynamic_address = external global i64 + +define i32 @test_load(i32* %a) sanitize_hwaddress { +; 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:   %[[A:[^ ]*]] = call i64 asm "", "=r,0"([0 x i8]* @__hwasan_shadow) +; CHECK-IFUNC:   add i64 %{{.*}}, %[[A]] + +; CHECK-NOIFUNC: load i64, i64* @__hwasan_shadow_memory_dynamic_address + +entry: +  %x = load i32, i32* %a, align 4 +  ret i32 %x +}  | 

