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 19using namespace __hwasan; 20using namespace __sanitizer; 21 22typedef _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. 32typedef _Unwind_Word GetGRFn(_Unwind_Context* context, int index); 33typedef _Unwind_Word GetCFAFn(_Unwind_Context* context); 34 35extern "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#else 60#error Unsupported architecture 61#endif 62 uptr sp = get_cfa(context); 63 TagMemory(sp, fp - sp, 0); 64 } 65 66 return rc; 67} 68