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