1e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh/*===---- unwind.h - Stack unwinding ----------------------------------------=== 2e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * 3e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * Permission is hereby granted, free of charge, to any person obtaining a copy 4e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * of this software and associated documentation files (the "Software"), to deal 5e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * in the Software without restriction, including without limitation the rights 6e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * copies of the Software, and to permit persons to whom the Software is 8e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * furnished to do so, subject to the following conditions: 9e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * 10e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * The above copyright notice and this permission notice shall be included in 11e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * all copies or substantial portions of the Software. 12e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * 13e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * THE SOFTWARE. 20e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * 21e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh *===-----------------------------------------------------------------------=== 22e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh */ 23e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 24e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh/* See "Data Definitions for libgcc_s" in the Linux Standard Base.*/ 25e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 26e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#ifndef __CLANG_UNWIND_H 27e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#define __CLANG_UNWIND_H 28e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 29e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#if __has_include_next(<unwind.h>) 30e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh/* Darwin and libunwind provide an unwind.h. If that's available, use 31e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * it. libunwind wraps some of its definitions in #ifdef _GNU_SOURCE, 32e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * so define that around the include.*/ 33e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# ifndef _GNU_SOURCE 34e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# define _SHOULD_UNDEFINE_GNU_SOURCE 35e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# define _GNU_SOURCE 36e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# endif 37e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh// libunwind's unwind.h reflects the current visibility. However, Mozilla 38e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh// builds with -fvisibility=hidden and relies on gcc's unwind.h to reset the 39e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh// visibility to default and export its contents. gcc also allows users to 40e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh// override its override by #defining HIDE_EXPORTS (but note, this only obeys 41e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh// the user's -fvisibility setting; it doesn't hide any exports on its own). We 42e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh// imitate gcc's header here: 43e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# ifdef HIDE_EXPORTS 44e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# include_next <unwind.h> 45e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# else 46e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# pragma GCC visibility push(default) 47e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# include_next <unwind.h> 48e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# pragma GCC visibility pop 49e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# endif 50e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# ifdef _SHOULD_UNDEFINE_GNU_SOURCE 51e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# undef _GNU_SOURCE 52e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# undef _SHOULD_UNDEFINE_GNU_SOURCE 53e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# endif 54e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#else 55e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 56e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#include <stdint.h> 57e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 58e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#ifdef __cplusplus 59e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehextern "C" { 60e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#endif 61e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 62e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh/* It is a bit strange for a header to play with the visibility of the 63e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh symbols it declares, but this matches gcc's behavior and some programs 64e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh depend on it */ 65e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#ifndef HIDE_EXPORTS 66e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#pragma GCC visibility push(default) 67e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#endif 68e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 69e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehstruct _Unwind_Context; 70e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehtypedef struct _Unwind_Context _Unwind_Context; 71e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehtypedef enum { 72e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _URC_NO_REASON = 0, 73e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _URC_FOREIGN_EXCEPTION_CAUGHT = 1, 74e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 75e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _URC_FATAL_PHASE2_ERROR = 2, 76e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _URC_FATAL_PHASE1_ERROR = 3, 77e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _URC_NORMAL_STOP = 4, 78e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 79e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _URC_END_OF_STACK = 5, 80e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _URC_HANDLER_FOUND = 6, 81e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _URC_INSTALL_CONTEXT = 7, 82e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _URC_CONTINUE_UNWIND = 8 83e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} _Unwind_Reason_Code; 84e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 85e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 86e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#ifdef __arm__ 87e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 88e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehtypedef enum { 89e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _UVRSC_CORE = 0, /* integer register */ 90e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _UVRSC_VFP = 1, /* vfp */ 91e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _UVRSC_WMMXD = 3, /* Intel WMMX data register */ 92e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _UVRSC_WMMXC = 4 /* Intel WMMX control register */ 93e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} _Unwind_VRS_RegClass; 94e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 95e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehtypedef enum { 96e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _UVRSD_UINT32 = 0, 97e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _UVRSD_VFPX = 1, 98e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _UVRSD_UINT64 = 3, 99e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _UVRSD_FLOAT = 4, 100e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _UVRSD_DOUBLE = 5 101e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} _Unwind_VRS_DataRepresentation; 102e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 103e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehtypedef enum { 104e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _UVRSR_OK = 0, 105e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _UVRSR_NOT_IMPLEMENTED = 1, 106e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _UVRSR_FAILED = 2 107e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} _Unwind_VRS_Result; 108e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 109e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh_Unwind_VRS_Result _Unwind_VRS_Get(struct _Unwind_Context *__context, 110e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _Unwind_VRS_RegClass __regclass, 111e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh uint32_t __regno, 112e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _Unwind_VRS_DataRepresentation __representation, 113e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh void *__valuep); 114e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 115e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehstatic inline uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { 116e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh uintptr_t ip = 0; 117e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh _Unwind_VRS_Get(context, _UVRSC_CORE, 15, _UVRSD_UINT32, &ip); 118e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh ip &= ~(uintptr_t)0x1; /* remove thumb mode bit */ 119e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return ip; 120e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 121e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 122e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#else 123e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 124e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehuintptr_t _Unwind_GetIP(struct _Unwind_Context* __context); 125e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 126e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#endif 127e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 128e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehtypedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context*, void*); 129e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh_Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void*); 130e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 131e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#ifndef HIDE_EXPORTS 132e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#pragma GCC visibility pop 133e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#endif 134e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 135e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#ifdef __cplusplus 136e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 137e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#endif 138e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 139e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#endif 140e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 141e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#endif /* __CLANG_UNWIND_H */ 142