summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/hwasan/CMakeLists.txt1
-rw-r--r--compiler-rt/lib/hwasan/hwasan_exceptions.cpp64
-rw-r--r--compiler-rt/test/hwasan/TestCases/try-catch.cpp7
-rw-r--r--compiler-rt/test/hwasan/lit.cfg.py9
-rw-r--r--llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp110
-rw-r--r--llvm/test/Instrumentation/HWAddressSanitizer/landingpad.ll10
-rw-r--r--llvm/test/Instrumentation/HWAddressSanitizer/personality.ll90
-rw-r--r--llvm/utils/gn/secondary/compiler-rt/lib/hwasan/BUILD.gn1
8 files changed, 277 insertions, 15 deletions
diff --git a/compiler-rt/lib/hwasan/CMakeLists.txt b/compiler-rt/lib/hwasan/CMakeLists.txt
index c094b273e65..c976f994651 100644
--- a/compiler-rt/lib/hwasan/CMakeLists.txt
+++ b/compiler-rt/lib/hwasan/CMakeLists.txt
@@ -5,6 +5,7 @@ set(HWASAN_RTL_SOURCES
hwasan.cpp
hwasan_allocator.cpp
hwasan_dynamic_shadow.cpp
+ hwasan_exceptions.cpp
hwasan_interceptors.cpp
hwasan_interceptors_vfork.S
hwasan_linux.cpp
diff --git a/compiler-rt/lib/hwasan/hwasan_exceptions.cpp b/compiler-rt/lib/hwasan/hwasan_exceptions.cpp
new file mode 100644
index 00000000000..57a1438064c
--- /dev/null
+++ b/compiler-rt/lib/hwasan/hwasan_exceptions.cpp
@@ -0,0 +1,64 @@
+//===-- hwasan_exceptions.cpp ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of HWAddressSanitizer.
+//
+// HWAddressSanitizer runtime.
+//===----------------------------------------------------------------------===//
+
+#include "hwasan_poisoning.h"
+#include "sanitizer_common/sanitizer_common.h"
+
+#include <unwind.h>
+
+using namespace __hwasan;
+using namespace __sanitizer;
+
+typedef _Unwind_Reason_Code PersonalityFn(int version, _Unwind_Action actions,
+ uint64_t exception_class,
+ _Unwind_Exception* unwind_exception,
+ _Unwind_Context* context);
+
+// Pointers to the _Unwind_GetGR and _Unwind_GetCFA functions are passed in
+// instead of being called directly. This is to handle cases where the unwinder
+// is statically linked and the sanitizer runtime and the program are linked
+// against different unwinders. The _Unwind_Context data structure is opaque so
+// it may be incompatible between unwinders.
+typedef _Unwind_Word GetGRFn(_Unwind_Context* context, int index);
+typedef _Unwind_Word GetCFAFn(_Unwind_Context* context);
+
+extern "C" _Unwind_Reason_Code __hwasan_personality_wrapper(
+ int version, _Unwind_Action actions, uint64_t exception_class,
+ _Unwind_Exception* unwind_exception, _Unwind_Context* context,
+ PersonalityFn* real_personality, GetGRFn* get_gr, GetCFAFn* get_cfa) {
+ _Unwind_Reason_Code rc;
+ if (real_personality)
+ rc = real_personality(version, actions, exception_class, unwind_exception,
+ context);
+ else
+ rc = _URC_CONTINUE_UNWIND;
+
+ // We only untag frames without a landing pad because landing pads are
+ // responsible for untagging the stack themselves if they resume.
+ //
+ // Here we assume that the frame record appears after any locals. This is not
+ // required by AAPCS but is a requirement for HWASAN instrumented functions.
+ if ((actions & _UA_CLEANUP_PHASE) && rc == _URC_CONTINUE_UNWIND) {
+#if defined(__x86_64__)
+ uptr fp = get_gr(context, 6); // rbp
+#elif defined(__aarch64__)
+ uptr fp = get_gr(context, 29); // x29
+#else
+#error Unsupported architecture
+#endif
+ uptr sp = get_cfa(context);
+ TagMemory(sp, fp - sp, 0);
+ }
+
+ return rc;
+}
diff --git a/compiler-rt/test/hwasan/TestCases/try-catch.cpp b/compiler-rt/test/hwasan/TestCases/try-catch.cpp
index df1f93d2bae..ce1a92b3484 100644
--- a/compiler-rt/test/hwasan/TestCases/try-catch.cpp
+++ b/compiler-rt/test/hwasan/TestCases/try-catch.cpp
@@ -1,5 +1,7 @@
// RUN: %clangxx_hwasan %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=GOOD
-// RUN: %clangxx_hwasan %s -mllvm -hwasan-instrument-landing-pads=0 -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=BAD
+// RUN: %clangxx_hwasan -DNO_SANITIZE_F %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=GOOD
+// RUN: %clangxx_hwasan_oldrt %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=GOOD
+// RUN: %clangxx_hwasan_oldrt %s -mllvm -hwasan-instrument-landing-pads=0 -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=BAD
// C++ tests on x86_64 require instrumented libc++/libstdc++.
// REQUIRES: aarch64-target-arch
@@ -40,6 +42,9 @@ __attribute__((noinline, no_sanitize("hwaddress"))) void after_catch() {
__attribute__((noinline))
+#ifdef NO_SANITIZE_F
+__attribute__((no_sanitize("hwaddress")))
+#endif
void f() {
char x[1000];
try {
diff --git a/compiler-rt/test/hwasan/lit.cfg.py b/compiler-rt/test/hwasan/lit.cfg.py
index 06a860d1850..d2e71ba6d57 100644
--- a/compiler-rt/test/hwasan/lit.cfg.py
+++ b/compiler-rt/test/hwasan/lit.cfg.py
@@ -11,13 +11,17 @@ config.test_source_root = os.path.dirname(__file__)
# Setup default compiler flags used with -fsanitize=memory option.
clang_cflags = [config.target_cflags] + config.debug_info_flags
clang_cxxflags = config.cxx_mode_flags + clang_cflags
-clang_hwasan_cflags = clang_cflags + ["-fsanitize=hwaddress", "-mllvm", "-hwasan-globals", "-fuse-ld=lld"]
+clang_hwasan_oldrt_cflags = clang_cflags + ["-fsanitize=hwaddress", "-fuse-ld=lld"]
if config.target_arch == 'x86_64':
# This does basically the same thing as tagged-globals on aarch64. Because
# the x86_64 implementation is for testing purposes only there is no
# equivalent target feature implemented on x86_64.
- clang_hwasan_cflags += ["-mcmodel=large"]
+ clang_hwasan_oldrt_cflags += ["-mcmodel=large"]
+clang_hwasan_cflags = clang_hwasan_oldrt_cflags + ["-mllvm", "-hwasan-globals",
+ "-mllvm", "-hwasan-instrument-landing-pads=0",
+ "-mllvm", "-hwasan-instrument-personality-functions"]
clang_hwasan_cxxflags = config.cxx_mode_flags + clang_hwasan_cflags
+clang_hwasan_oldrt_cxxflags = config.cxx_mode_flags + clang_hwasan_oldrt_cflags
def build_invocation(compile_flags):
return " " + " ".join([config.clang] + compile_flags) + " "
@@ -25,6 +29,7 @@ def build_invocation(compile_flags):
config.substitutions.append( ("%clangxx ", build_invocation(clang_cxxflags)) )
config.substitutions.append( ("%clang_hwasan ", build_invocation(clang_hwasan_cflags)) )
config.substitutions.append( ("%clangxx_hwasan ", build_invocation(clang_hwasan_cxxflags)) )
+config.substitutions.append( ("%clangxx_hwasan_oldrt ", build_invocation(clang_hwasan_oldrt_cxxflags)) )
config.substitutions.append( ("%compiler_rt_libdir", config.compiler_rt_libdir) )
default_hwasan_opts_str = ':'.join(['disable_allocator_tagging=1', 'random_tags=0'] + config.default_sanitizer_opts)
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 163ae3ec62f..874361d4755 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
@@ -55,6 +56,8 @@ using namespace llvm;
static const char *const kHwasanModuleCtorName = "hwasan.module_ctor";
static const char *const kHwasanNoteName = "hwasan.note";
static const char *const kHwasanInitName = "__hwasan_init";
+static const char *const kHwasanPersonalityThunkName =
+ "__hwasan_personality_thunk";
static const char *const kHwasanShadowMemoryDynamicAddress =
"__hwasan_shadow_memory_dynamic_address";
@@ -160,8 +163,12 @@ static cl::opt<bool>
static cl::opt<bool>
ClInstrumentLandingPads("hwasan-instrument-landing-pads",
- cl::desc("instrument landing pads"), cl::Hidden,
- cl::init(true));
+ cl::desc("instrument landing pads"), cl::Hidden,
+ cl::init(false));
+
+static cl::opt<bool> ClInstrumentPersonalityFunctions(
+ "hwasan-instrument-personality-functions",
+ cl::desc("instrument personality functions"), cl::Hidden, cl::init(false));
static cl::opt<bool> ClInlineAllChecks("hwasan-inline-all-checks",
cl::desc("inline all checks"),
@@ -224,6 +231,8 @@ public:
void instrumentGlobal(GlobalVariable *GV, uint8_t Tag);
void instrumentGlobals();
+ void instrumentPersonalityFunctions();
+
private:
LLVMContext *C;
Module &M;
@@ -250,6 +259,7 @@ private:
};
ShadowMapping Mapping;
+ Type *VoidTy = Type::getVoidTy(M.getContext());
Type *IntptrTy;
Type *Int8PtrTy;
Type *Int8Ty;
@@ -258,6 +268,7 @@ private:
bool CompileKernel;
bool Recover;
+ bool InstrumentLandingPads;
Function *HwasanCtorFunction;
@@ -373,14 +384,27 @@ void HWAddressSanitizer::initializeModule() {
});
// Older versions of Android do not have the required runtime support for
- // global instrumentation. On other platforms we currently require using the
- // latest version of the runtime.
- bool InstrumentGlobals =
+ // global or personality function instrumentation. On other platforms we
+ // currently require using the latest version of the runtime.
+ bool NewRuntime =
!TargetTriple.isAndroid() || !TargetTriple.isAndroidVersionLT(30);
- if (ClGlobals.getNumOccurrences())
- InstrumentGlobals = ClGlobals;
+
+ bool InstrumentGlobals =
+ ClGlobals.getNumOccurrences() ? ClGlobals : NewRuntime;
if (InstrumentGlobals)
instrumentGlobals();
+
+ // If we don't have personality function support, fall back to landing pads.
+ InstrumentLandingPads = ClInstrumentLandingPads.getNumOccurrences()
+ ? ClInstrumentLandingPads
+ : !NewRuntime;
+
+ bool InstrumentPersonalityFunctions =
+ ClInstrumentPersonalityFunctions.getNumOccurrences()
+ ? ClInstrumentPersonalityFunctions
+ : NewRuntime;
+ if (InstrumentPersonalityFunctions)
+ instrumentPersonalityFunctions();
}
if (!TargetTriple.isAndroid()) {
@@ -1092,7 +1116,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) {
if (auto *Alloca = dyn_cast_or_null<AllocaInst>(DDI->getAddress()))
AllocaDeclareMap[Alloca].push_back(DDI);
- if (ClInstrumentLandingPads && isa<LandingPadInst>(Inst))
+ if (InstrumentLandingPads && isa<LandingPadInst>(Inst))
LandingPadVec.push_back(&Inst);
Value *MaybeMask = nullptr;
@@ -1111,6 +1135,13 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) {
if (!LandingPadVec.empty())
instrumentLandingPads(LandingPadVec);
+ if (AllocasToInstrument.empty() && F.hasPersonalityFn() &&
+ F.getPersonalityFn()->getName() == kHwasanPersonalityThunkName) {
+ // __hwasan_personality_thunk is a no-op for functions without an
+ // instrumented stack, so we can drop it.
+ F.setPersonalityFn(nullptr);
+ }
+
if (AllocasToInstrument.empty() && ToInstrument.empty())
return false;
@@ -1386,6 +1417,69 @@ void HWAddressSanitizer::instrumentGlobals() {
}
}
+void HWAddressSanitizer::instrumentPersonalityFunctions() {
+ // We need to untag stack frames as we unwind past them. That is the job of
+ // the personality function wrapper, which either wraps an existing
+ // personality function or acts as a personality function on its own. Each
+ // function that has a personality function or that can be unwound past has
+ // its personality function changed to a thunk that calls the personality
+ // function wrapper in the runtime.
+ MapVector<Constant *, std::vector<Function *>> PersonalityFns;
+ for (Function &F : M) {
+ if (F.isDeclaration() || !F.hasFnAttribute(Attribute::SanitizeHWAddress))
+ continue;
+
+ if (F.hasPersonalityFn()) {
+ PersonalityFns[F.getPersonalityFn()->stripPointerCasts()].push_back(&F);
+ } else if (!F.hasFnAttribute(Attribute::NoUnwind)) {
+ PersonalityFns[nullptr].push_back(&F);
+ }
+ }
+
+ if (PersonalityFns.empty())
+ return;
+
+ FunctionCallee HwasanPersonalityWrapper = M.getOrInsertFunction(
+ "__hwasan_personality_wrapper", Int32Ty, Int32Ty, Int32Ty, Int64Ty,
+ Int8PtrTy, Int8PtrTy, Int8PtrTy, Int8PtrTy, Int8PtrTy);
+ FunctionCallee UnwindGetGR = M.getOrInsertFunction("_Unwind_GetGR", VoidTy);
+ FunctionCallee UnwindGetCFA = M.getOrInsertFunction("_Unwind_GetCFA", VoidTy);
+
+ for (auto &P : PersonalityFns) {
+ std::string ThunkName = kHwasanPersonalityThunkName;
+ if (P.first)
+ ThunkName += ("." + P.first->getName()).str();
+ FunctionType *ThunkFnTy = FunctionType::get(
+ Int32Ty, {Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int8PtrTy}, false);
+ bool IsLocal = P.first && (!isa<GlobalValue>(P.first) ||
+ cast<GlobalValue>(P.first)->hasLocalLinkage());
+ auto *ThunkFn = Function::Create(ThunkFnTy,
+ IsLocal ? GlobalValue::InternalLinkage
+ : GlobalValue::LinkOnceODRLinkage,
+ ThunkName, &M);
+ if (!IsLocal) {
+ ThunkFn->setVisibility(GlobalValue::HiddenVisibility);
+ ThunkFn->setComdat(M.getOrInsertComdat(ThunkName));
+ }
+
+ auto *BB = BasicBlock::Create(*C, "entry", ThunkFn);
+ IRBuilder<> IRB(BB);
+ CallInst *WrapperCall = IRB.CreateCall(
+ HwasanPersonalityWrapper,
+ {ThunkFn->getArg(0), ThunkFn->getArg(1), ThunkFn->getArg(2),
+ ThunkFn->getArg(3), ThunkFn->getArg(4),
+ P.first ? IRB.CreateBitCast(P.first, Int8PtrTy)
+ : Constant::getNullValue(Int8PtrTy),
+ IRB.CreateBitCast(UnwindGetGR.getCallee(), Int8PtrTy),
+ IRB.CreateBitCast(UnwindGetCFA.getCallee(), Int8PtrTy)});
+ WrapperCall->setTailCall();
+ IRB.CreateRet(WrapperCall);
+
+ for (Function *F : P.second)
+ F->setPersonalityFn(ThunkFn);
+ }
+}
+
void HWAddressSanitizer::ShadowMapping::init(Triple &TargetTriple) {
Scale = kDefaultShadowScale;
if (ClMappingOffset.getNumOccurrences() > 0) {
diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/landingpad.ll b/llvm/test/Instrumentation/HWAddressSanitizer/landingpad.ll
index 15cc0bc95d9..bb6eb02b469 100644
--- a/llvm/test/Instrumentation/HWAddressSanitizer/landingpad.ll
+++ b/llvm/test/Instrumentation/HWAddressSanitizer/landingpad.ll
@@ -1,5 +1,6 @@
-; RUN: opt < %s -mtriple aarch64-linux-android -hwasan -S | FileCheck %s --check-prefixes=COMMON,ARM
-; RUN: opt < %s -mtriple x86_64-linux -hwasan -S | FileCheck %s --check-prefixes=COMMON,X86
+; RUN: opt < %s -mtriple aarch64-linux-android29 -hwasan -S | FileCheck %s --check-prefixes=COMMON,LP,ARM
+; RUN: opt < %s -mtriple x86_64-linux -hwasan-instrument-landing-pads -hwasan -S | FileCheck %s --check-prefixes=COMMON,LP,X86
+; RUN: opt < %s -mtriple aarch64-linux-android30 -hwasan -S | FileCheck %s --check-prefixes=COMMON,NOLP
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64-unknown-linux-android"
@@ -15,8 +16,9 @@ lpad:
%0 = landingpad { i8*, i32 }
catch i8* null
- ; COMMON-NEXT: %[[X:[^ ]*]] = call i64 @llvm.read_register.i64(metadata ![[META:[^ ]*]])
- ; COMMON-NEXT: call void @__hwasan_handle_vfork(i64 %[[X]])
+ ; NOLP-NOT: call void @__hwasan_handle_vfork
+ ; LP-NEXT: %[[X:[^ ]*]] = call i64 @llvm.read_register.i64(metadata ![[META:[^ ]*]])
+ ; LP-NEXT: call void @__hwasan_handle_vfork(i64 %[[X]])
%1 = extractvalue { i8*, i32 } %0, 0
%2 = tail call i8* @__cxa_begin_catch(i8* %1)
diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/personality.ll b/llvm/test/Instrumentation/HWAddressSanitizer/personality.ll
new file mode 100644
index 00000000000..ad969e39332
--- /dev/null
+++ b/llvm/test/Instrumentation/HWAddressSanitizer/personality.ll
@@ -0,0 +1,90 @@
+; RUN: opt < %s -mtriple aarch64-linux-android29 -hwasan -S | FileCheck %s --check-prefix=NOPERS
+; RUN: opt < %s -mtriple aarch64-linux-android30 -hwasan -S | FileCheck %s --check-prefix=PERS
+
+; NOPERS: define void @nostack() #{{[0-9]+}} {
+; PERS: define void @nostack() #{{[0-9]+}} {
+define void @nostack() sanitize_hwaddress {
+ ret void
+}
+
+; NOPERS: define void @stack1() #{{[0-9]+}} {
+; PERS: personality {{.*}} @__hwasan_personality_thunk
+define void @stack1() sanitize_hwaddress {
+ %p = alloca i8
+ call void @sink(i8* %p)
+ ret void
+}
+
+
+; NOPERS: personality void ()* @global
+; PERS: personality {{.*}} @__hwasan_personality_thunk.global
+define void @stack2() sanitize_hwaddress personality void ()* @global {
+ %p = alloca i8
+ call void @sink(i8* %p)
+ ret void
+}
+
+define internal void @local() {
+ ret void
+}
+
+@local_alias = internal alias void (), void ()* @local
+
+; NOPERS: personality void ()* @local
+; PERS: personality {{.*}} @__hwasan_personality_thunk.local
+define void @stack3() sanitize_hwaddress personality void ()* @local {
+ %p = alloca i8
+ call void @sink(i8* %p)
+ ret void
+}
+
+; NOPERS: personality void ()* @local_alias
+; PERS: personality {{.*}} @__hwasan_personality_thunk.local_alias
+define void @stack4() sanitize_hwaddress personality void ()* @local_alias {
+ %p = alloca i8
+ call void @sink(i8* %p)
+ ret void
+}
+
+; NOPERS: personality void ()* inttoptr (i64 1 to void ()*)
+; PERS: personality i32 (i32, i32, i64, i8*, i8*)* @__hwasan_personality_thunk.
+define void @stack5() sanitize_hwaddress personality void ()* inttoptr (i64 1 to void ()*) {
+ %p = alloca i8
+ call void @sink(i8* %p)
+ ret void
+}
+
+; NOPERS: personality void ()* inttoptr (i64 2 to void ()*)
+; PERS: personality i32 (i32, i32, i64, i8*, i8*)* @__hwasan_personality_thunk..1
+define void @stack6() sanitize_hwaddress personality void ()* inttoptr (i64 2 to void ()*) {
+ %p = alloca i8
+ call void @sink(i8* %p)
+ ret void
+}
+
+declare void @global()
+declare void @sink(i8*)
+
+; PERS: define linkonce_odr hidden i32 @__hwasan_personality_thunk(i32 %0, i32 %1, i64 %2, i8* %3, i8* %4) comdat
+; PERS: %5 = tail call i32 @__hwasan_personality_wrapper(i32 %0, i32 %1, i64 %2, i8* %3, i8* %4, i8* null, i8* bitcast (void ()* @_Unwind_GetGR to i8*), i8* bitcast (void ()* @_Unwind_GetCFA to i8*))
+; PERS: ret i32 %5
+
+; PERS: define linkonce_odr hidden i32 @__hwasan_personality_thunk.global(i32 %0, i32 %1, i64 %2, i8* %3, i8* %4) comdat
+; PERS: %5 = tail call i32 @__hwasan_personality_wrapper(i32 %0, i32 %1, i64 %2, i8* %3, i8* %4, i8* bitcast (void ()* @global to i8*), i8* bitcast (void ()* @_Unwind_GetGR to i8*), i8* bitcast (void ()* @_Unwind_GetCFA to i8*))
+; PERS: ret i32 %5
+
+; PERS: define internal i32 @__hwasan_personality_thunk.local(i32 %0, i32 %1, i64 %2, i8* %3, i8* %4)
+; PERS: %5 = tail call i32 @__hwasan_personality_wrapper(i32 %0, i32 %1, i64 %2, i8* %3, i8* %4, i8* bitcast (void ()* @local to i8*), i8* bitcast (void ()* @_Unwind_GetGR to i8*), i8* bitcast (void ()* @_Unwind_GetCFA to i8*))
+; PERS: ret i32 %5
+
+; PERS: define internal i32 @__hwasan_personality_thunk.local_alias(i32 %0, i32 %1, i64 %2, i8* %3, i8* %4)
+; PERS: %5 = tail call i32 @__hwasan_personality_wrapper(i32 %0, i32 %1, i64 %2, i8* %3, i8* %4, i8* bitcast (void ()* @local_alias to i8*), i8* bitcast (void ()* @_Unwind_GetGR to i8*), i8* bitcast (void ()* @_Unwind_GetCFA to i8*))
+; PERS: ret i32 %5
+
+; PERS: define internal i32 @__hwasan_personality_thunk.(i32 %0, i32 %1, i64 %2, i8* %3, i8* %4) {
+; PERS: %5 = tail call i32 @__hwasan_personality_wrapper(i32 %0, i32 %1, i64 %2, i8* %3, i8* %4, i8* inttoptr (i64 1 to i8*), i8* bitcast (void ()* @_Unwind_GetGR to i8*), i8* bitcast (void ()* @_Unwind_GetCFA to i8*))
+; PERS: ret i32 %5
+
+; PERS: define internal i32 @__hwasan_personality_thunk..1(i32 %0, i32 %1, i64 %2, i8* %3, i8* %4) {
+; PERS: %5 = tail call i32 @__hwasan_personality_wrapper(i32 %0, i32 %1, i64 %2, i8* %3, i8* %4, i8* inttoptr (i64 2 to i8*), i8* bitcast (void ()* @_Unwind_GetGR to i8*), i8* bitcast (void ()* @_Unwind_GetCFA to i8*))
+; PERS: ret i32 %5
diff --git a/llvm/utils/gn/secondary/compiler-rt/lib/hwasan/BUILD.gn b/llvm/utils/gn/secondary/compiler-rt/lib/hwasan/BUILD.gn
index f29d2455a19..c2a4817c3fa 100644
--- a/llvm/utils/gn/secondary/compiler-rt/lib/hwasan/BUILD.gn
+++ b/llvm/utils/gn/secondary/compiler-rt/lib/hwasan/BUILD.gn
@@ -45,6 +45,7 @@ source_set("sources") {
"hwasan_allocator.h",
"hwasan_dynamic_shadow.cpp",
"hwasan_dynamic_shadow.h",
+ "hwasan_exceptions.cpp",
"hwasan_flags.h",
"hwasan_interceptors.cpp",
"hwasan_interceptors_vfork.S",
OpenPOWER on IntegriCloud