[llvm] 314c049 - [compiler-rt][hwasan] Decouple use of the TLS global for getting the shadow base and using the frame record feature

Leonard Chan via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 9 12:55:40 PDT 2021


Author: Leonard Chan
Date: 2021-06-09T12:55:19-07:00
New Revision: 314c049142ed22154fbe37de3a566ef38b884fab

URL: https://github.com/llvm/llvm-project/commit/314c049142ed22154fbe37de3a566ef38b884fab
DIFF: https://github.com/llvm/llvm-project/commit/314c049142ed22154fbe37de3a566ef38b884fab.diff

LOG: [compiler-rt][hwasan] Decouple use of the TLS global for getting the shadow base and using the frame record feature

This allows for using the frame record feature (which uses __hwasan_tls)
independently from however the user wants to access the shadow base, which
prior was only usable if shadow wasn't accessed through the TLS variable or ifuncs.

Frame recording can be explicitly set according to ShadowMapping::WithFrameRecord
in ShadowMapping::init. Currently, it is only enabled on Fuchsia and if TLS is
used, so this should mimic the old behavior.

Added an extra case to prologue.ll that covers this new case.

Differential Revision: https://reviews.llvm.org/D103841

Added: 
    

Modified: 
    llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
    llvm/test/Instrumentation/HWAddressSanitizer/prologue.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 3d6b12489a8d2..9b02410f09075 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -264,11 +264,15 @@ class HWAddressSanitizer {
   /// If InTls is true, then
   ///   extern char *__hwasan_tls;
   ///   shadow = (mem>>Scale) + align_up(__hwasan_shadow, kShadowBaseAlignment)
+  ///
+  /// If WithFrameRecord is true, then __hwasan_tls will be used to access the
+  /// ring buffer for storing stack allocations on targets that support it.
   struct ShadowMapping {
     int Scale;
     uint64_t Offset;
     bool InGlobal;
     bool InTls;
+    bool WithFrameRecord;
 
     void init(Triple &TargetTriple, bool InstrumentWithCalls);
     unsigned getObjectAlignment() const { return 1U << Scale; }
@@ -1042,15 +1046,13 @@ Value *HWAddressSanitizer::getHwasanThreadSlotPtr(IRBuilder<> &IRB, Type *Ty) {
 }
 
 void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) {
-  if (!Mapping.InTls) {
+  if (!Mapping.InTls)
     ShadowBase = getShadowNonTls(IRB);
-    return;
-  }
-
-  if (!WithFrameRecord && TargetTriple.isAndroid()) {
+  else if (!WithFrameRecord && TargetTriple.isAndroid())
     ShadowBase = getDynamicShadowIfunc(IRB);
+
+  if (!WithFrameRecord && ShadowBase)
     return;
-  }
 
   Value *SlotPtr = getHwasanThreadSlotPtr(IRB, IntptrTy);
   assert(SlotPtr);
@@ -1106,15 +1108,17 @@ void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) {
     IRB.CreateStore(ThreadLongNew, SlotPtr);
   }
 
-  // Get shadow base address by aligning RecordPtr up.
-  // Note: this is not correct if the pointer is already aligned.
-  // Runtime library will make sure this never happens.
-  ShadowBase = IRB.CreateAdd(
-      IRB.CreateOr(
-          ThreadLongMaybeUntagged,
-          ConstantInt::get(IntptrTy, (1ULL << kShadowBaseAlignment) - 1)),
-      ConstantInt::get(IntptrTy, 1), "hwasan.shadow");
-  ShadowBase = IRB.CreateIntToPtr(ShadowBase, Int8PtrTy);
+  if (!ShadowBase) {
+    // Get shadow base address by aligning RecordPtr up.
+    // Note: this is not correct if the pointer is already aligned.
+    // Runtime library will make sure this never happens.
+    ShadowBase = IRB.CreateAdd(
+        IRB.CreateOr(
+            ThreadLongMaybeUntagged,
+            ConstantInt::get(IntptrTy, (1ULL << kShadowBaseAlignment) - 1)),
+        ConstantInt::get(IntptrTy, 1), "hwasan.shadow");
+    ShadowBase = IRB.CreateIntToPtr(ShadowBase, Int8PtrTy);
+  }
 }
 
 Value *HWAddressSanitizer::readRegister(IRBuilder<> &IRB, StringRef Name) {
@@ -1273,7 +1277,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) {
   IRBuilder<> EntryIRB(InsertPt);
   emitPrologue(EntryIRB,
                /*WithFrameRecord*/ ClRecordStackHistory &&
-                   !AllocasToInstrument.empty());
+                   Mapping.WithFrameRecord && !AllocasToInstrument.empty());
 
   if (!AllocasToInstrument.empty()) {
     Value *StackTag =
@@ -1540,25 +1544,31 @@ void HWAddressSanitizer::ShadowMapping::init(Triple &TargetTriple,
     InGlobal = false;
     InTls = false;
     Offset = 0;
+    WithFrameRecord = true;
   } else if (ClMappingOffset.getNumOccurrences() > 0) {
     InGlobal = false;
     InTls = false;
     Offset = ClMappingOffset;
+    WithFrameRecord = false;
   } else if (ClEnableKhwasan || InstrumentWithCalls) {
     InGlobal = false;
     InTls = false;
     Offset = 0;
+    WithFrameRecord = false;
   } else if (ClWithIfunc) {
     InGlobal = true;
     InTls = false;
     Offset = kDynamicShadowSentinel;
+    WithFrameRecord = false;
   } else if (ClWithTls) {
     InGlobal = false;
     InTls = true;
     Offset = kDynamicShadowSentinel;
+    WithFrameRecord = true;
   } else {
     InGlobal = false;
     InTls = false;
     Offset = kDynamicShadowSentinel;
+    WithFrameRecord = false;
   }
 }

diff  --git a/llvm/test/Instrumentation/HWAddressSanitizer/prologue.ll b/llvm/test/Instrumentation/HWAddressSanitizer/prologue.ll
index d74940fe68a28..4a03922269039 100644
--- a/llvm/test/Instrumentation/HWAddressSanitizer/prologue.ll
+++ b/llvm/test/Instrumentation/HWAddressSanitizer/prologue.ll
@@ -1,15 +1,17 @@
 ; Test -hwasan-with-ifunc flag.
 ;
 ; RUN: opt -hwasan -S < %s | \
-; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-NOGLOBAL,CHECK-TLS,CHECK-HISTORY
+; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-NOGLOBAL,CHECK-TLS-SLOT,CHECK-HISTORY,CHECK-HISTORY-TLS-SLOT
 ; RUN: opt -hwasan -S -hwasan-with-ifunc=0 -hwasan-with-tls=1 -hwasan-record-stack-history=1 < %s | \
-; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-NOGLOBAL,CHECK-TLS,CHECK-HISTORY
+; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-NOGLOBAL,CHECK-TLS-SLOT,CHECK-HISTORY,CHECK-HISTORY-TLS-SLOT
 ; RUN: opt -hwasan -S -hwasan-with-ifunc=0 -hwasan-with-tls=1 -hwasan-record-stack-history=0 < %s | \
 ; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-NOGLOBAL,CHECK-IFUNC,CHECK-NOHISTORY
 ; RUN: opt -hwasan -S -hwasan-with-ifunc=0 -hwasan-with-tls=0 < %s | \
 ; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-GLOBAL,CHECK-NOHISTORY
 ; RUN: opt -hwasan -S -hwasan-with-ifunc=1  -hwasan-with-tls=0 < %s | \
 ; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-IFUNC,CHECK-NOHISTORY
+; RUN: opt -hwasan -S -mtriple=aarch64-fuchsia < %s | \
+; RUN:     FileCheck %s --check-prefixes=CHECK,CHECK-ZERO-OFFSET,CHECK-SHORT-GRANULES,CHECK-HISTORY,CHECK-HWASAN-TLS,CHECK-HISTORY-HWASAN-TLS
 
 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
 target triple = "aarch64--linux-android22"
@@ -25,6 +27,8 @@ define i32 @test_load(i32* %a) sanitize_hwaddress {
 
 ; CHECK-NOGLOBAL:   %[[A:[^ ]*]] = call i8* asm "", "=r,0"([0 x i8]* @__hwasan_shadow)
 ; CHECK-NOGLOBAL:   @llvm.hwasan.check.memaccess(i8* %[[A]]
+; CHECK-ZERO-OFFSET:  %[[A:[^ ]*]] = call i8* asm "", "=r,0"(i8* null)
+; CHECK-SHORT-GRANULES:  @llvm.hwasan.check.memaccess.shortgranules(i8* %[[A]]
 
 ; CHECK-GLOBAL: load i8*, i8** @__hwasan_shadow_memory_dynamic_address
 
@@ -52,11 +56,13 @@ define void @test_alloca() sanitize_hwaddress {
 
 ; CHECK-GLOBAL: load i8*, i8** @__hwasan_shadow_memory_dynamic_address
 
-; CHECK-TLS:   %[[A:[^ ]*]] = call i8* @llvm.thread.pointer()
-; CHECK-TLS:   %[[B:[^ ]*]] = getelementptr i8, i8* %[[A]], i32 48
-; CHECK-TLS:   %[[C:[^ ]*]] = bitcast i8* %[[B]] to i64*
-; CHECK-TLS:   %[[D:[^ ]*]] = load i64, i64* %[[C]]
-; CHECK-TLS:   %[[E:[^ ]*]] = ashr i64 %[[D]], 3
+; CHECK-TLS-SLOT:   %[[A:[^ ]*]] = call i8* @llvm.thread.pointer()
+; CHECK-TLS-SLOT:   %[[B:[^ ]*]] = getelementptr i8, i8* %[[A]], i32 48
+; CHECK-TLS-SLOT:   %[[C:[^ ]*]] = bitcast i8* %[[B]] to i64*
+; CHECK-TLS-SLOT:   %[[D:[^ ]*]] = load i64, i64* %[[C]]
+; CHECK-TLS-SLOT:   %[[E:[^ ]*]] = ashr i64 %[[D]], 3
+; CHECK-HWASAN-TLS: %[[D:[^ ]*]] = load i64, i64* @__hwasan_tls, align 8
+; CHECK-HWASAN-TLS: %[[E:[^ ]*]] = ashr i64 %[[D]], 3
 
 ; CHECK-NOHISTORY-NOT: store i64
 
@@ -68,7 +74,8 @@ define void @test_alloca() sanitize_hwaddress {
 ; CHECK-HISTORY: %[[D3:[^ ]*]] = xor i64 %[[D2]], -1
 ; CHECK-HISTORY: %[[D4:[^ ]*]] = add i64 %[[D]], 8
 ; CHECK-HISTORY: %[[D5:[^ ]*]] = and i64 %[[D4]], %[[D3]]
-; CHECK-HISTORY: store i64 %[[D5]], i64* %[[C]]
+; CHECK-HISTORY-TLS-SLOT: store i64 %[[D5]], i64* %[[C]]
+; CHECK-HISTORY-HWASAN-TLS: store i64 %[[D5]], i64* @__hwasan_tls
 
 ; CHECK-TLS:   %[[F:[^ ]*]] = or i64 %[[D]], 4294967295
 ; CHECK-TLS:   = add i64 %[[F]], 1


        


More information about the llvm-commits mailing list