121a18144SPeter Collingbourne //===-- hwasan_exceptions.cpp ---------------------------------------------===//
221a18144SPeter Collingbourne //
321a18144SPeter Collingbourne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
421a18144SPeter Collingbourne // See https://llvm.org/LICENSE.txt for license information.
521a18144SPeter Collingbourne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
621a18144SPeter Collingbourne //
721a18144SPeter Collingbourne //===----------------------------------------------------------------------===//
821a18144SPeter Collingbourne //
921a18144SPeter Collingbourne // This file is a part of HWAddressSanitizer.
1021a18144SPeter Collingbourne //
1121a18144SPeter Collingbourne // HWAddressSanitizer runtime.
1221a18144SPeter Collingbourne //===----------------------------------------------------------------------===//
1321a18144SPeter Collingbourne
1421a18144SPeter Collingbourne #include "hwasan_poisoning.h"
1521a18144SPeter Collingbourne #include "sanitizer_common/sanitizer_common.h"
1621a18144SPeter Collingbourne
1721a18144SPeter Collingbourne #include <unwind.h>
1821a18144SPeter Collingbourne
1921a18144SPeter Collingbourne using namespace __hwasan;
2021a18144SPeter Collingbourne using namespace __sanitizer;
2121a18144SPeter Collingbourne
2221a18144SPeter Collingbourne typedef _Unwind_Reason_Code PersonalityFn(int version, _Unwind_Action actions,
2321a18144SPeter Collingbourne uint64_t exception_class,
2421a18144SPeter Collingbourne _Unwind_Exception* unwind_exception,
2521a18144SPeter Collingbourne _Unwind_Context* context);
2621a18144SPeter Collingbourne
2721a18144SPeter Collingbourne // Pointers to the _Unwind_GetGR and _Unwind_GetCFA functions are passed in
2821a18144SPeter Collingbourne // instead of being called directly. This is to handle cases where the unwinder
2921a18144SPeter Collingbourne // is statically linked and the sanitizer runtime and the program are linked
3021a18144SPeter Collingbourne // against different unwinders. The _Unwind_Context data structure is opaque so
3121a18144SPeter Collingbourne // it may be incompatible between unwinders.
32815b9f53SFangrui Song typedef uintptr_t GetGRFn(_Unwind_Context* context, int index);
33815b9f53SFangrui Song typedef uintptr_t GetCFAFn(_Unwind_Context* context);
3421a18144SPeter Collingbourne
3533b758d2SPeter Collingbourne extern "C" SANITIZER_INTERFACE_ATTRIBUTE _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)3633b758d2SPeter Collingbourne __hwasan_personality_wrapper(int version, _Unwind_Action actions,
3733b758d2SPeter Collingbourne uint64_t exception_class,
3833b758d2SPeter Collingbourne _Unwind_Exception* unwind_exception,
3933b758d2SPeter Collingbourne _Unwind_Context* context,
4033b758d2SPeter Collingbourne PersonalityFn* real_personality, GetGRFn* get_gr,
4133b758d2SPeter Collingbourne GetCFAFn* get_cfa) {
4221a18144SPeter Collingbourne _Unwind_Reason_Code rc;
4321a18144SPeter Collingbourne if (real_personality)
4421a18144SPeter Collingbourne rc = real_personality(version, actions, exception_class, unwind_exception,
4521a18144SPeter Collingbourne context);
4621a18144SPeter Collingbourne else
4721a18144SPeter Collingbourne rc = _URC_CONTINUE_UNWIND;
4821a18144SPeter Collingbourne
4921a18144SPeter Collingbourne // We only untag frames without a landing pad because landing pads are
5021a18144SPeter Collingbourne // responsible for untagging the stack themselves if they resume.
5121a18144SPeter Collingbourne //
5221a18144SPeter Collingbourne // Here we assume that the frame record appears after any locals. This is not
5321a18144SPeter Collingbourne // required by AAPCS but is a requirement for HWASAN instrumented functions.
5421a18144SPeter Collingbourne if ((actions & _UA_CLEANUP_PHASE) && rc == _URC_CONTINUE_UNWIND) {
5521a18144SPeter Collingbourne #if defined(__x86_64__)
5621a18144SPeter Collingbourne uptr fp = get_gr(context, 6); // rbp
5721a18144SPeter Collingbourne #elif defined(__aarch64__)
5821a18144SPeter Collingbourne uptr fp = get_gr(context, 29); // x29
5938b04fd9SAlexey Baturo #elif SANITIZER_RISCV64
6038b04fd9SAlexey Baturo uptr fp = get_gr(context, 8); // x8
6121a18144SPeter Collingbourne #else
6221a18144SPeter Collingbourne #error Unsupported architecture
6321a18144SPeter Collingbourne #endif
6421a18144SPeter Collingbourne uptr sp = get_cfa(context);
65*5ac240bbSFlorian Mayer TagMemory(UntagAddr(sp), UntagAddr(fp) - UntagAddr(sp),
66*5ac240bbSFlorian Mayer GetTagFromPointer(sp));
6721a18144SPeter Collingbourne }
6821a18144SPeter Collingbourne
6921a18144SPeter Collingbourne return rc;
7021a18144SPeter Collingbourne }
71