[PATCH] D40936: Hardware-assisted AddressSanitizer (clang part).

2017-12-08 Thread Evgenii Stepanov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL320232: Hardware-assisted AddressSanitizer (clang part). 
(authored by eugenis).

Changed prior to commit:
  https://reviews.llvm.org/D40936?vs=126060=126252#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D40936

Files:
  cfe/trunk/include/clang/Basic/Sanitizers.def
  cfe/trunk/include/clang/Driver/SanitizerArgs.h
  cfe/trunk/lib/CodeGen/BackendUtil.cpp
  cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
  cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
  cfe/trunk/lib/CodeGen/CodeGenModule.cpp
  cfe/trunk/lib/CodeGen/SanitizerMetadata.cpp
  cfe/trunk/lib/Driver/SanitizerArgs.cpp
  cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp
  cfe/trunk/lib/Driver/ToolChains/Linux.cpp
  cfe/trunk/lib/Lex/PPMacroExpansion.cpp
  cfe/trunk/test/CodeGen/address-safety-attr-kasan-hwasan.cpp
  cfe/trunk/test/Driver/Inputs/resource_dir/hwasan_blacklist.txt
  
cfe/trunk/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.hwasan-aarch64.a.syms
  cfe/trunk/test/Driver/asan.c
  cfe/trunk/test/Driver/fsanitize-blacklist.c
  cfe/trunk/test/Driver/fsanitize-coverage.c
  cfe/trunk/test/Driver/fsanitize.c
  cfe/trunk/test/Driver/sanitize_unwind_tables.c
  cfe/trunk/test/Driver/sanitizer-ld.c
  cfe/trunk/test/Lexer/has_feature_address_sanitizer.cpp
  cfe/trunk/test/SemaCXX/attr-no-sanitize.cpp

Index: cfe/trunk/include/clang/Driver/SanitizerArgs.h
===
--- cfe/trunk/include/clang/Driver/SanitizerArgs.h
+++ cfe/trunk/include/clang/Driver/SanitizerArgs.h
@@ -55,12 +55,14 @@
   bool needsSharedRt() const { return SharedRuntime; }
 
   bool needsAsanRt() const { return Sanitizers.has(SanitizerKind::Address); }
+  bool needsHwasanRt() const { return Sanitizers.has(SanitizerKind::HWAddress); }
   bool needsTsanRt() const { return Sanitizers.has(SanitizerKind::Thread); }
   bool needsMsanRt() const { return Sanitizers.has(SanitizerKind::Memory); }
   bool needsFuzzer() const { return Sanitizers.has(SanitizerKind::Fuzzer); }
   bool needsLsanRt() const {
 return Sanitizers.has(SanitizerKind::Leak) &&
-   !Sanitizers.has(SanitizerKind::Address);
+   !Sanitizers.has(SanitizerKind::Address) &&
+   !Sanitizers.has(SanitizerKind::HWAddress);
   }
   bool needsUbsanRt() const;
   bool requiresMinimalRuntime() const { return MinimalRuntime; }
Index: cfe/trunk/include/clang/Basic/Sanitizers.def
===
--- cfe/trunk/include/clang/Basic/Sanitizers.def
+++ cfe/trunk/include/clang/Basic/Sanitizers.def
@@ -44,6 +44,8 @@
 // Kernel AddressSanitizer (KASan)
 SANITIZER("kernel-address", KernelAddress)
 
+SANITIZER("hwaddress", HWAddress)
+
 // MemorySanitizer
 SANITIZER("memory", Memory)
 
Index: cfe/trunk/test/Driver/fsanitize-coverage.c
===
--- cfe/trunk/test/Driver/fsanitize-coverage.c
+++ cfe/trunk/test/Driver/fsanitize-coverage.c
@@ -6,6 +6,7 @@
 
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=kernel-address -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=leak -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC
Index: cfe/trunk/test/Driver/asan.c
===
--- cfe/trunk/test/Driver/asan.c
+++ cfe/trunk/test/Driver/asan.c
@@ -6,8 +6,13 @@
 // RUN: %clang -O1 -target i386-unknown-linux -fsanitize=kernel-address %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-KASAN
 // RUN: %clang -O2 -target i386-unknown-linux -fsanitize=kernel-address %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-KASAN
 // RUN: %clang -O3 -target i386-unknown-linux -fsanitize=kernel-address %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-KASAN
+// RUN: %clang -target aarch64-unknown-linux -fsanitize=hwaddress %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-HWASAN
+// RUN: %clang -O1 -target aarch64-unknown-linux -fsanitize=hwaddress %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-HWASAN
+// RUN: %clang -O2 -target aarch64-unknown-linux -fsanitize=hwaddress %s -S 

[PATCH] D40936: Hardware-assisted AddressSanitizer (clang part).

2017-12-08 Thread Evgenii Stepanov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC320232: Hardware-assisted AddressSanitizer (clang part). 
(authored by eugenis).

Changed prior to commit:
  https://reviews.llvm.org/D40936?vs=126060=126251#toc

Repository:
  rC Clang

https://reviews.llvm.org/D40936

Files:
  include/clang/Basic/Sanitizers.def
  include/clang/Driver/SanitizerArgs.h
  lib/CodeGen/BackendUtil.cpp
  lib/CodeGen/CGDeclCXX.cpp
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/CodeGen/SanitizerMetadata.cpp
  lib/Driver/SanitizerArgs.cpp
  lib/Driver/ToolChains/CommonArgs.cpp
  lib/Driver/ToolChains/Linux.cpp
  lib/Lex/PPMacroExpansion.cpp
  test/CodeGen/address-safety-attr-kasan-hwasan.cpp
  test/Driver/Inputs/resource_dir/hwasan_blacklist.txt
  test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.hwasan-aarch64.a.syms
  test/Driver/asan.c
  test/Driver/fsanitize-blacklist.c
  test/Driver/fsanitize-coverage.c
  test/Driver/fsanitize.c
  test/Driver/sanitize_unwind_tables.c
  test/Driver/sanitizer-ld.c
  test/Lexer/has_feature_address_sanitizer.cpp
  test/SemaCXX/attr-no-sanitize.cpp

Index: lib/CodeGen/CodeGenFunction.cpp
===
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -846,6 +846,8 @@
   // Apply sanitizer attributes to the function.
   if (SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress))
 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
+  if (SanOpts.hasOneOf(SanitizerKind::HWAddress))
+Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
   if (SanOpts.has(SanitizerKind::Thread))
 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
   if (SanOpts.has(SanitizerKind::Memory))
Index: lib/CodeGen/BackendUtil.cpp
===
--- lib/CodeGen/BackendUtil.cpp
+++ lib/CodeGen/BackendUtil.cpp
@@ -237,6 +237,11 @@
   /*Recover*/true));
 }
 
+static void addHWAddressSanitizerPasses(const PassManagerBuilder ,
+legacy::PassManagerBase ) {
+  PM.add(createHWAddressSanitizerPass());
+}
+
 static void addMemorySanitizerPass(const PassManagerBuilder ,
legacy::PassManagerBase ) {
   const PassManagerBuilderWrapper  =
@@ -556,6 +561,13 @@
addKernelAddressSanitizerPasses);
   }
 
