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