Mercurial > hg > CbC > CbC_llvm
diff libunwind/test/forceunwind.pass.cpp @ 236:c4bab56944e8 llvm-original
LLVM 16
author | kono |
---|---|
date | Wed, 09 Nov 2022 17:45:10 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libunwind/test/forceunwind.pass.cpp Wed Nov 09 17:45:10 2022 +0900 @@ -0,0 +1,72 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: linux + +// TODO: Figure out why this fails with Memory Sanitizer. +// XFAIL: msan + +// Basic test for _Unwind_ForcedUnwind. +// See libcxxabi/test/forced_unwind* tests too. + +#undef NDEBUG +#include <assert.h> +#include <dlfcn.h> +#include <signal.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <unistd.h> +#include <unwind.h> + +void foo(); +_Unwind_Exception ex; + +_Unwind_Reason_Code stop(int version, _Unwind_Action actions, + _Unwind_Exception_Class exceptionClass, + _Unwind_Exception *exceptionObject, + struct _Unwind_Context *context, + void *stop_parameter) { + assert(version == 1); + assert((actions & _UA_FORCE_UNWIND) != 0); + (void)exceptionClass; + assert(exceptionObject == &ex); + assert(stop_parameter == &foo); + + Dl_info info = {0, 0, 0, 0}; + + // Unwind util the main is reached, above frames depend on the platform and + // architecture. + if (dladdr(reinterpret_cast<void *>(_Unwind_GetIP(context)), &info) && + info.dli_sname && !strcmp("main", info.dli_sname)) { + _Exit(0); + } + return _URC_NO_REASON; +} + +__attribute__((noinline)) void foo() { + + // Arm EHABI defines struct _Unwind_Control_Block as exception + // object. Ensure struct _Unwind_Exception* work there too, + // because _Unwind_Exception in this case is just an alias. + struct _Unwind_Exception *e = &ex; +#if defined(_LIBUNWIND_ARM_EHABI) + // Create a mock exception object. + memset(e, '\0', sizeof(*e)); + strcpy(reinterpret_cast<char *>(&e->exception_class), "CLNGUNW"); +#endif + _Unwind_ForcedUnwind(e, stop, (void *)&foo); +} + +int main() { + foo(); + return -2; +}