+  if (LangOpts.Sanitize.has(SanitizerKind::HWAddress)) {
+PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
+   addHWAddressSanitizerPasses);
+PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
+   addHWAddressSanitizerPasses);
+  }
+
   if (LangOpts.Sanitize.has(SanitizerKind::Memory)) {
 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
addMemorySanitizerPass);
Index: lib/CodeGen/CodeGenModule.cpp
===
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -1582,7 +1582,7 @@
StringRef Category) const {
   // For now globals can be blacklisted only in ASan and KASan.
   const SanitizerMask EnabledAsanMask = LangOpts.Sanitize.Mask &
-  (SanitizerKind::Address | SanitizerKind::KernelAddress);
+  (SanitizerKind::Address | SanitizerKind::KernelAddress | SanitizerKind::HWAddress);
   if (!EnabledAsanMask)
 return false;
   const auto  = getContext().getSanitizerBlacklist();
Index: lib/CodeGen/CGDeclCXX.cpp
===
--- lib/CodeGen/CGDeclCXX.cpp
+++ lib/CodeGen/CGDeclCXX.cpp
@@ -324,6 +324,10 @@
   !isInSanitizerBlacklist(SanitizerKind::KernelAddress, Fn, Loc))
 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
 
+  if (getLangOpts().Sanitize.has(SanitizerKind::HWAddress) &&
+  !isInSanitizerBlacklist(SanitizerKind::HWAddress, Fn, Loc))
+Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
+
   if (getLangOpts().Sanitize.has(SanitizerKind::Thread) &&
   !isInSanitizerBlacklist(SanitizerKind::Thread, Fn, Loc))
 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
