hwasan: Untag unwound stack frames by wrapping personality functions.
One problem with untagging memory in landing pads is that it only works correctly if the function that catches the exception is instrumented. If the function is uninstrumented, we have no opportunity to untag the memory. To address this, replace landing pad instrumentation with personality function wrapping. Each function with an instrumented stack has its personality function replaced with a wrapper provided by the runtime. Functions that did not have a personality function to begin with also get wrappers if they may be unwound past. As the unwinder calls personality functions during stack unwinding, the original personality function is called and the function's stack frame is untagged by the wrapper if the personality function instructs the unwinder to keep unwinding. If unwinding stops at a landing pad, the function is still responsible for untagging its stack frame if it resumes unwinding. The old landing pad mechanism is preserved for compatibility with old runtimes. Differential Revision: https://reviews.llvm.org/D66377 llvm-svn: 369721
This commit is contained in:
parent
90b6bb75e8
commit
21a1814417
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue