1*68d75effSDimitry Andric //===-- hwasan_exceptions.cpp ---------------------------------------------===// 2*68d75effSDimitry Andric // 3*68d75effSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*68d75effSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*68d75effSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*68d75effSDimitry Andric // 7*68d75effSDimitry Andric //===----------------------------------------------------------------------===// 8*68d75effSDimitry Andric // 9*68d75effSDimitry Andric // This file is a part of HWAddressSanitizer. 10*68d75effSDimitry Andric // 11*68d75effSDimitry Andric // HWAddressSanitizer runtime. 12*68d75effSDimitry Andric //===----------------------------------------------------------------------===// 13*68d75effSDimitry Andric 14*68d75effSDimitry Andric #include "hwasan_poisoning.h" 15*68d75effSDimitry Andric #include "sanitizer_common/sanitizer_common.h" 16*68d75effSDimitry Andric 17*68d75effSDimitry Andric #include <unwind.h> 18*68d75effSDimitry Andric 19*68d75effSDimitry Andric using namespace __hwasan; 20*68d75effSDimitry Andric using namespace __sanitizer; 21*68d75effSDimitry Andric 22*68d75effSDimitry Andric typedef _Unwind_Reason_Code PersonalityFn(int version, _Unwind_Action actions, 23*68d75effSDimitry Andric uint64_t exception_class, 24*68d75effSDimitry Andric _Unwind_Exception* unwind_exception, 25*68d75effSDimitry Andric _Unwind_Context* context); 26*68d75effSDimitry Andric 27*68d75effSDimitry Andric // Pointers to the _Unwind_GetGR and _Unwind_GetCFA functions are passed in 28*68d75effSDimitry Andric // instead of being called directly. This is to handle cases where the unwinder 29*68d75effSDimitry Andric // is statically linked and the sanitizer runtime and the program are linked 30*68d75effSDimitry Andric // against different unwinders. The _Unwind_Context data structure is opaque so 31*68d75effSDimitry Andric // it may be incompatible between unwinders. 32*68d75effSDimitry Andric typedef _Unwind_Word GetGRFn(_Unwind_Context* context, int index); 33*68d75effSDimitry Andric typedef _Unwind_Word GetCFAFn(_Unwind_Context* context); 34*68d75effSDimitry Andric 35*68d75effSDimitry Andric extern "C" SANITIZER_INTERFACE_ATTRIBUTE _Unwind_Reason_Code 36*68d75effSDimitry Andric __hwasan_personality_wrapper(int version, _Unwind_Action actions, 37*68d75effSDimitry Andric uint64_t exception_class, 38*68d75effSDimitry Andric _Unwind_Exception* unwind_exception, 39*68d75effSDimitry Andric _Unwind_Context* context, 40*68d75effSDimitry Andric PersonalityFn* real_personality, GetGRFn* get_gr, 41*68d75effSDimitry Andric GetCFAFn* get_cfa) { 42*68d75effSDimitry Andric _Unwind_Reason_Code rc; 43*68d75effSDimitry Andric if (real_personality) 44*68d75effSDimitry Andric rc = real_personality(version, actions, exception_class, unwind_exception, 45*68d75effSDimitry Andric context); 46*68d75effSDimitry Andric else 47*68d75effSDimitry Andric rc = _URC_CONTINUE_UNWIND; 48*68d75effSDimitry Andric 49*68d75effSDimitry Andric // We only untag frames without a landing pad because landing pads are 50*68d75effSDimitry Andric // responsible for untagging the stack themselves if they resume. 51*68d75effSDimitry Andric // 52*68d75effSDimitry Andric // Here we assume that the frame record appears after any locals. This is not 53*68d75effSDimitry Andric // required by AAPCS but is a requirement for HWASAN instrumented functions. 54*68d75effSDimitry Andric if ((actions & _UA_CLEANUP_PHASE) && rc == _URC_CONTINUE_UNWIND) { 55*68d75effSDimitry Andric #if defined(__x86_64__) 56*68d75effSDimitry Andric uptr fp = get_gr(context, 6); // rbp 57*68d75effSDimitry Andric #elif defined(__aarch64__) 58*68d75effSDimitry Andric uptr fp = get_gr(context, 29); // x29 59*68d75effSDimitry Andric #else 60*68d75effSDimitry Andric #error Unsupported architecture 61*68d75effSDimitry Andric #endif 62*68d75effSDimitry Andric uptr sp = get_cfa(context); 63*68d75effSDimitry Andric TagMemory(sp, fp - sp, 0); 64*68d75effSDimitry Andric } 65*68d75effSDimitry Andric 66*68d75effSDimitry Andric return rc; 67*68d75effSDimitry Andric } 68