Index: lib/CodeGen/SanitizerMetadata.cpp
===
--- lib/CodeGen/SanitizerMetadata.cpp
+++ lib/CodeGen/SanitizerMetadata.cpp
@@ -26,7 +26,8 @@
QualType Ty, bool IsDynInit,
bool IsBlacklisted) {
   if (!CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address |
-   SanitizerKind::KernelAddress))
+   SanitizerKind::KernelAddress |
+   SanitizerKind::HWAddress))
 return;
   IsDynInit &= !CGM.isInSanitizerBlacklist(GV, Loc, Ty, 

[PATCH] D40936: Hardware-assisted AddressSanitizer (clang part).

2017-12-07 Thread Evgenii Stepanov via Phabricator via cfe-commits
eugenis updated this revision to Diff 126060.
eugenis added a comment.

clang-format


https://reviews.llvm.org/D40936

Files:
  clang/include/clang/Basic/Sanitizers.def
  clang/include/clang/Driver/SanitizerArgs.h
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/SanitizerMetadata.cpp
  clang/lib/Driver/SanitizerArgs.cpp
  clang/lib/Driver/ToolChains/CommonArgs.cpp
  clang/lib/Driver/ToolChains/Linux.cpp
  clang/lib/Lex/PPMacroExpansion.cpp
  clang/test/CodeGen/address-safety-attr-kasan-hwasan.cpp
  clang/test/Driver/Inputs/resource_dir/hwasan_blacklist.txt
  
clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.hwasan-aarch64.a.syms
  clang/test/Driver/asan.c
  clang/test/Driver/fsanitize-blacklist.c
  clang/test/Driver/fsanitize-coverage.c
  clang/test/Driver/fsanitize.c
  clang/test/Driver/sanitize_unwind_tables.c
  clang/test/Driver/sanitizer-ld.c
  clang/test/Lexer/has_feature_address_sanitizer.cpp
  clang/test/SemaCXX/attr-no-sanitize.cpp

Index: clang/test/SemaCXX/attr-no-sanitize.cpp
===
--- clang/test/SemaCXX/attr-no-sanitize.cpp
+++ clang/test/SemaCXX/attr-no-sanitize.cpp
@@ -16,10 +16,15 @@
 // PRINT: int f4() {{\[\[}}clang::no_sanitize("thread")]]
 [[clang::no_sanitize("thread")]] int f4();
 
+// DUMP-LABEL: FunctionDecl {{.*}} f4
+// DUMP: NoSanitizeAttr {{.*}} hwaddress
+// PRINT: int f4() {{\[\[}}clang::no_sanitize("hwaddress")]]
+[[clang::no_sanitize("hwaddress")]] int f4();
+
 // DUMP-LABEL: FunctionDecl {{.*}} f5
-// DUMP: NoSanitizeAttr {{.*}} address thread
-// PRINT: int f5() __attribute__((no_sanitize("address", "thread")))
-int f5() __attribute__((no_sanitize("address", "thread")));
+// DUMP: NoSanitizeAttr {{.*}} address thread hwaddress
+// PRINT: int f5() __attribute__((no_sanitize("address", "thread", "hwaddress")))
+int f5() __attribute__((no_sanitize("address", "thread", "hwaddress")));
 
 // DUMP-LABEL: FunctionDecl {{.*}} f6
 // DUMP: NoSanitizeAttr {{.*}} unknown
Index: clang/test/Lexer/has_feature_address_sanitizer.cpp
===
--- clang/test/Lexer/has_feature_address_sanitizer.cpp
+++ clang/test/Lexer/has_feature_address_sanitizer.cpp
@@ -1,12 +1,25 @@
 // RUN: %clang_cc1 -E -fsanitize=address %s -o - | FileCheck --check-prefix=CHECK-ASAN %s
 // RUN: %clang_cc1 -E -fsanitize=kernel-address %s -o - | FileCheck --check-prefix=CHECK-ASAN %s
+// RUN: %clang_cc1 -E -fsanitize=hwaddress %s -o - | FileCheck --check-prefix=CHECK-HWASAN %s
 // RUN: %clang_cc1 -E  %s -o - | FileCheck --check-prefix=CHECK-NO-ASAN %s
 
 #if __has_feature(address_sanitizer)
 int AddressSanitizerEnabled();
 #else
 int AddressSanitizerDisabled();
 #endif
 
+#if __has_feature(hwaddress_sanitizer)
+int HWAddressSanitizerEnabled();
+#else
+int HWAddressSanitizerDisabled();
+#endif
+
 // CHECK-ASAN: AddressSanitizerEnabled
+// CHECK-ASAN: HWAddressSanitizerDisabled
+
+// CHECK-HWASAN: AddressSanitizerDisabled
+// CHECK-HWASAN: HWAddressSanitizerEnabled
+
 // CHECK-NO-ASAN: AddressSanitizerDisabled
+// CHECK-NO-ASAN: HWAddressSanitizerDisabled
Index: clang/test/Driver/sanitizer-ld.c
===
--- clang/test/Driver/sanitizer-ld.c
+++ clang/test/Driver/sanitizer-ld.c
@@ -694,3 +694,56 @@
 // CHECK-SCUDO-ANDROID-STATIC: "-whole-archive" "{{.*}}libclang_rt.scudo-arm-android.a" "-no-whole-archive"
 // CHECK-SCUDO-ANDROID-STATIC-NOT: "-lstdc++"
 // CHECK-SCUDO-ANDROID-STATIC: "-lpthread"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target aarch64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-HWASAN-LINUX %s
+//
+// CHECK-HWASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-HWASAN-LINUX-NOT: "-lc"
+// CHECK-HWASAN-LINUX: libclang_rt.hwasan-aarch64.a"
+// CHECK-HWASAN-LINUX-NOT: "-export-dynamic"
+// CHECK-HWASAN-LINUX: "--dynamic-list={{.*}}libclang_rt.hwasan-aarch64.a.syms"
+// CHECK-HWASAN-LINUX-NOT: "-export-dynamic"
+// CHECK-HWASAN-LINUX: "-lpthread"
+// CHECK-HWASAN-LINUX: "-lrt"
+// CHECK-HWASAN-LINUX: "-ldl"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target aarch64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress -shared-libsan \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-SHARED-HWASAN-LINUX %s
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target aarch64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress \
+// RUN: -shared-libsan \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | 

[PATCH] D40936: Hardware-assisted AddressSanitizer (clang part).

2017-12-07 Thread Evgenii Stepanov via Phabricator via cfe-commits
eugenis added inline comments.



Comment at: clang/include/clang/Basic/Sanitizers.def:47
 
+SANITIZER("hwaddress", HWAddress)
+

alekseyshl wrote:
> Why didn't we follow KASan style and name it "hw-address"?
A matter of taste, I guess.
I don't want the attribute to be sanitize_hw_address, too many underscores.
Also, kernel is a word and hw is just to letters.




Comment at: clang/lib/Driver/SanitizerArgs.cpp:383
+  std::make_pair(Efficiency, Address | HWAddress | Leak | Thread | Memory |
+ KernelAddress),
+  std::make_pair(Scudo, Address | HWAddress | Leak | Thread | Memory |

alekseyshl wrote:
> Nit: 4 less spaces here and for the next pair.
https://bugs.llvm.org/show_bug.cgi?id=35563


https://reviews.llvm.org/D40936



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D40936: Hardware-assisted AddressSanitizer (clang part).

2017-12-07 Thread Aleksey Shlyapnikov via Phabricator via cfe-commits
alekseyshl accepted this revision.
alekseyshl added inline comments.



Comment at: clang/include/clang/Basic/Sanitizers.def:47
 
+SANITIZER("hwaddress", HWAddress)
+

Why didn't we follow KASan style and name it "hw-address"?



Comment at: clang/lib/Driver/SanitizerArgs.cpp:383
+  std::make_pair(Efficiency, Address | HWAddress | Leak | Thread | Memory |
+ KernelAddress),
+  std::make_pair(Scudo, Address | HWAddress | Leak | Thread | Memory |

Nit: 4 less spaces here and for the next pair.


https://reviews.llvm.org/D40936



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D40936: Hardware-assisted AddressSanitizer (clang part).

2017-12-06 Thread Kostya Serebryany via Phabricator via cfe-commits
kcc accepted this revision.
kcc added a comment.
This revision is now accepted and ready to land.

LGTM
please give at least Aleksey a chance to review as well.


https://reviews.llvm.org/D40936



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D40936: Hardware-assisted AddressSanitizer (clang part).

2017-12-06 Thread Evgenii Stepanov via Phabricator via cfe-commits
eugenis created this revision.
Herald added subscribers: javed.absar, srhines.

Driver, frontend and LLVM codegen for HWASan.
A clone of ASan, basically.


https://reviews.llvm.org/D40936

Files:
  clang/include/clang/Basic/Sanitizers.def
  clang/include/clang/Driver/SanitizerArgs.h
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/SanitizerMetadata.cpp
  clang/lib/Driver/SanitizerArgs.cpp
  clang/lib/Driver/ToolChains/CommonArgs.cpp
  clang/lib/Driver/ToolChains/Linux.cpp
  clang/lib/Lex/PPMacroExpansion.cpp
  clang/test/CodeGen/address-safety-attr-kasan-hwasan.cpp
  clang/test/Driver/Inputs/resource_dir/hwasan_blacklist.txt
  
clang/test/Driver/Inputs/resource_dir/lib/linux/libclang_rt.hwasan-aarch64.a.syms
  clang/test/Driver/asan.c
  clang/test/Driver/fsanitize-blacklist.c
  clang/test/Driver/fsanitize-coverage.c
  clang/test/Driver/fsanitize.c
  clang/test/Driver/sanitize_unwind_tables.c
  clang/test/Driver/sanitizer-ld.c
  clang/test/Lexer/has_feature_address_sanitizer.cpp
  clang/test/SemaCXX/attr-no-sanitize.cpp

Index: clang/test/SemaCXX/attr-no-sanitize.cpp
===
--- clang/test/SemaCXX/attr-no-sanitize.cpp
+++ clang/test/SemaCXX/attr-no-sanitize.cpp
@@ -16,10 +16,15 @@
 // PRINT: int f4() {{\[\[}}clang::no_sanitize("thread")]]
 [[clang::no_sanitize("thread")]] int f4();
 
+// DUMP-LABEL: FunctionDecl {{.*}} f4
+// DUMP: NoSanitizeAttr {{.*}} hwaddress
+// PRINT: int f4() {{\[\[}}clang::no_sanitize("hwaddress")]]
+[[clang::no_sanitize("hwaddress")]] int f4();
+
 // DUMP-LABEL: FunctionDecl {{.*}} f5
-// DUMP: NoSanitizeAttr {{.*}} address thread
-// PRINT: int f5() __attribute__((no_sanitize("address", "thread")))
-int f5() __attribute__((no_sanitize("address", "thread")));
+// DUMP: NoSanitizeAttr {{.*}} address thread hwaddress
+// PRINT: int f5() __attribute__((no_sanitize("address", "thread", "hwaddress")))
+int f5() __attribute__((no_sanitize("address", "thread", "hwaddress")));
 
 // DUMP-LABEL: FunctionDecl {{.*}} f6
 // DUMP: NoSanitizeAttr {{.*}} unknown
Index: clang/test/Lexer/has_feature_address_sanitizer.cpp
===
--- clang/test/Lexer/has_feature_address_sanitizer.cpp
+++ clang/test/Lexer/has_feature_address_sanitizer.cpp
@@ -1,12 +1,25 @@
 // RUN: %clang_cc1 -E -fsanitize=address %s -o - | FileCheck --check-prefix=CHECK-ASAN %s
 // RUN: %clang_cc1 -E -fsanitize=kernel-address %s -o - | FileCheck --check-prefix=CHECK-ASAN %s
+// RUN: %clang_cc1 -E -fsanitize=hwaddress %s -o - | FileCheck --check-prefix=CHECK-HWASAN %s
 // RUN: %clang_cc1 -E  %s -o - | FileCheck --check-prefix=CHECK-NO-ASAN %s
 
 #if __has_feature(address_sanitizer)
 int AddressSanitizerEnabled();
 #else
 int AddressSanitizerDisabled();
 #endif
 
+#if __has_feature(hwaddress_sanitizer)
+int HWAddressSanitizerEnabled();
+#else
+int HWAddressSanitizerDisabled();
+#endif
+
 // CHECK-ASAN: AddressSanitizerEnabled
+// CHECK-ASAN: HWAddressSanitizerDisabled
+
+// CHECK-HWASAN: AddressSanitizerDisabled
+// CHECK-HWASAN: HWAddressSanitizerEnabled
+
 // CHECK-NO-ASAN: AddressSanitizerDisabled
+// CHECK-NO-ASAN: HWAddressSanitizerDisabled
Index: clang/test/Driver/sanitizer-ld.c
===
--- clang/test/Driver/sanitizer-ld.c
+++ clang/test/Driver/sanitizer-ld.c
@@ -694,3 +694,56 @@
 // CHECK-SCUDO-ANDROID-STATIC: "-whole-archive" "{{.*}}libclang_rt.scudo-arm-android.a" "-no-whole-archive"
 // CHECK-SCUDO-ANDROID-STATIC-NOT: "-lstdc++"
 // CHECK-SCUDO-ANDROID-STATIC: "-lpthread"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target aarch64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-HWASAN-LINUX %s
+//
+// CHECK-HWASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-HWASAN-LINUX-NOT: "-lc"
+// CHECK-HWASAN-LINUX: libclang_rt.hwasan-aarch64.a"
+// CHECK-HWASAN-LINUX-NOT: "-export-dynamic"
+// CHECK-HWASAN-LINUX: "--dynamic-list={{.*}}libclang_rt.hwasan-aarch64.a.syms"
+// CHECK-HWASAN-LINUX-NOT: "-export-dynamic"
+// CHECK-HWASAN-LINUX: "-lpthread"
+// CHECK-HWASAN-LINUX: "-lrt"
+// CHECK-HWASAN-LINUX: "-ldl"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target aarch64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress -shared-libsan \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-SHARED-HWASAN-LINUX %s
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target aarch64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress \
+// RUN: -shared-libsan \
+// RUN: -resource-dir=%S/Inputs/resource_dir