xref: /freebsd-src/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_exceptions.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
168d75effSDimitry Andric //===-- hwasan_exceptions.cpp ---------------------------------------------===//
268d75effSDimitry Andric //
368d75effSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
468d75effSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
568d75effSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
668d75effSDimitry Andric //
768d75effSDimitry Andric //===----------------------------------------------------------------------===//
868d75effSDimitry Andric //
968d75effSDimitry Andric // This file is a part of HWAddressSanitizer.
1068d75effSDimitry Andric //
1168d75effSDimitry Andric // HWAddressSanitizer runtime.
1268d75effSDimitry Andric //===----------------------------------------------------------------------===//
1368d75effSDimitry Andric 
1468d75effSDimitry Andric #include "hwasan_poisoning.h"
1568d75effSDimitry Andric #include "sanitizer_common/sanitizer_common.h"
1668d75effSDimitry Andric 
1768d75effSDimitry Andric #include <unwind.h>
1868d75effSDimitry Andric 
1968d75effSDimitry Andric using namespace __hwasan;
2068d75effSDimitry Andric using namespace __sanitizer;
2168d75effSDimitry Andric 
2268d75effSDimitry Andric typedef _Unwind_Reason_Code PersonalityFn(int version, _Unwind_Action actions,
2368d75effSDimitry Andric                                           uint64_t exception_class,
2468d75effSDimitry Andric                                           _Unwind_Exception* unwind_exception,
2568d75effSDimitry Andric                                           _Unwind_Context* context);
2668d75effSDimitry Andric 
2768d75effSDimitry Andric // Pointers to the _Unwind_GetGR and _Unwind_GetCFA functions are passed in
2868d75effSDimitry Andric // instead of being called directly. This is to handle cases where the unwinder
2968d75effSDimitry Andric // is statically linked and the sanitizer runtime and the program are linked
3068d75effSDimitry Andric // against different unwinders. The _Unwind_Context data structure is opaque so
3168d75effSDimitry Andric // it may be incompatible between unwinders.
32349cc55cSDimitry Andric typedef uintptr_t GetGRFn(_Unwind_Context* context, int index);
33349cc55cSDimitry Andric typedef uintptr_t GetCFAFn(_Unwind_Context* context);
3468d75effSDimitry Andric 
3568d75effSDimitry Andric 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)3668d75effSDimitry Andric __hwasan_personality_wrapper(int version, _Unwind_Action actions,
3768d75effSDimitry Andric                              uint64_t exception_class,
3868d75effSDimitry Andric                              _Unwind_Exception* unwind_exception,
3968d75effSDimitry Andric                              _Unwind_Context* context,
4068d75effSDimitry Andric                              PersonalityFn* real_personality, GetGRFn* get_gr,
4168d75effSDimitry Andric                              GetCFAFn* get_cfa) {
4268d75effSDimitry Andric   _Unwind_Reason_Code rc;
4368d75effSDimitry Andric   if (real_personality)
4468d75effSDimitry Andric     rc = real_personality(version, actions, exception_class, unwind_exception,
4568d75effSDimitry Andric                           context);
4668d75effSDimitry Andric   else
4768d75effSDimitry Andric     rc = _URC_CONTINUE_UNWIND;
4868d75effSDimitry Andric 
4968d75effSDimitry Andric   // We only untag frames without a landing pad because landing pads are
5068d75effSDimitry Andric   // responsible for untagging the stack themselves if they resume.
5168d75effSDimitry Andric   //
5268d75effSDimitry Andric   // Here we assume that the frame record appears after any locals. This is not
5368d75effSDimitry Andric   // required by AAPCS but is a requirement for HWASAN instrumented functions.
5468d75effSDimitry Andric   if ((actions & _UA_CLEANUP_PHASE) && rc == _URC_CONTINUE_UNWIND) {
5568d75effSDimitry Andric #if defined(__x86_64__)
5668d75effSDimitry Andric     uptr fp = get_gr(context, 6); // rbp
5768d75effSDimitry Andric #elif defined(__aarch64__)
5868d75effSDimitry Andric     uptr fp = get_gr(context, 29); // x29
59bdd1243dSDimitry Andric #elif SANITIZER_RISCV64
60bdd1243dSDimitry Andric     uptr fp = get_gr(context, 8);  // x8
6168d75effSDimitry Andric #else
6268d75effSDimitry Andric #error Unsupported architecture
6368d75effSDimitry Andric #endif
6468d75effSDimitry Andric     uptr sp = get_cfa(context);
65*06c3fb27SDimitry Andric     TagMemory(UntagAddr(sp), UntagAddr(fp) - UntagAddr(sp),
66*06c3fb27SDimitry Andric               GetTagFromPointer(sp));
6768d75effSDimitry Andric   }
6868d75effSDimitry Andric 
6968d75effSDimitry Andric   return rc;
7068d75effSDimitry Andric }
71